PT-131 Disable QRT plugin in pt-table-checksum

The use of QRT plugin to monitor the health of production worloads cause the QRT data
to show massive spikes in latency, even thought the workload is relatively unaffected.

Tags: pt-table-checksum
See also: PS-235
This commit is contained in:
Carlos Salguero
2018-04-27 15:37:00 -03:00
parent e3a7c8036d
commit 0ade173d0f
4 changed files with 164 additions and 26 deletions

View File

@@ -9847,6 +9847,7 @@ use sigtrap 'handler', \&sig_int, 'normal-signals';
my $oktorun = 1;
my $print_header = 1;
my $exit_status = 0;
my $original_qrt_plugin_master_status = undef;
# "exit codes 1 - 2, 126 - 165, and 255 [1] have special meanings,
# and should therefore be avoided for user-specified exit parameters"
@@ -10052,30 +10053,28 @@ sub main {
# instead, it should check if it's already set to STATEMENT.
# This is becase starting with MySQL 5.1.29, changing the format
# requires a SUPER user.
if ( $o->get('check-binlog-format') ) {
if ( VersionParser->new($dbh) >= '5.1.5' ) {
$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";
}
}
}
if ( VersionParser->new($dbh) >= '5.1.5' ) {
$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";
}
}
}
# Set transaction isolation level. We set binlog_format to STATEMENT,
@@ -10103,6 +10102,7 @@ sub main {
. "level to REPEATABLE-READ.\n";
}
return;
};
@@ -10131,6 +10131,20 @@ sub main {
my $master_dbh = $master_cxn->dbh(); # just for brevity
my $master_dsn = $master_cxn->dsn(); # just for brevity
if ($o->get('disable-qrt-plugin')) {
eval {
$master_dbh->selectrow_arrayref('SELECT @@query_response_time_session_stats' );
};
if ($EVAL_ERROR) {
$original_qrt_plugin_master_status = undef;
PTDEBUG && _d('QRT plugin is not installed: '.$EVAL_ERROR);
} else {
($original_qrt_plugin_master_status) = $master_dbh->selectrow_arrayref('SELECT @@query_response_time_stats' );
PTDEBUG && _d("Disabling qrt plugin on master server");
$master_dbh->do('SET GLOBAL query_response_time_stats = off');
}
}
my @ignored_engines = keys %{$o->get('ignore-engines')};
my @rocksdb_ignored = grep(/^ROCKSDB$/i, @ignored_engines);
if (!@rocksdb_ignored) {
@@ -10451,6 +10465,23 @@ sub main {
}
}
for my $slave (@$slaves) {
my $qrt_plugin_status;
eval {
($qrt_plugin_status) = $slave->{dbh}->selectrow_arrayref('SELECT @@QUERY_RESPONSE_TIME_SESSION_STATS' );
};
if ($EVAL_ERROR) {
PTDEBUG && _d('QRT plugin is not installed on slave '.$slave->{dsn_name});
$slave->{qrt_plugin_status} = undef;
next;
}
$slave->{qrt_plugin_status} = $qrt_plugin_status->[0];
if ($slave->{qrt_plugin_status}) {
PTDEBUG && _d("Disabling qrt plugin state on slave ".$slave->{dsn_name});
$slave->{dbh}->do('SET GLOBAL query_response_time_stats = off');
}
}
if ( $o->get('check-slave-lag') ) {
PTDEBUG && _d('Will use --check-slave-lag to check for slave lag');
my $cxn = $make_cxn->(
@@ -11453,6 +11484,25 @@ sub main {
}
}
# Restore origin QRT pligin state
if ($o->get('disable-qrt-plugin')) {
eval {
if ($original_qrt_plugin_master_status) {
PTDEBUG && _d("Restoring qrt plugin state on master server");
$master_dbh->do("SET GLOBAL query_response_time_stats = $original_qrt_plugin_master_status->[0]");
}
for my $slave (@$slaves) {
if ($slave->{qrt_plugin_status}) {
PTDEBUG && _d("Restoring qrt plugin state on slave ".$slave->{dsn_name});
$slave->{dbh}->do("SET GLOBAL query_response_time_stats = $slave->{qrt_plugin_status}");
}
}
};
if ($EVAL_ERROR) {
warn "Cannot restore qrt_plugin status: $EVAL_ERROR";
}
}
PTDEBUG && _d('Exit status', $exit_status,
'oktorun', $oktorun,
'have time', $have_time->());
@@ -13138,6 +13188,10 @@ short form: -F; type: string; group: Connection
Only read mysql options from the given file. You must give an absolute
pathname.
=item --disable-qrt-plugin
Disable the QRT (Query Response Time) plugin if it is enabled.
=item --[no]empty-replicate-table
default: yes
@@ -13950,6 +14004,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
=head1 VERSION
pt-table-checksum 3.0.9
pt-table-checksum 3.0.10-dev
=cut

View File

@@ -391,7 +391,7 @@ sub verify_test_data {
my @diffs;
foreach my $c ( @checksums ) {
next unless $c->{checksum};
if ( $c->{checksum} ne $ref->{$c->{table}}->{checksum} ) {
if ( $ref->{$c->{table}} && $c->{checksum} ne $ref->{$c->{table}}->{checksum} ) {
push @diffs, $c->{table};
}
}

View File

@@ -0,0 +1,68 @@
#!/usr/bin/env perl
BEGIN {
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
};
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use Test::More;
use PerconaTest;
use Sandbox;
use SqlModes;
require "$trunk/bin/pt-table-checksum";
my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $dbh = $sb->get_dbh_for('master');
my $sb_version = VersionParser->new($dbh);
my $rows = $dbh->selectall_hashref("SHOW VARIABLES LIKE '%version%'", ['variable_name']);
if ( !$dbh ) {
plan skip_all => 'Cannot connect to sandbox master';
} elsif ( $sb_version < '5.7.21' || !($rows->{version_comment}->{value} =~ m/percona server/i) ) {
plan skip_all => 'This test file needs Percona Server 5.7.21.21+';
} else {
plan tests => 3;
}
eval {
$dbh->selectrow_arrayref('SELECT @@query_response_time_session_stats' );
};
if ($EVAL_ERROR) {
$sb->load_file('master', 't/pt-table-checksum/samples/pt-131.sql');
}
# The sandbox servers run with lock_wait_timeout=3 and it is not dynamic
# so we need to specify --set-vars innodb_lock_wait_timeout=3 else the tool will die.
# And --max-load "" prevents waiting for status variables.
my $master_dsn = $sb->dsn_for('master');
my $output;
my $exit_status;
$ENV{PTDEBUG} = 1;
my $cmd ="PTDEBUG=1 $trunk/bin/pt-table-checksum $master_dsn --disable-qrt-plugin 2>&1";
$output = `$cmd`;
like (
$output,
qr/Restoring qrt plugin state/,
"QRT plugin status has been restored",
);
like (
$output,
qr/Disabling qrt plugin on master server/,
"QRT plugin has been disabled",
);
delete $ENV{PTDEBUG};
# #############################################################################
# Done.
# #############################################################################
$sb->wipe_clean($dbh);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
exit;

View File

@@ -0,0 +1,16 @@
-- See https://www.percona.com/doc/percona-server/LATEST/diagnostics/response_time_distribution.html
-- This plugin is used for gathering statistics.
INSTALL PLUGIN QUERY_RESPONSE_TIME_AUDIT SONAME 'query_response_time.so';
-- This plugin provides the interface (QUERY_RESPONSE_TIME) to output gathered statistics.
INSTALL PLUGIN QUERY_RESPONSE_TIME SONAME 'query_response_time.so';
-- This plugin provides the interface (QUERY_RESPONSE_TIME_READ) to output gathered statistics.
INSTALL PLUGIN QUERY_RESPONSE_TIME_READ SONAME 'query_response_time.so';
-- This plugin provides the interface (QUERY_RESPONSE_TIME_WRITE) to output gathered statistics.
INSTALL PLUGIN QUERY_RESPONSE_TIME_WRITE SONAME 'query_response_time.so';
-- Start collecting query time metrics,
SET GLOBAL query_response_time_stats = on;