mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-20 10:55:01 +00:00
Do not ever create --new-table. Rewrite basics.t. Add more debug statements.
This commit is contained in:
@@ -5208,15 +5208,15 @@ sub main {
|
||||
print "Starting a dry run. $orig_tbl->{name} will not be altered. "
|
||||
. "Specify --execute instead of --dry-run to alter the table.\n";
|
||||
}
|
||||
elsif ( !$o->get('execute') ) {
|
||||
elsif ( $o->get('execute') ) {
|
||||
print "Altering $orig_tbl->{name}...\n";
|
||||
}
|
||||
else {
|
||||
print "Exiting without altering $orig_tbl->{name} because neither "
|
||||
. "--dry-run nor --execute was specified. Please read the tool's "
|
||||
. "documentation carefully before using this tool.\n";
|
||||
return $exit_status;
|
||||
}
|
||||
else {
|
||||
print "Altering $orig_tbl->{name}...\n";
|
||||
}
|
||||
|
||||
# ########################################################################
|
||||
# Check and create PID file if user specified --pid.
|
||||
@@ -5241,7 +5241,15 @@ sub main {
|
||||
db => $db,
|
||||
tbl => $tbl,
|
||||
);
|
||||
if ( !$new_table_exists ) {
|
||||
if ( $new_table_exists ) {
|
||||
# Do not create the new table if it already exists in case the user
|
||||
# does something bad like --new-table wrong.table because then we'll
|
||||
# modify the wrong table and really break stuff.
|
||||
die "The --new-table $new_table already exists. Please specify "
|
||||
. "a new table name that does not yet exist.\n";
|
||||
}
|
||||
else {
|
||||
# --new-table does not exist. Create it?
|
||||
if ( $o->get('create-new-table') ) {
|
||||
my $sql = "CREATE TABLE $new_table LIKE $orig_tbl->{name}";
|
||||
PTDEBUG && _d($sql);
|
||||
@@ -5711,6 +5719,7 @@ sub main {
|
||||
. "by executing: $drop_new_table_sql\n";
|
||||
}
|
||||
}
|
||||
PTDEBUG && _d('Old table:', Dumper($old_tbl));
|
||||
|
||||
# #####################################################################
|
||||
# Update foreign key constraints if there are child tables.
|
||||
@@ -5984,6 +5993,8 @@ sub find_child_tables {
|
||||
}
|
||||
my ($tbl, $cxn, $q) = @args{@required_args};
|
||||
|
||||
PTDEBUG && _d('Finding child tables');
|
||||
|
||||
my $sql = "SELECT table_name "
|
||||
. "FROM information_schema.key_column_usage "
|
||||
. "WHERE constraint_schema='$tbl->{db}' "
|
||||
@@ -5995,8 +6006,8 @@ sub find_child_tables {
|
||||
return;
|
||||
}
|
||||
|
||||
PTDEBUG && _d("Child tables:", Dumper($child_tables));
|
||||
my @child_tables = map { $_->[0] } @$child_tables;
|
||||
PTDEBUG && _d("Child tables:", @child_tables);
|
||||
return \@child_tables;
|
||||
}
|
||||
|
||||
@@ -6013,6 +6024,8 @@ sub rebuild_constraints {
|
||||
my $exit_status = 0;
|
||||
my $constraint = qr/^\s+(CONSTRAINT.+?REFERENCES `$old_tbl->{tbl}`.+)$/m;
|
||||
|
||||
PTDEBUG && _d('Rebuilding fk constraint:', $constraint);
|
||||
|
||||
if ( $o->get('dry-run') ) {
|
||||
print "Not rebuilding foreign key constraints because this is a dry run.\n";
|
||||
}
|
||||
@@ -6043,19 +6056,26 @@ sub rebuild_constraints {
|
||||
}
|
||||
|
||||
foreach my $constraint ( @constraints ) {
|
||||
my ($fk_symbol) = $constraint =~ m/CONSTRAINT\s+(\S+)/;
|
||||
PTDEBUG && _d('Rewriting fk constraint:', $constraint);
|
||||
my ($fk) = $constraint =~ m/CONSTRAINT\s+(\S+)/;
|
||||
|
||||
# Drop the reference to the old table/renamed orig table.
|
||||
$sql = "ALTER TABLE $child_table DROP FOREIGN KEY $fk_symbol";
|
||||
$sql = "ALTER TABLE $child_table DROP FOREIGN KEY $fk";
|
||||
print $sql, "\n" if $o->get('print');
|
||||
$cxn->dbh()->do($sql) if $o->get('execute');
|
||||
if ( $o->get('execute') ) {
|
||||
PTDEBUG && _d($sql);
|
||||
$cxn->dbh()->do($sql);
|
||||
}
|
||||
|
||||
# Make the child reference the new table, i.e. the table name it
|
||||
# originally referenced instead of the old/renamed orig table.
|
||||
$constraint =~ s/REFERENCES `$old_tbl->{tbl}`/REFERENCES `$orig_tbl->{tbl}`/o;
|
||||
$constraint =~ s/REFERENCES `$old_tbl->{tbl}`/REFERENCES `$orig_tbl->{tbl}`/;
|
||||
$sql = "ALTER TABLE $child_table ADD $constraint";
|
||||
print $sql, "\n" if $o->get('print');
|
||||
$cxn->dbh()->do($sql) if $o->get('execute');
|
||||
if ( $o->get('execute') ) {
|
||||
PTDEBUG && _d($sql);
|
||||
$cxn->dbh()->do($sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,150 +16,227 @@ use Sandbox;
|
||||
require "$trunk/bin/pt-online-schema-change";
|
||||
|
||||
use Data::Dumper;
|
||||
$Data::Dumper::Indent = 1;
|
||||
$Data::Dumper::Sortkeys = 1;
|
||||
$Data::Dumper::Quotekeys = 0;
|
||||
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('master');
|
||||
my $master_dbh = $sb->get_dbh_for('master');
|
||||
my $slave_dbh = $sb->get_dbh_for('slave1');
|
||||
|
||||
if ( !$dbh ) {
|
||||
if ( !$master_dbh ) {
|
||||
plan skip_all => 'Cannot connect to sandbox master';
|
||||
}
|
||||
else {
|
||||
plan tests => 23;
|
||||
plan tests => 38;
|
||||
}
|
||||
|
||||
my $q = new Quoter();
|
||||
my $tp = new TableParser(Quoter => $q);
|
||||
my @args = qw(--lock-wait-timeout 3);
|
||||
my $output = "";
|
||||
my $cnf = '/tmp/12345/my.sandbox.cnf';
|
||||
my @args = ('-F', $cnf, '--execute');
|
||||
my $dsn = "h=127.1,P=12345,u=msandbox,p=msandbox";
|
||||
my $exit = 0;
|
||||
my $sample = "t/pt-online-schema-change/samples";
|
||||
my $rows;
|
||||
|
||||
$sb->load_file('master', "t/pt-online-schema-change/samples/small_table.sql");
|
||||
$dbh->do('use mkosc');
|
||||
|
||||
# #############################################################################
|
||||
# Tool shouldn't run without --execute (bug 933232).
|
||||
# #############################################################################
|
||||
|
||||
$sb->load_file('master', "$sample/basic_no_fks.sql");
|
||||
PerconaTest::wait_for_table($slave_dbh, "pt_osc.t", "id=20");
|
||||
|
||||
# --new-table really ensures the tool exists before doing stuff because
|
||||
# setting up the new table is the first thing the tool does and this would
|
||||
# cause an error because mysql.user already exists. To prove this, add
|
||||
# --dry-run and the test will fail because the code doesn't exit early.
|
||||
$output = output(
|
||||
sub { pt_online_schema_change::main('h=127.1,P=12345,u=msandbox,p=msandbox,D=mkosc,t=a') },
|
||||
sub { $exit = pt_online_schema_change::main(@args, "$dsn,t=pt_osc.t",
|
||||
qw(--new-table mysql.user)) }
|
||||
);
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/you did not specify --execute/,
|
||||
"Doesn't run without --execute"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# --check-tables-and-exit
|
||||
# #############################################################################
|
||||
eval {
|
||||
$exit = pt_online_schema_change::main(@args,
|
||||
'D=mkosc,t=a', qw(--check-tables-and-exit --quiet))
|
||||
};
|
||||
|
||||
is(
|
||||
$EVAL_ERROR,
|
||||
"",
|
||||
"--check-tables-and-exit"
|
||||
qr/neither --dry-run nor --execute was specified/,
|
||||
"Doesn't run without --execute (bug 933232)"
|
||||
);
|
||||
|
||||
is(
|
||||
$exit,
|
||||
0,
|
||||
"Exit status 0"
|
||||
"Exit 0"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# --cleanup-and-exit
|
||||
# A helper sub to do the heavy lifting for us.
|
||||
# #############################################################################
|
||||
eval {
|
||||
$exit = pt_online_schema_change::main(@args,
|
||||
'D=mkosc,t=a', qw(--cleanup-and-exit --quiet))
|
||||
};
|
||||
|
||||
is(
|
||||
$EVAL_ERROR,
|
||||
"",
|
||||
"--cleanup-and-exit",
|
||||
sub test_alter_table {
|
||||
my (%args) = @_;
|
||||
return if $args{skip};
|
||||
|
||||
my @required_args = qw(name table test_type cmds);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($name, $table, $test_type, $cmds) = @args{@required_args};
|
||||
|
||||
my ($db, $tbl) = $q->split_unquote($table);
|
||||
my $pk_col = $args{pk_col} || 'id';
|
||||
|
||||
if ( my $file = $args{file} ) {
|
||||
$sb->load_file('master', "$sample/$file");
|
||||
if ( my $wait = $args{wait} ) {
|
||||
PerconaTest::wait_for_table($slave_dbh, @$wait);
|
||||
}
|
||||
else {
|
||||
PerconaTest::wait_for_table($slave_dbh, $table, "`$pk_col`=$args{max_id}");
|
||||
}
|
||||
$master_dbh->do("USE `$db`");
|
||||
$slave_dbh->do("USE `$db`");
|
||||
}
|
||||
|
||||
my $ddl = $tp->get_create_table($master_dbh, $db, $tbl);
|
||||
my $tbl_struct = $tp->parse($ddl);
|
||||
|
||||
my $cols = '*';
|
||||
if ( $test_type eq 'drop_col' && !grep { $_ eq '--dry-run' } @$cmds ) {
|
||||
# Don't select the column being dropped.
|
||||
my $col = $args{drop_col};
|
||||
die "I need a drop_col argument" unless $col;
|
||||
$cols = join(', ', grep { $_ ne $col } @{$tbl_struct->{cols}});
|
||||
}
|
||||
my $orig_rows = $master_dbh->selectall_arrayref(
|
||||
"SELECT $cols FROM $table ORDER BY `$pk_col`");
|
||||
|
||||
my $orig_tbls = $master_dbh->selectall_arrayref(
|
||||
"SHOW TABLES FROM `$db`");
|
||||
|
||||
my @orig_fks;
|
||||
if ( $args{check_fks} ) {
|
||||
foreach my $tbl ( @$orig_tbls ) {
|
||||
my $fks = $tp->get_fks(
|
||||
$tp->get_create_table($master_dbh, $db, $tbl->[0]));
|
||||
push @orig_fks, $fks;
|
||||
}
|
||||
}
|
||||
|
||||
$output = output(
|
||||
sub { $exit = pt_online_schema_change::main(
|
||||
@args,
|
||||
"$dsn,D=$db,t=$tbl",
|
||||
@$cmds,
|
||||
)},
|
||||
);
|
||||
|
||||
is(
|
||||
$exit,
|
||||
0,
|
||||
"Exit status 0"
|
||||
"$name exit 0"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# The most basic: copy, alter and rename a small table that's not even active.
|
||||
# #############################################################################
|
||||
|
||||
output(
|
||||
sub { $exit = pt_online_schema_change::main(@args,
|
||||
'D=mkosc,t=a', qw(--alter ENGINE=InnoDB)) },
|
||||
# There should be no new or missing tables.
|
||||
my $new_tbls = $master_dbh->selectall_arrayref("SHOW TABLES FROM `$db`");
|
||||
is_deeply(
|
||||
$new_tbls,
|
||||
$orig_tbls,
|
||||
"$name tables"
|
||||
);
|
||||
|
||||
$rows = $dbh->selectall_hashref('show table status from mkosc', 'name');
|
||||
is(
|
||||
$rows->{a}->{engine},
|
||||
'InnoDB',
|
||||
"New table ENGINE=InnoDB"
|
||||
);
|
||||
|
||||
is(
|
||||
$rows->{__old_a}->{engine},
|
||||
'MyISAM',
|
||||
"Kept old table, ENGINE=MyISAM"
|
||||
);
|
||||
|
||||
my $org_rows = $dbh->selectall_arrayref('select * from mkosc.__old_a order by i');
|
||||
my $new_rows = $dbh->selectall_arrayref('select * from mkosc.a order by i');
|
||||
# Rows in the original and new table should be identical.
|
||||
my $new_rows = $master_dbh->selectall_arrayref("SELECT * FROM $table ORDER BY `$pk_col`");
|
||||
is_deeply(
|
||||
$new_rows,
|
||||
$org_rows,
|
||||
"New tables rows identical to old table rows"
|
||||
$orig_rows,
|
||||
"$name rows"
|
||||
);
|
||||
|
||||
# Check if the ALTER was actually done.
|
||||
if ( $test_type eq 'drop_col' ) {
|
||||
my $col = $q->quote($args{drop_col});
|
||||
my $ddl = $tp->get_create_table($master_dbh, $db, $tbl);
|
||||
if ( grep { $_ eq '--dry-run' } @$cmds ) {
|
||||
like(
|
||||
$ddl,
|
||||
qr/^\s+$col\s+/m,
|
||||
"$name ALTER DROP COLUMN=$args{drop_col} (dry run)"
|
||||
);
|
||||
}
|
||||
else {
|
||||
unlike(
|
||||
$ddl,
|
||||
qr/^\s+$col\s+/m,
|
||||
"$name ALTER DROP COLUMN=$args{drop_col}"
|
||||
);
|
||||
}
|
||||
}
|
||||
elsif ( $test_type eq 'add_col' ) {
|
||||
}
|
||||
elsif ( $test_type eq 'new_engine' ) {
|
||||
my $new_engine = lc($args{new_engine});
|
||||
die "I need a new_engine argument" unless $new_engine;
|
||||
my $rows = $master_dbh->selectall_hashref(
|
||||
"SHOW TABLE STATUS FROM `$db`", "name");
|
||||
is(
|
||||
$exit,
|
||||
0,
|
||||
"Exit status 0"
|
||||
lc($rows->{$tbl}->{engine}),
|
||||
$new_engine,
|
||||
"$name ALTER ENGINE=$args{new_engine}"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# No --alter and --drop-old-table.
|
||||
# #############################################################################
|
||||
$dbh->do('drop table if exists mkosc.__old_a'); # from previous run
|
||||
$sb->load_file('master', "t/pt-online-schema-change/samples/small_table.sql");
|
||||
}
|
||||
|
||||
output(
|
||||
sub { $exit = pt_online_schema_change::main(@args,
|
||||
'D=mkosc,t=a', qw(--drop-old-table)) },
|
||||
);
|
||||
|
||||
$rows = $dbh->selectall_hashref('show table status from mkosc', 'name');
|
||||
is(
|
||||
$rows->{a}->{engine},
|
||||
'MyISAM',
|
||||
"No --alter, new table still ENGINE=MyISAM"
|
||||
);
|
||||
|
||||
ok(
|
||||
!exists $rows->{__old_a},
|
||||
"--drop-old-table"
|
||||
);
|
||||
|
||||
$new_rows = $dbh->selectall_arrayref('select * from mkosc.a order by i');
|
||||
if ( $args{check_fks} ) {
|
||||
my @new_fks;
|
||||
foreach my $tbl ( @$orig_tbls ) {
|
||||
my $fks = $tp->get_fks(
|
||||
$tp->get_create_table($master_dbh, $db, $tbl->[0]));
|
||||
push @new_fks, $fks;
|
||||
}
|
||||
is_deeply(
|
||||
$new_rows,
|
||||
$org_rows, # from previous run since old table was dropped this run
|
||||
"New tables rows identical to old table rows"
|
||||
\@new_fks,
|
||||
\@orig_fks,
|
||||
"$name FK constraints"
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# #############################################################################
|
||||
# The most basic: alter a small table with no fks that's not active.
|
||||
# #############################################################################
|
||||
|
||||
test_alter_table(
|
||||
name => "Basic no fks --dry-run",
|
||||
table => "pt_osc.t",
|
||||
file => "basic_no_fks.sql",
|
||||
max_id => 20,
|
||||
test_type => "new_engine",
|
||||
new_engine => "MyISAM",
|
||||
cmds => [qw(--dry-run --alter ENGINE=InnoDB)],
|
||||
);
|
||||
|
||||
is(
|
||||
$exit,
|
||||
0,
|
||||
"Exit status 0"
|
||||
test_alter_table(
|
||||
name => "Basic no fks --execute",
|
||||
table => "pt_osc.t",
|
||||
# The previous test should not have modified the table.
|
||||
# file => "basic_no_fks.sql",
|
||||
# max_id => 20,
|
||||
test_type => "new_engine",
|
||||
new_engine => "InnoDB",
|
||||
cmds => [qw(--execute --alter ENGINE=InnoDB)],
|
||||
);
|
||||
|
||||
test_alter_table(
|
||||
name => "--execute but no --alter",
|
||||
table => "pt_osc.t",
|
||||
file => "basic_no_fks.sql",
|
||||
max_id => 20,
|
||||
test_type => "new_engine",
|
||||
new_engine => "MyISAM",
|
||||
cmds => [qw(--execute)],
|
||||
);
|
||||
|
||||
# ############################################################################
|
||||
@@ -167,82 +244,93 @@ is(
|
||||
# ############################################################################
|
||||
|
||||
# The tables we're loading have fk constraints like:
|
||||
# country
|
||||
# ^- city (on update cascade)
|
||||
# ^- address (on update cascade)
|
||||
# country <-- city <-- address
|
||||
|
||||
############################
|
||||
# rebuild_constraints method
|
||||
############################
|
||||
$sb->load_file('master', "t/pt-online-schema-change/samples/fk_tables_schema.sql");
|
||||
# rebuild_constraints method -- This parses the fk constraint ddls from
|
||||
# the create table ddl, rewrites them, then does an alter table on the
|
||||
# child tables so they point back to the original table name.
|
||||
|
||||
# city has a fk constraint on country, so get its original table def.
|
||||
my $orig_table_def = $dbh->selectrow_hashref('show create table mkosc.city')->{'create table'};
|
||||
|
||||
# Alter the parent table. The error we need to avoid is:
|
||||
# DBD::mysql::db do failed: Cannot delete or update a parent row:
|
||||
# a foreign key constraint fails [for Statement "DROP TABLE
|
||||
# `mkosc`.`__old_country`"]
|
||||
output(
|
||||
sub { $exit = pt_online_schema_change::main(@args,
|
||||
'D=mkosc,t=country', qw(--child-tables auto_detect --drop-old-table),
|
||||
qw(--update-foreign-keys-method rebuild_constraints)) },
|
||||
);
|
||||
is(
|
||||
$exit,
|
||||
0,
|
||||
"Exit status 0 (rebuild_constraints method)"
|
||||
test_alter_table(
|
||||
name => "Basic FK rebuild --dry-run",
|
||||
table => "pt_osc.country",
|
||||
pk_col => "country_id",
|
||||
file => "basic_with_fks.sql",
|
||||
wait => ["pt_osc.address", "address_id=5"],
|
||||
test_type => "drop_col",
|
||||
drop_col => "last_update",
|
||||
check_fks => 1,
|
||||
cmds => [
|
||||
qw(
|
||||
--dry-run
|
||||
--find-child-tables
|
||||
--update-foreign-keys-method rebuild_constraints
|
||||
),
|
||||
'--alter', 'DROP COLUMN last_update',
|
||||
],
|
||||
);
|
||||
|
||||
$rows = $dbh->selectall_arrayref('show tables from mkosc like "\_\_%"');
|
||||
is_deeply(
|
||||
$rows,
|
||||
[],
|
||||
"Old table dropped (rebuild_constraints method)"
|
||||
test_alter_table(
|
||||
name => "Basic FK rebuild --execute",
|
||||
table => "pt_osc.country",
|
||||
pk_col => "country_id",
|
||||
# The previous test should not have modified the table.
|
||||
# file => "basic_with_fks.sql",
|
||||
# wait => ["pt_osc.address", "address_id=5"],
|
||||
test_type => "drop_col",
|
||||
drop_col => "last_update",
|
||||
check_fks => 1,
|
||||
cmds => [
|
||||
qw(
|
||||
--execute
|
||||
--find-child-tables
|
||||
--update-foreign-keys-method rebuild_constraints
|
||||
),
|
||||
'--alter', 'DROP COLUMN last_update',
|
||||
],
|
||||
);
|
||||
|
||||
# Get city's table def again and verify that its fk constraint still
|
||||
# references country. When country was renamed to __old_country, MySQL
|
||||
# also updated city's fk constraint to __old_country. We should have
|
||||
# dropped and re-added that constraint exactly, changing only __old_country
|
||||
# to country, like it originally was.
|
||||
my $new_table_def = $dbh->selectrow_hashref('show create table mkosc.city')->{'create table'};
|
||||
is(
|
||||
$new_table_def,
|
||||
$orig_table_def,
|
||||
"Updated child table foreign key constraint (rebuild_constraints method)"
|
||||
# drop_old_table method -- This method tricks MySQL by disabling fk checks,
|
||||
# then dropping the original table and renaming the new table in its place.
|
||||
# Since fk checks were disabled, MySQL doesn't update the child table fk refs.
|
||||
# Somewhat dangerous, but quick. Downside: table doesn't exist for a moment.
|
||||
|
||||
test_alter_table(
|
||||
name => "Basic FK drop-swap --dry-run",
|
||||
table => "pt_osc.country",
|
||||
pk_col => "country_id",
|
||||
file => "basic_with_fks.sql",
|
||||
wait => ["pt_osc.address", "address_id=5"],
|
||||
test_type => "drop_col",
|
||||
drop_col => "last_update",
|
||||
check_fks => 1,
|
||||
cmds => [
|
||||
qw(
|
||||
--dry-run
|
||||
--find-child-tables
|
||||
--update-foreign-keys-method drop_old_table
|
||||
),
|
||||
'--alter', 'DROP COLUMN last_update',
|
||||
],
|
||||
);
|
||||
|
||||
#######################
|
||||
# drop_old_table method
|
||||
#######################
|
||||
$sb->load_file('master', "t/pt-online-schema-change/samples/fk_tables_schema.sql");
|
||||
|
||||
$orig_table_def = $dbh->selectrow_hashref('show create table mkosc.city')->{'create table'};
|
||||
|
||||
output(
|
||||
sub { $exit = pt_online_schema_change::main(@args,
|
||||
'D=mkosc,t=country', qw(--child-tables auto_detect),
|
||||
qw(--update-foreign-keys-method drop_old_table)) },
|
||||
);
|
||||
is(
|
||||
$exit,
|
||||
0,
|
||||
"Exit status 0 (drop_old_table method)"
|
||||
);
|
||||
|
||||
$rows = $dbh->selectall_arrayref('show tables from mkosc like "\_\_%"');
|
||||
is_deeply(
|
||||
$rows,
|
||||
[],
|
||||
"Old table dropped (drop_old_table method)"
|
||||
) or print Dumper($rows);
|
||||
|
||||
$new_table_def = $dbh->selectrow_hashref('show create table mkosc.city')->{'create table'};
|
||||
is(
|
||||
$new_table_def,
|
||||
$orig_table_def,
|
||||
"Updated child table foreign key constraint (drop_old_table method)"
|
||||
test_alter_table(
|
||||
name => "Basic FK drop-swap --execute",
|
||||
table => "pt_osc.country",
|
||||
pk_col => "country_id",
|
||||
# The previous test should not have modified the table.
|
||||
# file => "basic_with_fks.sql",
|
||||
# wait => ["pt_osc.address", "address_id=5"],
|
||||
test_type => "drop_col",
|
||||
drop_col => "last_update",
|
||||
check_fks => 1,
|
||||
cmds => [
|
||||
qw(
|
||||
--execute
|
||||
--find-child-tables
|
||||
--update-foreign-keys-method drop_old_table
|
||||
),
|
||||
'--alter', 'DROP COLUMN last_update',
|
||||
],
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
@@ -253,19 +341,19 @@ sub test_table {
|
||||
my ($file, $name) = @args{qw(file name)};
|
||||
|
||||
$sb->load_file('master', "t/lib/samples/osc/$file");
|
||||
PerconaTest::wait_for_table($dbh, "osc.t", "id=5");
|
||||
PerconaTest::wait_for_table($dbh, "osc.__new_t");
|
||||
$dbh->do('use osc');
|
||||
$dbh->do("DROP TABLE IF EXISTS osc.__new_t");
|
||||
PerconaTest::wait_for_table($master_dbh, "osc.t", "id=5");
|
||||
PerconaTest::wait_for_table($master_dbh, "osc.__new_t");
|
||||
$master_dbh->do('use osc');
|
||||
$master_dbh->do("DROP TABLE IF EXISTS osc.__new_t");
|
||||
|
||||
$org_rows = $dbh->selectall_arrayref('select * from osc.t order by id');
|
||||
my $org_rows = $master_dbh->selectall_arrayref('select * from osc.t order by id');
|
||||
|
||||
output(
|
||||
sub { $exit = pt_online_schema_change::main(@args,
|
||||
'D=osc,t=t', qw(--alter ENGINE=InnoDB)) },
|
||||
"$dsn,D=osc,t=t", qw(--alter ENGINE=InnoDB)) },
|
||||
);
|
||||
|
||||
$new_rows = $dbh->selectall_arrayref('select * from osc.t order by id');
|
||||
my $new_rows = $master_dbh->selectall_arrayref('select * from osc.t order by id');
|
||||
|
||||
is_deeply(
|
||||
$new_rows,
|
||||
@@ -293,5 +381,5 @@ test_table(
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
$sb->wipe_clean($dbh);
|
||||
$sb->wipe_clean($master_dbh);
|
||||
exit;
|
||||
|
@@ -1,12 +1,13 @@
|
||||
DROP DATABASE IF EXISTS `mkosc`;
|
||||
CREATE DATABASE `mkosc`;
|
||||
USE `mkosc`;
|
||||
CREATE TABLE a (
|
||||
i int auto_increment primary key,
|
||||
DROP DATABASE IF EXISTS pt_osc;
|
||||
CREATE DATABASE pt_osc;
|
||||
USE pt_osc;
|
||||
CREATE TABLE t (
|
||||
id int auto_increment primary key,
|
||||
c char(16),
|
||||
d date
|
||||
d date,
|
||||
unique index (c(16))
|
||||
) ENGINE=MyISAM;
|
||||
INSERT INTO a VALUES
|
||||
INSERT INTO pt_osc.t VALUES
|
||||
(null, 'a', now()),
|
||||
(null, 'b', now()),
|
||||
(null, 'c', now()),
|
||||
@@ -16,7 +17,7 @@ INSERT INTO a VALUES
|
||||
(null, 'g', now()),
|
||||
(null, 'h', now()),
|
||||
(null, 'i', now()),
|
||||
(null, 'j', now()),
|
||||
(null, 'j', now()), -- 10
|
||||
(null, 'k', now()),
|
||||
(null, 'l', now()),
|
||||
(null, 'm', now()),
|
||||
@@ -24,4 +25,6 @@ INSERT INTO a VALUES
|
||||
(null, 'o', now()),
|
||||
(null, 'p', now()),
|
||||
(null, 'q', now()),
|
||||
(null, 'r', now());
|
||||
(null, 'r', now()),
|
||||
(null, 's', now()),
|
||||
(null, 't', now()); -- 20
|
@@ -1,6 +1,8 @@
|
||||
DROP DATABASE IF EXISTS `mkosc`;
|
||||
CREATE DATABASE `mkosc`;
|
||||
USE `mkosc`;
|
||||
DROP DATABASE IF EXISTS pt_osc;
|
||||
CREATE DATABASE pt_osc;
|
||||
USE pt_osc;
|
||||
|
||||
SET foreign_key_checks=0;
|
||||
|
||||
CREATE TABLE `country` (
|
||||
`country_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
|
||||
@@ -29,3 +31,26 @@ CREATE TABLE `address` (
|
||||
KEY `idx_fk_city_id` (`city_id`),
|
||||
CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `city` (`city_id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO pt_osc.country VALUES
|
||||
(1, 'Canada', null),
|
||||
(2, 'USA', null),
|
||||
(3, 'Mexico', null),
|
||||
(4, 'France', null),
|
||||
(5, 'Spain', null);
|
||||
|
||||
INSERT INTO pt_osc.city VALUES
|
||||
(null, 'Montréal', 1, null),
|
||||
(null, 'New York', 2, null),
|
||||
(null, 'Durango', 3, null),
|
||||
(null, 'Paris', 4, null),
|
||||
(null, 'Madrid', 5, null);
|
||||
|
||||
INSERT INTO pt_osc.address VALUES
|
||||
(null, 'addy 1', 1, '10000', null),
|
||||
(null, 'addy 2', 2, '20000', null),
|
||||
(null, 'addy 3', 3, '30000', null),
|
||||
(null, 'addy 4', 4, '40000', null),
|
||||
(null, 'addy 5', 5, '50000', null);
|
||||
|
||||
SET foreign_key_checks=1;
|
Reference in New Issue
Block a user