From 0afd03e5eb31d88155142241ae2fdaf35502cce5 Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Thu, 22 Jan 2026 19:29:40 +0300 Subject: [PATCH] PT-2220 - pt-heartbeat's --check-read-only option behaves strangely - Created fix and test case --- bin/pt-heartbeat | 4 +- t/pt-heartbeat/pt-2220.t | 123 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 t/pt-heartbeat/pt-2220.t diff --git a/bin/pt-heartbeat b/bin/pt-heartbeat index e178eeae..46461353 100755 --- a/bin/pt-heartbeat +++ b/bin/pt-heartbeat @@ -6793,8 +6793,8 @@ sub main { sub server_is_readonly { my ($dbh) = @_; - my ( $is_read_only ) = $dbh->selectrow_array(q{SELECT @@global.read_only}); - if ( $is_read_only ) { + my ( $is_read_only, $is_super_read_only ) = $dbh->selectrow_array(q{SELECT @@global.read_only, @@global.super_read_only}); + if ( $is_read_only and not $is_super_read_only ) { my ( $privs ) = eval { $dbh->selectrow_array(q{SHOW GRANTS}) }; if ( $privs && $privs =~ /\b(?:ALL|SUPER)\b/ ) { $is_read_only = undef; diff --git a/t/pt-heartbeat/pt-2220.t b/t/pt-heartbeat/pt-2220.t new file mode 100644 index 00000000..c50bfb10 --- /dev/null +++ b/t/pt-heartbeat/pt-2220.t @@ -0,0 +1,123 @@ +#!/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 Data::Dumper; + +use PerconaTest; +use Sandbox; +require "$trunk/bin/pt-heartbeat"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('source'); + +if ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox source'; +} +elsif ( $sandbox_version lt '8.0' ) { + plan skip_all => "Requires MySQL 8.0 or newer"; +} + +$sb->create_dbs($dbh, ['test']); + +my ($output, $exit_code); +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $cmd = "$trunk/bin/pt-heartbeat -F $cnf "; + +$dbh->do('drop table if exists test.heartbeat'); +$dbh->do(q{CREATE TABLE test.heartbeat ( + id int NOT NULL PRIMARY KEY, + ts datetime NOT NULL + ) ENGINE=MEMORY}); +$sb->wait_for_replicas; + +$sb->do_as_root('source', 'SET GLOBAL read_only=0, super_read_only=0'); + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=$cnf,h=127.1,P=12345", + qw(-D test --check-read-only --update --utc --run-time=5) + ) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "pt-heartbeat exited with 0 with read_only=0, super_read_only=0" +) or diag($exit_code); + +is( + $output, + '', + "Nothing printed with read_only=0, super_read_only=0" +) or diag($output); + +$sb->do_as_root('source', 'SET GLOBAL read_only=1, super_read_only=0'); + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=$cnf,h=127.1,P=12345", + qw(-D test --check-read-only --update --utc --run-time=5) + ) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "pt-heartbeat exited with 0 with read_only=1, super_read_only=0" +) or diag($exit_code); + +is( + $output, + '', + "Nothing printed with read_only=1, super_read_only=0" +) or diag($output); + +$sb->do_as_root('source', 'SET GLOBAL super_read_only=1'); + +($output, $exit_code) = full_output( + sub { pt_heartbeat::main("F=$cnf,h=127.1,P=12345", + qw(-D test --check-read-only --update --utc --run-time=5) + ) }, + stderr => 1, +); + +is( + $exit_code, + 0, + "pt-heartbeat exited with 0 with read_only=1, super_read_only=1" +) or diag($exit_code); + +is( + $output, + '', + "Nothing printed with read_only=1, super_read_only=1" +) or diag($output); + +unlike( + $output, + qr/The MySQL server is running with the --super-read-only option so it cannot execute this statement/, + "No error printed with read_only=1, super_read_only=1" +) or diag($output); + +$sb->do_as_root('source', 'SET GLOBAL read_only=0, super_read_only=0'); + +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root('source', 'SET GLOBAL read_only=0, super_read_only=0'); + +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); + +done_testing; +exit;