From 02664694e2ac482ebb2c6058fa6a8075b2263ba9 Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Fri, 5 Apr 2024 17:57:42 +0300 Subject: [PATCH 1/9] PT-1194 - LP #1266896: pt-table-sync port problem - Implemented the fix - Added test case --- bin/pt-table-sync | 12 ++++- t/pt-table-sync/pt-1194.t | 106 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 t/pt-table-sync/pt-1194.t diff --git a/bin/pt-table-sync b/bin/pt-table-sync index f2193373..dce6fa8d 100755 --- a/bin/pt-table-sync +++ b/bin/pt-table-sync @@ -10230,7 +10230,17 @@ sub main { unshift @dsns, $master; # dsn[0]=master, dsn[1]=slave $dsns[0]->{dbh} = get_cxn($dsns[0], %modules); if ( $o->get('check-master') ) { - $ms->is_master_of($dsns[0]->{dbh}, $dsns[1]->{dbh}); + my $is_master_of = eval { + $ms->is_master_of($dsns[0]->{dbh}, $dsns[1]->{dbh}); + }; + + # We should not die if replica connected via tunnel or port redirection + if ( $EVAL_ERROR ) { + $EVAL_ERROR =~ m/The slave is connected to (\d+) but the master's port is \d+/; + if ( !$1 || $1 != $dsns[0]->{P} ) { + die $EVAL_ERROR; + } + } } } diff --git a/t/pt-table-sync/pt-1194.t b/t/pt-table-sync/pt-1194.t new file mode 100644 index 00000000..6e49b201 --- /dev/null +++ b/t/pt-table-sync/pt-1194.t @@ -0,0 +1,106 @@ +#!/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; +require "$trunk/bin/pt-table-sync"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $master_dbh = $sb->get_dbh_for('master'); +my $slave1_dbh = $sb->get_dbh_for('slave1'); +my $slave2_dbh = $sb->get_dbh_for('slave2'); +my $have_ncat = `which ncat 2>/dev/null`; + +if ( !$master_dbh ) { + plan skip_all => 'Cannot connect to sandbox master'; +} +elsif ( !$slave1_dbh ) { + plan skip_all => 'Cannot connect to sandbox slave1'; +} +elsif ( !$slave1_dbh ) { + plan skip_all => 'Cannot connect to sandbox slave2'; +} +elsif (!$have_ncat) { + plan skip_all => 'ncat, required for this test, is not installed or not in PATH'; +} +else { + plan tests => 3; +} + +$sb->load_file('master', "t/pt-table-sync/samples/pt-1205.sql"); +$sb->wait_for_slaves(); + +# Setting up tunnels +my $pid1 = fork(); + +if ( !$pid1 ) { + setpgrp; + system('ncat -k -l localhost 3333 --sh-exec "ncat 127.0.0.1 12345"'); + exit; +} + +my $pid2 = fork(); + +if ( !$pid2 ) { + setpgrp; + system('ncat -k -l localhost 3334 --sh-exec "ncat 127.0.0.1 12346"'); + exit; +} + +my $o = new OptionParser(); +my $q = new Quoter(); +my $ms = new MasterSlave( + OptionParser=>$o, + DSNParser=>$dp, + Quoter=>$q, + ); +my $ss = $ms->get_slave_status($slave1_dbh); + +$slave1_dbh->do('STOP SLAVE'); +$slave1_dbh->do("CHANGE MASTER TO MASTER_PORT=3333, MASTER_LOG_POS=$ss->{exec_master_log_pos}"); +$slave1_dbh->do('START SLAVE'); + +my $output = `$trunk/bin/pt-table-sync h=127.0.0.1,P=3334,u=msandbox,p=msandbox --database=test --table=t1 --sync-to-master --execute --verbose 2>&1`; + +unlike( + $output, + qr/The slave is connected to \d+ but the master's port is/, + 'No error for redirected replica' +) or diag($output); + +kill -1, getpgrp($pid1); +kill -1, getpgrp($pid2); + +$slave1_dbh->do('STOP SLAVE'); +$ss = $ms->get_slave_status($slave1_dbh); +$slave1_dbh->do("CHANGE MASTER TO MASTER_PORT=12347, MASTER_LOG_POS=$ss->{exec_master_log_pos}"); +$slave1_dbh->do('START SLAVE SQL_THREAD'); + +$output = `$trunk/bin/pt-table-sync h=127.0.0.1,P=12346,u=msandbox,p=msandbox --database=test --table=t1 --sync-to-master --execute --verbose 2>&1`; + +like( + $output, + qr/The server specified as a master has no connected slaves/, + 'Error printed for the wrong master' +) or diag($output); + +$slave1_dbh->do('STOP SLAVE'); +$slave1_dbh->do("CHANGE MASTER TO MASTER_PORT=12345, MASTER_LOG_POS=$ss->{exec_master_log_pos}"); +$slave1_dbh->do('START SLAVE'); +# ############################################################################# +# Done. +# ############################################################################# +$sb->wipe_clean($master_dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit; From a4c2fd349686e9f592ca3c685e98bb9e556be98e Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Sat, 6 Apr 2024 12:46:55 +0300 Subject: [PATCH 2/9] PT-1194 - LP #1266896: pt-table-sync port problem - Fixed typos --- bin/pt-deadlock-logger | 2 +- bin/pt-fk-error-logger | 2 +- lib/SchemaIterator.pm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/pt-deadlock-logger b/bin/pt-deadlock-logger index 16176a7a..3b082258 100755 --- a/bin/pt-deadlock-logger +++ b/bin/pt-deadlock-logger @@ -5533,7 +5533,7 @@ is undefined which means an infinite number of iterations. The tool always exits for L<"--run-time">, regardless of the value specified for this option. For example, the tool will exit after 1 minute with C<--run-time 1m --iterations 4 --interval 30> because 4 iterations at 30 -second intervals would take 2 minutes, longer than the 1 mintue run-time. +second intervals would take 2 minutes, longer than the 1 minute run-time. =item --log diff --git a/bin/pt-fk-error-logger b/bin/pt-fk-error-logger index 72ec795e..8c4744d5 100755 --- a/bin/pt-fk-error-logger +++ b/bin/pt-fk-error-logger @@ -4530,7 +4530,7 @@ is undefined which means an infinite number of iterations. The tool always exits for L<"--run-time">, regardless of the value specified for this option. For example, the tool will exit after 1 minute with C<--run-time 1m --iterations 4 --interval 30> because 4 iterations at 30 -second intervals would take 2 minutes, longer than the 1 mintue run-time. +second intervals would take 2 minutes, longer than the 1 minute run-time. =item --log diff --git a/lib/SchemaIterator.pm b/lib/SchemaIterator.pm index 4336d024..c4b36046 100644 --- a/lib/SchemaIterator.pm +++ b/lib/SchemaIterator.pm @@ -495,7 +495,7 @@ sub table_is_allowed { # then we'll get d1 tables when the user only wants d2 tables. So when # a table passes allow filters, reaching this point, meaning it is allowed, # we make this final to check to see if it's allowed in any database (*) - # or allowed in the specific database that the user qualifed the table with. + # or allowed in the specific database that the user qualified the table with. # The first two checks are to prevent auto-vivifying the filters which will # cause bad results (see a similar comment in _make_filters()). if ( $filter->{'tables'} From 841ddb2edcb7e6549d4e9d31466f3a51968e975d Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Wed, 10 Apr 2024 23:31:20 +0300 Subject: [PATCH 3/9] PT-2327 - pt-mysql-summary fails to connect if password has a single quote character - Implemented the fix - Added test case - Run update-modules --- bin/pt-ioprofile | 4 +- bin/pt-mext | 4 +- bin/pt-mysql-summary | 4 +- bin/pt-pmp | 4 +- bin/pt-sift | 4 +- bin/pt-stalk | 4 +- bin/pt-summary | 4 +- lib/bash/parse_options.sh | 4 +- t/pt-mysql-summary/pt-2327.t | 77 ++++++++++++++++++++++++++++++++++++ 9 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 t/pt-mysql-summary/pt-2327.t diff --git a/bin/pt-ioprofile b/bin/pt-ioprofile index 785e7dfb..ae4f3698 100755 --- a/bin/pt-ioprofile +++ b/bin/pt-ioprofile @@ -408,7 +408,7 @@ _parse_command_line() { fi if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then - val="$(echo $opt | awk -F= '{print $2}')" + val="$(echo "$opt" | awk '{ st = index($0,"="); print substr($0, st+1)}')" opt="$(echo $opt | awk -F= '{print $1}')" fi @@ -453,7 +453,7 @@ _parse_command_line() { val=$(size_to_bytes $val) fi - eval "OPT_$opt"="'$val'" + eval "OPT_$opt"='$val' opt="" val="" diff --git a/bin/pt-mext b/bin/pt-mext index df068aab..42d6f787 100755 --- a/bin/pt-mext +++ b/bin/pt-mext @@ -449,7 +449,7 @@ _parse_command_line() { fi if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then - val="$(echo $opt | awk -F= '{print $2}')" + val="$(echo "$opt" | awk '{ st = index($0,"="); print substr($0, st+1)}')" opt="$(echo $opt | awk -F= '{print $1}')" fi @@ -494,7 +494,7 @@ _parse_command_line() { val=$(size_to_bytes $val) fi - eval "OPT_$opt"="'$val'" + eval "OPT_$opt"='$val' opt="" val="" diff --git a/bin/pt-mysql-summary b/bin/pt-mysql-summary index 681b153f..8d8bbd54 100755 --- a/bin/pt-mysql-summary +++ b/bin/pt-mysql-summary @@ -410,7 +410,7 @@ _parse_command_line() { fi if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then - val="$(echo $opt | awk -F= '{print $2}')" + val="$(echo "$opt" | awk '{ st = index($0,"="); print substr($0, st+1)}')" opt="$(echo $opt | awk -F= '{print $1}')" fi @@ -455,7 +455,7 @@ _parse_command_line() { val=$(size_to_bytes $val) fi - eval "OPT_$opt"="'$val'" + eval "OPT_$opt"='$val' opt="" val="" diff --git a/bin/pt-pmp b/bin/pt-pmp index 0aacb473..8a8b7e0e 100755 --- a/bin/pt-pmp +++ b/bin/pt-pmp @@ -451,7 +451,7 @@ _parse_command_line() { fi if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then - val="$(echo $opt | awk -F= '{print $2}')" + val="$(echo "$opt" | awk '{ st = index($0,"="); print substr($0, st+1)}')" opt="$(echo $opt | awk -F= '{print $1}')" fi @@ -496,7 +496,7 @@ _parse_command_line() { val=$(size_to_bytes $val) fi - eval "OPT_$opt"="'$val'" + eval "OPT_$opt"='$val' opt="" val="" diff --git a/bin/pt-sift b/bin/pt-sift index bbf077cf..9e0c02fe 100755 --- a/bin/pt-sift +++ b/bin/pt-sift @@ -449,7 +449,7 @@ _parse_command_line() { fi if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then - val="$(echo $opt | awk -F= '{print $2}')" + val="$(echo "$opt" | awk '{ st = index($0,"="); print substr($0, st+1)}')" opt="$(echo $opt | awk -F= '{print $1}')" fi @@ -494,7 +494,7 @@ _parse_command_line() { val=$(size_to_bytes $val) fi - eval "OPT_$opt"="'$val'" + eval "OPT_$opt"='$val' opt="" val="" diff --git a/bin/pt-stalk b/bin/pt-stalk index 9f8d86a6..e83228d4 100755 --- a/bin/pt-stalk +++ b/bin/pt-stalk @@ -462,7 +462,7 @@ _parse_command_line() { fi if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then - val="$(echo $opt | awk -F= '{print $2}')" + val="$(echo "$opt" | awk '{ st = index($0,"="); print substr($0, st+1)}')" opt="$(echo $opt | awk -F= '{print $1}')" fi @@ -507,7 +507,7 @@ _parse_command_line() { val=$(size_to_bytes $val) fi - eval "OPT_$opt"="'$val'" + eval "OPT_$opt"='$val' opt="" val="" diff --git a/bin/pt-summary b/bin/pt-summary index cf000117..983df245 100755 --- a/bin/pt-summary +++ b/bin/pt-summary @@ -417,7 +417,7 @@ _parse_command_line() { fi if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then - val="$(echo $opt | awk -F= '{print $2}')" + val="$(echo "$opt" | awk '{ st = index($0,"="); print substr($0, st+1)}')" opt="$(echo $opt | awk -F= '{print $1}')" fi @@ -462,7 +462,7 @@ _parse_command_line() { val=$(size_to_bytes $val) fi - eval "OPT_$opt"="'$val'" + eval "OPT_$opt"='$val' opt="" val="" diff --git a/lib/bash/parse_options.sh b/lib/bash/parse_options.sh index 97fe0c4e..1fee5c6b 100644 --- a/lib/bash/parse_options.sh +++ b/lib/bash/parse_options.sh @@ -475,7 +475,7 @@ _parse_command_line() { # Split opt=val pair. if $(echo $opt | grep '^[a-z-][a-z-]*=' >/dev/null 2>&1); then - val="$(echo $opt | awk -F= '{print $2}')" + val="$(echo "$opt" | awk '{ st = index($0,"="); print substr($0, st+1)}')" opt="$(echo $opt | awk -F= '{print $1}')" fi @@ -533,7 +533,7 @@ _parse_command_line() { fi # Re-eval the option to update its global variable value. - eval "OPT_$opt"="'$val'" + eval "OPT_$opt"='$val' opt="" val="" diff --git a/t/pt-mysql-summary/pt-2327.t b/t/pt-mysql-summary/pt-2327.t new file mode 100644 index 00000000..69c68021 --- /dev/null +++ b/t/pt-mysql-summary/pt-2327.t @@ -0,0 +1,77 @@ +#!/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 PerconaTest; +use Sandbox; +use DSNParser; +require VersionParser; +use Test::More; + +local $ENV{PTDEBUG} = ""; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $dbh = $sb->get_dbh_for('master'); +my $cnf = '/tmp/12345/my.sandbox.cnf'; +my $output; + +if ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox master'; +} +else { + plan tests => 5; +} + +$sb->do_as_root("master", q/create user pt2302 identified by "root_'f<=*password"/); +$sb->do_as_root("master", q/grant all on *.* to pt2302/); + +my $cmd = "$trunk/bin/pt-mysql-summary --sleep 1 -- --defaults-file=$cnf --user=pt2302 --password=\"root_'f<=*password\""; + +$output = `$cmd 2>&1`; + +unlike( + $output, + qr/eval: Syntax error: Unterminated quoted string/s, + "pt-mysql-summary does not stop with password containing an apostrophe" +); + +unlike( + $output, + qr/Access denied for user/s, + "pt-mysql-summary works fine with password containing an apostrophe" +); + +$sb->do_as_root("master", q/drop user pt2302/); +$sb->do_as_root("master", q/create user pt2302 identified by 'root_"f<=*password'/); +$sb->do_as_root("master", q/grant all on *.* to pt2302/); + +$cmd = "$trunk/bin/pt-mysql-summary --sleep 1 -- --defaults-file=$cnf --user=pt2302 --password='root_\"f<=*password'"; + +$output = `$cmd 2>&1`; + +unlike( + $output, + qr/eval: Syntax error: Unterminated quoted string/s, + "pt-mysql-summary does not stop with password containing a quote" +); + +unlike( + $output, + qr/Access denied for user/s, + "pt-mysql-summary works fine with password containing a quote" +); +# ############################################################################# +# Done. +# ############################################################################# +$sb->do_as_root("master", q/drop user pt2302/); +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit; From ba08b2edf3a983a514150ee1b68327f60208b53a Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Thu, 11 Apr 2024 18:58:39 +0300 Subject: [PATCH 4/9] PT-2217 - pt-mongodb-summary gives error with psmdb6.0 - Removed not supported request for recordStats - Adjusted docker-compose.yml, so it fires standalone server correctly --- src/go/docker-compose.yml | 2 +- src/go/pt-mongodb-summary/main.go | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/go/docker-compose.yml b/src/go/docker-compose.yml index f9458c45..1c0cb6b1 100644 --- a/src/go/docker-compose.yml +++ b/src/go/docker-compose.yml @@ -186,7 +186,7 @@ services: image: ${TEST_MONGODB_IMAGE:-mongo:4.2} ports: - "${TEST_MONGODB_STANDALONE_PORT:-27017}:27017" - command: mongod --replSet rs1 --shardsvr --port 27017 --oplogSize 16 + command: mongod --port 27017 --oplogSize 16 postgres9: image: ${POSTGRE_IMAGE:-postgres:9.6} container_name: go_postgres9_1 diff --git a/src/go/pt-mongodb-summary/main.go b/src/go/pt-mongodb-summary/main.go index 2fb7a209..3dce453c 100644 --- a/src/go/pt-mongodb-summary/main.go +++ b/src/go/pt-mongodb-summary/main.go @@ -374,14 +374,14 @@ func getHostInfo(ctx context.Context, client *mongo.Client) (*hostInfo, error) { } cmdOpts := proto.CommandLineOptions{} - query := primitive.D{{Key: "getCmdLineOpts", Value: 1}, {Key: "recordStats", Value: 1}} + query := primitive.D{{Key: "getCmdLineOpts", Value: 1}} err := client.Database("admin").RunCommand(ctx, query).Decode(&cmdOpts) if err != nil { return nil, errors.Wrap(err, "cannot get command line options") } ss := proto.ServerStatus{} - query = primitive.D{{Key: "serverStatus", Value: 1}, {Key: "recordStats", Value: 1}} + query = primitive.D{{Key: "serverStatus", Value: 1}} if err := client.Database("admin").RunCommand(ctx, query).Decode(&ss); err != nil { return nil, errors.Wrap(err, "GetHostInfo.serverStatus") } @@ -528,7 +528,6 @@ func getSecuritySettings(ctx context.Context, client *mongo.Client, ver string) cmdOpts := proto.CommandLineOptions{} err = client.Database("admin").RunCommand(ctx, primitive.D{ {Key: "getCmdLineOpts", Value: 1}, - {Key: "recordStats", Value: 1}, }).Decode(&cmdOpts) if err != nil { return nil, errors.Wrap(err, "cannot get command line options") @@ -633,7 +632,6 @@ func getOpCountersStats(ctx context.Context, client *mongo.Client, count int, err := client.Database("admin").RunCommand(ctx, primitive.D{ {Key: "serverStatus", Value: 1}, - {Key: "recordStats", Value: 1}, }).Decode(&ss) if err != nil { return nil, err From b5efd2a6ecdc6a0206f262baec1c6689fda7e789 Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Thu, 11 Apr 2024 19:53:43 +0300 Subject: [PATCH 5/9] Added exceptions for advices and thr to .typos.toml --- .typos.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.typos.toml b/.typos.toml index 7fb9db2e..44a90db2 100644 --- a/.typos.toml +++ b/.typos.toml @@ -33,6 +33,7 @@ extend-ignore-re = [ ] [default.extend-identifiers] +"advices" = "advices" # typo in version_check.go "Bootstraping" = "Bootstraping" # typo in Galera lib "Continuent" = "Continuent" "END_ND_SUMMARY" = "END_ND_SUMMARY" @@ -61,6 +62,7 @@ extend-ignore-re = [ "RegexXtrabackupISTReceived" = "RegexXtrabackupISTReceived" "START_ND_SUMMARY" = "START_ND_SUMMARY" "START_ND_TOOLTIPS" = "START_ND_TOOLTIPS" +"thr" = "thr" # common abbreviation "TOI" = "TOI" "UNIONed" = "UNIONed" "UNIONs" = "UNIONs" From c5cafbb4869dbbeffd8a291413309be3d0409250 Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Thu, 11 Apr 2024 21:47:11 +0300 Subject: [PATCH 6/9] PT-2231 - pt-osc + PTDEBUG=1 fails with Use of uninitialized value in concatenation (.) or string at ./pt-online-schema-change line 4309. - Re-implemented fix for PT-1799 properly - Added test case - Updated modules --- bin/pt-archiver | 3 +- bin/pt-heartbeat | 3 +- bin/pt-kill | 3 +- bin/pt-online-schema-change | 3 +- bin/pt-query-digest | 3 +- bin/pt-slave-find | 3 +- bin/pt-slave-restart | 3 +- bin/pt-table-checksum | 3 +- bin/pt-table-sync | 3 +- lib/MasterSlave.pm | 3 +- t/pt-online-schema-change/pt-2231.t | 63 +++++++++++++++++++++++++++++ 11 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 t/pt-online-schema-change/pt-2231.t diff --git a/bin/pt-archiver b/bin/pt-archiver index 563d6b6d..2bf7a99f 100755 --- a/bin/pt-archiver +++ b/bin/pt-archiver @@ -3781,7 +3781,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/bin/pt-heartbeat b/bin/pt-heartbeat index e03c9001..a0cf5c02 100755 --- a/bin/pt-heartbeat +++ b/bin/pt-heartbeat @@ -242,7 +242,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/bin/pt-kill b/bin/pt-kill index 38cee058..3c2da447 100755 --- a/bin/pt-kill +++ b/bin/pt-kill @@ -4058,7 +4058,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/bin/pt-online-schema-change b/bin/pt-online-schema-change index fea52be9..42967021 100755 --- a/bin/pt-online-schema-change +++ b/bin/pt-online-schema-change @@ -4346,7 +4346,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/bin/pt-query-digest b/bin/pt-query-digest index 1ccb8e5a..f12b0063 100755 --- a/bin/pt-query-digest +++ b/bin/pt-query-digest @@ -10652,7 +10652,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/bin/pt-slave-find b/bin/pt-slave-find index 5c6557d7..3a2b9295 100755 --- a/bin/pt-slave-find +++ b/bin/pt-slave-find @@ -2383,7 +2383,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/bin/pt-slave-restart b/bin/pt-slave-restart index 046a2635..284f0367 100755 --- a/bin/pt-slave-restart +++ b/bin/pt-slave-restart @@ -2794,7 +2794,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index e0185f9a..78570d60 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -5298,7 +5298,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/bin/pt-table-sync b/bin/pt-table-sync index dce6fa8d..55ca97cd 100755 --- a/bin/pt-table-sync +++ b/bin/pt-table-sync @@ -6812,7 +6812,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/lib/MasterSlave.pm b/lib/MasterSlave.pm index 007c4d6d..135411dc 100644 --- a/lib/MasterSlave.pm +++ b/lib/MasterSlave.pm @@ -181,7 +181,8 @@ sub recurse_to_slaves { my $slave_dsn = $dsn; if ($slave_user) { $slave_dsn->{u} = $slave_user; - PTDEBUG && _d("Using slave user $slave_user on ".$slave_dsn->{h}.":".$slave_dsn->{P}); + PTDEBUG && _d("Using slave user $slave_user on " + . $slave_dsn->{h} . ":" . ( $slave_dsn->{P} ? $slave_dsn->{P} : "")); } if ($slave_password) { $slave_dsn->{p} = $slave_password; diff --git a/t/pt-online-schema-change/pt-2231.t b/t/pt-online-schema-change/pt-2231.t new file mode 100644 index 00000000..4ff53406 --- /dev/null +++ b/t/pt-online-schema-change/pt-2231.t @@ -0,0 +1,63 @@ +#!/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; +require "$trunk/bin/pt-online-schema-change"; + +my $dp = new DSNParser(opts=>$dsn_opts); +my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp); +my $master_dbh = $sb->get_dbh_for('master'); +my $slave1_dbh = $sb->get_dbh_for('slave1'); +my $slave2_dbh = $sb->get_dbh_for('slave2'); + +if ( !$master_dbh ) { + plan skip_all => 'Cannot connect to sandbox master'; +} +elsif ( !$slave1_dbh ) { + plan skip_all => 'Cannot connect to sandbox slave1'; +} +elsif ( !$slave1_dbh ) { + plan skip_all => 'Cannot connect to sandbox slave2'; +} +else { + plan tests => 2; +} + +$sb->load_file('master', "t/pt-online-schema-change/samples/basic_no_fks.sql"); + +$sb->wait_for_slaves(); + +# Save original PTDEBUG env because we modify it below. +my $dbg = $ENV{PTDEBUG}; + +$ENV{PTDEBUG} = 1; + +my $output = `$trunk/bin/pt-online-schema-change h=localhost,S=/tmp/12345/mysql_sandbox12345.sock,D=pt_osc,t=t --user=msandbox --password=msandbox --slave-user=msandbox --slave-password=msandbox --alter "FORCE" --recursion-method=processlist --no-check-replication-filters --no-check-alter --no-check-plan --chunk-index=PRIMARY --no-version-check --execute 2>&1`; + +unlike( + $output, + qr/Use of uninitialized value in concatenation (.) or string/, + 'No error with PTDEBUG output' +) or diag($output); + +# Restore PTDEBUG env. +delete $ENV{PTDEBUG}; +$ENV{PTDEBUG} = $dbg || 0; + +# ############################################################################# +# Done. +# ############################################################################# +$sb->wipe_clean($master_dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit; From 3b04d080cdc6caa738b8be8f61b915063297d63f Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Fri, 12 Apr 2024 20:51:37 +0300 Subject: [PATCH 7/9] Update .typos.toml Will implement fix from PR-801 --- .typos.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/.typos.toml b/.typos.toml index 44a90db2..a1702340 100644 --- a/.typos.toml +++ b/.typos.toml @@ -33,7 +33,6 @@ extend-ignore-re = [ ] [default.extend-identifiers] -"advices" = "advices" # typo in version_check.go "Bootstraping" = "Bootstraping" # typo in Galera lib "Continuent" = "Continuent" "END_ND_SUMMARY" = "END_ND_SUMMARY" From 4f6197181ba99c7f8aa635e87c64448cb33b1a20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 09:52:50 +0000 Subject: [PATCH 8/9] build(deps): bump go.mongodb.org/mongo-driver from 1.14.0 to 1.15.0 Bumps [go.mongodb.org/mongo-driver](https://github.com/mongodb/mongo-go-driver) from 1.14.0 to 1.15.0. - [Release notes](https://github.com/mongodb/mongo-go-driver/releases) - [Commits](https://github.com/mongodb/mongo-go-driver/compare/v1.14.0...v1.15.0) --- updated-dependencies: - dependency-name: go.mongodb.org/mongo-driver dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 633d746f..3968b439 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 github.com/xlab/treeprint v1.2.0 - go.mongodb.org/mongo-driver v1.14.0 + go.mongodb.org/mongo-driver v1.15.0 golang.org/x/crypto v0.22.0 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 diff --git a/go.sum b/go.sum index b4437c91..c94791a5 100644 --- a/go.sum +++ b/go.sum @@ -118,8 +118,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= -go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc= +go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= From 95c9020fa9e654ae96ebe3917bc45551f8d4cade Mon Sep 17 00:00:00 2001 From: Artem Gavrilov Date: Thu, 18 Apr 2024 11:48:37 +0200 Subject: [PATCH 9/9] Fix typo (#801) --- src/go/lib/versioncheck/version_check.go | 10 +++++----- src/go/lib/versioncheck/version_check_test.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/go/lib/versioncheck/version_check.go b/src/go/lib/versioncheck/version_check.go index 114b2148..37409908 100644 --- a/src/go/lib/versioncheck/version_check.go +++ b/src/go/lib/versioncheck/version_check.go @@ -73,15 +73,15 @@ func checkUpdates(url string, timeout time.Duration, toolName, version string) ( if err != nil { return "", err } - advices := []Advice{} - err = json.Unmarshal(body, &advices) + var advice []Advice + err = json.Unmarshal(body, &advice) if err != nil { return "", err } - for _, advice := range advices { - if advice.ToolName == PERCONA_TOOLKIT { - return advice.Advice, nil + for _, a := range advice { + if a.ToolName == PERCONA_TOOLKIT { + return a.Advice, nil } } diff --git a/src/go/lib/versioncheck/version_check_test.go b/src/go/lib/versioncheck/version_check_test.go index 0d449df0..357a0e74 100644 --- a/src/go/lib/versioncheck/version_check_test.go +++ b/src/go/lib/versioncheck/version_check_test.go @@ -16,7 +16,7 @@ func TestCheckUpdates(t *testing.T) { body, _ := ioutil.ReadAll(r.Body) m := strings.Split(string(body), ";") - advices := []Advice{ + advice := []Advice{ { Hash: m[0], ToolName: m[1], @@ -24,7 +24,7 @@ func TestCheckUpdates(t *testing.T) { }, } - buf, _ := json.Marshal(advices) + buf, _ := json.Marshal(advice) w.Header().Set("Content-Type", "application/json") fmt.Fprint(w, string(buf)) }))