Revert "Merge pull request #427 from percona/PT-1747"

This reverts commit 25b637d4bd, reversing
changes made to 38c169031e.
This commit is contained in:
Carlos Salguero
2020-04-03 14:40:35 -03:00
parent 54f90e4bdf
commit 208fb86586
4 changed files with 316 additions and 435 deletions

View File

@@ -8376,7 +8376,6 @@ my $dont_interrupt_now = 0;
my @drop_trigger_sqls;
my @triggers_not_dropped;
my $pxc_version = '0';
my $can_drop_triggers = 1;
my $triggers_info = [];
@@ -9551,7 +9550,6 @@ sub main {
# called which will drop whichever triggers were created.
my $drop_triggers = $o->get('drop-triggers');
push @cleanup_tasks, sub {
PTDEBUG && _d('Clean up triggers');
# --plugin hook
if ( $plugin && $plugin->can('before_drop_triggers') ) {
@@ -9562,12 +9560,12 @@ sub main {
);
}
if ( !$oktorun || !_can_drop_triggers()) {
if ( !$oktorun ) {
print "Not dropping triggers because the tool was interrupted. "
. "To drop the triggers, execute:\n"
. join("\n", @drop_trigger_sqls) . "\n";
}
elsif ( !$drop_triggers || !_can_drop_triggers()) {
elsif ( !$drop_triggers ) {
print "Not dropping triggers because --no-drop-triggers was "
. "specified. To drop the triggers, execute:\n"
. join("\n", @drop_trigger_sqls) . "\n";
@@ -10000,76 +9998,6 @@ sub main {
$plugin->after_copy_rows();
}
# #####################################################################
# Step 5a: Update foreign key constraints if there are child tables.
# #####################################################################
if ( $child_tables ) {
# --plugin hook
if ( $plugin && $plugin->can('before_update_foreign_keys') ) {
$plugin->before_update_foreign_keys();
}
eval {
if ( $alter_fk_method eq 'none' ) {
# This shouldn't happen, but in case it does we should know.
warn "The tool detected child tables but "
. "--alter-foreign-keys-method=none";
}
elsif ( $alter_fk_method eq 'rebuild_constraints' ) {
rebuild_constraints(
orig_tbl => $new_tbl,
old_tbl => $orig_tbl,
# orig_tbl => $orig_tbl,
# old_tbl => $old_tbl,
child_tables => $child_tables,
OptionParser => $o,
Quoter => $q,
Cxn => $cxn,
TableParser => $tp,
stats => \%stats,
Retry => $retry,
tries => $tries,
);
}
elsif ( $alter_fk_method eq 'drop_swap' ) {
drop_swap(
orig_tbl => $new_tbl,
new_tbl => $orig_tbl,
# orig_tbl => $orig_tbl,
# new_tbl => $new_tbl,
Cxn => $cxn,
OptionParser => $o,
stats => \%stats,
Retry => $retry,
tries => $tries,
analyze_table => $analyze_table,
);
}
elsif ( !$alter_fk_method
&& $o->has('alter-foreign-keys-method')
&& ($o->get('alter-foreign-keys-method') || '') eq 'auto' ) {
# If --alter-foreign-keys-method is 'auto' and we are on a dry run,
# $alter_fk_method is left as an empty string.
print "Not updating foreign key constraints because this is a dry run.\n";
}
else {
# This should "never" happen because we check this var earlier.
_die("Invalid --alter-foreign-keys-method: $alter_fk_method", INVALID_ALTER_FK_METHOD);
}
};
if ( $EVAL_ERROR ) {
# TODO: improve error message and handling.
$can_drop_triggers=undef;
$oktorun=undef;
_die("Error updating foreign key constraints: $EVAL_ERROR", ERROR_UPDATING_FKS);
}
# --plugin hook
if ( $plugin && $plugin->can('after_update_foreign_keys') ) {
$plugin->after_update_foreign_keys();
}
}
# #####################################################################
# XXX
# Step 5: Rename tables: orig -> old, new -> orig
@@ -10164,66 +10092,66 @@ sub main {
# #####################################################################
# Step 6: Update foreign key constraints if there are child tables.
# #####################################################################
# if ( $child_tables ) {
# # --plugin hook
# if ( $plugin && $plugin->can('before_update_foreign_keys') ) {
# $plugin->before_update_foreign_keys();
# }
#
# eval {
# if ( $alter_fk_method eq 'none' ) {
# # This shouldn't happen, but in case it does we should know.
# warn "The tool detected child tables but "
# . "--alter-foreign-keys-method=none";
# }
# elsif ( $alter_fk_method eq 'rebuild_constraints' ) {
# rebuild_constraints(
# orig_tbl => $orig_tbl,
# old_tbl => $old_tbl,
# child_tables => $child_tables,
# OptionParser => $o,
# Quoter => $q,
# Cxn => $cxn,
# TableParser => $tp,
# stats => \%stats,
# Retry => $retry,
# tries => $tries,
# );
# }
# elsif ( $alter_fk_method eq 'drop_swap' ) {
# drop_swap(
# orig_tbl => $orig_tbl,
# new_tbl => $new_tbl,
# Cxn => $cxn,
# OptionParser => $o,
# stats => \%stats,
# Retry => $retry,
# tries => $tries,
# analyze_table => $analyze_table,
# );
# }
# elsif ( !$alter_fk_method
# && $o->has('alter-foreign-keys-method')
# && ($o->get('alter-foreign-keys-method') || '') eq 'auto' ) {
# # If --alter-foreign-keys-method is 'auto' and we are on a dry run,
# # $alter_fk_method is left as an empty string.
# print "Not updating foreign key constraints because this is a dry run.\n";
# }
# else {
# # This should "never" happen because we check this var earlier.
# _die("Invalid --alter-foreign-keys-method: $alter_fk_method", INVALID_ALTER_FK_METHOD);
# }
# };
# if ( $EVAL_ERROR ) {
# # TODO: improve error message and handling.
# _die("Error updating foreign key constraints: $EVAL_ERROR", ERROR_UPDATING_FKS);
# }
#
# # --plugin hook
# if ( $plugin && $plugin->can('after_update_foreign_keys') ) {
# $plugin->after_update_foreign_keys();
# }
# }
if ( $child_tables ) {
# --plugin hook
if ( $plugin && $plugin->can('before_update_foreign_keys') ) {
$plugin->before_update_foreign_keys();
}
eval {
if ( $alter_fk_method eq 'none' ) {
# This shouldn't happen, but in case it does we should know.
warn "The tool detected child tables but "
. "--alter-foreign-keys-method=none";
}
elsif ( $alter_fk_method eq 'rebuild_constraints' ) {
rebuild_constraints(
orig_tbl => $orig_tbl,
old_tbl => $old_tbl,
child_tables => $child_tables,
OptionParser => $o,
Quoter => $q,
Cxn => $cxn,
TableParser => $tp,
stats => \%stats,
Retry => $retry,
tries => $tries,
);
}
elsif ( $alter_fk_method eq 'drop_swap' ) {
drop_swap(
orig_tbl => $orig_tbl,
new_tbl => $new_tbl,
Cxn => $cxn,
OptionParser => $o,
stats => \%stats,
Retry => $retry,
tries => $tries,
analyze_table => $analyze_table,
);
}
elsif ( !$alter_fk_method
&& $o->has('alter-foreign-keys-method')
&& ($o->get('alter-foreign-keys-method') || '') eq 'auto' ) {
# If --alter-foreign-keys-method is 'auto' and we are on a dry run,
# $alter_fk_method is left as an empty string.
print "Not updating foreign key constraints because this is a dry run.\n";
}
else {
# This should "never" happen because we check this var earlier.
_die("Invalid --alter-foreign-keys-method: $alter_fk_method", INVALID_ALTER_FK_METHOD);
}
};
if ( $EVAL_ERROR ) {
# TODO: improve error message and handling.
_die("Error updating foreign key constraints: $EVAL_ERROR", ERROR_UPDATING_FKS);
}
# --plugin hook
if ( $plugin && $plugin->can('after_update_foreign_keys') ) {
$plugin->after_update_foreign_keys();
}
}
# ########################################################################
# Step 7: Drop the old table.
@@ -10297,10 +10225,6 @@ sub main {
# Subroutines.
# ############################################################################
sub _can_drop_triggers {
return $can_drop_triggers;
}
sub validate_tries {
my ($o) = @_;
my @ops = qw(
@@ -11082,8 +11006,6 @@ sub rebuild_constraints {
print ts("Rebuilding foreign key constraints...\n");
}
my $foreign_key_checks;
CHILD_TABLE:
foreach my $child_tbl ( @$child_tables ) {
my $table_def = $tp->get_create_table(
@@ -11141,22 +11063,15 @@ sub rebuild_constraints {
$constraint =~ s/CONSTRAINT `$fk`/CONSTRAINT `$new_fk`/;
my $sql = "DROP FOREIGN KEY `$fk`, ADD $constraint";
my $sql = "DROP FOREIGN KEY `$fk`, "
. "ADD $constraint";
push @rebuilt_constraints, $sql;
}
my $server_version = VersionParser->new($cxn->dbh());
if ($server_version >= '5.6' && $o->get('disable-fk-checks')) {
my $row = $cxn->dbh()->selectrow_arrayref('SELECT @@foreign_key_checks');
$foreign_key_checks = @$row[0];
ts("Disabling FK checks");
$cxn->dbh()->do("SET FOREIGN_KEY_CHECKS=0");
}
my $sql = "ALTER TABLE $child_tbl->{name} "
. join(', ', @rebuilt_constraints);
print $sql, "\n" if $o->get('print');
if ( $o->get('execute') ) {
eval {
osc_retry(
Cxn => $cxn,
Retry => $retry,
@@ -11168,20 +11083,6 @@ sub rebuild_constraints {
$stats->{rebuilt_constraint}++;
},
);
};
if ($foreign_key_checks) {
ts("Re-enabling FK checks");
$cxn->dbh()->do("SET FOREIGN_KEY_CHECKS=$foreign_key_checks");
}
if ($EVAL_ERROR) {
$can_drop_triggers=undef;
$oktorun=undef;
_d("Foreing keys rebuild failed. To rebuild constraints please manually run:");
foreach my $cmd (@rebuilt_constraints) {
print "$cmd\n";
}
_die("Foreing keys were not rebuilt");
}
}
}
@@ -11308,11 +11209,10 @@ sub create_triggers {
"$new_tbl->{name}.$new_qcol <=> OLD.$old_qcol"
} @{$tbl_struct->{keys}->{$del_index}->{cols}} );
my $ignore_clause = $o->get("delete-ignore") ? "IGNORE" : "";
my $delete_trigger
= "CREATE TRIGGER `${prefix}_del` AFTER DELETE ON $orig_tbl->{name} "
. "FOR EACH ROW "
. "DELETE $ignore_clause FROM $new_tbl->{name} "
. "DELETE IGNORE FROM $new_tbl->{name} "
. "WHERE $del_index_cols";
# ---------------------------------------------------------------------------------------
@@ -11338,7 +11238,7 @@ sub create_triggers {
= "CREATE TRIGGER `${prefix}_upd` AFTER UPDATE ON $orig_tbl->{name} "
. "FOR EACH ROW "
. "BEGIN "
. "DELETE $ignore_clause FROM $new_tbl->{name} WHERE !($upd_index_cols) AND $del_index_cols;"
. "DELETE IGNORE FROM $new_tbl->{name} WHERE !($upd_index_cols) AND $del_index_cols;"
. "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals);"
. "END ";
@@ -11637,11 +11537,6 @@ sub osc_retry {
) {
# These errors/warnings can be retried, so don't print
# a warning yet; do that in final_fail.
# If we found a lock wait timeout and $tries == 0, we are in the rebuilt_constraints part
# so we should keep retrying
if ($error =~ m/Lock wait timeout exceeded/ && !$tries->{tries}) {
return 1;
}
$stats->{ error_event($error) }++;
return 1; # try again
}
@@ -11964,10 +11859,6 @@ foreign keys and indexes as the original table (unless you specify differently
in your ALTER statement), but the names of the objects may be changed slightly
to avoid object name collisions in MySQL and InnoDB.
You should take into consideration that data consistency is not maintained by
default if you have FKs, and you must pass this additional new argument to
avoid data loss. Please read L<"--delete-ignore">
For safety, the tool does not modify the table unless you specify the
L<"--execute"> option, which is not enabled by default. The tool supports a
variety of other measures to prevent unwanted load or other problems, including
@@ -12485,21 +12376,6 @@ short form: -F; type: string
Only read mysql options from the given file. You must give an absolute
pathname.
=item --[no]delete-ignore
default: yes
Do not use C<IGNORE> on C<DELETE> triggers.
This is an special case that affects forign keys handling. Since C<DELETE> only return errors when
there is a problem deleting rows affected by foreign keys, it might be cases when we want to
receive such errors during the program execution to ensure FKs handling is correct.
=item --disable-fk-checks
Disable foreign keys check during rebuild constraints. This option improves the process speed
but it is risky since FKs checks will be disabled for a short period of time, allowing invalid
values in tables. Please use it carefully.
=item --[no]drop-new-table
default: yes

View File

@@ -51,6 +51,7 @@ ok(
);
SKIP: {
skip "Skipping in MySQL 8.0.4-rc since there is an error in the server itself. See https://bugs.mysql.com/bug.php?id=89441", 9 if ($sandbox_version ge '8.0');
($output, $exit_status) = full_output(
sub { pt_online_schema_change::main(@args,
"$master_dsn,D=issue26211,t=process_model_inst",

View File

@@ -23,6 +23,10 @@ my $master_dbh = $sb->get_dbh_for('master');
my $vp = VersionParser->new($master_dbh);
if ($vp->cmp('8.0.14') > -1 && $vp->flavor() !~ m/maria/i) {
plan skip_all => 'Cannot run this test under the current MySQL version';
}
if ( !$master_dbh ) {
plan skip_all => 'Cannot connect to sandbox master';
}

View File

@@ -65,8 +65,8 @@ is_deeply(
$constraints,
[
['person', '_fk_testId'],
['test_table', 'fk_person'],
['test_table', 'fk_refId'],
['test_table', '_fk_person'],
['test_table', '__fk_refId'],
],
"First run adds or removes underscore from constraint names, accordingly"
);
@@ -94,9 +94,9 @@ $constraints = $master_dbh->selectall_arrayref($query);
is_deeply(
$constraints,
[
['person', '_fk_testId'],
['test_table', 'fk_person'],
['test_table', 'fk_refId'],
['person', '__fk_testId'],
['test_table', '_fk_refId'],
['test_table', '__fk_person'],
],
"Second run self-referencing will be one due to rebuild_constraints"
);
@@ -123,7 +123,7 @@ $constraints = $master_dbh->selectall_arrayref($query);
is_deeply(
$constraints,
[
['person', '_fk_testId'],
['person', 'fk_testId'],
['test_table', 'fk_person'],
['test_table', 'fk_refId'],
],