Merge lp:~percona-toolkit-dev/percona-toolkit/fix-sync-ignore-bug-1002365-2.0 into lp:percona-toolkit/2.0

Proposed by Daniel Nichter
Status: Merged
Merged at revision: 245
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/fix-sync-ignore-bug-1002365-2.0
Merge into: lp:percona-toolkit/2.0
Diff against target: 2885 lines (+1834/-520)
11 files modified
bin/pt-table-sync (+580/-423)
lib/SchemaIterator.pm (+26/-44)
lib/TableChecksum.pm (+1/-2)
t/lib/SchemaIterator.t (+9/-50)
t/lib/samples/SchemaIterator/all-dbs-tbls-5.0.txt (+421/-0)
t/lib/samples/SchemaIterator/all-dbs-tbls.txt (+486/-0)
t/lib/samples/SchemaIterator/resume-from-ignored-sakila-payment-5.0.txt (+52/-0)
t/lib/samples/SchemaIterator/resume-from-ignored-sakila-payment.txt (+49/-0)
t/lib/samples/SchemaIterator/resume-from-sakila-payment-5.0.txt (+70/-0)
t/lib/samples/SchemaIterator/resume-from-sakila-payment.txt (+66/-0)
t/pt-table-sync/filters.t (+74/-1)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-sync-ignore-bug-1002365-2.0
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+108069@code.launchpad.net
To post a comment you must log in.
244. By Daniel Nichter

Update all modules in pt-table-sync.

