fixed need for SBR in pt-heartbeat

This commit is contained in:
frank-cizmich
2016-01-15 21:41:55 -03:00
parent ec8ceec463
commit 66e30fdecf

View File

@@ -5749,33 +5749,6 @@ sub main {
: $dsn_defaults;
my $dbh = $dp->get_dbh($dp->get_cxn_params($dsn), {AutoCommit=>1});
# we need binlog_format = STATEMENT for this session
# note that ROW is the default format in 5.7+
if ( VersionParser->new($dbh) >= '5.1.5' ) {
my $sql = 'SELECT @@binlog_format';
PTDEBUG && _d($dbh, $sql);
my ($original_binlog_format) = $dbh->selectrow_array($sql);
PTDEBUG && _d('Original binlog_format:', $original_binlog_format);
if ( $original_binlog_format !~ /STATEMENT/i ) {
$sql = q{/*!50108 SET @@binlog_format = 'STATEMENT'*/};
eval {
PTDEBUG && _d($dbh, $sql);
$dbh->do($sql);
};
if ( $EVAL_ERROR ) {
die "Failed to $sql: $EVAL_ERROR\n"
. "This tool requires binlog_format=STATEMENT, "
. "but the current binlog_format is set to "
."$original_binlog_format and an error occurred while "
. "attempting to change it. If running MySQL 5.1.29 or newer, "
. "setting binlog_format requires the SUPER privilege. "
. "You will need to manually set binlog_format to 'STATEMENT' "
. "before running this tool.\n";
}
}
}
$dbh->{InactiveDestroy} = 1; # Don't disconnect on fork
$dbh->{FetchHashKeyName} = 'NAME_lc';
$dbh->do("USE `$db`");
@@ -5818,20 +5791,34 @@ sub main {
$sql =~ s/heartbeat/IF NOT EXISTS $db_tbl/;
PTDEBUG && _d($sql);
$dbh->do($sql);
# Now we insert first row.
# Some caveats:
$sql = ($o->get('replace') ? "REPLACE" : "INSERT")
. qq/ INTO $db_tbl (ts, server_id) VALUES ($now_func, $server_id)/;
PTDEBUG && _d($sql);
# 1)
# This may fail if the table already existed and already had this row.
# We eval to ignore this possibility.
# NOTE: This can break replication though! See:
# https://bugs.launchpad.net/percona-toolkit/+bug/1004567
# So --replace should be used in most cases.
#
# Addendum: binlog_format = ROW makes both REPLACE and INSERT fail in
# Perl's DBI in this cirumstance. Until this is fixed we have to
# attempt to change binlog_row to STATEMENT at the start of the run
eval { $dbh->do($sql); };
my $sql_insert_row = ($o->get('replace') ? "REPLACE" : "INSERT")
. qq/ INTO $db_tbl (ts, server_id) VALUES ($now_func, $server_id)/;
# 2)
# RBR (Row Based Replication) converts REPLACE to INSERT if row isn't
# present in master. This breakes replication when the row is present in slave.
# Other workarounds also fail.
# INSERT IGNORE (ignore is not replicated if no error in master)
# DELETE then INSERT (DELETE is ignored, INSERT breaks replication)
# INSERT ON DUPLICATE UPDATE (converts to simple INSERT)
# TRUNCATE gets trough and replicates! So we use that to wipe slave(s).
if ($o->get('replace')) {
my $sql_truncate = "TRUNCATE TABLE $db_tbl";
PTDEBUG && _d($sql_truncate);
eval { $dbh->do($sql_truncate) };
}
PTDEBUG && _d($sql_insert_row);
eval { $dbh->do($sql_insert_row); };
}
# ########################################################################