From d5edeee38193da24cadc15d89458f226810b8e9f Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Wed, 4 Oct 2023 16:35:03 +0300 Subject: [PATCH 1/2] PT-2109 - pt-mysql-summary throws an error when using sql_mode="ANSI_QUOTES" - Fixed issues still visible with SQL mode ANSI_QUOTES - Added test cases for this mode --- bin/pt-mysql-summary | 8 +- lib/bash/collect_mysql_info.sh | 8 +- t/pt-mysql-summary/pt-2109.t | 80 +++++++++++++++++++ .../pt-mysql-summary_encryption.t | 29 +++++++ 4 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 t/pt-mysql-summary/pt-2109.t diff --git a/bin/pt-mysql-summary b/bin/pt-mysql-summary index eb2d401b0..b3fc0a2ff 100755 --- a/bin/pt-mysql-summary +++ b/bin/pt-mysql-summary @@ -957,9 +957,9 @@ collect_mysql_processlist () { } collect_mysql_users () { - $CMD_MYSQL $EXT_ARGV -ss -e 'SELECT COUNT(*), SUM(user=""), SUM(password=""), SUM(password NOT LIKE "*%") FROM mysql.user' 2>/dev/null + $CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(password=''), SUM(password NOT LIKE '*%') FROM mysql.user" 2>/dev/null if [ "$?" -ne 0 ]; then - $CMD_MYSQL $EXT_ARGV -ss -e 'SELECT COUNT(*), SUM(user=""), SUM(authentication_string=""), SUM(authentication_string NOT LIKE "*%") FROM mysql.user WHERE account_locked <> "Y" AND password_expired <> "Y" AND authentication_string <> ""' 2>/dev/null + $CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(authentication_string=''), SUM(authentication_string NOT LIKE '*%') FROM mysql.user WHERE account_locked <> 'Y' AND password_expired <> 'Y' AND authentication_string <> ''" 2>/dev/null fi } @@ -989,7 +989,7 @@ collect_internal_vars () { local mysqld_executables="${1:-""}" local FNV_64="" - if $CMD_MYSQL $EXT_ARGV -e 'SELECT FNV_64("a")' >/dev/null 2>&1; then + if $CMD_MYSQL $EXT_ARGV -e "SELECT FNV_64('a')" >/dev/null 2>&1; then FNV_64="Enabled"; else FNV_64="Unknown"; @@ -1035,7 +1035,7 @@ collect_internal_vars () { } collect_keyring_plugins() { - $CMD_MYSQL $EXT_ARGV --table -ss -e 'SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE "keyring%";' + $CMD_MYSQL $EXT_ARGV --table -ss -e "SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';" } collect_encrypted_tables() { diff --git a/lib/bash/collect_mysql_info.sh b/lib/bash/collect_mysql_info.sh index d60f87f3b..7838c3798 100644 --- a/lib/bash/collect_mysql_info.sh +++ b/lib/bash/collect_mysql_info.sh @@ -135,9 +135,9 @@ collect_mysql_processlist () { collect_mysql_users () { # The where clause has been added to skip listing MySQL 8+ roles as users. # ROLES are locked accounts, without passwords and expired. - $CMD_MYSQL $EXT_ARGV -ss -e 'SELECT COUNT(*), SUM(user=""), SUM(password=""), SUM(password NOT LIKE "*%") FROM mysql.user' 2>/dev/null + $CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(password=''), SUM(password NOT LIKE '*%') FROM mysql.user" 2>/dev/null if [ "$?" -ne 0 ]; then - $CMD_MYSQL $EXT_ARGV -ss -e 'SELECT COUNT(*), SUM(user=""), SUM(authentication_string=""), SUM(authentication_string NOT LIKE "*%") FROM mysql.user WHERE account_locked <> "Y" AND password_expired <> "Y" AND authentication_string <> ""' 2>/dev/null + $CMD_MYSQL $EXT_ARGV -ss -e "SELECT COUNT(*), SUM(user=''), SUM(authentication_string=''), SUM(authentication_string NOT LIKE '*%') FROM mysql.user WHERE account_locked <> 'Y' AND password_expired <> 'Y' AND authentication_string <> ''" 2>/dev/null fi } @@ -168,7 +168,7 @@ collect_internal_vars () { local mysqld_executables="${1:-""}" local FNV_64="" - if $CMD_MYSQL $EXT_ARGV -e 'SELECT FNV_64("a")' >/dev/null 2>&1; then + if $CMD_MYSQL $EXT_ARGV -e "SELECT FNV_64('a')" >/dev/null 2>&1; then FNV_64="Enabled"; else FNV_64="Unknown"; @@ -215,7 +215,7 @@ collect_internal_vars () { } collect_keyring_plugins() { - $CMD_MYSQL $EXT_ARGV --table -ss -e 'SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE "keyring%";' + $CMD_MYSQL $EXT_ARGV --table -ss -e "SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';" } collect_encrypted_tables() { diff --git a/t/pt-mysql-summary/pt-2109.t b/t/pt-mysql-summary/pt-2109.t new file mode 100644 index 000000000..4375bdd9b --- /dev/null +++ b/t/pt-mysql-summary/pt-2109.t @@ -0,0 +1,80 @@ +#!/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; +use File::Temp qw( tempdir ); + +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 $has_keyring_plugin; + +if ( !$dbh ) { + plan skip_all => 'Cannot connect to sandbox master'; +} +else { + plan tests => 3; +} + +my $db_flavor = VersionParser->new($dbh)->flavor(); +if ( $db_flavor =~ m/Percona Server/ ) { + my $rows = $dbh->selectall_hashref("SHOW PLUGINS", "name"); + while (my ($key, $values) = each %$rows) { + if ($key =~ m/^keyring_/) { + $has_keyring_plugin=1; + last; + } + } +} + +if (!$has_keyring_plugin) { + plan skip_all => 'Keyring plugins are not enabled.'; +} elsif ( $sandbox_version lt '5.7' || $db_flavor !~ m/Percona Server/) { + plan skip_all => 'These tests need Percona Server 5.7+'; +} + +my $dir = tempdir( "percona-testXXXXXXXX", CLEANUP => 1 ); + +my $output; +my $cnf = '/tmp/12345/my.sandbox.cnf'; + +my ($orig_sql_mode) = $dbh->selectrow_array(q{SELECT @@SQL_MODE}); +$dbh->do("SET GLOBAL SQL_MODE='ANSI_QUOTES'"); + +my $cmd = "$trunk/bin/pt-mysql-summary --sleep 1 -- --defaults-file=$cnf"; + +$output = `$cmd 2>&1`; + +unlike( + $output, + qr/You have an error in your SQL syntax.*keyring/s, + "pt-mysql-summary works fine with SQL Mode ANSI_QUOTES" +); + +unlike( + $output, + qr/You have an error in your SQL syntax.*wsrep_on/s, + "pt-mysql-summary works fine with PXC and SQL Mode ANSI_QUOTES" +); + +# ############################################################################# +# Done. +# ############################################################################# +$dbh->do("SET GLOBAL SQL_MODE='${orig_sql_mode}'"); +$sb->wipe_clean($dbh); +ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); +exit; diff --git a/t/pt-mysql-summary/pt-mysql-summary_encryption.t b/t/pt-mysql-summary/pt-mysql-summary_encryption.t index 1424e28d6..61f1446fd 100644 --- a/t/pt-mysql-summary/pt-mysql-summary_encryption.t +++ b/t/pt-mysql-summary/pt-mysql-summary_encryption.t @@ -97,6 +97,35 @@ like( "Security works" ); +# +# SQL Mode ANSI_QUOTES +# + +my ($orig_sql_mode) = $master_dbh->selectrow_array(q{SELECT @@SQL_MODE}); +$master_dbh->do("SET GLOBAL SQL_MODE='ANSI_QUOTES'"); + +$out = `$env $trunk/bin/$tool --sleep 1 --databases mysql 2>/dev/null -- --defaults-file=/tmp/12345/my.sandbox.cnf`; + +like( + $out, + qr/Database Tables Views SPs Trigs Funcs FKs Partn\s+\Qmysql\E/, + "--databases works with SQL Mode ANSI_QUOTES" +); + +like( + $out, + qr/# InnoDB #.*Version.*# MyISAM #/s, + "InnoDB section present with SQL Mode ANSI_QUOTES" +); + +like( + $out, + qr/Users \| 2/, + "Security works with SQL Mode ANSI_QUOTES" +); + +$master_dbh->do("SET GLOBAL SQL_MODE='${orig_sql_mode}'"); + # --read-samples for my $i (2..9) { ok( From c907a0cfb858ecb3b6fe08c9f80ec592402ab4f9 Mon Sep 17 00:00:00 2001 From: Sveta Smirnova Date: Thu, 2 Nov 2023 20:47:10 +0300 Subject: [PATCH 2/2] PT-2109 - pt-mysql-summary throws an error when using sql_mode="ANSI_QUOTES" - Removed keyring plugin check in the beginning of the test, because reported error would show up even on servers that do not have keyring plugin installed. Same applies to wsrep_on check and Percona Server features checks. - Removed temporary dir setup, because not needed for this test. --- t/pt-mysql-summary/pt-2109.t | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/t/pt-mysql-summary/pt-2109.t b/t/pt-mysql-summary/pt-2109.t index 4375bdd9b..b2ebea4f8 100644 --- a/t/pt-mysql-summary/pt-2109.t +++ b/t/pt-mysql-summary/pt-2109.t @@ -14,7 +14,6 @@ use Sandbox; use DSNParser; require VersionParser; use Test::More; -use File::Temp qw( tempdir ); local $ENV{PTDEBUG} = ""; @@ -30,25 +29,6 @@ else { plan tests => 3; } -my $db_flavor = VersionParser->new($dbh)->flavor(); -if ( $db_flavor =~ m/Percona Server/ ) { - my $rows = $dbh->selectall_hashref("SHOW PLUGINS", "name"); - while (my ($key, $values) = each %$rows) { - if ($key =~ m/^keyring_/) { - $has_keyring_plugin=1; - last; - } - } -} - -if (!$has_keyring_plugin) { - plan skip_all => 'Keyring plugins are not enabled.'; -} elsif ( $sandbox_version lt '5.7' || $db_flavor !~ m/Percona Server/) { - plan skip_all => 'These tests need Percona Server 5.7+'; -} - -my $dir = tempdir( "percona-testXXXXXXXX", CLEANUP => 1 ); - my $output; my $cnf = '/tmp/12345/my.sandbox.cnf'; @@ -61,7 +41,7 @@ $output = `$cmd 2>&1`; unlike( $output, - qr/You have an error in your SQL syntax.*keyring/s, + qr/Unknown column 'keyring%' in 'where clause'/s, "pt-mysql-summary works fine with SQL Mode ANSI_QUOTES" );