Revision history for this message
Daniel Nichter (daniel-nichter) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bin/pt-table-sync'
--- bin/pt-table-sync 2012-05-24 17:52:01 +0000
+++ bin/pt-table-sync 2012-05-30 22:08:19 +0000
@@ -959,7 +959,7 @@
959 $opt->{value} = ($pre || '') . $num;959 $opt->{value} = ($pre || '') . $num;
960 }960 }
961 else {961 else {
962 $self->save_error("Invalid size for --$opt->{long}");962 $self->save_error("Invalid size for --$opt->{long}: $val");
963 }963 }
964 return;964 return;
965}965}
@@ -1288,12 +1288,14 @@
1288sub as_string {1288sub as_string {
1289 my ( $self, $dsn, $props ) = @_;1289 my ( $self, $dsn, $props ) = @_;
1290 return $dsn unless ref $dsn;1290 return $dsn unless ref $dsn;
1291 my %allowed = $props ? map { $_=>1 } @$props : ();1291 my @keys = $props ? @$props : sort keys %$dsn;
1292 return join(',',1292 return join(',',
1293 map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }1293 map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
1294 grep { defined $dsn->{$_} && $self->{opts}->{$_} }1294 grep {
1295 grep { !$props || $allowed{$_} }1295 exists $self->{opts}->{$_}
1296 sort keys %$dsn );1296 && exists $dsn->{$_}
1297 && defined $dsn->{$_}
1298 } @keys);
1297}1299}
12981300
1299sub usage {1301sub usage {
@@ -1744,19 +1746,58 @@
1744 return bless $self, $class;1746 return bless $self, $class;
1745}1747}
17461748
1749sub get_create_table {
1750 my ( $self, $dbh, $db, $tbl ) = @_;
1751 die "I need a dbh parameter" unless $dbh;
1752 die "I need a db parameter" unless $db;
1753 die "I need a tbl parameter" unless $tbl;
1754 my $q = $self->{Quoter};
1755
1756 my $new_sql_mode
1757 = '/*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, '
1758 . q{@@SQL_MODE := REPLACE(REPLACE(@@SQL_MODE, 'ANSI_QUOTES', ''), ',,', ','), }
1759 . '@OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, '
1760 . '@@SQL_QUOTE_SHOW_CREATE := 1 */';
1761
1762 my $old_sql_mode = '/*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, '
1763 . '@@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */';
1764
1765 PTDEBUG && _d($new_sql_mode);
1766 eval { $dbh->do($new_sql_mode); };
1767 PTDEBUG && $EVAL_ERROR && _d($EVAL_ERROR);
1768
1769 my $use_sql = 'USE ' . $q->quote($db);
1770 PTDEBUG && _d($dbh, $use_sql);
1771 $dbh->do($use_sql);
1772
1773 my $show_sql = "SHOW CREATE TABLE " . $q->quote($db, $tbl);
1774 PTDEBUG && _d($show_sql);
1775 my $href;
1776 eval { $href = $dbh->selectrow_hashref($show_sql); };
1777 if ( $EVAL_ERROR ) {
1778 PTDEBUG && _d($EVAL_ERROR);
1779
1780 PTDEBUG && _d($old_sql_mode);
1781 $dbh->do($old_sql_mode);
1782
1783 return;
1784 }
1785
1786 PTDEBUG && _d($old_sql_mode);
1787 $dbh->do($old_sql_mode);
1788
1789 my ($key) = grep { m/create (?:table|view)/i } keys %$href;
1790 if ( !$key ) {
1791 die "Error: no 'Create Table' or 'Create View' in result set from "
1792 . "$show_sql: " . Dumper($href);
1793 }
1794
1795 return $href->{$key};
1796}
1797
1747sub parse {1798sub parse {
1748 my ( $self, $ddl, $opts ) = @_;1799 my ( $self, $ddl, $opts ) = @_;
1749 return unless $ddl;1800 return unless $ddl;
1750 if ( ref $ddl eq 'ARRAY' ) {
1751 if ( lc $ddl->[0] eq 'table' ) {
1752 $ddl = $ddl->[1];
1753 }
1754 else {
1755 return {
1756 engine => 'VIEW',
1757 };
1758 }
1759 }
17601801
1761 if ( $ddl !~ m/CREATE (?:TEMPORARY )?TABLE `/ ) {1802 if ( $ddl !~ m/CREATE (?:TEMPORARY )?TABLE `/ ) {
1762 die "Cannot parse table definition; is ANSI quoting "1803 die "Cannot parse table definition; is ANSI quoting "
@@ -2063,41 +2104,31 @@
2063 return $ddl;2104 return $ddl;
2064}2105}
20652106
2066sub remove_secondary_indexes {2107sub get_table_status {
2067 my ( $self, $ddl ) = @_;2108 my ( $self, $dbh, $db, $like ) = @_;
2068 my $sec_indexes_ddl;2109 my $q = $self->{Quoter};
2069 my $tbl_struct = $self->parse($ddl);2110 my $sql = "SHOW TABLE STATUS FROM " . $q->quote($db);
20702111 my @params;
2071 if ( ($tbl_struct->{engine} || '') =~ m/InnoDB/i ) {2112 if ( $like ) {
2072 my $clustered_key = $tbl_struct->{clustered_key};2113 $sql .= ' LIKE ?';
2073 $clustered_key ||= '';2114 push @params, $like;
20742115 }
2075 my @sec_indexes = map {2116 PTDEBUG && _d($sql, @params);
2076 my $key_def = $_->{ddl};2117 my $sth = $dbh->prepare($sql);
2077 $key_def =~ s/([\(\)])/\\$1/g;2118 eval { $sth->execute(@params); };
2078 $ddl =~ s/\s+$key_def//i;2119 if ($EVAL_ERROR) {
20792120 PTDEBUG && _d($EVAL_ERROR);
2080 my $key_ddl = "ADD $_->{ddl}";2121 return;
2081 $key_ddl .= ',' unless $key_ddl =~ m/,$/;2122 }
2082 $key_ddl;2123 my @tables = @{$sth->fetchall_arrayref({})};
2083 }2124 @tables = map {
2084 grep { $_->{name} ne $clustered_key }2125 my %tbl; # Make a copy with lowercased keys
2085 values %{$tbl_struct->{keys}};2126 @tbl{ map { lc $_ } keys %$_ } = values %$_;
2086 PTDEBUG && _d('Secondary indexes:', Dumper(\@sec_indexes));2127 $tbl{engine} ||= $tbl{type} || $tbl{comment};
20872128 delete $tbl{type};
2088 if ( @sec_indexes ) {2129 \%tbl;
2089 $sec_indexes_ddl = join(' ', @sec_indexes);2130 } @tables;
2090 $sec_indexes_ddl =~ s/,$//;2131 return @tables;
2091 }
2092
2093 $ddl =~ s/,(\n\) )/$1/s;
2094 }
2095 else {
2096 PTDEBUG && _d('Not removing secondary indexes from',
2097 $tbl_struct->{engine}, 'table');
2098 }
2099
2100 return $ddl, $sec_indexes_ddl, $tbl_struct;
2101}2132}
21022133
2103sub _d {2134sub _d {
@@ -4220,10 +4251,9 @@
4220 . "FROM $table "4251 . "FROM $table "
4221 . "WHERE master_cnt <> this_cnt OR master_crc <> this_crc "4252 . "WHERE master_cnt <> this_cnt OR master_crc <> this_crc "
4222 . "OR ISNULL(master_crc) <> ISNULL(this_crc)";4253 . "OR ISNULL(master_crc) <> ISNULL(this_crc)";
4223
4224 PTDEBUG && _d($sql);4254 PTDEBUG && _d($sql);
4225 my $diffs = $dbh->selectall_arrayref($sql, { Slice => {} });4255 my $diffs = $dbh->selectall_arrayref($sql, { Slice => {} });
4226 return @$diffs;4256 return $diffs;
4227}4257}
42284258
4229sub _d {4259sub _d {
@@ -5448,11 +5478,12 @@
54485478
5449 eval {5479 eval {
5450 if ( my $timeout = $args{wait} ) {5480 if ( my $timeout = $args{wait} ) {
5451 my $wait = $args{wait_retry_args}->{wait} || 10;5481 my $ms = $self->{MasterSlave};
5452 my $tries = $args{wait_retry_args}->{tries} || 3;5482 my $tries = $args{wait_retry_args}->{tries} || 3;
5483 my $wait;
5453 $self->{Retry}->retry(5484 $self->{Retry}->retry(
5454 wait => sub { sleep $wait; },
5455 tries => $tries,5485 tries => $tries,
5486 wait => sub { sleep $args{wait_retry_args}->{wait} || 10 },
5456 try => sub {5487 try => sub {
5457 my ( %args ) = @_;5488 my ( %args ) = @_;
54585489
@@ -5460,12 +5491,18 @@
5460 warn "Retrying MASTER_POS_WAIT() for --wait $timeout...";5491 warn "Retrying MASTER_POS_WAIT() for --wait $timeout...";
5461 }5492 }
54625493
5463 my $ms = $self->{MasterSlave};5494 $wait = $ms->wait_for_master(
5464 my $wait = $ms->wait_for_master(
5465 master_status => $ms->get_master_status($src->{misc_dbh}),5495 master_status => $ms->get_master_status($src->{misc_dbh}),
5466 slave_dbh => $dst->{dbh},5496 slave_dbh => $dst->{dbh},
5467 timeout => $timeout,5497 timeout => $timeout,
5468 );5498 );
5499 if ( defined $wait->{result} && $wait->{result} != -1 ) {
5500 return; # slave caught up
5501 }
5502 die; # call fail
5503 },
5504 fail => sub {
5505 my (%args) = @_;
5469 if ( !defined $wait->{result} ) {5506 if ( !defined $wait->{result} ) {
5470 my $msg;5507 my $msg;
5471 if ( $wait->{waited} ) {5508 if ( $wait->{waited} ) {
@@ -5480,20 +5517,14 @@
5480 $msg .= " Sleeping $wait seconds then retrying "5517 $msg .= " Sleeping $wait seconds then retrying "
5481 . ($tries - $args{tryno}) . " more times.";5518 . ($tries - $args{tryno}) . " more times.";
5482 }5519 }
5483 warn $msg;5520 warn "$msg\n";
5484 return;5521 return 1; # call wait, call try
5485 }5522 }
5486 elsif ( $wait->{result} == -1 ) {5523 elsif ( $wait->{result} == -1 ) {
5487 die "Slave did not catch up to its master after waiting "5524 return 0; # call final_fail
5488 . "$timeout seconds with MASTER_POS_WAIT. Try inceasing "
5489 . "the --wait time, or disable this feature by specifying "
5490 . "--wait 0.";
5491 }
5492 else {
5493 return $result; # slave caught up
5494 }5525 }
5495 },5526 },
5496 on_failure => sub {5527 final_fail => sub {
5497 die "Slave did not catch up to its master after $tries attempts "5528 die "Slave did not catch up to its master after $tries attempts "
5498 . "of waiting $timeout seconds with MASTER_POS_WAIT. "5529 . "of waiting $timeout seconds with MASTER_POS_WAIT. "
5499 . "Check that the slave is running, increase the --wait "5530 . "Check that the slave is running, increase the --wait "
@@ -5606,23 +5637,21 @@
5606 die "I need a $arg argument" unless defined $args{$arg};5637 die "I need a $arg argument" unless defined $args{$arg};
5607 }5638 }
5608 my ($tbl_struct, $index) = @args{@required_args};5639 my ($tbl_struct, $index) = @args{@required_args};
5609 my @cols = $args{cols} ? @{$args{cols}} : @{$tbl_struct->{cols}};5640 my @cols = $args{cols} ? @{$args{cols}} : @{$tbl_struct->{cols}};
5610 my $q = $self->{Quoter};5641 my $q = $self->{Quoter};
56115642
5612 die "Index '$index' does not exist in table"5643 die "Index '$index' does not exist in table"
5613 unless exists $tbl_struct->{keys}->{$index};5644 unless exists $tbl_struct->{keys}->{$index};
5645 PTDEBUG && _d('Will ascend index', $index);
56145646
5615 my @asc_cols = @{$tbl_struct->{keys}->{$index}->{cols}};5647 my @asc_cols = @{$tbl_struct->{keys}->{$index}->{cols}};
5616 my @asc_slice;
5617
5618 @asc_cols = @{$tbl_struct->{keys}->{$index}->{cols}};
5619 PTDEBUG && _d('Will ascend index', $index);
5620 PTDEBUG && _d('Will ascend columns', join(', ', @asc_cols));
5621 if ( $args{asc_first} ) {5648 if ( $args{asc_first} ) {
5622 @asc_cols = $asc_cols[0];5649 @asc_cols = $asc_cols[0];
5623 PTDEBUG && _d('Ascending only first column');5650 PTDEBUG && _d('Ascending only first column');
5624 }5651 }
5652 PTDEBUG && _d('Will ascend columns', join(', ', @asc_cols));
56255653
5654 my @asc_slice;
5626 my %col_posn = do { my $i = 0; map { $_ => $i++ } @cols };5655 my %col_posn = do { my $i = 0; map { $_ => $i++ } @cols };
5627 foreach my $col ( @asc_cols ) {5656 foreach my $col ( @asc_cols ) {
5628 if ( !exists $col_posn{$col} ) {5657 if ( !exists $col_posn{$col} ) {
@@ -6723,292 +6752,427 @@
6723# ###########################################################################6752# ###########################################################################
67246753
6725# ###########################################################################6754# ###########################################################################
6726# SchemaIterator r71416755# SchemaIterator package
6727# Don't update this package!6756# This package is a copy without comments from the original. The original
6757# with comments and its test file can be found in the Bazaar repository at,
6758# lib/SchemaIterator.pm
6759# t/lib/SchemaIterator.t
6760# See https://launchpad.net/percona-toolkit for more information.
6728# ###########################################################################6761# ###########################################################################
6762{
6729package SchemaIterator;6763package SchemaIterator;
67306764
6731use strict;6765use strict;
6732use warnings FATAL => 'all';6766use warnings FATAL => 'all';
6733
6734use English qw(-no_match_vars);6767use English qw(-no_match_vars);
6768use constant PTDEBUG => $ENV{PTDEBUG} || 0;
6769
6735use Data::Dumper;6770use Data::Dumper;
6736$Data::Dumper::Indent = 1;6771$Data::Dumper::Indent = 1;
6737$Data::Dumper::Sortkeys = 1;6772$Data::Dumper::Sortkeys = 1;
6738$Data::Dumper::Quotekeys = 0;6773$Data::Dumper::Quotekeys = 0;
67396774
6740use constant PTDEBUG => $ENV{PTDEBUG} || 0;6775my $open_comment = qr{/\*!\d{5} };
6776my $tbl_name = qr{
6777 CREATE\s+
6778 (?:TEMPORARY\s+)?
6779 TABLE\s+
6780 (?:IF NOT EXISTS\s+)?
6781 ([^\(]+)
6782}x;
6783
67416784
6742sub new {6785sub new {
6743 my ( $class, %args ) = @_;6786 my ( $class, %args ) = @_;
6744 foreach my $arg ( qw(Quoter) ) {6787 my @required_args = qw(OptionParser TableParser Quoter);
6788 foreach my $arg ( @required_args ) {
6745 die "I need a $arg argument" unless $args{$arg};6789 die "I need a $arg argument" unless $args{$arg};
6746 }6790 }
6791
6792 my ($file_itr, $dbh) = @args{qw(file_itr dbh)};
6793 die "I need either a dbh or file_itr argument"
6794 if (!$dbh && !$file_itr) || ($dbh && $file_itr);
6795
6796 my %resume;
6797 if ( my $table = $args{resume} ) {
6798 PTDEBUG && _d('Will resume from or after', $table);
6799 my ($db, $tbl) = $args{Quoter}->split_unquote($table);
6800 die "Resume table must be database-qualified: $table"
6801 unless $db && $tbl;
6802 $resume{db} = $db;
6803 $resume{tbl} = $tbl;
6804 }
6805
6747 my $self = {6806 my $self = {
6748 %args,6807 %args,
6749 filter => undef,6808 resume => \%resume,
6750 dbs => [],6809 filters => _make_filters(%args),
6751 };6810 };
6811
6752 return bless $self, $class;6812 return bless $self, $class;
6753}6813}
67546814
6755sub make_filter {6815sub _make_filters {
6756 my ( $self, $o ) = @_;6816 my ( %args ) = @_;
6757 my @lines = (6817 my @required_args = qw(OptionParser Quoter);
6758 'sub {',
6759 ' my ( $dbh, $db, $tbl ) = @_;',
6760 ' my $engine = undef;',
6761 );
6762
6763
6764 my @permit_dbs = _make_filter('unless', '$db', $o->get('databases'))
6765 if $o->has('databases');
6766 my @reject_dbs = _make_filter('if', '$db', $o->get('ignore-databases'))
6767 if $o->has('ignore-databases');
6768 my @dbs_regex;
6769 if ( $o->has('databases-regex') && (my $p = $o->get('databases-regex')) ) {
6770 push @dbs_regex, " return 0 unless \$db && (\$db =~ m/$p/o);";
6771 }
6772 my @reject_dbs_regex;
6773 if ( $o->has('ignore-databases-regex')
6774 && (my $p = $o->get('ignore-databases-regex')) ) {
6775 push @reject_dbs_regex, " return 0 if \$db && (\$db =~ m/$p/o);";
6776 }
6777 if ( @permit_dbs || @reject_dbs || @dbs_regex || @reject_dbs_regex ) {
6778 push @lines,
6779 ' if ( $db ) {',
6780 (@permit_dbs ? @permit_dbs : ()),
6781 (@reject_dbs ? @reject_dbs : ()),
6782 (@dbs_regex ? @dbs_regex : ()),
6783 (@reject_dbs_regex ? @reject_dbs_regex : ()),
6784 ' }';
6785 }
6786
6787 if ( $o->has('tables') || $o->has('ignore-tables')
6788 || $o->has('ignore-tables-regex') ) {
6789
6790 my $have_qtbl = 0;
6791 my $have_only_qtbls = 0;
6792 my %qtbls;
6793
6794 my @permit_tbls;
6795 my @permit_qtbls;
6796 my %permit_qtbls;
6797 if ( $o->get('tables') ) {
6798 my %tbls;
6799 map {
6800 if ( $_ =~ m/\./ ) {
6801 $permit_qtbls{$_} = 1;
6802 }
6803 else {
6804 $tbls{$_} = 1;
6805 }
6806 } keys %{ $o->get('tables') };
6807 @permit_tbls = _make_filter('unless', '$tbl', \%tbls);
6808 @permit_qtbls = _make_filter('unless', '$qtbl', \%permit_qtbls);
6809
6810 if ( @permit_qtbls ) {
6811 push @lines,
6812 ' my $qtbl = ($db ? "$db." : "") . ($tbl ? $tbl : "");';
6813 $have_qtbl = 1;
6814 }
6815 }
6816
6817 my @reject_tbls;
6818 my @reject_qtbls;
6819 my %reject_qtbls;
6820 if ( $o->get('ignore-tables') ) {
6821 my %tbls;
6822 map {
6823 if ( $_ =~ m/\./ ) {
6824 $reject_qtbls{$_} = 1;
6825 }
6826 else {
6827 $tbls{$_} = 1;
6828 }
6829 } keys %{ $o->get('ignore-tables') };
6830 @reject_tbls= _make_filter('if', '$tbl', \%tbls);
6831 @reject_qtbls = _make_filter('if', '$qtbl', \%reject_qtbls);
6832
6833 if ( @reject_qtbls && !$have_qtbl ) {
6834 push @lines,
6835 ' my $qtbl = ($db ? "$db." : "") . ($tbl ? $tbl : "");';
6836 }
6837 }
6838
6839 if ( keys %permit_qtbls && !@permit_dbs ) {
6840 my $dbs = {};
6841 map {
6842 my ($db, undef) = split(/\./, $_);
6843 $dbs->{$db} = 1;
6844 } keys %permit_qtbls;
6845 PTDEBUG && _d('Adding restriction "--databases',
6846 (join(',', keys %$dbs) . '"'));
6847 if ( keys %$dbs ) {
6848 $o->set('databases', $dbs);
6849 return $self->make_filter($o);
6850 }
6851 }
6852
6853 my @tbls_regex;
6854 if ( $o->has('tables-regex') && (my $p = $o->get('tables-regex')) ) {
6855 push @tbls_regex, " return 0 unless \$tbl && (\$tbl =~ m/$p/o);";
6856 }
6857 my @reject_tbls_regex;
6858 if ( $o->has('ignore-tables-regex')
6859 && (my $p = $o->get('ignore-tables-regex')) ) {
6860 push @reject_tbls_regex,
6861 " return 0 if \$tbl && (\$tbl =~ m/$p/o);";
6862 }
6863
6864 my @get_eng;
6865 my @permit_engs;
6866 my @reject_engs;
6867 if ( ($o->has('engines') && $o->get('engines'))
6868 || ($o->has('ignore-engines') && $o->get('ignore-engines')) ) {
6869 push @get_eng,
6870 ' my $sql = "SHOW TABLE STATUS "',
6871 ' . ($db ? "FROM `$db`" : "")',
6872 ' . " LIKE \'$tbl\'";',
6873 ' PTDEBUG && _d($sql);',
6874 ' eval {',
6875 ' $engine = $dbh->selectrow_hashref($sql)->{engine};',
6876 ' };',
6877 ' PTDEBUG && $EVAL_ERROR && _d($EVAL_ERROR);',
6878 ' PTDEBUG && _d($tbl, "uses engine", $engine);',
6879 ' $engine = lc $engine if $engine;',
6880 @permit_engs
6881 = _make_filter('unless', '$engine', $o->get('engines'), 1);
6882 @reject_engs
6883 = _make_filter('if', '$engine', $o->get('ignore-engines'), 1)
6884 }
6885
6886 if ( @permit_tbls || @permit_qtbls || @reject_tbls || @tbls_regex
6887 || @reject_tbls_regex || @permit_engs || @reject_engs ) {
6888 push @lines,
6889 ' if ( $tbl ) {',
6890 (@permit_tbls ? @permit_tbls : ()),
6891 (@reject_tbls ? @reject_tbls : ()),
6892 (@tbls_regex ? @tbls_regex : ()),
6893 (@reject_tbls_regex ? @reject_tbls_regex : ()),
6894 (@permit_qtbls ? @permit_qtbls : ()),
6895 (@reject_qtbls ? @reject_qtbls : ()),
6896 (@get_eng ? @get_eng : ()),
6897 (@permit_engs ? @permit_engs : ()),
6898 (@reject_engs ? @reject_engs : ()),
6899 ' }';
6900 }
6901 }
6902
6903 push @lines,
6904 ' PTDEBUG && _d(\'Passes filters:\', $db, $tbl, $engine, $dbh);',
6905 ' return 1;', '}';
6906
6907 my $code = join("\n", @lines);
6908 PTDEBUG && _d('filter sub:', $code);
6909 my $filter_sub= eval $code
6910 or die "Error compiling subroutine code:\n$code\n$EVAL_ERROR";
6911
6912 return $filter_sub;
6913}
6914
6915sub set_filter {
6916 my ( $self, $filter_sub ) = @_;
6917 $self->{filter} = $filter_sub;
6918 PTDEBUG && _d('Set filter sub');
6919 return;
6920}
6921
6922sub get_db_itr {
6923 my ( $self, %args ) = @_;
6924 my @required_args = qw(dbh);
6925 foreach my $arg ( @required_args ) {6818 foreach my $arg ( @required_args ) {
6926 die "I need a $arg argument" unless $args{$arg};6819 die "I need a $arg argument" unless $args{$arg};
6927 }6820 }
6928 my ($dbh) = @args{@required_args};6821 my ($o, $q) = @args{@required_args};
69296822
6930 my $filter = $self->{filter};6823 my %filters;
6931 my @dbs;6824
6932 eval {6825
6826 my @simple_filters = qw(
6827 databases tables engines
6828 ignore-databases ignore-tables ignore-engines);
6829 FILTER:
6830 foreach my $filter ( @simple_filters ) {
6831 if ( $o->has($filter) ) {
6832 my $objs = $o->get($filter);
6833 next FILTER unless $objs && scalar keys %$objs;
6834 my $is_table = $filter =~ m/table/ ? 1 : 0;
6835 foreach my $obj ( keys %$objs ) {
6836 die "Undefined value for --$filter" unless $obj;
6837 $obj = lc $obj;
6838 if ( $is_table ) {
6839 my ($db, $tbl) = $q->split_unquote($obj);
6840 $db ||= '*';
6841 PTDEBUG && _d('Filter', $filter, 'value:', $db, $tbl);
6842 $filters{$filter}->{$tbl} = $db;
6843 }
6844 else { # database
6845 PTDEBUG && _d('Filter', $filter, 'value:', $obj);
6846 $filters{$filter}->{$obj} = 1;
6847 }
6848 }
6849 }
6850 }
6851
6852 my @regex_filters = qw(
6853 databases-regex tables-regex
6854 ignore-databases-regex ignore-tables-regex);
6855 REGEX_FILTER:
6856 foreach my $filter ( @regex_filters ) {
6857 if ( $o->has($filter) ) {
6858 my $pat = $o->get($filter);
6859 next REGEX_FILTER unless $pat;
6860 $filters{$filter} = qr/$pat/;
6861 PTDEBUG && _d('Filter', $filter, 'value:', $filters{$filter});
6862 }
6863 }
6864
6865 PTDEBUG && _d('Schema object filters:', Dumper(\%filters));
6866 return \%filters;
6867}
6868
6869sub next {
6870 my ( $self ) = @_;
6871
6872 if ( !$self->{initialized} ) {
6873 $self->{initialized} = 1;
6874 if ( $self->{resume}->{tbl}
6875 && !$self->table_is_allowed(@{$self->{resume}}{qw(db tbl)}) ) {
6876 PTDEBUG && _d('Will resume after',
6877 join('.', @{$self->{resume}}{qw(db tbl)}));
6878 $self->{resume}->{after} = 1;
6879 }
6880 }
6881
6882 my $schema_obj;
6883 if ( $self->{file_itr} ) {
6884 $schema_obj= $self->_iterate_files();
6885 }
6886 else { # dbh
6887 $schema_obj= $self->_iterate_dbh();
6888 }
6889
6890 if ( $schema_obj ) {
6891 if ( my $schema = $self->{Schema} ) {
6892 $schema->add_schema_object($schema_obj);
6893 }
6894 PTDEBUG && _d('Next schema object:',
6895 $schema_obj->{db}, $schema_obj->{tbl});
6896 }
6897
6898 return $schema_obj;
6899}
6900
6901sub _iterate_files {
6902 my ( $self ) = @_;
6903
6904 if ( !$self->{fh} ) {
6905 my ($fh, $file) = $self->{file_itr}->();
6906 if ( !$fh ) {
6907 PTDEBUG && _d('No more files to iterate');
6908 return;
6909 }
6910 $self->{fh} = $fh;
6911 $self->{file} = $file;
6912 }
6913 my $fh = $self->{fh};
6914 PTDEBUG && _d('Getting next schema object from', $self->{file});
6915
6916 local $INPUT_RECORD_SEPARATOR = '';
6917 CHUNK:
6918 while (defined(my $chunk = <$fh>)) {
6919 if ($chunk =~ m/Database: (\S+)/) {
6920 my $db = $1; # XXX
6921 $db =~ s/^`//; # strip leading `
6922 $db =~ s/`$//; # and trailing `
6923 if ( $self->database_is_allowed($db)
6924 && $self->_resume_from_database($db) ) {
6925 $self->{db} = $db;
6926 }
6927 }
6928 elsif ($self->{db} && $chunk =~ m/CREATE TABLE/) {
6929 if ($chunk =~ m/DROP VIEW IF EXISTS/) {
6930 PTDEBUG && _d('Table is a VIEW, skipping');
6931 next CHUNK;
6932 }
6933
6934 my ($tbl) = $chunk =~ m/$tbl_name/;
6935 $tbl =~ s/^\s*`//;
6936 $tbl =~ s/`\s*$//;
6937 if ( $self->_resume_from_table($tbl)
6938 && $self->table_is_allowed($self->{db}, $tbl) ) {
6939 my ($ddl) = $chunk =~ m/^(?:$open_comment)?(CREATE TABLE.+?;)$/ms;
6940 if ( !$ddl ) {
6941 warn "Failed to parse CREATE TABLE from\n" . $chunk;
6942 next CHUNK;
6943 }
6944 $ddl =~ s/ \*\/;\Z/;/; # remove end of version comment
6945 my $tbl_struct = $self->{TableParser}->parse($ddl);
6946 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
6947 return {
6948 db => $self->{db},
6949 tbl => $tbl,
6950 name => $self->{Quoter}->quote($self->{db}, $tbl),
6951 ddl => $ddl,
6952 tbl_struct => $tbl_struct,
6953 };
6954 }
6955 }
6956 }
6957 } # CHUNK
6958
6959 PTDEBUG && _d('No more schema objects in', $self->{file});
6960 close $self->{fh};
6961 $self->{fh} = undef;
6962
6963 return $self->_iterate_files();
6964}
6965
6966sub _iterate_dbh {
6967 my ( $self ) = @_;
6968 my $q = $self->{Quoter};
6969 my $tp = $self->{TableParser};
6970 my $dbh = $self->{dbh};
6971 PTDEBUG && _d('Getting next schema object from dbh', $dbh);
6972
6973 if ( !defined $self->{dbs} ) {
6933 my $sql = 'SHOW DATABASES';6974 my $sql = 'SHOW DATABASES';
6934 PTDEBUG && _d($sql);6975 PTDEBUG && _d($sql);
6935 @dbs = grep {6976 my @dbs = grep { $self->database_is_allowed($_) }
6936 my $ok = $filter ? $filter->($dbh, $_, undef) : 1;6977 @{$dbh->selectcol_arrayref($sql)};
6937 $ok = 0 if $_ =~ m/information_schema|performance_schema|lost\+found/;
6938 $ok;
6939 } @{ $dbh->selectcol_arrayref($sql) };
6940 PTDEBUG && _d('Found', scalar @dbs, 'databases');6978 PTDEBUG && _d('Found', scalar @dbs, 'databases');
6941 };6979 $self->{dbs} = \@dbs;
69426980 }
6943 PTDEBUG && $EVAL_ERROR && _d($EVAL_ERROR);6981
6944 my $iterator = sub {6982 if ( !$self->{db} ) {
6945 return shift @dbs;6983 do {
6946 };6984 $self->{db} = shift @{$self->{dbs}};
69476985 } until $self->_resume_from_database($self->{db});
6948 if (wantarray) {6986 PTDEBUG && _d('Next database:', $self->{db});
6949 return ($iterator, scalar @dbs);6987 return unless $self->{db};
6950 }6988 }
6951 else {6989
6952 return $iterator;6990 if ( !defined $self->{tbls} ) {
6953 }6991 my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM ' . $q->quote($self->{db});
6954}6992 PTDEBUG && _d($sql);
69556993 my @tbls = map {
6956sub get_tbl_itr {6994 $_->[0]; # (tbl, type)
6957 my ( $self, %args ) = @_;6995 }
6958 my @required_args = qw(dbh db);6996 grep {
6959 foreach my $arg ( @required_args ) {6997 my ($tbl, $type) = @$_;
6960 die "I need a $arg argument" unless $args{$arg};6998 (!$type || ($type ne 'VIEW'))
6961 }6999 && $self->_resume_from_table($tbl)
6962 my ($dbh, $db, $views) = @args{@required_args, 'views'};7000 && $self->table_is_allowed($self->{db}, $tbl);
69637001 }
6964 my $filter = $self->{filter};7002 @{$dbh->selectall_arrayref($sql)};
6965 my @tbls;7003 PTDEBUG && _d('Found', scalar @tbls, 'tables in database', $self->{db});
6966 if ( $db ) {7004 $self->{tbls} = \@tbls;
6967 eval {7005 }
6968 my $sql = 'SHOW /*!50002 FULL*/ TABLES FROM '7006
6969 . $self->{Quoter}->quote($db);7007 while ( my $tbl = shift @{$self->{tbls}} ) {
6970 PTDEBUG && _d($sql);7008 my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);
6971 @tbls = map {7009 my $tbl_struct = $tp->parse($ddl);
6972 $_->[0]7010 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
6973 }7011 return {
6974 grep {7012 db => $self->{db},
6975 my ($tbl, $type) = @$_;7013 tbl => $tbl,
6976 my $ok = $filter ? $filter->($dbh, $db, $tbl) : 1;7014 name => $q->quote($self->{db}, $tbl),
6977 if ( !$views ) {7015 ddl => $ddl,
6978 $ok = 0 if ($type || '') eq 'VIEW';7016 tbl_struct => $tbl_struct,
6979 }7017 };
6980 $ok;7018 }
6981 }7019 }
6982 @{ $dbh->selectall_arrayref($sql) };7020
6983 PTDEBUG && _d('Found', scalar @tbls, 'tables in', $db);7021 PTDEBUG && _d('No more tables in database', $self->{db});
6984 };7022 $self->{db} = undef;
6985 PTDEBUG && $EVAL_ERROR && _d($EVAL_ERROR);7023 $self->{tbls} = undef;
6986 }7024
6987 else {7025 return $self->_iterate_dbh();
6988 PTDEBUG && _d('No db given so no tables');7026}
6989 }7027
69907028sub database_is_allowed {
6991 my $iterator = sub {7029 my ( $self, $db ) = @_;
6992 return shift @tbls;7030 die "I need a db argument" unless $db;
6993 };7031
69947032 $db = lc $db;
6995 if ( wantarray ) {7033
6996 return ($iterator, scalar @tbls);7034 my $filter = $self->{filters};
6997 }7035
6998 else {7036 if ( $db =~ m/information_schema|performance_schema|lost\+found/ ) {
6999 return $iterator;7037 PTDEBUG && _d('Database', $db, 'is a system database, ignoring');
7000 }7038 return 0;
7001}7039 }
70027040
7003sub _make_filter {7041 if ( $self->{filters}->{'ignore-databases'}->{$db} ) {
7004 my ( $cond, $var_name, $objs, $lc ) = @_;7042 PTDEBUG && _d('Database', $db, 'is in --ignore-databases list');
7005 my @lines;7043 return 0;
7006 if ( scalar keys %$objs ) {7044 }
7007 my $test = join(' || ',7045
7008 map { "$var_name eq '" . ($lc ? lc $_ : $_) ."'" } keys %$objs);7046 if ( $filter->{'ignore-databases-regex'}
7009 push @lines, " return 0 $cond $var_name && ($test);",7047 && $db =~ $filter->{'ignore-databases-regex'} ) {
7010 }7048 PTDEBUG && _d('Database', $db, 'matches --ignore-databases-regex');
7011 return @lines;7049 return 0;
7050 }
7051
7052 if ( $filter->{'databases'}
7053 && !$filter->{'databases'}->{$db} ) {
7054 PTDEBUG && _d('Database', $db, 'is not in --databases list, ignoring');
7055 return 0;
7056 }
7057
7058 if ( $filter->{'databases-regex'}
7059 && $db !~ $filter->{'databases-regex'} ) {
7060 PTDEBUG && _d('Database', $db, 'does not match --databases-regex, ignoring');
7061 return 0;
7062 }
7063
7064 return 1;
7065}
7066
7067sub table_is_allowed {
7068 my ( $self, $db, $tbl ) = @_;
7069 die "I need a db argument" unless $db;
7070 die "I need a tbl argument" unless $tbl;
7071
7072 $db = lc $db;
7073 $tbl = lc $tbl;
7074
7075 my $filter = $self->{filters};
7076
7077 if ( $db eq 'mysql' && ($tbl eq 'general_log' || $tbl eq 'slow_log') ) {
7078 return 0;
7079 }
7080
7081 if ( $filter->{'ignore-tables'}->{$tbl}
7082 && ($filter->{'ignore-tables'}->{$tbl} eq '*'
7083 || $filter->{'ignore-tables'}->{$tbl} eq $db) ) {
7084 PTDEBUG && _d('Table', $tbl, 'is in --ignore-tables list');
7085 return 0;
7086 }
7087
7088 if ( $filter->{'ignore-tables-regex'}
7089 && $tbl =~ $filter->{'ignore-tables-regex'} ) {
7090 PTDEBUG && _d('Table', $tbl, 'matches --ignore-tables-regex');
7091 return 0;
7092 }
7093
7094 if ( $filter->{'tables'}
7095 && !$filter->{'tables'}->{$tbl} ) {
7096 PTDEBUG && _d('Table', $tbl, 'is not in --tables list, ignoring');
7097 return 0;
7098 }
7099
7100 if ( $filter->{'tables-regex'}
7101 && $tbl !~ $filter->{'tables-regex'} ) {
7102 PTDEBUG && _d('Table', $tbl, 'does not match --tables-regex, ignoring');
7103 return 0;
7104 }
7105
7106 if ( $filter->{'tables'}
7107 && $filter->{'tables'}->{$tbl}
7108 && $filter->{'tables'}->{$tbl} ne '*'
7109 && $filter->{'tables'}->{$tbl} ne $db ) {
7110 PTDEBUG && _d('Table', $tbl, 'is only allowed in database',
7111 $filter->{'tables'}->{$tbl});
7112 return 0;
7113 }
7114
7115 return 1;
7116}
7117
7118sub engine_is_allowed {
7119 my ( $self, $engine ) = @_;
7120
7121 if ( !$engine ) {
7122 PTDEBUG && _d('No engine specified; allowing the table');
7123 return 1;
7124 }
7125
7126 $engine = lc $engine;
7127
7128 my $filter = $self->{filters};
7129
7130 if ( $filter->{'ignore-engines'}->{$engine} ) {
7131 PTDEBUG && _d('Engine', $engine, 'is in --ignore-databases list');
7132 return 0;
7133 }
7134
7135 if ( $filter->{'engines'}
7136 && !$filter->{'engines'}->{$engine} ) {
7137 PTDEBUG && _d('Engine', $engine, 'is not in --engines list, ignoring');
7138 return 0;
7139 }
7140
7141 return 1;
7142}
7143
7144sub _resume_from_database {
7145 my ($self, $db) = @_;
7146
7147 return 1 unless $self->{resume}->{db};
7148
7149 if ( $db eq $self->{resume}->{db} ) {
7150 PTDEBUG && _d('At resume db', $db);
7151 delete $self->{resume}->{db};
7152 return 1;
7153 }
7154
7155 return 0;
7156}
7157
7158sub _resume_from_table {
7159 my ($self, $tbl) = @_;
7160
7161 return 1 unless $self->{resume}->{tbl};
7162
7163 if ( $tbl eq $self->{resume}->{tbl} ) {
7164 if ( !$self->{resume}->{after} ) {
7165 PTDEBUG && _d('Resuming from table', $tbl);
7166 delete $self->{resume}->{tbl};
7167 return 1;
7168 }
7169 else {
7170 PTDEBUG && _d('Resuming after table', $tbl);
7171 delete $self->{resume}->{tbl};
7172 }
7173 }
7174
7175 return 0;
7012}7176}
70137177
7014sub _d {7178sub _d {
@@ -7020,7 +7184,7 @@
7020}7184}
70217185
70221;71861;
70237187}
7024# ###########################################################################7188# ###########################################################################
7025# End SchemaIterator package7189# End SchemaIterator package
7026# ###########################################################################7190# ###########################################################################
@@ -7307,48 +7471,42 @@
73077471
7308sub retry {7472sub retry {
7309 my ( $self, %args ) = @_;7473 my ( $self, %args ) = @_;
7310 my @required_args = qw(try wait);7474 my @required_args = qw(try fail final_fail);
7311 foreach my $arg ( @required_args ) {7475 foreach my $arg ( @required_args ) {
7312 die "I need a $arg argument" unless $args{$arg};7476 die "I need a $arg argument" unless $args{$arg};
7313 };7477 };
7314 my ($try, $wait) = @args{@required_args};7478 my ($try, $fail, $final_fail) = @args{@required_args};
7479 my $wait = $args{wait} || sub { sleep 1; };
7315 my $tries = $args{tries} || 3;7480 my $tries = $args{tries} || 3;
73167481
7482 my $last_error;
7317 my $tryno = 0;7483 my $tryno = 0;
7484 TRY:
7318 while ( ++$tryno <= $tries ) {7485 while ( ++$tryno <= $tries ) {
7319 PTDEBUG && _d("Retry", $tryno, "of", $tries);7486 PTDEBUG && _d("Try", $tryno, "of", $tries);
7320 my $result;7487 my $result;
7321 eval {7488 eval {
7322 $result = $try->(tryno=>$tryno);7489 $result = $try->(tryno=>$tryno);
7323 };7490 };
7491 if ( $EVAL_ERROR ) {
7492 PTDEBUG && _d("Try code failed:", $EVAL_ERROR);
7493 $last_error = $EVAL_ERROR;
73247494
7325 if ( defined $result ) {7495 if ( $tryno < $tries ) { # more retries
7496 my $retry = $fail->(tryno=>$tryno, error=>$last_error);
7497 last TRY unless $retry;
7498 PTDEBUG && _d("Calling wait code");
7499 $wait->(tryno=>$tryno);
7500 }
7501 }
7502 else {
7326 PTDEBUG && _d("Try code succeeded");7503 PTDEBUG && _d("Try code succeeded");
7327 if ( my $on_success = $args{on_success} ) {
7328 PTDEBUG && _d("Calling on_success code");
7329 $on_success->(tryno=>$tryno, result=>$result);
7330 }
7331 return $result;7504 return $result;
7332 }7505 }
73337506 }
7334 if ( $EVAL_ERROR ) {7507
7335 PTDEBUG && _d("Try code died:", $EVAL_ERROR);7508 PTDEBUG && _d('Try code did not succeed');
7336 die $EVAL_ERROR unless $args{retry_on_die};7509 return $final_fail->(error=>$last_error);
7337 }
7338
7339 if ( $tryno < $tries ) {
7340 PTDEBUG && _d("Try code failed, calling wait code");
7341 $wait->(tryno=>$tryno);
7342 }
7343 }
7344
7345 PTDEBUG && _d("Try code did not succeed");
7346 if ( my $on_failure = $args{on_failure} ) {
7347 PTDEBUG && _d("Calling on_failure code");
7348 $on_failure->();
7349 }
7350
7351 return;
7352}7510}
73537511
7354sub _d {7512sub _d {
@@ -7824,11 +7982,16 @@
7824 tbl => undef, # set later7982 tbl => undef, # set later
7825 };7983 };
78267984
7827 # Filters for --databases and --tables. We have to do these manually7985 # Used to filter which tables are synced.
7828 # since we don't use MySQLFind for --replicate.7986 # https://bugs.launchpad.net/percona-toolkit/+bug/1002365
7829 my $databases = $o->get('databases');7987 my $schema_iter = new SchemaIterator(
7830 my $tables = $o->get('tables');7988 dbh => $src->{dbh},
7989 OptionParser => $o,
7990 TableParser => $args{TableParser},
7991 Quoter => $args{Quoter},
7992 );
78317993
7994 my %skip_table;
7832 my $exit_status = 0;7995 my $exit_status = 0;
78337996
7834 # Connect to the master and treat it as the source, then find7997 # Connect to the master and treat it as the source, then find
@@ -7844,30 +8007,29 @@
78448007
7845 # First, check that the master (source) has no discrepancies itself,8008 # First, check that the master (source) has no discrepancies itself,
7846 # and ignore tables that do.8009 # and ignore tables that do.
7847 my %skip_table;8010 my $src_diffs = $checksum->find_replication_differences(
7848 map { $skip_table{$_->{db}}->{$_->{tbl}}++ }8011 $src->{dbh}, $o->get('replicate'));
7849 $checksum->find_replication_differences(8012 map { $skip_table{lc $_->{db}}->{lc $_->{tbl}}++ } @$src_diffs;
7850 $src->{dbh}, $o->get('replicate'));
78518013
7852 # Now check the slave for differences and sync them if necessary.8014 # Now check the slave for differences and sync them if necessary.
7853 my @diffs = filter_diffs(8015 my $dst_diffs = $checksum->find_replication_differences(
7854 \%skip_table,8016 $dst->{dbh}, $o->get('replicate'));
7855 $databases,8017 my $diffs = filter_diffs(
7856 $tables,8018 diffs => $dst_diffs,
7857 $checksum->find_replication_differences(8019 SchemaIterator => $schema_iter,
7858 $dst->{dbh}, $o->get('replicate'))8020 skip_table => \%skip_table,
7859 );8021 );
78608022
7861 if ( $o->get('verbose') ) {8023 if ( $o->get('verbose') ) {
7862 print_header("# Syncing via replication " . $dp->as_string($dst->{dsn})8024 print_header("# Syncing via replication " .$dp->as_string($dst->{dsn})
7863 . ($o->get('dry-run') ?8025 . ($o->get('dry-run') ?
7864 ' in dry-run mode, without accessing or comparing data' : ''));8026 ' in dry-run mode, without accessing or comparing data' : ''));
7865 }8027 }
78668028
7867 if ( @diffs ) {8029 if ( $diffs && scalar @$diffs ) {
7868 lock_server(src => $src, dst => $dst, %args);8030 lock_server(src => $src, dst => $dst, %args);
78698031
7870 foreach my $diff ( @diffs ) {8032 foreach my $diff ( @$diffs ) {
7871 $src->{db} = $dst->{db} = $diff->{db};8033 $src->{db} = $dst->{db} = $diff->{db};
7872 $src->{tbl} = $dst->{tbl} = $diff->{tbl};8034 $src->{tbl} = $dst->{tbl} = $diff->{tbl};
78738035
@@ -7892,7 +8054,6 @@
7892 # The DSN is the master. Connect to each slave, find differences,8054 # The DSN is the master. Connect to each slave, find differences,
7893 # then sync them.8055 # then sync them.
7894 else {8056 else {
7895 my %skip_table;
7896 $ms->recurse_to_slaves(8057 $ms->recurse_to_slaves(
7897 { dbh => $src->{dbh},8058 { dbh => $src->{dbh},
7898 dsn => $src->{dsn},8059 dsn => $src->{dsn},
@@ -7900,20 +8061,20 @@
7900 recurse => 1,8061 recurse => 1,
7901 callback => sub {8062 callback => sub {
7902 my ( $dsn, $dbh, $level, $parent ) = @_;8063 my ( $dsn, $dbh, $level, $parent ) = @_;
7903 my @diffs = $checksum8064 my $all_diffs = $checksum->find_replication_differences(
7904 ->find_replication_differences($dbh, $o->get('replicate'));8065 $dbh, $o->get('replicate'));
7905 if ( !$level ) {8066 if ( !$level ) {
7906 # This is the master; don't sync any tables that are wrong8067 # This is the master; don't sync any tables that are wrong
7907 # here, for obvious reasons.8068 # here, for obvious reasons.
7908 map { $skip_table{$_->{db}}->{$_->{tbl}}++ } @diffs;8069 map { $skip_table{lc $_->{db}}->{lc $_->{tbl}}++ }
8070 @$all_diffs;
7909 }8071 }
7910 else {8072 else {
7911 # This is a slave.8073 # This is a slave.
7912 @diffs = filter_diffs(8074 my $diffs = filter_diffs(
7913 \%skip_table,8075 diffs => $all_diffs,
7914 $databases,8076 SchemaIterator => $schema_iter,
7915 $tables,8077 skip_table => \%skip_table,
7916 @diffs
7917 );8078 );
79188079
7919 if ( $o->get('verbose') ) {8080 if ( $o->get('verbose') ) {
@@ -7925,7 +8086,7 @@
7925 : ''));8086 : ''));
7926 }8087 }
79278088
7928 if ( @diffs ) {8089 if ( $diffs && scalar @$diffs ) {
7929 my $dst = {8090 my $dst = {
7930 dsn => $dsn,8091 dsn => $dsn,
7931 dbh => $dbh,8092 dbh => $dbh,
@@ -7936,7 +8097,7 @@
79368097
7937 lock_server(src => $src, dst => $dst, %args);8098 lock_server(src => $src, dst => $dst, %args);
79388099
7939 foreach my $diff ( @diffs ) {8100 foreach my $diff ( @$diffs ) {
7940 $src->{db} = $dst->{db} = $diff->{db};8101 $src->{db} = $dst->{db} = $diff->{db};
7941 $src->{tbl} = $dst->{tbl} = $diff->{tbl};8102 $src->{tbl} = $dst->{tbl} = $diff->{tbl};
79428103
@@ -8009,27 +8170,20 @@
8009 tbl => undef, # set later8170 tbl => undef, # set later
8010 };8171 };
80118172
8012 my $si = new SchemaIterator(8173 my $schema_iter = new SchemaIterator(
8013 Quoter => $args{Quoter},8174 dbh => $src->{dbh},
8175 OptionParser => $o,
8176 TableParser => $args{TableParser},
8177 Quoter => $args{Quoter},
8014 );8178 );
8015 $si->set_filter($si->make_filter($o));
80168179
8017 # Make a list of all dbs.tbls on the source. It's more efficient this8180 # Make a list of all dbs.tbls on the source. It's more efficient this
8018 # way because it avoids open/closing a dbh for each tbl and dsn, unless8181 # way because it avoids open/closing a dbh for each tbl and dsn, unless
8019 # we pre-opened the dsn. It would also cause confusing verbose output.8182 # we pre-opened the dsn. It would also cause confusing verbose output.
8020 my @dbs_tbls;8183 my @dbs_tbls;
8021 my $next_db = $si->get_db_itr(dbh => $src->{dbh});8184 while ( my $tbl = $schema_iter->next() ) {
8022 while ( my $db = $next_db->() ) {8185 PTDEBUG && _d('Got table', $tbl->{db}, $tbl->{tbl});
8023 PTDEBUG && _d('Getting tables from', $db);8186 push @dbs_tbls, $tbl;
8024 my $next_tbl = $si->get_tbl_itr(
8025 dbh => $src->{dbh},
8026 db => $db,
8027 views => 0,
8028 );
8029 while ( my $tbl = $next_tbl->() ) {
8030 PTDEBUG && _d('Got table', $tbl);
8031 push @dbs_tbls, { db => $db, tbl => $tbl };
8032 }
8033 }8187 }
80348188
8035 my $exit_status = 0;8189 my $exit_status = 0;
@@ -8578,19 +8732,16 @@
8578 # this isn't always the case.8732 # this isn't always the case.
8579 my $src_tbl_ddl;8733 my $src_tbl_ddl;
8580 eval {8734 eval {
8581 # FYI: get_create_table() does USE db but doesn't eval it.8735 $src_tbl_ddl = $tp->get_create_table(
8582 $src->{dbh}->do("USE `$src->{db}`");8736 $src->{dbh}, $src->{db}, $src->{tbl});
8583 $src_tbl_ddl = $du->get_create_table($src->{dbh}, $q,
8584 $src->{db}, $src->{tbl});
8585 };8737 };
8586 die $EVAL_ERROR if $EVAL_ERROR;8738 die $EVAL_ERROR if $EVAL_ERROR;
85878739
8588 my $dst_tbl_ddl;8740 my $dst_tbl_ddl;
8589 eval {8741 eval {
8590 # FYI: get_create_table() does USE db but doesn't eval it.8742 # FYI: get_create_table() does USE db but doesn't eval it.
8591 $dst->{dbh}->do("USE `$dst->{db}`");8743 $dst_tbl_ddl = $tp->get_create_table(
8592 $dst_tbl_ddl = $du->get_create_table($dst->{dbh}, $q,8744 $dst->{dbh}, $dst->{db}, $dst->{tbl});
8593 $dst->{db}, $dst->{tbl});
8594 };8745 };
8595 die $EVAL_ERROR if $EVAL_ERROR;8746 die $EVAL_ERROR if $EVAL_ERROR;
85968747
@@ -8640,22 +8791,28 @@
8640# filters. This sub is called in <sync_via_replication()> to implement8791# filters. This sub is called in <sync_via_replication()> to implement
8641# schema object filters like --databases and --tables.8792# schema object filters like --databases and --tables.
8642#8793#
8643# Parameters:
8644# $skip_table - Hashref of databases and tables to skip
8645# $databases - Hashref of databases to skip
8646# $tables - Hashref of tables to skip
8647# @diffs - Array of hashrefs, one for each different slave table
8648#
8649# Returns:8794# Returns:
8650# Array of different slave tables that pass the filters8795# Arrayref of different slave tables that pass the filters
8651sub filter_diffs {8796sub filter_diffs {
8652 my ( $skip_table, $databases, $tables, @diffs ) = @_;8797 my ( %args ) = @_;
8653 return grep {8798 my @required_args = qw(diffs SchemaIterator skip_table);
8654 my ($db, $tbl) = $q->split_unquote($_->{table});8799 foreach my $arg ( @required_args ) {
8655 !$skip_table->{$db}->{$tbl}8800 die "I need a $arg argument" unless $args{$arg};
8656 && (!$databases || $databases->{$db})8801 }
8657 && (!$tables || ($tables->{$tbl} || $tables->{$_->{table}}))8802 my ($diffs, $si, $skip_table) = @args{@required_args};
8658 } @diffs;8803
8804 my @filtered_diffs;
8805 foreach my $diff ( @$diffs ) {
8806 my $db = lc $diff->{db};
8807 my $tbl = lc $diff->{tbl};
8808 if ( !$skip_table->{$db}->{$tbl}
8809 && $si->database_is_allowed($db)
8810 && $si->table_is_allowed($db, $tbl) ) {
8811 push @filtered_diffs, $diff;
8812 }
8813 }
8814
8815 return \@filtered_diffs;
8659}8816}
86608817
8661# Sub: disconnect8818# Sub: disconnect
86628819
=== modified file 'lib/SchemaIterator.pm'
--- lib/SchemaIterator.pm 2012-01-19 19:46:56 +0000
+++ lib/SchemaIterator.pm 2012-05-30 22:08:19 +0000
@@ -55,12 +55,10 @@
55# OptionParser - <OptionParser> object. All filters are gotten from this55# OptionParser - <OptionParser> object. All filters are gotten from this
56# obj: --databases, --tables, etc.56# obj: --databases, --tables, etc.
57# Quoter - <Quoter> object.57# Quoter - <Quoter> object.
58# TableParser - <TableParser> object get tbl_struct.
58#59#
59# Optional Arguments:60# Optional Arguments:
60# Schema - <Schema> object to initialize while iterating.61# Schema - <Schema> object to initialize while iterating.
61# TableParser - <TableParser> object get tbl_struct.
62# keep_ddl - Keep SHOW CREATE TABLE (default false).
63# keep_tbl_status - Keep SHOW TABLE STATUS (default false).
64# resume - Skip tables so first call to <next()> returns62# resume - Skip tables so first call to <next()> returns
65# this "db.table".63# this "db.table".
66#64#
@@ -68,7 +66,7 @@
68# SchemaIterator object66# SchemaIterator object
69sub new {67sub new {
70 my ( $class, %args ) = @_;68 my ( $class, %args ) = @_;
71 my @required_args = qw(OptionParser Quoter);69 my @required_args = qw(OptionParser TableParser Quoter);
72 foreach my $arg ( @required_args ) {70 foreach my $arg ( @required_args ) {
73 die "I need a $arg argument" unless $args{$arg};71 die "I need a $arg argument" unless $args{$arg};
74 }72 }
@@ -222,18 +220,11 @@
222 }220 }
223221
224 if ( $schema_obj ) {222 if ( $schema_obj ) {
225 if ( $schema_obj->{ddl} && $self->{TableParser} ) {
226 $schema_obj->{tbl_struct}
227 = $self->{TableParser}->parse($schema_obj->{ddl});
228 }
229
230 delete $schema_obj->{ddl} unless $self->{keep_ddl};
231 delete $schema_obj->{tbl_status} unless $self->{keep_tbl_status};
232
233 if ( my $schema = $self->{Schema} ) {223 if ( my $schema = $self->{Schema} ) {
234 $schema->add_schema_object($schema_obj);224 $schema->add_schema_object($schema_obj);
235 }225 }
236 PTDEBUG && _d('Next schema object:', $schema_obj->{db}, $schema_obj->{tbl});226 PTDEBUG && _d('Next schema object:',
227 $schema_obj->{db}, $schema_obj->{tbl});
237 }228 }
238229
239 return $schema_obj;230 return $schema_obj;
@@ -295,14 +286,14 @@
295 next CHUNK;286 next CHUNK;
296 }287 }
297 $ddl =~ s/ \*\/;\Z/;/; # remove end of version comment288 $ddl =~ s/ \*\/;\Z/;/; # remove end of version comment
298289 my $tbl_struct = $self->{TableParser}->parse($ddl);
299 my ($engine) = $ddl =~ m/\).*?(?:ENGINE|TYPE)=(\w+)/; 290 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
300
301 if ( !$engine || $self->engine_is_allowed($engine) ) {
302 return {291 return {
303 db => $self->{db},292 db => $self->{db},
304 tbl => $tbl,293 tbl => $tbl,
305 ddl => $ddl,294 name => $self->{Quoter}->quote($self->{db}, $tbl),
295 ddl => $ddl,
296 tbl_struct => $tbl_struct,
306 };297 };
307 }298 }
308 }299 }
@@ -321,6 +312,7 @@
321sub _iterate_dbh {312sub _iterate_dbh {
322 my ( $self ) = @_;313 my ( $self ) = @_;
323 my $q = $self->{Quoter};314 my $q = $self->{Quoter};
315 my $tp = $self->{TableParser};
324 my $dbh = $self->{dbh};316 my $dbh = $self->{dbh};
325 PTDEBUG && _d('Getting next schema object from dbh', $dbh);317 PTDEBUG && _d('Getting next schema object from dbh', $dbh);
326318
@@ -360,33 +352,15 @@
360 }352 }
361353
362 while ( my $tbl = shift @{$self->{tbls}} ) {354 while ( my $tbl = shift @{$self->{tbls}} ) {
363 # If there are engine filters, we have to get the table status.355 my $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);
364 # Else, get it if the user wants to keep it since they'll expect356 my $tbl_struct = $tp->parse($ddl);
365 # it to be available.357 if ( $self->engine_is_allowed($tbl_struct->{engine}) ) {
366 my $tbl_status;
367 if ( $self->{filters}->{'engines'}
368 || $self->{filters}->{'ignore-engines'}
369 || $self->{keep_tbl_status} )
370 {
371 my $sql = "SHOW TABLE STATUS FROM " . $q->quote($self->{db})
372 . " LIKE \'$tbl\'";
373 PTDEBUG && _d($sql);
374 $tbl_status = $dbh->selectrow_hashref($sql);
375 PTDEBUG && _d(Dumper($tbl_status));
376 }
377
378 if ( !$tbl_status
379 || $self->engine_is_allowed($tbl_status->{engine}) ) {
380 my $ddl;
381 if ( my $tp = $self->{TableParser} ) {
382 $ddl = $tp->get_create_table($dbh, $self->{db}, $tbl);
383 }
384
385 return {358 return {
386 db => $self->{db},359 db => $self->{db},
387 tbl => $tbl,360 tbl => $tbl,
361 name => $q->quote($self->{db}, $tbl),
388 ddl => $ddl,362 ddl => $ddl,
389 tbl_status => $tbl_status,363 tbl_struct => $tbl_struct,
390 };364 };
391 }365 }
392 }366 }
@@ -502,7 +476,15 @@
502476
503sub engine_is_allowed {477sub engine_is_allowed {
504 my ( $self, $engine ) = @_;478 my ( $self, $engine ) = @_;
505 die "I need an engine argument" unless $engine;479
480 if ( !$engine ) {
481 # This normally doesn't happen, but it can if the user
482 # is iterating a file of their own table dumps, i.e. that
483 # weren't created by mysqldump, so there's no ENGINE=
484 # on the CREATE TABLE.
485 PTDEBUG && _d('No engine specified; allowing the table');
486 return 1;
487 }
506488
507 $engine = lc $engine;489 $engine = lc $engine;
508490
509491
=== modified file 'lib/TableChecksum.pm'
--- lib/TableChecksum.pm 2012-01-19 19:46:56 +0000
+++ lib/TableChecksum.pm 2012-05-30 22:08:19 +0000
@@ -480,10 +480,9 @@
480 . "FROM $table "480 . "FROM $table "
481 . "WHERE master_cnt <> this_cnt OR master_crc <> this_crc "481 . "WHERE master_cnt <> this_cnt OR master_crc <> this_crc "
482 . "OR ISNULL(master_crc) <> ISNULL(this_crc)";482 . "OR ISNULL(master_crc) <> ISNULL(this_crc)";
483
484 PTDEBUG && _d($sql);483 PTDEBUG && _d($sql);
485 my $diffs = $dbh->selectall_arrayref($sql, { Slice => {} });484 my $diffs = $dbh->selectall_arrayref($sql, { Slice => {} });
486 return @$diffs;485 return $diffs;
487}486}
488487
489sub _d {488sub _d {
490489
=== modified file 't/lib/SchemaIterator.t'
--- t/lib/SchemaIterator.t 2012-03-07 16:35:50 +0000
+++ t/lib/SchemaIterator.t 2012-05-30 22:08:19 +0000
@@ -9,7 +9,7 @@
9use strict;9use strict;
10use warnings FATAL => 'all';10use warnings FATAL => 'all';
11use English qw(-no_match_vars);11use English qw(-no_match_vars);
12use Test::More tests => 31;12use Test::More tests => 29;
1313
14use SchemaIterator;14use SchemaIterator;
15use FileIterator;15use FileIterator;
@@ -32,7 +32,7 @@
32my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);32my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
33my $dbh = $sb->get_dbh_for('master');33my $dbh = $sb->get_dbh_for('master');
3434
35my $tp;35my $tp = new TableParser(Quoter => $q);
36my $fi = new FileIterator();36my $fi = new FileIterator();
37my $o = new OptionParser(description => 'SchemaIterator');37my $o = new OptionParser(description => 'SchemaIterator');
38$o->get_specs("$trunk/bin/pt-table-checksum");38$o->get_specs("$trunk/bin/pt-table-checksum");
@@ -55,7 +55,6 @@
55 my $file_itr = $fi->get_file_itr(@{$args{files}});55 my $file_itr = $fi->get_file_itr(@{$args{files}});
56 $si = new SchemaIterator(56 $si = new SchemaIterator(
57 file_itr => $file_itr,57 file_itr => $file_itr,
58 keep_ddl => defined $args{keep_ddl} ? $args{keep_ddl} : 1,
59 resume => $args{resume},58 resume => $args{resume},
60 OptionParser => $o,59 OptionParser => $o,
61 Quoter => $q,60 Quoter => $q,
@@ -65,7 +64,6 @@
65 else {64 else {
66 $si = new SchemaIterator(65 $si = new SchemaIterator(
67 dbh => $dbh,66 dbh => $dbh,
68 keep_ddl => defined $args{keep_ddl} ? $args{keep_ddl} : 1,
69 resume => $args{resume},67 resume => $args{resume},
70 OptionParser => $o,68 OptionParser => $o,
71 Quoter => $q,69 Quoter => $q,
@@ -132,7 +130,7 @@
132 # Test simple, unfiltered get_db_itr().130 # Test simple, unfiltered get_db_itr().
133 # ########################################################################131 # ########################################################################
134 test_so(132 test_so(
135 result => $sandbox_version eq '5.1' ? "$out/all-dbs-tbls.txt"133 result => $sandbox_version ge '5.1' ? "$out/all-dbs-tbls.txt"
136 : "$out/all-dbs-tbls-5.0.txt",134 : "$out/all-dbs-tbls-5.0.txt",
137 test_name => "Iterate all schema objects with dbh",135 test_name => "Iterate all schema objects with dbh",
138 );136 );
@@ -311,7 +309,6 @@
311 # ########################################################################309 # ########################################################################
312 # Getting CREATE TALBE (ddl).310 # Getting CREATE TALBE (ddl).
313 # ########################################################################311 # ########################################################################
314 $tp = new TableParser(Quoter => $q);
315 test_so(312 test_so(
316 filters => [qw(-t mysql.user)],313 filters => [qw(-t mysql.user)],
317 result => $sandbox_version ge '5.1' ? "$out/mysql-user-ddl.txt"314 result => $sandbox_version ge '5.1' ? "$out/mysql-user-ddl.txt"
@@ -319,9 +316,6 @@
319 test_name => "Get CREATE TABLE with dbh",316 test_name => "Get CREATE TABLE with dbh",
320 );317 );
321318
322 # Kill the TableParser obj in case the next tests don't want to use it.
323 $tp = undef;
324
325 $sb->wipe_clean($dbh);319 $sb->wipe_clean($dbh);
326};320};
327321
@@ -370,55 +364,18 @@
370364
371is(365is(
372 $n_tbl_structs,366 $n_tbl_structs,
373 0,
374 'No tbl_struct without TableParser'
375);
376
377$tp = new TableParser(Quoter => $q);
378
379$objs = test_so(
380 files => ["$in/dump001.txt"],
381 result => "", # hack to let return_objs work
382 test_name => "", # hack to let return_objs work
383 return_objs => 1,
384);
385
386$n_tbl_structs = grep { exists $_->{tbl_struct} } @$objs;
387
388is(
389 $n_tbl_structs,
390 scalar @$objs,367 scalar @$objs,
391 'Got tbl_struct for each schema object'368 'Got tbl_struct for each schema object'
392);369);
393370
394# Kill the TableParser obj in case the next tests don't want to use it.
395$tp = undef;
396
397# ############################################################################
398# keep_ddl
399# ############################################################################
400$objs = test_so(
401 files => ["$in/dump001.txt"],
402 result => "", # hack to let return_objs work
403 test_name => "", # hack to let return_objs work
404 return_objs => 1,
405 keep_ddl => 0,
406);
407
408my $n_ddls = grep { exists $_->{ddl} } @$objs;
409
410is(
411 $n_ddls,
412 0,
413 'DDL deleted unless keep_ddl'
414);
415
416# ############################################################################371# ############################################################################
417# Resume372# Resume
418# ############################################################################373# ############################################################################
419test_so(374test_so(
420 filters => [qw(-d sakila)],375 filters => [qw(-d sakila)],
421 result => "$out/resume-from-sakila-payment.txt",376 result => $sandbox_version ge '5.1'
377 ? "$out/resume-from-sakila-payment.txt"
378 : "$out/resume-from-sakila-payment-5.0.txt",
422 resume => 'sakila.payment',379 resume => 'sakila.payment',
423 test_name => "Resume"380 test_name => "Resume"
424);381);
@@ -426,7 +383,9 @@
426# Ignore the table being resumed from; resume from next table.383# Ignore the table being resumed from; resume from next table.
427test_so(384test_so(
428 filters => [qw(-d sakila --ignore-tables sakila.payment)],385 filters => [qw(-d sakila --ignore-tables sakila.payment)],
429 result => "$out/resume-from-ignored-sakila-payment.txt",386 result => $sandbox_version ge '5.1'
387 ? "$out/resume-from-ignored-sakila-payment.txt"
388 : "$out/resume-from-ignored-sakila-payment-5.0.txt",
430 resume => 'sakila.payment',389 resume => 'sakila.payment',
431 test_name => "Resume from ignored table"390 test_name => "Resume from ignored table"
432);391);
433392
=== modified file 't/lib/samples/SchemaIterator/all-dbs-tbls-5.0.txt'
--- t/lib/samples/SchemaIterator/all-dbs-tbls-5.0.txt 2011-08-19 18:17:26 +0000
+++ t/lib/samples/SchemaIterator/all-dbs-tbls-5.0.txt 2012-05-30 22:08:19 +0000
@@ -1,33 +1,454 @@
1mysql.columns_priv1mysql.columns_priv
2CREATE TABLE `columns_priv` (
3 `Host` char(60) collate utf8_bin NOT NULL default '',
4 `Db` char(64) collate utf8_bin NOT NULL default '',
5 `User` char(16) collate utf8_bin NOT NULL default '',
6 `Table_name` char(64) collate utf8_bin NOT NULL default '',
7 `Column_name` char(64) collate utf8_bin NOT NULL default '',
8 `Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
9 `Column_priv` set('Select','Insert','Update','References') character set utf8 NOT NULL default '',
10 PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`,`Column_name`)
11) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Column privileges'
12
2mysql.db13mysql.db
14CREATE TABLE `db` (
15 `Host` char(60) collate utf8_bin NOT NULL default '',
16 `Db` char(64) collate utf8_bin NOT NULL default '',
17 `User` char(16) collate utf8_bin NOT NULL default '',
18 `Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
19 `Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
20 `Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
21 `Delete_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
22 `Create_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
23 `Drop_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
24 `Grant_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
25 `References_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
26 `Index_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
27 `Alter_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
28 `Create_tmp_table_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
29 `Lock_tables_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
30 `Create_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
31 `Show_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
32 `Create_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
33 `Alter_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
34 `Execute_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
35 PRIMARY KEY (`Host`,`Db`,`User`),
36 KEY `User` (`User`)
37) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
38
3mysql.func39mysql.func
40CREATE TABLE `func` (
41 `name` char(64) collate utf8_bin NOT NULL default '',
42 `ret` tinyint(1) NOT NULL default '0',
43 `dl` char(128) collate utf8_bin NOT NULL default '',
44 `type` enum('function','aggregate') character set utf8 NOT NULL,
45 PRIMARY KEY (`name`)
46) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='User defined functions'
47
4mysql.help_category48mysql.help_category
49CREATE TABLE `help_category` (
50 `help_category_id` smallint(5) unsigned NOT NULL,
51 `name` char(64) NOT NULL,
52 `parent_category_id` smallint(5) unsigned default NULL,
53 `url` char(128) NOT NULL,
54 PRIMARY KEY (`help_category_id`),
55 UNIQUE KEY `name` (`name`)
56) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='help categories'
57
5mysql.help_keyword58mysql.help_keyword
59CREATE TABLE `help_keyword` (
60 `help_keyword_id` int(10) unsigned NOT NULL,
61 `name` char(64) NOT NULL,
62 PRIMARY KEY (`help_keyword_id`),
63 UNIQUE KEY `name` (`name`)
64) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='help keywords'
65
6mysql.help_relation66mysql.help_relation
67CREATE TABLE `help_relation` (
68 `help_topic_id` int(10) unsigned NOT NULL,
69 `help_keyword_id` int(10) unsigned NOT NULL,
70 PRIMARY KEY (`help_keyword_id`,`help_topic_id`)
71) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='keyword-topic relation'
72
7mysql.help_topic73mysql.help_topic
74CREATE TABLE `help_topic` (
75 `help_topic_id` int(10) unsigned NOT NULL,
76 `name` char(64) NOT NULL,
77 `help_category_id` smallint(5) unsigned NOT NULL,
78 `description` text NOT NULL,
79 `example` text NOT NULL,
80 `url` char(128) NOT NULL,
81 PRIMARY KEY (`help_topic_id`),
82 UNIQUE KEY `name` (`name`)
83) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='help topics'
84
8mysql.host85mysql.host
86CREATE TABLE `host` (
87 `Host` char(60) collate utf8_bin NOT NULL default '',
88 `Db` char(64) collate utf8_bin NOT NULL default '',
89 `Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
90 `Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
91 `Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
92 `Delete_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
93 `Create_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
94 `Drop_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
95 `Grant_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
96 `References_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
97 `Index_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
98 `Alter_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
99 `Create_tmp_table_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
100 `Lock_tables_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
101 `Create_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
102 `Show_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
103 `Create_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
104 `Alter_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
105 `Execute_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
106 PRIMARY KEY (`Host`,`Db`)
107) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Host privileges; Merged with database privileges'
108
9mysql.proc109mysql.proc
110CREATE TABLE `proc` (
111 `db` char(64) character set utf8 collate utf8_bin NOT NULL default '',
112 `name` char(64) NOT NULL default '',
113 `type` enum('FUNCTION','PROCEDURE') NOT NULL,
114 `specific_name` char(64) NOT NULL default '',
115 `language` enum('SQL') NOT NULL default 'SQL',
116 `sql_data_access` enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') NOT NULL default 'CONTAINS_SQL',
117 `is_deterministic` enum('YES','NO') NOT NULL default 'NO',
118 `security_type` enum('INVOKER','DEFINER') NOT NULL default 'DEFINER',
119 `param_list` blob NOT NULL,
120 `returns` char(64) NOT NULL default '',
121 `body` longblob NOT NULL,
122 `definer` char(77) character set utf8 collate utf8_bin NOT NULL default '',
123 `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
124 `modified` timestamp NOT NULL default '0000-00-00 00:00:00',
125 `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') NOT NULL default '',
126 `comment` char(64) character set utf8 collate utf8_bin NOT NULL default '',
127 PRIMARY KEY (`db`,`name`,`type`)
128) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stored Procedures'
129
10mysql.procs_priv130mysql.procs_priv
131CREATE TABLE `procs_priv` (
132 `Host` char(60) collate utf8_bin NOT NULL default '',
133 `Db` char(64) collate utf8_bin NOT NULL default '',
134 `User` char(16) collate utf8_bin NOT NULL default '',
135 `Routine_name` char(64) collate utf8_bin NOT NULL default '',
136 `Routine_type` enum('FUNCTION','PROCEDURE') collate utf8_bin NOT NULL,
137 `Grantor` char(77) collate utf8_bin NOT NULL default '',
138 `Proc_priv` set('Execute','Alter Routine','Grant') character set utf8 NOT NULL default '',
139 `Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
140 PRIMARY KEY (`Host`,`Db`,`User`,`Routine_name`,`Routine_type`),
141 KEY `Grantor` (`Grantor`)
142) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Procedure privileges'
143
11mysql.tables_priv144mysql.tables_priv
145CREATE TABLE `tables_priv` (
146 `Host` char(60) collate utf8_bin NOT NULL default '',
147 `Db` char(64) collate utf8_bin NOT NULL default '',
148 `User` char(16) collate utf8_bin NOT NULL default '',
149 `Table_name` char(64) collate utf8_bin NOT NULL default '',
150 `Grantor` char(77) collate utf8_bin NOT NULL default '',
151 `Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
152 `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') character set utf8 NOT NULL default '',
153 `Column_priv` set('Select','Insert','Update','References') character set utf8 NOT NULL default '',
154 PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`),
155 KEY `Grantor` (`Grantor`)
156) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Table privileges'
157
12mysql.time_zone158mysql.time_zone
159CREATE TABLE `time_zone` (
160 `Time_zone_id` int(10) unsigned NOT NULL auto_increment,
161 `Use_leap_seconds` enum('Y','N') NOT NULL default 'N',
162 PRIMARY KEY (`Time_zone_id`)
163) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Time zones'
164
13mysql.time_zone_leap_second165mysql.time_zone_leap_second
166CREATE TABLE `time_zone_leap_second` (
167 `Transition_time` bigint(20) NOT NULL,
168 `Correction` int(11) NOT NULL,
169 PRIMARY KEY (`Transition_time`)
170) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Leap seconds information for time zones'
171
14mysql.time_zone_name172mysql.time_zone_name
173CREATE TABLE `time_zone_name` (
174 `Name` char(64) NOT NULL,
175 `Time_zone_id` int(10) unsigned NOT NULL,
176 PRIMARY KEY (`Name`)
177) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Time zone names'
178
15mysql.time_zone_transition179mysql.time_zone_transition
180CREATE TABLE `time_zone_transition` (
181 `Time_zone_id` int(10) unsigned NOT NULL,
182 `Transition_time` bigint(20) NOT NULL,
183 `Transition_type_id` int(10) unsigned NOT NULL,
184 PRIMARY KEY (`Time_zone_id`,`Transition_time`)
185) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Time zone transitions'
186
16mysql.time_zone_transition_type187mysql.time_zone_transition_type
188CREATE TABLE `time_zone_transition_type` (
189 `Time_zone_id` int(10) unsigned NOT NULL,
190 `Transition_type_id` int(10) unsigned NOT NULL,
191 `Offset` int(11) NOT NULL default '0',
192 `Is_DST` tinyint(3) unsigned NOT NULL default '0',
193 `Abbreviation` char(8) NOT NULL default '',
194 PRIMARY KEY (`Time_zone_id`,`Transition_type_id`)
195) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Time zone transition types'
196
17mysql.user197mysql.user
198CREATE TABLE `user` (
199 `Host` char(60) collate utf8_bin NOT NULL default '',
200 `User` char(16) collate utf8_bin NOT NULL default '',
201 `Password` char(41) character set latin1 collate latin1_bin NOT NULL default '',
202 `Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
203 `Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
204 `Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
205 `Delete_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
206 `Create_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
207 `Drop_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
208 `Reload_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
209 `Shutdown_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
210 `Process_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
211 `File_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
212 `Grant_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
213 `References_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
214 `Index_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
215 `Alter_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
216 `Show_db_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
217 `Super_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
218 `Create_tmp_table_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
219 `Lock_tables_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
220 `Execute_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
221 `Repl_slave_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
222 `Repl_client_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
223 `Create_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
224 `Show_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
225 `Create_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
226 `Alter_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
227 `Create_user_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
228 `ssl_type` enum('','ANY','X509','SPECIFIED') character set utf8 NOT NULL default '',
229 `ssl_cipher` blob NOT NULL,
230 `x509_issuer` blob NOT NULL,
231 `x509_subject` blob NOT NULL,
232 `max_questions` int(11) unsigned NOT NULL default '0',
233 `max_updates` int(11) unsigned NOT NULL default '0',
234 `max_connections` int(11) unsigned NOT NULL default '0',
235 `max_user_connections` int(11) unsigned NOT NULL default '0',
236 PRIMARY KEY (`Host`,`User`)
237) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'
238
18sakila.actor239sakila.actor
240CREATE TABLE `actor` (
241 `actor_id` smallint(5) unsigned NOT NULL auto_increment,
242 `first_name` varchar(45) NOT NULL,
243 `last_name` varchar(45) NOT NULL,
244 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
245 PRIMARY KEY (`actor_id`),
246 KEY `idx_actor_last_name` (`last_name`)
247) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8
248
19sakila.address249sakila.address
250CREATE TABLE `address` (
251 `address_id` smallint(5) unsigned NOT NULL auto_increment,
252 `address` varchar(50) NOT NULL,
253 `address2` varchar(50) default NULL,
254 `district` varchar(20) NOT NULL,
255 `city_id` smallint(5) unsigned NOT NULL,
256 `postal_code` varchar(10) default NULL,
257 `phone` varchar(20) NOT NULL,
258 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
259 PRIMARY KEY (`address_id`),
260 KEY `idx_fk_city_id` (`city_id`),
261 CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `city` (`city_id`) ON UPDATE CASCADE
262) ENGINE=InnoDB AUTO_INCREMENT=606 DEFAULT CHARSET=utf8
263
20sakila.category264sakila.category
265CREATE TABLE `category` (
266 `category_id` tinyint(3) unsigned NOT NULL auto_increment,
267 `name` varchar(25) NOT NULL,
268 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
269 PRIMARY KEY (`category_id`)
270) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8
271
21sakila.city272sakila.city
273CREATE TABLE `city` (
274 `city_id` smallint(5) unsigned NOT NULL auto_increment,
275 `city` varchar(50) NOT NULL,
276 `country_id` smallint(5) unsigned NOT NULL,
277 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
278 PRIMARY KEY (`city_id`),
279 KEY `idx_fk_country_id` (`country_id`),
280 CONSTRAINT `fk_city_country` FOREIGN KEY (`country_id`) REFERENCES `country` (`country_id`) ON UPDATE CASCADE
281) ENGINE=InnoDB AUTO_INCREMENT=601 DEFAULT CHARSET=utf8
282
22sakila.country283sakila.country
284CREATE TABLE `country` (
285 `country_id` smallint(5) unsigned NOT NULL auto_increment,
286 `country` varchar(50) NOT NULL,
287 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
288 PRIMARY KEY (`country_id`)
289) ENGINE=InnoDB AUTO_INCREMENT=110 DEFAULT CHARSET=utf8
290
23sakila.customer291sakila.customer
292CREATE TABLE `customer` (
293 `customer_id` smallint(5) unsigned NOT NULL auto_increment,
294 `store_id` tinyint(3) unsigned NOT NULL,
295 `first_name` varchar(45) NOT NULL,
296 `last_name` varchar(45) NOT NULL,
297 `email` varchar(50) default NULL,
298 `address_id` smallint(5) unsigned NOT NULL,
299 `active` tinyint(1) NOT NULL default '1',
300 `create_date` datetime NOT NULL,
301 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
302 PRIMARY KEY (`customer_id`),
303 KEY `idx_fk_store_id` (`store_id`),
304 KEY `idx_fk_address_id` (`address_id`),
305 KEY `idx_last_name` (`last_name`),
306 CONSTRAINT `fk_customer_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE,
307 CONSTRAINT `fk_customer_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE
308) ENGINE=InnoDB AUTO_INCREMENT=600 DEFAULT CHARSET=utf8
309
24sakila.film310sakila.film
311CREATE TABLE `film` (
312 `film_id` smallint(5) unsigned NOT NULL auto_increment,
313 `title` varchar(255) NOT NULL,
314 `description` text,
315 `release_year` year(4) default NULL,
316 `language_id` tinyint(3) unsigned NOT NULL,
317 `original_language_id` tinyint(3) unsigned default NULL,
318 `rental_duration` tinyint(3) unsigned NOT NULL default '3',
319 `rental_rate` decimal(4,2) NOT NULL default '4.99',
320 `length` smallint(5) unsigned default NULL,
321 `replacement_cost` decimal(5,2) NOT NULL default '19.99',
322 `rating` enum('G','PG','PG-13','R','NC-17') default 'G',
323 `special_features` set('Trailers','Commentaries','Deleted Scenes','Behind the Scenes') default NULL,
324 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
325 PRIMARY KEY (`film_id`),
326 KEY `idx_title` (`title`),
327 KEY `idx_fk_language_id` (`language_id`),
328 KEY `idx_fk_original_language_id` (`original_language_id`),
329 CONSTRAINT `fk_film_language` FOREIGN KEY (`language_id`) REFERENCES `language` (`language_id`) ON UPDATE CASCADE,
330 CONSTRAINT `fk_film_language_original` FOREIGN KEY (`original_language_id`) REFERENCES `language` (`language_id`) ON UPDATE CASCADE
331) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8
332
25sakila.film_actor333sakila.film_actor
334CREATE TABLE `film_actor` (
335 `actor_id` smallint(5) unsigned NOT NULL,
336 `film_id` smallint(5) unsigned NOT NULL,
337 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
338 PRIMARY KEY (`actor_id`,`film_id`),
339 KEY `idx_fk_film_id` (`film_id`),
340 CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`) ON UPDATE CASCADE,
341 CONSTRAINT `fk_film_actor_film` FOREIGN KEY (`film_id`) REFERENCES `film` (`film_id`) ON UPDATE CASCADE
342) ENGINE=InnoDB DEFAULT CHARSET=utf8
343
26sakila.film_category344sakila.film_category
345CREATE TABLE `film_category` (
346 `film_id` smallint(5) unsigned NOT NULL,
347 `category_id` tinyint(3) unsigned NOT NULL,
348 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
349 PRIMARY KEY (`film_id`,`category_id`),
350 KEY `fk_film_category_category` (`category_id`),
351 CONSTRAINT `fk_film_category_film` FOREIGN KEY (`film_id`) REFERENCES `film` (`film_id`) ON UPDATE CASCADE,
352 CONSTRAINT `fk_film_category_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`) ON UPDATE CASCADE
353) ENGINE=InnoDB DEFAULT CHARSET=utf8
354
27sakila.film_text355sakila.film_text
356CREATE TABLE `film_text` (
357 `film_id` smallint(6) NOT NULL,
358 `title` varchar(255) NOT NULL,
359 `description` text,
360 PRIMARY KEY (`film_id`),
361 FULLTEXT KEY `idx_title_description` (`title`,`description`)
362) ENGINE=MyISAM DEFAULT CHARSET=utf8
363
28sakila.inventory364sakila.inventory
365CREATE TABLE `inventory` (
366 `inventory_id` mediumint(8) unsigned NOT NULL auto_increment,
367 `film_id` smallint(5) unsigned NOT NULL,
368 `store_id` tinyint(3) unsigned NOT NULL,
369 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
370 PRIMARY KEY (`inventory_id`),
371 KEY `idx_fk_film_id` (`film_id`),
372 KEY `idx_store_id_film_id` (`store_id`,`film_id`),
373 CONSTRAINT `fk_inventory_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE,
374 CONSTRAINT `fk_inventory_film` FOREIGN KEY (`film_id`) REFERENCES `film` (`film_id`) ON UPDATE CASCADE
375) ENGINE=InnoDB AUTO_INCREMENT=4582 DEFAULT CHARSET=utf8
376
29sakila.language377sakila.language
378CREATE TABLE `language` (
379 `language_id` tinyint(3) unsigned NOT NULL auto_increment,
380 `name` char(20) NOT NULL,
381 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
382 PRIMARY KEY (`language_id`)
383) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
384
30sakila.payment385sakila.payment
386CREATE TABLE `payment` (
387 `payment_id` smallint(5) unsigned NOT NULL auto_increment,
388 `customer_id` smallint(5) unsigned NOT NULL,
389 `staff_id` tinyint(3) unsigned NOT NULL,
390 `rental_id` int(11) default NULL,
391 `amount` decimal(5,2) NOT NULL,
392 `payment_date` datetime NOT NULL,
393 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
394 PRIMARY KEY (`payment_id`),
395 KEY `idx_fk_staff_id` (`staff_id`),
396 KEY `idx_fk_customer_id` (`customer_id`),
397 KEY `fk_payment_rental` (`rental_id`),
398 CONSTRAINT `fk_payment_rental` FOREIGN KEY (`rental_id`) REFERENCES `rental` (`rental_id`) ON DELETE SET NULL ON UPDATE CASCADE,
399 CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE,
400 CONSTRAINT `fk_payment_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE
401) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
402
31sakila.rental403sakila.rental
404CREATE TABLE `rental` (
405 `rental_id` int(11) NOT NULL auto_increment,
406 `rental_date` datetime NOT NULL,
407 `inventory_id` mediumint(8) unsigned NOT NULL,
408 `customer_id` smallint(5) unsigned NOT NULL,
409 `return_date` datetime default NULL,
410 `staff_id` tinyint(3) unsigned NOT NULL,
411 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
412 PRIMARY KEY (`rental_id`),
413 UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`),
414 KEY `idx_fk_inventory_id` (`inventory_id`),
415 KEY `idx_fk_customer_id` (`customer_id`),
416 KEY `idx_fk_staff_id` (`staff_id`),
417 CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
418 CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `inventory` (`inventory_id`) ON UPDATE CASCADE,
419 CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE
420) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
421
32sakila.staff422sakila.staff
423CREATE TABLE `staff` (
424 `staff_id` tinyint(3) unsigned NOT NULL auto_increment,
425 `first_name` varchar(45) NOT NULL,
426 `last_name` varchar(45) NOT NULL,
427 `address_id` smallint(5) unsigned NOT NULL,
428 `picture` blob,
429 `email` varchar(50) default NULL,
430 `store_id` tinyint(3) unsigned NOT NULL,
431 `active` tinyint(1) NOT NULL default '1',
432 `username` varchar(16) NOT NULL,
433 `password` varchar(40) character set utf8 collate utf8_bin default NULL,
434 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
435 PRIMARY KEY (`staff_id`),
436 KEY `idx_fk_store_id` (`store_id`),
437 KEY `idx_fk_address_id` (`address_id`),
438 CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE,
439 CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
440) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
441
33sakila.store442sakila.store
443CREATE TABLE `store` (
444 `store_id` tinyint(3) unsigned NOT NULL auto_increment,
445 `manager_staff_id` tinyint(3) unsigned NOT NULL,
446 `address_id` smallint(5) unsigned NOT NULL,
447 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
448 PRIMARY KEY (`store_id`),
449 UNIQUE KEY `idx_unique_manager` (`manager_staff_id`),
450 KEY `idx_fk_address_id` (`address_id`),
451 CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
452 CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
453) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
454
34455
=== modified file 't/lib/samples/SchemaIterator/all-dbs-tbls.txt'
--- t/lib/samples/SchemaIterator/all-dbs-tbls.txt 2011-09-23 14:07:03 +0000
+++ t/lib/samples/SchemaIterator/all-dbs-tbls.txt 2012-05-30 22:08:19 +0000
@@ -1,37 +1,523 @@
1mysql.columns_priv1mysql.columns_priv
2CREATE TABLE `columns_priv` (
3 `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
4 `Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
5 `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
6 `Table_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
7 `Column_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
8 `Timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
9 `Column_priv` set('Select','Insert','Update','References') CHARACTER SET utf8 NOT NULL DEFAULT '',
10 PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`,`Column_name`)
11) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Column privileges'
12
2mysql.db13mysql.db
14CREATE TABLE `db` (
15 `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
16 `Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
17 `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
18 `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
19 `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
20 `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
21 `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
22 `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
23 `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
24 `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
25 `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
26 `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
27 `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
28 `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
29 `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
30 `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
31 `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
32 `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
33 `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
34 `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
35 `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
36 `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
37 PRIMARY KEY (`Host`,`Db`,`User`),
38 KEY `User` (`User`)
39) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
40
3mysql.event41mysql.event
42CREATE TABLE `event` (
43 `db` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
44 `name` char(64) NOT NULL DEFAULT '',
45 `body` longblob NOT NULL,
46 `definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
47 `execute_at` datetime DEFAULT NULL,
48 `interval_value` int(11) DEFAULT NULL,
49 `interval_field` enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') DEFAULT NULL,
50 `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
51 `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
52 `last_executed` datetime DEFAULT NULL,
53 `starts` datetime DEFAULT NULL,
54 `ends` datetime DEFAULT NULL,
55 `status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
56 `on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
57 `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
58 `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
59 `originator` int(10) unsigned NOT NULL,
60 `time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
61 `character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
62 `collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
63 `db_collation` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
64 `body_utf8` longblob,
65 PRIMARY KEY (`db`,`name`)
66) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
67
4mysql.func68mysql.func
69CREATE TABLE `func` (
70 `name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
71 `ret` tinyint(1) NOT NULL DEFAULT '0',
72 `dl` char(128) COLLATE utf8_bin NOT NULL DEFAULT '',
73 `type` enum('function','aggregate') CHARACTER SET utf8 NOT NULL,
74 PRIMARY KEY (`name`)
75) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='User defined functions'
76
5mysql.help_category77mysql.help_category
78CREATE TABLE `help_category` (
79 `help_category_id` smallint(5) unsigned NOT NULL,
80 `name` char(64) NOT NULL,
81 `parent_category_id` smallint(5) unsigned DEFAULT NULL,
82 `url` char(128) NOT NULL,
83 PRIMARY KEY (`help_category_id`),
84 UNIQUE KEY `name` (`name`)
85) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='help categories'
86
6mysql.help_keyword87mysql.help_keyword
88CREATE TABLE `help_keyword` (
89 `help_keyword_id` int(10) unsigned NOT NULL,
90 `name` char(64) NOT NULL,
91 PRIMARY KEY (`help_keyword_id`),
92 UNIQUE KEY `name` (`name`)
93) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='help keywords'
94
7mysql.help_relation95mysql.help_relation
96CREATE TABLE `help_relation` (
97 `help_topic_id` int(10) unsigned NOT NULL,
98 `help_keyword_id` int(10) unsigned NOT NULL,
99 PRIMARY KEY (`help_keyword_id`,`help_topic_id`)
100) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='keyword-topic relation'
101
8mysql.help_topic102mysql.help_topic
103CREATE TABLE `help_topic` (
104 `help_topic_id` int(10) unsigned NOT NULL,
105 `name` char(64) NOT NULL,
106 `help_category_id` smallint(5) unsigned NOT NULL,
107 `description` text NOT NULL,
108 `example` text NOT NULL,
109 `url` char(128) NOT NULL,
110 PRIMARY KEY (`help_topic_id`),
111 UNIQUE KEY `name` (`name`)
112) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='help topics'
113
9mysql.host114mysql.host
115CREATE TABLE `host` (
116 `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
117 `Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
118 `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
119 `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
120 `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
121 `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
122 `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
123 `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
124 `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
125 `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
126 `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
127 `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
128 `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
129 `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
130 `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
131 `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
132 `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
133 `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
134 `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
135 `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
136 PRIMARY KEY (`Host`,`Db`)
137) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Host privileges; Merged with database privileges'
138
10mysql.ndb_binlog_index139mysql.ndb_binlog_index
140CREATE TABLE `ndb_binlog_index` (
141 `Position` bigint(20) unsigned NOT NULL,
142 `File` varchar(255) NOT NULL,
143 `epoch` bigint(20) unsigned NOT NULL,
144 `inserts` bigint(20) unsigned NOT NULL,
145 `updates` bigint(20) unsigned NOT NULL,
146 `deletes` bigint(20) unsigned NOT NULL,
147 `schemaops` bigint(20) unsigned NOT NULL,
148 PRIMARY KEY (`epoch`)
149) ENGINE=MyISAM DEFAULT CHARSET=latin1
150
11mysql.plugin151mysql.plugin
152CREATE TABLE `plugin` (
153 `name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
154 `dl` char(128) COLLATE utf8_bin NOT NULL DEFAULT '',
155 PRIMARY KEY (`name`)
156) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='MySQL plugins'
157
12mysql.proc158mysql.proc
159CREATE TABLE `proc` (
160 `db` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
161 `name` char(64) NOT NULL DEFAULT '',
162 `type` enum('FUNCTION','PROCEDURE') NOT NULL,
163 `specific_name` char(64) NOT NULL DEFAULT '',
164 `language` enum('SQL') NOT NULL DEFAULT 'SQL',
165 `sql_data_access` enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') NOT NULL DEFAULT 'CONTAINS_SQL',
166 `is_deterministic` enum('YES','NO') NOT NULL DEFAULT 'NO',
167 `security_type` enum('INVOKER','DEFINER') NOT NULL DEFAULT 'DEFINER',
168 `param_list` blob NOT NULL,
169 `returns` longblob NOT NULL,
170 `body` longblob NOT NULL,
171 `definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
172 `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
173 `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
174 `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
175 `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
176 `character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
177 `collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
178 `db_collation` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
179 `body_utf8` longblob,
180 PRIMARY KEY (`db`,`name`,`type`)
181) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stored Procedures'
182
13mysql.procs_priv183mysql.procs_priv
184CREATE TABLE `procs_priv` (
185 `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
186 `Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
187 `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
188 `Routine_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
189 `Routine_type` enum('FUNCTION','PROCEDURE') COLLATE utf8_bin NOT NULL,
190 `Grantor` char(77) COLLATE utf8_bin NOT NULL DEFAULT '',
191 `Proc_priv` set('Execute','Alter Routine','Grant') CHARACTER SET utf8 NOT NULL DEFAULT '',
192 `Timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
193 PRIMARY KEY (`Host`,`Db`,`User`,`Routine_name`,`Routine_type`),
194 KEY `Grantor` (`Grantor`)
195) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Procedure privileges'
196
14mysql.servers197mysql.servers
198CREATE TABLE `servers` (
199 `Server_name` char(64) NOT NULL DEFAULT '',
200 `Host` char(64) NOT NULL DEFAULT '',
201 `Db` char(64) NOT NULL DEFAULT '',
202 `Username` char(64) NOT NULL DEFAULT '',
203 `Password` char(64) NOT NULL DEFAULT '',
204 `Port` int(4) NOT NULL DEFAULT '0',
205 `Socket` char(64) NOT NULL DEFAULT '',
206 `Wrapper` char(64) NOT NULL DEFAULT '',
207 `Owner` char(64) NOT NULL DEFAULT '',
208 PRIMARY KEY (`Server_name`)
209) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table'
210
15mysql.tables_priv211mysql.tables_priv
212CREATE TABLE `tables_priv` (
213 `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
214 `Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
215 `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
216 `Table_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
217 `Grantor` char(77) COLLATE utf8_bin NOT NULL DEFAULT '',
218 `Timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
219 `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') CHARACTER SET utf8 NOT NULL DEFAULT '',
220 `Column_priv` set('Select','Insert','Update','References') CHARACTER SET utf8 NOT NULL DEFAULT '',
221 PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`),
222 KEY `Grantor` (`Grantor`)
223) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Table privileges'
224
16mysql.time_zone225mysql.time_zone
226CREATE TABLE `time_zone` (
227 `Time_zone_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
228 `Use_leap_seconds` enum('Y','N') NOT NULL DEFAULT 'N',
229 PRIMARY KEY (`Time_zone_id`)
230) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Time zones'
231
17mysql.time_zone_leap_second232mysql.time_zone_leap_second
233CREATE TABLE `time_zone_leap_second` (
234 `Transition_time` bigint(20) NOT NULL,
235 `Correction` int(11) NOT NULL,
236 PRIMARY KEY (`Transition_time`)
237) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Leap seconds information for time zones'
238
18mysql.time_zone_name239mysql.time_zone_name
240CREATE TABLE `time_zone_name` (
241 `Name` char(64) NOT NULL,
242 `Time_zone_id` int(10) unsigned NOT NULL,
243 PRIMARY KEY (`Name`)
244) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Time zone names'
245
19mysql.time_zone_transition246mysql.time_zone_transition
247CREATE TABLE `time_zone_transition` (
248 `Time_zone_id` int(10) unsigned NOT NULL,
249 `Transition_time` bigint(20) NOT NULL,
250 `Transition_type_id` int(10) unsigned NOT NULL,
251 PRIMARY KEY (`Time_zone_id`,`Transition_time`)
252) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Time zone transitions'
253
20mysql.time_zone_transition_type254mysql.time_zone_transition_type
255CREATE TABLE `time_zone_transition_type` (
256 `Time_zone_id` int(10) unsigned NOT NULL,
257 `Transition_type_id` int(10) unsigned NOT NULL,
258 `Offset` int(11) NOT NULL DEFAULT '0',
259 `Is_DST` tinyint(3) unsigned NOT NULL DEFAULT '0',
260 `Abbreviation` char(8) NOT NULL DEFAULT '',
261 PRIMARY KEY (`Time_zone_id`,`Transition_type_id`)
262) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Time zone transition types'
263
21mysql.user264mysql.user
265CREATE TABLE `user` (
266 `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
267 `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
268 `Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
269 `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
270 `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
271 `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
272 `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
273 `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
274 `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
275 `Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
276 `Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
277 `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
278 `File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
279 `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
280 `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
281 `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
282 `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
283 `Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
284 `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
285 `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
286 `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
287 `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
288 `Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
289 `Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
290 `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
291 `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
292 `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
293 `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
294 `Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
295 `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
296 `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
297 `ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',
298 `ssl_cipher` blob NOT NULL,
299 `x509_issuer` blob NOT NULL,
300 `x509_subject` blob NOT NULL,
301 `max_questions` int(11) unsigned NOT NULL DEFAULT '0',
302 `max_updates` int(11) unsigned NOT NULL DEFAULT '0',
303 `max_connections` int(11) unsigned NOT NULL DEFAULT '0',
304 `max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
305 PRIMARY KEY (`Host`,`User`)
306) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'
307
22sakila.actor308sakila.actor
309CREATE TABLE `actor` (
310 `actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
311 `first_name` varchar(45) NOT NULL,
312 `last_name` varchar(45) NOT NULL,
313 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
314 PRIMARY KEY (`actor_id`),
315 KEY `idx_actor_last_name` (`last_name`)
316) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8
317
23sakila.address318sakila.address
319CREATE TABLE `address` (
320 `address_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
321 `address` varchar(50) NOT NULL,
322 `address2` varchar(50) DEFAULT NULL,
323 `district` varchar(20) NOT NULL,
324 `city_id` smallint(5) unsigned NOT NULL,
325 `postal_code` varchar(10) DEFAULT NULL,
326 `phone` varchar(20) NOT NULL,
327 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
328 PRIMARY KEY (`address_id`),
329 KEY `idx_fk_city_id` (`city_id`),
330 CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `city` (`city_id`) ON UPDATE CASCADE
331) ENGINE=InnoDB AUTO_INCREMENT=606 DEFAULT CHARSET=utf8
332
24sakila.category333sakila.category
334CREATE TABLE `category` (
335 `category_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
336 `name` varchar(25) NOT NULL,
337 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
338 PRIMARY KEY (`category_id`)
339) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8
340
25sakila.city341sakila.city
342CREATE TABLE `city` (
343 `city_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
344 `city` varchar(50) NOT NULL,
345 `country_id` smallint(5) unsigned NOT NULL,
346 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
347 PRIMARY KEY (`city_id`),
348 KEY `idx_fk_country_id` (`country_id`),
349 CONSTRAINT `fk_city_country` FOREIGN KEY (`country_id`) REFERENCES `country` (`country_id`) ON UPDATE CASCADE
350) ENGINE=InnoDB AUTO_INCREMENT=601 DEFAULT CHARSET=utf8
351
26sakila.country352sakila.country
353CREATE TABLE `country` (
354 `country_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
355 `country` varchar(50) NOT NULL,
356 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
357 PRIMARY KEY (`country_id`)
358) ENGINE=InnoDB AUTO_INCREMENT=110 DEFAULT CHARSET=utf8
359
27sakila.customer360sakila.customer
361CREATE TABLE `customer` (
362 `customer_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
363 `store_id` tinyint(3) unsigned NOT NULL,
364 `first_name` varchar(45) NOT NULL,
365 `last_name` varchar(45) NOT NULL,
366 `email` varchar(50) DEFAULT NULL,
367 `address_id` smallint(5) unsigned NOT NULL,
368 `active` tinyint(1) NOT NULL DEFAULT '1',
369 `create_date` datetime NOT NULL,
370 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
371 PRIMARY KEY (`customer_id`),
372 KEY `idx_fk_store_id` (`store_id`),
373 KEY `idx_fk_address_id` (`address_id`),
374 KEY `idx_last_name` (`last_name`),
375 CONSTRAINT `fk_customer_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE,
376 CONSTRAINT `fk_customer_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE
377) ENGINE=InnoDB AUTO_INCREMENT=600 DEFAULT CHARSET=utf8
378
28sakila.film379sakila.film
380CREATE TABLE `film` (
381 `film_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
382 `title` varchar(255) NOT NULL,
383 `description` text,
384 `release_year` year(4) DEFAULT NULL,
385 `language_id` tinyint(3) unsigned NOT NULL,
386 `original_language_id` tinyint(3) unsigned DEFAULT NULL,
387 `rental_duration` tinyint(3) unsigned NOT NULL DEFAULT '3',
388 `rental_rate` decimal(4,2) NOT NULL DEFAULT '4.99',
389 `length` smallint(5) unsigned DEFAULT NULL,
390 `replacement_cost` decimal(5,2) NOT NULL DEFAULT '19.99',
391 `rating` enum('G','PG','PG-13','R','NC-17') DEFAULT 'G',
392 `special_features` set('Trailers','Commentaries','Deleted Scenes','Behind the Scenes') DEFAULT NULL,
393 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
394 PRIMARY KEY (`film_id`),
395 KEY `idx_title` (`title`),
396 KEY `idx_fk_language_id` (`language_id`),
397 KEY `idx_fk_original_language_id` (`original_language_id`),
398 CONSTRAINT `fk_film_language` FOREIGN KEY (`language_id`) REFERENCES `language` (`language_id`) ON UPDATE CASCADE,
399 CONSTRAINT `fk_film_language_original` FOREIGN KEY (`original_language_id`) REFERENCES `language` (`language_id`) ON UPDATE CASCADE
400) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8
401
29sakila.film_actor402sakila.film_actor
403CREATE TABLE `film_actor` (
404 `actor_id` smallint(5) unsigned NOT NULL,
405 `film_id` smallint(5) unsigned NOT NULL,
406 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
407 PRIMARY KEY (`actor_id`,`film_id`),
408 KEY `idx_fk_film_id` (`film_id`),
409 CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`) ON UPDATE CASCADE,
410 CONSTRAINT `fk_film_actor_film` FOREIGN KEY (`film_id`) REFERENCES `film` (`film_id`) ON UPDATE CASCADE
411) ENGINE=InnoDB DEFAULT CHARSET=utf8
412
30sakila.film_category413sakila.film_category
414CREATE TABLE `film_category` (
415 `film_id` smallint(5) unsigned NOT NULL,
416 `category_id` tinyint(3) unsigned NOT NULL,
417 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
418 PRIMARY KEY (`film_id`,`category_id`),
419 KEY `fk_film_category_category` (`category_id`),
420 CONSTRAINT `fk_film_category_film` FOREIGN KEY (`film_id`) REFERENCES `film` (`film_id`) ON UPDATE CASCADE,
421 CONSTRAINT `fk_film_category_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`) ON UPDATE CASCADE
422) ENGINE=InnoDB DEFAULT CHARSET=utf8
423
31sakila.film_text424sakila.film_text
425CREATE TABLE `film_text` (
426 `film_id` smallint(6) NOT NULL,
427 `title` varchar(255) NOT NULL,
428 `description` text,
429 PRIMARY KEY (`film_id`),
430 FULLTEXT KEY `idx_title_description` (`title`,`description`)
431) ENGINE=MyISAM DEFAULT CHARSET=utf8
432
32sakila.inventory433sakila.inventory
434CREATE TABLE `inventory` (
435 `inventory_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
436 `film_id` smallint(5) unsigned NOT NULL,
437 `store_id` tinyint(3) unsigned NOT NULL,
438 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
439 PRIMARY KEY (`inventory_id`),
440 KEY `idx_fk_film_id` (`film_id`),
441 KEY `idx_store_id_film_id` (`store_id`,`film_id`),
442 CONSTRAINT `fk_inventory_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE,
443 CONSTRAINT `fk_inventory_film` FOREIGN KEY (`film_id`) REFERENCES `film` (`film_id`) ON UPDATE CASCADE
444) ENGINE=InnoDB AUTO_INCREMENT=4582 DEFAULT CHARSET=utf8
445
33sakila.language446sakila.language
447CREATE TABLE `language` (
448 `language_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
449 `name` char(20) NOT NULL,
450 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
451 PRIMARY KEY (`language_id`)
452) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
453
34sakila.payment454sakila.payment
455CREATE TABLE `payment` (
456 `payment_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
457 `customer_id` smallint(5) unsigned NOT NULL,
458 `staff_id` tinyint(3) unsigned NOT NULL,
459 `rental_id` int(11) DEFAULT NULL,
460 `amount` decimal(5,2) NOT NULL,
461 `payment_date` datetime NOT NULL,
462 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
463 PRIMARY KEY (`payment_id`),
464 KEY `idx_fk_staff_id` (`staff_id`),
465 KEY `idx_fk_customer_id` (`customer_id`),
466 KEY `fk_payment_rental` (`rental_id`),
467 CONSTRAINT `fk_payment_rental` FOREIGN KEY (`rental_id`) REFERENCES `rental` (`rental_id`) ON DELETE SET NULL ON UPDATE CASCADE,
468 CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE,
469 CONSTRAINT `fk_payment_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE
470) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
471
35sakila.rental472sakila.rental
473CREATE TABLE `rental` (
474 `rental_id` int(11) NOT NULL AUTO_INCREMENT,
475 `rental_date` datetime NOT NULL,
476 `inventory_id` mediumint(8) unsigned NOT NULL,
477 `customer_id` smallint(5) unsigned NOT NULL,
478 `return_date` datetime DEFAULT NULL,
479 `staff_id` tinyint(3) unsigned NOT NULL,
480 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
481 PRIMARY KEY (`rental_id`),
482 UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`),
483 KEY `idx_fk_inventory_id` (`inventory_id`),
484 KEY `idx_fk_customer_id` (`customer_id`),
485 KEY `idx_fk_staff_id` (`staff_id`),
486 CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
487 CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `inventory` (`inventory_id`) ON UPDATE CASCADE,
488 CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE
489) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
490
36sakila.staff491sakila.staff
492CREATE TABLE `staff` (
493 `staff_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
494 `first_name` varchar(45) NOT NULL,
495 `last_name` varchar(45) NOT NULL,
496 `address_id` smallint(5) unsigned NOT NULL,
497 `picture` blob,
498 `email` varchar(50) DEFAULT NULL,
499 `store_id` tinyint(3) unsigned NOT NULL,
500 `active` tinyint(1) NOT NULL DEFAULT '1',
501 `username` varchar(16) NOT NULL,
502 `password` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
503 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
504 PRIMARY KEY (`staff_id`),
505 KEY `idx_fk_store_id` (`store_id`),
506 KEY `idx_fk_address_id` (`address_id`),
507 CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE,
508 CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
509) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
510
37sakila.store511sakila.store
512CREATE TABLE `store` (
513 `store_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
514 `manager_staff_id` tinyint(3) unsigned NOT NULL,
515 `address_id` smallint(5) unsigned NOT NULL,
516 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
517 PRIMARY KEY (`store_id`),
518 UNIQUE KEY `idx_unique_manager` (`manager_staff_id`),
519 KEY `idx_fk_address_id` (`address_id`),
520 CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
521 CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
522) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
523
38524
=== added file 't/lib/samples/SchemaIterator/resume-from-ignored-sakila-payment-5.0.txt'
--- t/lib/samples/SchemaIterator/resume-from-ignored-sakila-payment-5.0.txt 1970-01-01 00:00:00 +0000
+++ t/lib/samples/SchemaIterator/resume-from-ignored-sakila-payment-5.0.txt 2012-05-30 22:08:19 +0000
@@ -0,0 +1,52 @@
1sakila.rental
2CREATE TABLE `rental` (
3 `rental_id` int(11) NOT NULL auto_increment,
4 `rental_date` datetime NOT NULL,
5 `inventory_id` mediumint(8) unsigned NOT NULL,
6 `customer_id` smallint(5) unsigned NOT NULL,
7 `return_date` datetime default NULL,
8 `staff_id` tinyint(3) unsigned NOT NULL,
9 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
10 PRIMARY KEY (`rental_id`),
11 UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`),
12 KEY `idx_fk_inventory_id` (`inventory_id`),
13 KEY `idx_fk_customer_id` (`customer_id`),
14 KEY `idx_fk_staff_id` (`staff_id`),
15 CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
16 CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `inventory` (`inventory_id`) ON UPDATE CASCADE,
17 CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE
18) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
19
20sakila.staff
21CREATE TABLE `staff` (
22 `staff_id` tinyint(3) unsigned NOT NULL auto_increment,
23 `first_name` varchar(45) NOT NULL,
24 `last_name` varchar(45) NOT NULL,
25 `address_id` smallint(5) unsigned NOT NULL,
26 `picture` blob,
27 `email` varchar(50) default NULL,
28 `store_id` tinyint(3) unsigned NOT NULL,
29 `active` tinyint(1) NOT NULL default '1',
30 `username` varchar(16) NOT NULL,
31 `password` varchar(40) character set utf8 collate utf8_bin default NULL,
32 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
33 PRIMARY KEY (`staff_id`),
34 KEY `idx_fk_store_id` (`store_id`),
35 KEY `idx_fk_address_id` (`address_id`),
36 CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE,
37 CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
38) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
39
40sakila.store
41CREATE TABLE `store` (
42 `store_id` tinyint(3) unsigned NOT NULL auto_increment,
43 `manager_staff_id` tinyint(3) unsigned NOT NULL,
44 `address_id` smallint(5) unsigned NOT NULL,
45 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
46 PRIMARY KEY (`store_id`),
47 UNIQUE KEY `idx_unique_manager` (`manager_staff_id`),
48 KEY `idx_fk_address_id` (`address_id`),
49 CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
50 CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
51) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
52
053
=== modified file 't/lib/samples/SchemaIterator/resume-from-ignored-sakila-payment.txt'
--- t/lib/samples/SchemaIterator/resume-from-ignored-sakila-payment.txt 2011-11-08 17:20:59 +0000
+++ t/lib/samples/SchemaIterator/resume-from-ignored-sakila-payment.txt 2012-05-30 22:08:19 +0000
@@ -1,3 +1,52 @@
1sakila.rental1sakila.rental
2CREATE TABLE `rental` (
3 `rental_id` int(11) NOT NULL AUTO_INCREMENT,
4 `rental_date` datetime NOT NULL,
5 `inventory_id` mediumint(8) unsigned NOT NULL,
6 `customer_id` smallint(5) unsigned NOT NULL,
7 `return_date` datetime DEFAULT NULL,
8 `staff_id` tinyint(3) unsigned NOT NULL,
9 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
10 PRIMARY KEY (`rental_id`),
11 UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`),
12 KEY `idx_fk_inventory_id` (`inventory_id`),
13 KEY `idx_fk_customer_id` (`customer_id`),
14 KEY `idx_fk_staff_id` (`staff_id`),
15 CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
16 CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `inventory` (`inventory_id`) ON UPDATE CASCADE,
17 CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE
18) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
19
2sakila.staff20sakila.staff
21CREATE TABLE `staff` (
22 `staff_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
23 `first_name` varchar(45) NOT NULL,
24 `last_name` varchar(45) NOT NULL,
25 `address_id` smallint(5) unsigned NOT NULL,
26 `picture` blob,
27 `email` varchar(50) DEFAULT NULL,
28 `store_id` tinyint(3) unsigned NOT NULL,
29 `active` tinyint(1) NOT NULL DEFAULT '1',
30 `username` varchar(16) NOT NULL,
31 `password` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
32 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
33 PRIMARY KEY (`staff_id`),
34 KEY `idx_fk_store_id` (`store_id`),
35 KEY `idx_fk_address_id` (`address_id`),
36 CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE,
37 CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
38) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
39
3sakila.store40sakila.store
41CREATE TABLE `store` (
42 `store_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
43 `manager_staff_id` tinyint(3) unsigned NOT NULL,
44 `address_id` smallint(5) unsigned NOT NULL,
45 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
46 PRIMARY KEY (`store_id`),
47 UNIQUE KEY `idx_unique_manager` (`manager_staff_id`),
48 KEY `idx_fk_address_id` (`address_id`),
49 CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
50 CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
51) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
52
453
=== added file 't/lib/samples/SchemaIterator/resume-from-sakila-payment-5.0.txt'
--- t/lib/samples/SchemaIterator/resume-from-sakila-payment-5.0.txt 1970-01-01 00:00:00 +0000
+++ t/lib/samples/SchemaIterator/resume-from-sakila-payment-5.0.txt 2012-05-30 22:08:19 +0000
@@ -0,0 +1,70 @@
1sakila.payment
2CREATE TABLE `payment` (
3 `payment_id` smallint(5) unsigned NOT NULL auto_increment,
4 `customer_id` smallint(5) unsigned NOT NULL,
5 `staff_id` tinyint(3) unsigned NOT NULL,
6 `rental_id` int(11) default NULL,
7 `amount` decimal(5,2) NOT NULL,
8 `payment_date` datetime NOT NULL,
9 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
10 PRIMARY KEY (`payment_id`),
11 KEY `idx_fk_staff_id` (`staff_id`),
12 KEY `idx_fk_customer_id` (`customer_id`),
13 KEY `fk_payment_rental` (`rental_id`),
14 CONSTRAINT `fk_payment_rental` FOREIGN KEY (`rental_id`) REFERENCES `rental` (`rental_id`) ON DELETE SET NULL ON UPDATE CASCADE,
15 CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE,
16 CONSTRAINT `fk_payment_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE
17) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
18
19sakila.rental
20CREATE TABLE `rental` (
21 `rental_id` int(11) NOT NULL auto_increment,
22 `rental_date` datetime NOT NULL,
23 `inventory_id` mediumint(8) unsigned NOT NULL,
24 `customer_id` smallint(5) unsigned NOT NULL,
25 `return_date` datetime default NULL,
26 `staff_id` tinyint(3) unsigned NOT NULL,
27 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
28 PRIMARY KEY (`rental_id`),
29 UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`),
30 KEY `idx_fk_inventory_id` (`inventory_id`),
31 KEY `idx_fk_customer_id` (`customer_id`),
32 KEY `idx_fk_staff_id` (`staff_id`),
33 CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
34 CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `inventory` (`inventory_id`) ON UPDATE CASCADE,
35 CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE
36) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
37
38sakila.staff
39CREATE TABLE `staff` (
40 `staff_id` tinyint(3) unsigned NOT NULL auto_increment,
41 `first_name` varchar(45) NOT NULL,
42 `last_name` varchar(45) NOT NULL,
43 `address_id` smallint(5) unsigned NOT NULL,
44 `picture` blob,
45 `email` varchar(50) default NULL,
46 `store_id` tinyint(3) unsigned NOT NULL,
47 `active` tinyint(1) NOT NULL default '1',
48 `username` varchar(16) NOT NULL,
49 `password` varchar(40) character set utf8 collate utf8_bin default NULL,
50 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
51 PRIMARY KEY (`staff_id`),
52 KEY `idx_fk_store_id` (`store_id`),
53 KEY `idx_fk_address_id` (`address_id`),
54 CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE,
55 CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
56) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
57
58sakila.store
59CREATE TABLE `store` (
60 `store_id` tinyint(3) unsigned NOT NULL auto_increment,
61 `manager_staff_id` tinyint(3) unsigned NOT NULL,
62 `address_id` smallint(5) unsigned NOT NULL,
63 `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
64 PRIMARY KEY (`store_id`),
65 UNIQUE KEY `idx_unique_manager` (`manager_staff_id`),
66 KEY `idx_fk_address_id` (`address_id`),
67 CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
68 CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
69) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
70
071
=== modified file 't/lib/samples/SchemaIterator/resume-from-sakila-payment.txt'
--- t/lib/samples/SchemaIterator/resume-from-sakila-payment.txt 2011-09-27 19:06:24 +0000
+++ t/lib/samples/SchemaIterator/resume-from-sakila-payment.txt 2012-05-30 22:08:19 +0000
@@ -1,4 +1,70 @@
1sakila.payment1sakila.payment
2CREATE TABLE `payment` (
3 `payment_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
4 `customer_id` smallint(5) unsigned NOT NULL,
5 `staff_id` tinyint(3) unsigned NOT NULL,
6 `rental_id` int(11) DEFAULT NULL,
7 `amount` decimal(5,2) NOT NULL,
8 `payment_date` datetime NOT NULL,
9 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
10 PRIMARY KEY (`payment_id`),
11 KEY `idx_fk_staff_id` (`staff_id`),
12 KEY `idx_fk_customer_id` (`customer_id`),
13 KEY `fk_payment_rental` (`rental_id`),
14 CONSTRAINT `fk_payment_rental` FOREIGN KEY (`rental_id`) REFERENCES `rental` (`rental_id`) ON DELETE SET NULL ON UPDATE CASCADE,
15 CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE,
16 CONSTRAINT `fk_payment_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE
17) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
18
2sakila.rental19sakila.rental
20CREATE TABLE `rental` (
21 `rental_id` int(11) NOT NULL AUTO_INCREMENT,
22 `rental_date` datetime NOT NULL,
23 `inventory_id` mediumint(8) unsigned NOT NULL,
24 `customer_id` smallint(5) unsigned NOT NULL,
25 `return_date` datetime DEFAULT NULL,
26 `staff_id` tinyint(3) unsigned NOT NULL,
27 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
28 PRIMARY KEY (`rental_id`),
29 UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`),
30 KEY `idx_fk_inventory_id` (`inventory_id`),
31 KEY `idx_fk_customer_id` (`customer_id`),
32 KEY `idx_fk_staff_id` (`staff_id`),
33 CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
34 CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `inventory` (`inventory_id`) ON UPDATE CASCADE,
35 CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE
36) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
37
3sakila.staff38sakila.staff
39CREATE TABLE `staff` (
40 `staff_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
41 `first_name` varchar(45) NOT NULL,
42 `last_name` varchar(45) NOT NULL,
43 `address_id` smallint(5) unsigned NOT NULL,
44 `picture` blob,
45 `email` varchar(50) DEFAULT NULL,
46 `store_id` tinyint(3) unsigned NOT NULL,
47 `active` tinyint(1) NOT NULL DEFAULT '1',
48 `username` varchar(16) NOT NULL,
49 `password` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
50 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
51 PRIMARY KEY (`staff_id`),
52 KEY `idx_fk_store_id` (`store_id`),
53 KEY `idx_fk_address_id` (`address_id`),
54 CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON UPDATE CASCADE,
55 CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
56) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
57
4sakila.store58sakila.store
59CREATE TABLE `store` (
60 `store_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
61 `manager_staff_id` tinyint(3) unsigned NOT NULL,
62 `address_id` smallint(5) unsigned NOT NULL,
63 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
64 PRIMARY KEY (`store_id`),
65 UNIQUE KEY `idx_unique_manager` (`manager_staff_id`),
66 KEY `idx_fk_address_id` (`address_id`),
67 CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE,
68 CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON UPDATE CASCADE
69) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
70
571
=== modified file 't/pt-table-sync/filters.t'
--- t/pt-table-sync/filters.t 2011-12-22 22:43:15 +0000
+++ t/pt-table-sync/filters.t 2012-05-30 22:08:19 +0000
@@ -29,7 +29,7 @@
29 plan skip_all => 'Cannot connect to sandbox slave';29 plan skip_all => 'Cannot connect to sandbox slave';
30}30}
31else {31else {
32 plan tests => 4;32 plan tests => 8;
33}33}
3434
35# Previous tests slave 12347 to 12346 which makes pt-table-checksum35# Previous tests slave 12347 to 12346 which makes pt-table-checksum
@@ -106,6 +106,79 @@
106);106);
107107
108# #############################################################################108# #############################################################################
109# pt-table-sync --ignore-* options don't work with --replicate
110# https://bugs.launchpad.net/percona-toolkit/+bug/1002365
111# #############################################################################
112$sb->wipe_clean($master_dbh);
113
114$sb->load_file("master", "t/pt-table-sync/samples/simple-tbls.sql");
115PerconaTest::wait_for_table($slave_dbh, "test.mt1", "id=10");
116
117# Create a checksum diff in a table that we're going to ignore
118# when we sync.
119$slave_dbh->do("INSERT INTO test.empty_it VALUES (null,11,11,'eleven')");
120
121# Create the checksums.
122diag(`$trunk/bin/pt-table-checksum h=127.1,P=12345,u=msandbox,p=msandbox -d test --quiet --quiet --lock-wait-timeout 3 --max-load ''`);
123
124# Make sure all the tables were checksummed.
125my $rows = $master_dbh->selectall_arrayref("SELECT DISTINCT db, tbl FROM percona.checksums ORDER BY db, tbl");
126is_deeply(
127 $rows,
128 [ [qw(test empty_it) ],
129 [qw(test empty_mt) ],
130 [qw(test it1) ],
131 [qw(test it2) ],
132 [qw(test mt1) ],
133 [qw(test mt2) ],
134 ],
135 "Six checksum tables (bug 1002365)"
136);
137
138# Sync the checksummed tables, but ignore the table with the diff we created.
139$output = output(
140 sub { pt_table_sync::main("h=127.1,P=12346,u=msandbox,p=msandbox",
141 qw(--print --sync-to-master --replicate percona.checksums),
142 "--ignore-tables", "test.empty_it") },
143 stderr => 1,
144);
145
146is(
147 $output,
148 "",
149 "Table ignored, nothing to sync (bug 1002365)"
150);
151
152# Sync the checksummed tables, but ignore the database.
153$output = output(
154 sub { pt_table_sync::main("h=127.1,P=12346,u=msandbox,p=msandbox",
155 qw(--print --sync-to-master --replicate percona.checksums),
156 "--ignore-databases", "test") },
157 stderr => 1,
158);
159
160is(
161 $output,
162 "",
163 "Database ignored, nothing to sync (bug 1002365)"
164);
165
166# The same should work for just --sync-to-master.
167$output = output(
168 sub { pt_table_sync::main("h=127.1,P=12346,u=msandbox,p=msandbox",
169 qw(--print --sync-to-master),
170 "--ignore-tables", "test.empty_it",
171 "--ignore-databases", "percona") },
172 stderr => 1,
173);
174
175unlike(
176 $output,
177 qr/empty_it/,
178 "Table ignored, nothing to sync-to-master (bug 1002365)"
179);
180
181# #############################################################################
109# Done.182# Done.
110# #############################################################################183# #############################################################################
111$sb->wipe_clean($master_dbh);184$sb->wipe_clean($master_dbh);

Subscribers

People subscribed via source and target branches