From d5ceddb39140b34dd6fc9ac68ef3f5f17cae857d Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 7 Dec 2021 01:28:51 +0100 Subject: [PATCH 01/52] Appveyor - cache chocolatey packages --- appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 9797aec6b44..e8902eec589 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,6 +6,10 @@ init: version: build-{build}~branch-{branch} +cache: + - C:\ProgramData\chocolatey\bin -> appveyor.yml + - C:\ProgramData\chocolatey\lib -> appveyor.yml + clone_depth: 1 build_script: From 375ae890c76228c1f827bdc8f7684e81d5414466 Mon Sep 17 00:00:00 2001 From: forkfun Date: Tue, 7 Dec 2021 15:25:43 +0100 Subject: [PATCH 02/52] enable rpl_semi_sync_after_sync and rpl_semi_sync_slave_compressed_protocol tests --- mysql-test/suite/rpl/disabled.def | 3 --- 1 file changed, 3 deletions(-) diff --git a/mysql-test/suite/rpl/disabled.def b/mysql-test/suite/rpl/disabled.def index 94073575606..5f5dc459ffa 100644 --- a/mysql-test/suite/rpl/disabled.def +++ b/mysql-test/suite/rpl/disabled.def @@ -10,9 +10,6 @@ # ############################################################################## -#rpl_get_master_version_and_clock : Bug#11766137 Jan 05 2011 joro Valgrind warnings rpl_partition_archive : MDEV-5077 2013-09-27 svoj Cannot exchange partition with archive table rpl_row_binlog_max_cache_size : MDEV-11092 rpl_row_index_choice : MDEV-11666 -rpl_semi_sync_after_sync : fails after MDEV-16172 -rpl_semi_sync_slave_compressed_protocol : MDEV-25580 2021-05-05 Sujatha From 8dd1f01d0933596f3dde87f32b39bebca5aa1bff Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 7 Dec 2021 17:42:47 +0100 Subject: [PATCH 03/52] MDEV-27191 MariaDB client - "system" command does not work on Windows - define USE_POPEN, like it is done elsewhere. - use Notepad as default editor on Windows for the "edit" command. --- client/mysql.cc | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 177d0f60757..382c216f772 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -96,8 +96,8 @@ extern "C" { # include # endif #define HAVE_READLINE -#define USE_POPEN #endif +#define USE_POPEN } #ifdef HAVE_VIDATTR @@ -4210,11 +4210,6 @@ com_nopager(String *buffer __attribute__((unused)), } #endif - -/* - Sorry, you can't send the result to an editor in Win32 -*/ - #ifdef USE_POPEN static int com_edit(String *buffer,char *line __attribute__((unused))) @@ -4236,7 +4231,7 @@ com_edit(String *buffer,char *line __attribute__((unused))) if (!(editor = (char *)getenv("EDITOR")) && !(editor = (char *)getenv("VISUAL"))) - editor = "vi"; + editor = IF_WIN("notepad","vi"); strxmov(buff,editor," ",filename,NullS); if ((error= system(buff))) { @@ -4251,7 +4246,7 @@ com_edit(String *buffer,char *line __attribute__((unused))) if ((fd = my_open(filename,O_RDONLY, MYF(MY_WME))) < 0) goto err; (void) buffer->alloc((uint) stat_arg.st_size); - if ((tmp=read(fd,(char*) buffer->ptr(),buffer->alloced_length())) >= 0L) + if ((tmp=(int)my_read(fd,(uchar*) buffer->ptr(),buffer->alloced_length(),MYF(0))) >= 0) buffer->length((uint) tmp); else buffer->length(0); From f13c2107b39a6dd1e52bb582545631a4d93f2681 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 7 Dec 2021 17:46:29 +0100 Subject: [PATCH 04/52] Don't beep in mysql_upgrade_service.exe This beep looks especially strange, as mysqladmin output is redirected to the log file --- sql/mysql_upgrade_service.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc index 5afe4ccbc52..78302520f82 100644 --- a/sql/mysql_upgrade_service.cc +++ b/sql/mysql_upgrade_service.cc @@ -464,8 +464,8 @@ int main(int argc, char **argv) if (WaitForSingleObject(mysqld_process, 0) != WAIT_TIMEOUT) die("mysqld.exe did not start"); - if (run_tool(P_WAIT, mysqladmin_path, "--protocol=pipe", - socket_param, "ping", NULL) == 0) + if (run_tool(P_WAIT, mysqladmin_path, "--protocol=pipe", socket_param, + "ping", "--no-beep", NULL) == 0) { break; } From f974062c519e95a00dbd5a1711e2bb95490eb4dc Mon Sep 17 00:00:00 2001 From: Sergei Krivonos Date: Tue, 7 Dec 2021 19:34:31 +0200 Subject: [PATCH 05/52] MDEV-19129: Fixed configure for Xcode, CMake generate CMake Error in wsrep-lib/CMakeLists.txt: The custom command generating /Users/name/build/mariadb-server/sql/lex_token.h is attached to multiple targets: GenServerSource sql but none of these is a common dependency of the other(s). This is not allowed by the Xcode "new build system". --- sql/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 17779adcff8..47716274966 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -351,6 +351,7 @@ ADD_CUSTOM_TARGET( GenServerSource DEPENDS ${GEN_SOURCES} ) +ADD_DEPENDENCIES(sql GenServerSource) #Need this only for embedded SET_TARGET_PROPERTIES(GenServerSource PROPERTIES EXCLUDE_FROM_ALL TRUE) From 5c8e628dda8be24544941b1892ce24c33b14e004 Mon Sep 17 00:00:00 2001 From: Alexey Yurchenko Date: Thu, 2 Dec 2021 22:26:01 +0200 Subject: [PATCH 06/52] wsrep-lib update: bugfixes, cleanups, event API, state transition cleanups Don't switch state to DONOR in `wsrep_sst_donate()` - wsrep-lib does it now --- sql/wsrep_mysqld.cc | 14 -------------- sql/wsrep_mysqld.h | 2 -- sql/wsrep_sst.cc | 5 ----- wsrep-lib | 2 +- 4 files changed, 1 insertion(+), 22 deletions(-) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 3fc03054014..a2856b5034d 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2623,20 +2623,6 @@ void wsrep_wait_appliers_close(THD *thd) */ } -void -wsrep_last_committed_id(wsrep_gtid_t* gtid) -{ - wsrep::gtid ret= Wsrep_server_state::instance().last_committed_gtid(); - memcpy(gtid->uuid.data, ret.id().data(), sizeof(gtid->uuid.data)); - gtid->seqno= ret.seqno().get(); -} - -void -wsrep_node_uuid(wsrep_uuid_t& uuid) -{ - uuid= node_uuid; -} - int wsrep_must_ignore_error(THD* thd) { const int error= thd->get_stmt_da()->sql_errno(); diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index db3e9b09b51..279f2bd44aa 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -210,7 +210,6 @@ extern bool wsrep_must_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_RE extern bool wsrep_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_READ); extern enum wsrep::provider::status wsrep_sync_wait_upto (THD* thd, wsrep_gtid_t* upto, int timeout); -extern void wsrep_last_committed_id (wsrep_gtid_t* gtid); extern int wsrep_check_opts(); extern void wsrep_prepend_PATH (const char* path); extern bool wsrep_append_fk_parent_table(THD* thd, TABLE_LIST* table, wsrep::key_array* keys); @@ -382,7 +381,6 @@ bool wsrep_node_is_synced(); void wsrep_init_SR(); void wsrep_verify_SE_checkpoint(const wsrep_uuid_t& uuid, wsrep_seqno_t seqno); int wsrep_replay_from_SR_store(THD*, const wsrep_trx_meta_t&); -void wsrep_node_uuid(wsrep_uuid_t&); class Log_event; int wsrep_ignored_error_code(Log_event* ev, int error); diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 88bee67a2fc..a11c2fcb78a 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -1892,11 +1892,6 @@ int wsrep_sst_donate(const std::string& msg, const wsrep::gtid& current_gtid, const bool bypass) { - /* This will be reset when sync callback is called. - * Should we set wsrep_ready to FALSE here too? */ - - wsrep_config_state->set(wsrep::server_state::s_donor); - const char* method= msg.data(); size_t method_len= strlen (method); diff --git a/wsrep-lib b/wsrep-lib index 22921e7082d..14b3612a308 160000 --- a/wsrep-lib +++ b/wsrep-lib @@ -1 +1 @@ -Subproject commit 22921e7082ddfb45222f21a585aa8b877e62aa8b +Subproject commit 14b3612a308132d819237bba322f3373ac5a5135 From 5e8148819eac7e48ce962ae27b9d27ac0c32f8ed Mon Sep 17 00:00:00 2001 From: forkfun Date: Wed, 8 Dec 2021 14:28:42 +0100 Subject: [PATCH 07/52] minor cleanup of backup_lock_binlog.test, so that test passes also with statement binlog format --- mysql-test/main/backup_lock_binlog.result | 3 --- mysql-test/main/backup_lock_binlog.test | 1 - 2 files changed, 4 deletions(-) diff --git a/mysql-test/main/backup_lock_binlog.result b/mysql-test/main/backup_lock_binlog.result index adf960a9cb1..b07e1b59e58 100644 --- a/mysql-test/main/backup_lock_binlog.result +++ b/mysql-test/main/backup_lock_binlog.result @@ -2,9 +2,6 @@ # MDEV-25334 FTWRL/Backup blocks DDL on temporary tables with binlog # enabled assertion fails in Diagnostics_area::set_error_status # -select @@binlog_format; -@@binlog_format -MIXED connect con1,localhost,root,,; connection default; # diff --git a/mysql-test/main/backup_lock_binlog.test b/mysql-test/main/backup_lock_binlog.test index 45b3f1cfbd9..71463d6a8d5 100644 --- a/mysql-test/main/backup_lock_binlog.test +++ b/mysql-test/main/backup_lock_binlog.test @@ -9,7 +9,6 @@ --echo # enabled assertion fails in Diagnostics_area::set_error_status --echo # -select @@binlog_format; --connect (con1,localhost,root,,) connection default; From a9b5f5998927b423b39f8ff3697595bf88e77496 Mon Sep 17 00:00:00 2001 From: forkfun Date: Wed, 8 Dec 2021 14:06:33 +0100 Subject: [PATCH 08/52] enable rpl_parallel2 test, as MDEV-23089 is fixed --- mysql-test/suite/rpl/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/suite/rpl/disabled.def b/mysql-test/suite/rpl/disabled.def index 6b8340699aa..34f23c5494e 100644 --- a/mysql-test/suite/rpl/disabled.def +++ b/mysql-test/suite/rpl/disabled.def @@ -18,4 +18,3 @@ rpl_semi_sync_after_sync : fails after MDEV-16172 rpl_semi_sync_slave_compressed_protocol : MDEV-25580 2021-05-05 Sujatha rpl_auto_increment_update_failure : disabled for now rpl_current_user : waits for MDEV-22374 fix -rpl_parallel2 : waits for MDEV-23089 From eafa2a1411d373fc21e82cc49cc1e6d7a33c127a Mon Sep 17 00:00:00 2001 From: forkfun Date: Thu, 9 Dec 2021 16:29:22 +0100 Subject: [PATCH 09/52] enable partition_open_files_limit test --- mysql-test/disabled.def | 1 - mysql-test/r/partition_open_files_limit.result | 2 ++ mysql-test/suite/binlog/t/binlog_sf.test | 8 ++------ mysql-test/t/compound.test | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/mysql-test/disabled.def b/mysql-test/disabled.def index 8ba5b271c2b..6ae67e00eca 100644 --- a/mysql-test/disabled.def +++ b/mysql-test/disabled.def @@ -16,4 +16,3 @@ mysql_embedded : Bug#12561297 2011-05-14 Anitha Dependent on PB2 chang #show_explain : Psergey: random timeout in range-checked-for-each record query. file_contents : MDEV-6526 these files are not installed anymore max_statement_time : cannot possibly work, depends on timing -partition_open_files_limit : open_files_limit check broken by MDEV-18360 diff --git a/mysql-test/r/partition_open_files_limit.result b/mysql-test/r/partition_open_files_limit.result index fed32a69c44..327fe24d27d 100644 --- a/mysql-test/r/partition_open_files_limit.result +++ b/mysql-test/r/partition_open_files_limit.result @@ -1,4 +1,6 @@ DROP TABLE IF EXISTS `t1`; +call mtr.add_suppression("option 'table_open_cache'"); +call mtr.add_suppression("option 'max_connections'"); # Bug#46922: crash when adding partitions and open_files_limit is reached CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=MyISAM PARTITION BY KEY () PARTITIONS 1; diff --git a/mysql-test/suite/binlog/t/binlog_sf.test b/mysql-test/suite/binlog/t/binlog_sf.test index 05b31afcb58..fecc4736972 100644 --- a/mysql-test/suite/binlog/t/binlog_sf.test +++ b/mysql-test/suite/binlog/t/binlog_sf.test @@ -1,4 +1,3 @@ --- source include/have_log_bin.inc # We change binlog format inside the test, so no need to re-run with # more than one binlog_format. @@ -9,13 +8,9 @@ # save status -let $oblf=`select @@SESSION.BINLOG_FORMAT`; let $otfc=`select @@log_bin_trust_function_creators`; - set global log_bin_trust_function_creators=0; - - # fail *on definition* set binlog_format=STATEMENT; @@ -186,6 +181,7 @@ drop function fn16456; # restore status --disable_query_log -eval set binlog_format=$oblf; +set binlog_format=STATEMENT; eval set global log_bin_trust_function_creators=$otfc; +reset master; --enable_query_log diff --git a/mysql-test/t/compound.test b/mysql-test/t/compound.test index 7583bc1cca9..046a9b9767e 100644 --- a/mysql-test/t/compound.test +++ b/mysql-test/t/compound.test @@ -1,7 +1,7 @@ # # MDEV-5317 Compound statement / anonymous blocks # -source include/have_log_bin.inc; +source include/have_binlog_format_mixed_or_statement.inc; delimiter |; CREATE TABLE t1 (a INT PRIMARY KEY)| From 0745db71798ea7179140f4ffe85d6d69c9ba7da6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 9 Dec 2021 19:14:17 +0100 Subject: [PATCH 10/52] don't use buffered_option_error_reporter without perfschema it's not printed, not cleaned up without perfschema, so isn't supposed to be written into either this fixes "Memory not freed" warnings when early command line options produce warnings in non-perfschema builds --- sql/mysqld.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d7a44138780..6a7ea117c84 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1392,12 +1392,13 @@ static MYSQL_SOCKET unix_sock, base_ip_sock, extra_ip_sock; struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD() #ifndef EMBEDDED_LIBRARY +C_MODE_START +#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE /** Error reporter that buffer log messages. @param level log message level @param format log message format string */ -C_MODE_START static void buffered_option_error_reporter(enum loglevel level, const char *format, ...) { @@ -1409,6 +1410,7 @@ static void buffered_option_error_reporter(enum loglevel level, va_end(args); buffered_logs.buffer(level, buffer); } +#endif /** @@ -5809,7 +5811,7 @@ int mysqld_main(int argc, char **argv) Initialize the array of performance schema instrument configurations. */ init_pfs_instrument_array(); -#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ + /* Logs generated while parsing the command line options are buffered and printed later. @@ -5817,7 +5819,7 @@ int mysqld_main(int argc, char **argv) buffered_logs.init(); my_getopt_error_reporter= buffered_option_error_reporter; my_charset_error_reporter= buffered_option_error_reporter; -#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE + pfs_param.m_pfs_instrument= const_cast(""); #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ my_timer_init(&sys_timer_info); From 74b3d4252a291456982c8e61a3af3d9936c6fbdd Mon Sep 17 00:00:00 2001 From: sjaakola Date: Fri, 10 Dec 2021 11:38:27 +0200 Subject: [PATCH 11/52] MDEV-27218 mtr test galera.MDEV-20793 has sporadic false positive failures Fixes to make the galera.MDEV-20793 test deterministic. Specifically, after --send COMMIT, there is now a sync point to catch a known state of the COMMIT execution --- mysql-test/suite/galera/r/MDEV-20793.result | 7 +++++- mysql-test/suite/galera/t/MDEV-20793.test | 26 ++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/r/MDEV-20793.result b/mysql-test/suite/galera/r/MDEV-20793.result index b420c8720f5..feb068f258f 100644 --- a/mysql-test/suite/galera/r/MDEV-20793.result +++ b/mysql-test/suite/galera/r/MDEV-20793.result @@ -9,7 +9,6 @@ connection node_1; SET SESSION wsrep_retry_autocommit = 0; START TRANSACTION; UPDATE t1 SET f2 = 1; -SET SESSION debug_sync = "wsrep_before_replay SIGNAL reached WAIT_FOR continue"; connection node_1_ctrl; SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; connection node_2; @@ -24,9 +23,15 @@ UPDATE t1 SET f2 = 2 WHERE f1 = 5; connection node_1_ctrl; SET SESSION wsrep_on = 0; SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync'; connection node_1; +SET SESSION debug_sync = "wsrep_before_replay SIGNAL reached WAIT_FOR continue"; COMMIT; connection node_1_ctrl; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync'; SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; SET SESSION debug_sync = "now WAIT_FOR reached"; SET GLOBAL wsrep_provider_options = 'signal=local_monitor_slave_enter_sync'; diff --git a/mysql-test/suite/galera/t/MDEV-20793.test b/mysql-test/suite/galera/t/MDEV-20793.test index 13ff3cbe77b..6835a73a2a4 100644 --- a/mysql-test/suite/galera/t/MDEV-20793.test +++ b/mysql-test/suite/galera/t/MDEV-20793.test @@ -30,9 +30,9 @@ SET GLOBAL wsrep_slave_threads = 2; SET SESSION wsrep_retry_autocommit = 0; START TRANSACTION; UPDATE t1 SET f2 = 1; -SET SESSION debug_sync = "wsrep_before_replay SIGNAL reached WAIT_FOR continue"; --connection node_1_ctrl +# set sync point for incoming applier --let $galera_sync_point = apply_monitor_slave_enter_sync --source include/galera_set_sync_point.inc @@ -42,8 +42,11 @@ SET SESSION debug_sync = "wsrep_before_replay SIGNAL reached WAIT_FOR continue"; INSERT INTO t1 VALUES (2, 2); --connection node_1_ctrl +# wait to see the INSERT from node_2 reaching applier sync point --source include/galera_wait_sync_point.inc --source include/galera_clear_sync_point.inc + +# set sync point to catch other write set applying from node_2 --let $galera_sync_point = local_monitor_slave_enter_sync --source include/galera_set_sync_point.inc @@ -52,17 +55,38 @@ INSERT INTO t1 VALUES (2, 2); UPDATE t1 SET f2 = 2 WHERE f1 = 5; --connection node_1_ctrl +# wait until both appliers are stopped in sync points --let $galera_sync_point = apply_monitor_slave_enter_sync local_monitor_slave_enter_sync --source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +# set sync point for catching node_1 transaction just before committing +--let $galera_sync_point = after_replicate_sync +--source include/galera_set_sync_point.inc --connection node_1 +# set sync point, which will stop execution after COMMIT has been BF aborted +# and send the COMMIT, it should stop in commit_monitor_master_enter_sync point +SET SESSION debug_sync = "wsrep_before_replay SIGNAL reached WAIT_FOR continue"; --send COMMIT --connection node_1_ctrl +# wait until both appliers and local COMMIT are idle in their sync points +--let $galera_sync_point = after_replicate_sync apply_monitor_slave_enter_sync local_monitor_slave_enter_sync +--source include/galera_wait_sync_point.inc + +# release local COMMIT processing, it will continue and pause first before certification, +--let $galera_sync_point = after_replicate_sync +--source include/galera_signal_sync_point.inc + +# release first applier (INSERT), it should BF abort the local COMMIT processing --let $galera_sync_point = apply_monitor_slave_enter_sync --source include/galera_signal_sync_point.inc + +# wait to see that COMMIT was BF aborted and has reached replaying state SET SESSION debug_sync = "now WAIT_FOR reached"; +# release the latter applier, with real lock conflict --let $galera_sync_point = local_monitor_slave_enter_sync --source include/galera_signal_sync_point.inc --source include/galera_clear_sync_point.inc From 88b339805d7a9ddebc3fd61e9dee83270dbf474d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 11 Dec 2021 15:27:14 +0200 Subject: [PATCH 12/52] Fix a test for cmake -DPLUGIN_PERFSCHEMA=NO --- mysql-test/suite/perfschema/t/digest_view.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/perfschema/t/digest_view.test b/mysql-test/suite/perfschema/t/digest_view.test index 462d60556eb..f718d7530e6 100644 --- a/mysql-test/suite/perfschema/t/digest_view.test +++ b/mysql-test/suite/perfschema/t/digest_view.test @@ -8,6 +8,7 @@ # Test requires: sp-protocol/ps-protocol/view-protocol/cursor-protocol disabled --source include/no_protocol.inc --source include/not_embedded.inc +--source include/have_perfschema.inc CREATE TABLE test.v1 (a int, b int); INSERT INTO test.v1 VALUES (1, 100), (2, 200), (3, 300); From 6b066ec33285c089ce770c2d1eb50bc49787ee92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 Dec 2021 08:04:45 +0200 Subject: [PATCH 13/52] MDEV-27235: Crash on SET GLOBAL innodb_encrypt_tables fil_crypt_set_encrypt_tables(): If no encryption threads have been initialized, do nothing. --- mysql-test/suite/innodb/r/temporary_table.result | 1 + mysql-test/suite/innodb/t/temporary_table.test | 2 ++ storage/innobase/fil/fil0crypt.cc | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/mysql-test/suite/innodb/r/temporary_table.result b/mysql-test/suite/innodb/r/temporary_table.result index 0307ba88200..9a11b7561af 100644 --- a/mysql-test/suite/innodb/r/temporary_table.result +++ b/mysql-test/suite/innodb/r/temporary_table.result @@ -136,6 +136,7 @@ show tables; Tables_in_test create temporary table t1 (keyc int, c1 char(100), c2 char(100)) engine = innodb; ERROR HY000: Can't create table `test`.`t1` (errno: 165 "Table is read only") +SET GLOBAL innodb_encrypt_tables=DEFAULT; # test various bad start-up parameters FOUND 2 /InnoDB: Unable to create temporary file/ in mysqld.1.err FOUND 1 /innodb_temporary and innodb_system file names seem to be the same/ in mysqld.1.err diff --git a/mysql-test/suite/innodb/t/temporary_table.test b/mysql-test/suite/innodb/t/temporary_table.test index d7fe66e2efb..46ac867c1c2 100644 --- a/mysql-test/suite/innodb/t/temporary_table.test +++ b/mysql-test/suite/innodb/t/temporary_table.test @@ -121,6 +121,8 @@ show tables; --error ER_CANT_CREATE_TABLE create temporary table t1 (keyc int, c1 char(100), c2 char(100)) engine = innodb; +SET GLOBAL innodb_encrypt_tables=DEFAULT; + --echo # test various bad start-up parameters let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err; diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 46fc12ee6b0..a8ffa3e2578 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -2470,6 +2470,10 @@ void fil_crypt_set_encrypt_tables( uint val) { + if (!fil_crypt_threads_inited) { + return; + } + mutex_enter(&fil_system->mutex); srv_encrypt_tables = val; From 8bb55633699612279744c055e22eeca8d4058273 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Mon, 13 Dec 2021 02:15:57 +0100 Subject: [PATCH 14/52] MDEV-27181: Galera SST scripts should use ssl_capath for CA directory 1. Galera SST scripts should use ssl_capath (not ssl_ca) for CA directory. The current implementation tries to automatically detect the path using the trailing slash in the ssl_ca variable value, but this approach is not compatible with the server configuration. Now, by analogy with the server, SST scripts also use a separate ssl_capath variable. In addition, a similar tcapath variable has been added for the old-style configuration (in the "sst" section). 2. Openssl utility detection made more reliable. 3. Removed extra spaces in automatically generated command lines - to simplify debugging of the SST scripts. 4. In general, the code for detecting the presence or absence of auxiliary utilities has been improved - it is made more reliable in some configurations (and for shells other than bash). --- mysql-test/std_data/capath/3106f582.0 | 1 + mysql-test/std_data/capath/cacert.pem | 79 ++++ mysql-test/std_data/capath/ed1f42db.0 | 1 + mysql-test/suite/galera/disabled.def | 1 - ...alera_sst_rsync_encrypt_with_capath.result | 398 ++++++++++++++++++ .../galera_sst_rsync_encrypt_with_key.result | 2 - ...alera_sst_rsync_encrypt_with_server.result | 2 - .../galera_sst_mariabackup_table_options.test | 1 + .../galera_sst_rsync_encrypt_with_capath.cnf | 20 + .../galera_sst_rsync_encrypt_with_capath.test | 26 ++ .../t/galera_sst_rsync_encrypt_with_key.test | 3 - .../galera_sst_rsync_encrypt_with_server.test | 3 - .../t/galera_ipv6_mariabackup.test | 1 + .../t/galera_ipv6_mariabackup_section.test | 1 + scripts/wsrep_sst_common.sh | 142 ++++--- scripts/wsrep_sst_mariabackup.sh | 292 +++++++------ scripts/wsrep_sst_mysqldump.sh | 11 +- scripts/wsrep_sst_rsync.sh | 117 ++--- scripts/wsrep_sst_xtrabackup-v2.sh | 321 +++++++------- scripts/wsrep_sst_xtrabackup.sh | 5 +- vio/viosslfactories.c | 17 + 21 files changed, 1033 insertions(+), 411 deletions(-) create mode 120000 mysql-test/std_data/capath/3106f582.0 create mode 100644 mysql-test/std_data/capath/cacert.pem create mode 120000 mysql-test/std_data/capath/ed1f42db.0 create mode 100644 mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test diff --git a/mysql-test/std_data/capath/3106f582.0 b/mysql-test/std_data/capath/3106f582.0 new file mode 120000 index 00000000000..1310cfcff20 --- /dev/null +++ b/mysql-test/std_data/capath/3106f582.0 @@ -0,0 +1 @@ +cacert.pem \ No newline at end of file diff --git a/mysql-test/std_data/capath/cacert.pem b/mysql-test/std_data/capath/cacert.pem new file mode 100644 index 00000000000..23dda2318e1 --- /dev/null +++ b/mysql-test/std_data/capath/cacert.pem @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + d0:4d:23:85:ee:59:b3:fa + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Validity + Not Before: Jan 27 10:11:10 2019 GMT + Not After : Jan 22 10:11:10 2039 GMT + Subject: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e8:0e:a7:84:d3:75:30:06:30:b2:10:b9:d1:88: + 36:2b:5e:f8:c8:44:57:cb:67:72:ab:96:95:33:d5: + 88:d1:8f:23:50:98:ba:6d:20:00:80:bd:35:d5:c1: + bf:98:49:c4:0a:15:4a:34:a6:21:9b:2e:8c:15:09: + f0:63:81:02:c2:7c:e2:53:e0:f7:a1:1a:40:5e:8f: + 41:4a:4c:56:d4:20:f1:d5:a7:c1:53:2e:ff:7e:37: + 17:cc:7e:74:bd:e2:22:33:ce:8c:77:62:a4:c5:3f: + 44:35:7b:7e:b9:f5:7d:8c:7a:27:58:fd:2c:42:86: + 2e:e7:6b:01:99:7b:fe:7d:a7:a1:4f:3e:39:39:54: + 1f:61:de:74:66:d1:77:4f:43:1b:66:70:29:85:de: + fc:8f:8e:1b:7b:a2:66:48:26:7f:9b:a6:fd:4a:e4: + dc:eb:ed:bd:f8:e3:f1:57:98:13:6f:f1:a3:2a:e3: + 73:bd:8d:7c:6f:4b:59:35:bc:b5:42:3e:99:a7:13: + 8d:be:2e:5c:9a:c6:5b:ab:ae:bf:00:e9:c8:ee:05: + 22:8e:d5:67:1a:47:9a:6d:9c:f9:42:3e:15:34:f8: + 31:ec:b4:7e:d3:92:95:b0:b8:f9:66:f3:bd:1d:31: + 2c:b1:90:62:a1:f8:4e:a6:5d:26:22:f0:e1:fe:16: + 2b:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + X509v3 Authority Key Identifier: + keyid:CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + df:fd:74:29:5b:5e:9a:8b:09:02:40:59:73:cb:71:47:3f:97: + 3d:a9:fd:c4:8c:01:29:c9:86:b8:71:55:ff:72:0e:50:dc:c8: + b5:e6:91:41:52:47:21:30:cc:4d:e7:3b:4b:db:55:ea:7d:46: + eb:53:e0:b7:1b:80:7c:b1:0c:d3:d1:bc:a0:73:ae:96:1f:fd: + 05:52:7e:54:d5:03:52:69:7b:34:5f:27:d7:98:da:98:76:73: + e6:bb:50:59:2a:94:90:67:03:1c:a4:76:2f:ee:ef:59:60:09: + 48:33:03:2b:52:ed:83:42:f8:71:19:7f:d8:be:40:ed:20:01: + 90:3c:7e:1c:8b:d2:9f:f3:2f:09:1f:50:c8:10:e1:8a:d9:a5: + 49:9c:0b:74:17:b9:2b:68:f6:1e:73:c2:73:10:38:b3:35:e2: + 87:91:1b:a1:d1:9b:81:9d:1b:32:cc:03:6e:4c:82:95:81:11: + 42:56:e2:16:2b:22:65:db:40:2c:ca:dc:03:f4:d5:07:cf:f5: + 13:b2:cf:51:5b:24:cd:c7:d1:9b:42:8e:f9:df:5d:1e:5a:09: + a3:4f:a9:0b:f4:21:c5:bb:ff:02:93:67:e8:2d:ee:ab:d9:59: + 76:03:2c:a1:bd:fb:dc:af:b6:82:94:71:85:53:a8:18:0d:3a: + 9e:42:eb:59 +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIJANBNI4XuWbP6MA0GCSqGSIb3DQEBCwUAMFYxDzANBgNV +BAMMBmNhY2VydDELMAkGA1UEBhMCRkkxETAPBgNVBAgMCEhlbHNpbmtpMREwDwYD +VQQHDAhIZWxzaW5raTEQMA4GA1UECgwHTWFyaWFEQjAeFw0xOTAxMjcxMDExMTBa +Fw0zOTAxMjIxMDExMTBaMFYxDzANBgNVBAMMBmNhY2VydDELMAkGA1UEBhMCRkkx +ETAPBgNVBAgMCEhlbHNpbmtpMREwDwYDVQQHDAhIZWxzaW5raTEQMA4GA1UECgwH +TWFyaWFEQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOgOp4TTdTAG +MLIQudGINite+MhEV8tncquWlTPViNGPI1CYum0gAIC9NdXBv5hJxAoVSjSmIZsu +jBUJ8GOBAsJ84lPg96EaQF6PQUpMVtQg8dWnwVMu/343F8x+dL3iIjPOjHdipMU/ +RDV7frn1fYx6J1j9LEKGLudrAZl7/n2noU8+OTlUH2HedGbRd09DG2ZwKYXe/I+O +G3uiZkgmf5um/Urk3Ovtvfjj8VeYE2/xoyrjc72NfG9LWTW8tUI+macTjb4uXJrG +W6uuvwDpyO4FIo7VZxpHmm2c+UI+FTT4Mey0ftOSlbC4+WbzvR0xLLGQYqH4TqZd +JiLw4f4WK2kCAwEAAaNQME4wHQYDVR0OBBYEFMpxmYnwcqt1ZrtlagMEcqV7laaT +MB8GA1UdIwQYMBaAFMpxmYnwcqt1ZrtlagMEcqV7laaTMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBAN/9dClbXpqLCQJAWXPLcUc/lz2p/cSMASnJhrhx +Vf9yDlDcyLXmkUFSRyEwzE3nO0vbVep9RutT4LcbgHyxDNPRvKBzrpYf/QVSflTV +A1JpezRfJ9eY2ph2c+a7UFkqlJBnAxykdi/u71lgCUgzAytS7YNC+HEZf9i+QO0g +AZA8fhyL0p/zLwkfUMgQ4YrZpUmcC3QXuSto9h5zwnMQOLM14oeRG6HRm4GdGzLM +A25MgpWBEUJW4hYrImXbQCzK3AP01QfP9ROyz1FbJM3H0ZtCjvnfXR5aCaNPqQv0 +IcW7/wKTZ+gt7qvZWXYDLKG9+9yvtoKUcYVTqBgNOp5C61k= +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/capath/ed1f42db.0 b/mysql-test/std_data/capath/ed1f42db.0 new file mode 120000 index 00000000000..1310cfcff20 --- /dev/null +++ b/mysql-test/std_data/capath/ed1f42db.0 @@ -0,0 +1 @@ +cacert.pem \ No newline at end of file diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d92f3f7d6b8..955a2c82ebc 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -29,5 +29,4 @@ versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest galera_wsrep_provider_unset_set: wsrep_provider is read-only for security reasons pxc-421: wsrep_provider is read-only for security reasons galera_sst_xtrabackup-v2: Test fails due to innodb issues -galera_sst_xtrabackup-v2_encrypt_with_key: Test fails due to innodb issues galera_sst_xtrabackup-v2_data_dir: Test fails due to innodb issues diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result new file mode 100644 index 00000000000..170ba62dd12 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result @@ -0,0 +1,398 @@ +connection node_1; +connection node_2; +connection node_1; +Performing State Transfer on a server that has been shut down cleanly and restarted +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_shutdown_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that starts from a clean var directory +This is accomplished by shutting down node #2 and removing its var directory before restarting it +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +Cleaning var directory ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_clean_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_clean_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +while a DDL was in progress on it +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +connection node_2; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; +connection node_1; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +connection node_2; +SET wsrep_sync_wait = 0; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +connection node_2; +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave_ddl; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +SET GLOBAL debug_dbug = $debug_orig; +include/assert_grep.inc [Using stunnel for SSL encryption] diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result index 251c087412b..170ba62dd12 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result @@ -1,7 +1,5 @@ connection node_1; connection node_2; -connection node_2; -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); connection node_1; Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result index 251c087412b..170ba62dd12 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result @@ -1,7 +1,5 @@ connection node_1; connection node_2; -connection node_2; -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); connection node_1; Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test b/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test index 953a1635559..7a3a6c825c4 100644 --- a/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test @@ -66,6 +66,7 @@ COMMIT; --source include/wait_condition.inc --echo Cleaning var directory ... +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mtr --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/performance_schema --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/test diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf new file mode 100644 index 00000000000..3ab762df013 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf @@ -0,0 +1,20 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=rsync +ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem +ssl-key=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem +ssl-capath=@ENV.MYSQL_TEST_DIR/std_data/capath +# We need to turn off the default setting for the duration +# of the test (to test working with a directory instead of +# a file): +ssl-ca= + +[sst] +ssl-mode=VERIFY_CA + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test new file mode 100644 index 00000000000..a2d92723ec4 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test @@ -0,0 +1,26 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_debug.inc +--source include/have_stunnel.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--connection node_1 +--source suite/galera/include/galera_st_shutdown_slave.inc +--source suite/galera/include/galera_st_clean_slave.inc + +--source suite/galera/include/galera_st_kill_slave.inc +--source suite/galera/include/galera_st_kill_slave_ddl.inc + +# Confirm that transfer was SSL-encrypted +--let $assert_text = Using stunnel for SSL encryption +--let $assert_select = Using stunnel for SSL encryption +--let $assert_count = 5 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = CURRENT_TEST +--source include/assert_grep.inc + +--source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test index 838c473b9ce..a2d92723ec4 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test @@ -8,9 +8,6 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.inc ---connection node_2 -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); - --connection node_1 --source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_clean_slave.inc diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test index 838c473b9ce..a2d92723ec4 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test @@ -8,9 +8,6 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.inc ---connection node_2 -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); - --connection node_1 --source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_clean_slave.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test index dc3331d1be3..2bb2bb284e9 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/check_ipv6.inc --source include/have_innodb.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test index c88ff99790c..86607e61542 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/check_ipv6.inc --source include/have_innodb.inc diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index dbd639595df..5c84aa7c17f 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -19,6 +19,9 @@ set -u +# Setting the path for some utilities on CentOS +export PATH="$PATH:/usr/sbin:/usr/bin:/sbin:/bin" + WSREP_SST_OPT_BYPASS=0 WSREP_SST_OPT_BINLOG="" WSREP_SST_OPT_BINLOG_INDEX="" @@ -384,10 +387,8 @@ case "$1" in skip_mysqld_arg=1 ;; '--innodb-force-recovery') - if [ -n "$value" ]; then - if [ "$value" -ne 0 ]; then - INNODB_FORCE_RECOVERY="$value" - fi + if [ -n "$value" -a "$value" != "0" ]; then + INNODB_FORCE_RECOVERY="$value" fi skip_mysqld_arg=1 ;; @@ -584,7 +585,8 @@ get_binlog() if [ -n "$WSREP_SST_OPT_ADDR_PORT" ]; then if [ -n "$WSREP_SST_OPT_PORT" ]; then if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then - echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 + echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT" \ + "differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 exit 2 fi else @@ -616,8 +618,19 @@ fi readonly WSREP_SST_OPT_ADDR readonly WSREP_SST_OPT_ADDR_PORT -# try to use my_print_defaults, mysql and mysqldump that come with the sources -# (for MTR suite) +commandex() +{ + if [ -n "$BASH_VERSION" ]; then + command -v "$1" || : + elif [ -x "$1" ]; then + echo "$1" + else + which "$1" || : + fi +} + +# try to use my_print_defaults, mysql and mysqldump that come +# with the sources (for MTR suite): script_binary=$(dirname "$0") SCRIPTS_DIR=$(cd "$script_binary"; pwd -P) EXTRA_DIR="$SCRIPTS_DIR/../extra" @@ -626,13 +639,13 @@ CLIENT_DIR="$SCRIPTS_DIR/../client" if [ -x "$CLIENT_DIR/mysql" ]; then MYSQL_CLIENT="$CLIENT_DIR/mysql" else - MYSQL_CLIENT="$(command -v mysql)" + MYSQL_CLIENT=$(commandex 'mysql') fi if [ -x "$CLIENT_DIR/mysqldump" ]; then MYSQLDUMP="$CLIENT_DIR/mysqldump" else - MYSQLDUMP="$(command -v mysqldump)" + MYSQLDUMP=$(commandex 'mysqldump') fi wsrep_log() @@ -663,7 +676,7 @@ if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults" else - MY_PRINT_DEFAULTS="$(command -v my_print_defaults)" + MY_PRINT_DEFAULTS=$(commandex 'my_print_defaults') if [ -z "$MY_PRINT_DEFAULTS" ]; then wsrep_log_error "my_print_defaults not found in path" exit 2 @@ -673,16 +686,16 @@ fi readonly MY_PRINT_DEFAULTS wsrep_defaults="$WSREP_SST_OPT_DEFAULTS" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULTS:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" -readonly WSREP_SST_OPT_CONF="$wsrep_defaults" +readonly WSREP_SST_OPT_CONF="${wsrep_defaults:+ }$wsrep_defaults" wsrep_defaults="$WSREP_SST_OPT_DEFAULT" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULT" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULT:+ }$WSREP_SST_OPT_EXTRA_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" -readonly WSREP_SST_OPT_CONF_UNQUOTED="$wsrep_defaults" +readonly WSREP_SST_OPT_CONF_UNQUOTED="${wsrep_defaults:+ }$wsrep_defaults" # # User can specify mariabackup specific settings that will be used during sst @@ -819,8 +832,7 @@ if wsrep_auth_not_set; then fi # Splitting WSREP_SST_OPT_AUTH as "user:password" pair: -if ! wsrep_auth_not_set -then +if ! wsrep_auth_not_set; then # Extract username as shortest prefix up to first ':' character: WSREP_SST_OPT_AUTH_USER="${WSREP_SST_OPT_AUTH%%:*}" if [ -z "$WSREP_SST_OPT_USER" ]; then @@ -848,8 +860,7 @@ readonly WSREP_SST_OPT_USER readonly WSREP_SST_OPT_PSWD readonly WSREP_SST_OPT_AUTH -if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ] -then +if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ]; then # Split auth string at the last ':' readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%%:*}" readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH#*:}" @@ -860,8 +871,7 @@ fi readonly WSREP_SST_OPT_REMOTE_AUTH -if [ -n "$WSREP_SST_OPT_DATA" ] -then +if [ -n "$WSREP_SST_OPT_DATA" ]; then SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress" else SST_PROGRESS_FILE="" @@ -870,13 +880,14 @@ fi wsrep_cleanup_progress_file() { [ -n "$SST_PROGRESS_FILE" -a \ - -f "$SST_PROGRESS_FILE" ] && rm -f "$SST_PROGRESS_FILE" 2>/dev/null || true + -f "$SST_PROGRESS_FILE" ] && \ + rm -f "$SST_PROGRESS_FILE" 2>/dev/null || : } wsrep_check_program() { local prog="$1" - local cmd=$(command -v "$prog") + local cmd=$(commandex "$prog") if [ -z "$cmd" ]; then echo "'$prog' not found in PATH" return 2 # no such file or directory @@ -898,9 +909,9 @@ wsrep_check_programs() wsrep_check_datadir() { - if [ -z "$WSREP_SST_OPT_DATA" ] - then - wsrep_log_error "The '--datadir' parameter must be passed to the SST script" + if [ -z "$WSREP_SST_OPT_DATA" ]; then + wsrep_log_error \ + "The '--datadir' parameter must be passed to the SST script" exit 2 fi } @@ -912,10 +923,10 @@ get_openssl() return fi # Let's look for openssl: - OPENSSL_BINARY="$(command -v openssl)" + OPENSSL_BINARY=$(commandex 'openssl') if [ -z "$OPENSSL_BINARY" ]; then OPENSSL_BINARY='/usr/bin/openssl' - if [ -z "$OPENSSL_BINARY" ]; then + if [ ! -x "$OPENSSL_BINARY" ]; then OPENSSL_BINARY="" fi fi @@ -928,13 +939,12 @@ get_openssl() wsrep_gen_secret() { get_openssl - if [ -n "$OPENSSL_BINARY" ] - then + if [ -n "$OPENSSL_BINARY" ]; then echo $("$OPENSSL_BINARY" rand -hex 16) else printf "%04x%04x%04x%04x%04x%04x%04x%04x" \ - $RANDOM $RANDOM $RANDOM $RANDOM \ - $RANDOM $RANDOM $RANDOM $RANDOM + $RANDOM $RANDOM $RANDOM $RANDOM \ + $RANDOM $RANDOM $RANDOM $RANDOM fi } @@ -968,14 +978,14 @@ is_local_ip() fi # Now let's check if the given address is assigned to # one of the network cards: - local ip_util="$(command -v ip)" + local ip_util=$(commandex 'ip') if [ -n "$ip_util" ]; then # ip address show ouput format is " inet[6]
/": "$ip_util" address show \ | grep -E "^[[:space:]]*inet.? [^[:space:]]+/" -o \ | grep -F " $1/" >/dev/null && return 0 else - local ifconfig_util="$(command -v ifconfig)" + local ifconfig_util=$(commandex 'ifconfig') if [ -n "$ifconfig_util" ]; then # ifconfig output format is " inet[6]
...": "$ifconfig_util" \ @@ -992,15 +1002,15 @@ check_sockets_utils() sockstat_available=0 ss_available=0 - [ -n "$(command -v lsof)" ] && lsof_available=1 - [ -n "$(command -v sockstat)" ] && sockstat_available=1 - [ -n "$(command -v ss)" ] && ss_available=1 + [ -n "$(commandex lsof)" ] && lsof_available=1 + [ -n "$(commandex sockstat)" ] && sockstat_available=1 + [ -n "$(commandex ss)" ] && ss_available=1 if [ $lsof_available -eq 0 -a \ $sockstat_available -eq 0 -a \ $ss_available -eq 0 ] then - wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in " \ + wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in" \ "the PATH. Make sure you have it installed." exit 2 # ENOENT fi @@ -1085,26 +1095,38 @@ check_for_dhparams() # verify_ca_matches_cert() { - local ca="$1" - local cert="$2" - local path=${3:-0} + local cert="$1" + local ca="$2" + local cap="$3" # If the openssl utility is not installed, then # we will not do this certificate check: get_openssl if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_info "openssl utility not found" return fi - local not_match=0 + local readable=1; [ ! -r "$cert" ] && readable=0 + [ -n "$ca" ] && [ ! -r "$ca" ] && readable=0 + [ -n "$cap" ] && [ ! -r "$cap" ] && readable=0 - if [ $path -eq 0 ]; then - "$OPENSSL_BINARY" verify -verbose -CAfile "$ca" "$cert" >/dev/null 2>&1 || not_match=1 - else - "$OPENSSL_BINARY" verify -verbose -CApath "$ca" "$cert" >/dev/null 2>&1 || not_match=1 + if [ readable -eq 0 ]; then + wsrep_log_error \ + "Both PEM file and CA file (or path) must be readable" + exit 22 fi + local not_match=0 + local errmsg + errmsg=$("$OPENSSL_BINARY" verify -verbose \ + ${ca:+ -CAfile} ${ca:+ "$ca"} \ + ${cap:+ -CApath} ${cap:+ "$cap"} \ + "$cert" 2>&1) || not_match=1 + if [ $not_match -eq 1 ]; then + wsrep_log_info "run: \"$OPENSSL_BINARY\" verify -verbose${ca:+ -CAfile \"$ca\"}${cap:+ -CApath \"$cap\"} \"$cert\"" + wsrep_log_info "output: $errmsg" wsrep_log_error "******** FATAL ERROR ********************************************" wsrep_log_error "* The certifcate and CA (certificate authority) do not match. *" wsrep_log_error "* It does not appear that the certificate was issued by the CA. *" @@ -1124,12 +1146,18 @@ verify_ca_matches_cert() # verify_cert_matches_key() { - local cert_path="$1" - local key_path="$2" + local cert="$1" + local key="$2" + + if [ ! -r "$key" -o ! -r "$cert" ]; then + wsrep_log_error "Both the certificate file and the key file" \ + "must be readable" + exit 22 + fi # If the diff utility is not installed, then # we will not do this certificate check: - if [ -z "$(command -v diff)" ]; then + if [ -z "$(commandex diff)" ]; then return fi @@ -1142,13 +1170,13 @@ verify_cert_matches_key() # Generate the public key from the cert and the key. # They should match (otherwise we can't create an SSL connection). - if ! diff <("$OPENSSL_BINARY" x509 -in "$cert_path" -pubkey -noout 2>/dev/null) \ - <("$OPENSSL_BINARY" pkey -in "$key_path" -pubout 2>/dev/null) >/dev/null 2>&1 + if ! diff <("$OPENSSL_BINARY" x509 -in "$cert" -pubkey -noout 2>/dev/null) \ + <("$OPENSSL_BINARY" pkey -in "$key" -pubout 2>/dev/null) >/dev/null 2>&1 then - wsrep_log_error "******************* FATAL ERROR ****************" - wsrep_log_error "* The certifcate and private key do not match. *" - wsrep_log_error "* Please check your certificate and key files. *" - wsrep_log_error "************************************************" + wsrep_log_error "******************* FATAL ERROR *****************" + wsrep_log_error "* The certificate and private key do not match. *" + wsrep_log_error "* Please check your certificate and key files. *" + wsrep_log_error "*************************************************" exit 22 fi } @@ -1305,9 +1333,9 @@ get_proc() elif [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ]; then nproc=$(sysctl -n hw.ncpu) fi + set -e if [ -z "$nproc" ] || [ $nproc -eq 0 ]; then nproc=1 fi - set -e fi } diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index b429a9effd5..4bca785fcad 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -20,10 +20,11 @@ # https://mariadb.com/kb/en/mariabackup-overview/ # Make sure to read that before proceeding! +OS="$(uname)" + . $(dirname "$0")/wsrep_sst_common wsrep_check_datadir -OS="$(uname)" ealgo="" eformat="" ekey="" @@ -34,7 +35,7 @@ ssyslog="" ssystag="" BACKUP_PID="" tcert="" -tpath=0 +tcap="" tpem="" tkey="" tmode="DISABLED" @@ -88,14 +89,14 @@ readonly SECRET_TAG="secret" # For backup locks it is 1 sent by joiner sst_ver=1 -if [ -n "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then +if [ -n "$(commandex pv)" ] && pv --help | grep -qw -- '-F'; then pvopts="$pvopts $pvformat" fi pcmd="pv $pvopts" declare -a RC -BACKUP_BIN="$(command -v mariabackup)" -if [ ! -x "$BACKUP_BIN" ]; then +BACKUP_BIN=$(commandex 'mariabackup') +if [ -z "$BACKUP_BIN" ]; then wsrep_log_error 'mariabackup binary not found in path' exit 42 fi @@ -145,14 +146,14 @@ get_keys() if [ $encrypt -eq 0 ]; then if [ -n "$ealgo" -o -n "$ekey" -o -n "$ekeyfile" ]; then - wsrep_log_error "Options for encryption are specified, " \ + wsrep_log_error "Options for encryption are specified," \ "but encryption itself is disabled. SST may fail." fi return fi if [ $sfmt = 'tar' ]; then - wsrep_log_info "NOTE: key-based encryption (encrypt=1) " \ + wsrep_log_info "NOTE: key-based encryption (encrypt=1)" \ "cannot be enabled with tar format" encrypt=-1 return @@ -165,16 +166,18 @@ get_keys() exit 3 fi - if [ -z "$ekey" -a ! -r "$ekeyfile" ]; then - wsrep_log_error "FATAL: Either key must be specified " \ - "or keyfile must be readable" - exit 3 + if [ -z "$ekey" ]; then + if [ ! -r "$ekeyfile" ]; then + wsrep_log_error "FATAL: Either key must be specified" \ + "or keyfile must be readable" + exit 3 + fi fi if [ "$eformat" = 'openssl' ]; then get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error "If encryption using the openssl is enabled, " \ + wsrep_log_error "If encryption using the openssl is enabled," \ "then you need to install openssl" exit 2 fi @@ -192,12 +195,12 @@ get_keys() ecmd="$ecmd -k '$ekey'" fi elif [ "$eformat" = 'xbcrypt' ]; then - if [ -z "$(command -v xbcrypt)" ]; then - wsrep_log_error "If encryption using the xbcrypt is enabled, " \ + if [ -z "$(commandex xbcrypt)" ]; then + wsrep_log_error "If encryption using the xbcrypt is enabled," \ "then you need to install xbcrypt" exit 2 fi - wsrep_log_info "NOTE: xbcrypt-based encryption, " \ + wsrep_log_info "NOTE: xbcrypt-based encryption," \ "supported only from Xtrabackup 2.1.4" if [ -z "$ekey" ]; then ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'" @@ -342,40 +345,34 @@ get_transfer() CN_option=",commonname=''" if [ $encrypt -eq 2 ]; then - wsrep_log_info "Using openssl based encryption with socat: with crt and pem" - if [ -z "$tpem" -o -z "$tcert" ]; then + wsrep_log_info \ + "Using openssl based encryption with socat: with crt and pem" + if [ -z "$tpem" -o -z "$tcert$tcap" ]; then wsrep_log_error \ "Both PEM file and CRT file (or path) are required" exit 22 fi - if [ ! -r "$tpem" -o ! -r "$tcert" ]; then - wsrep_log_error \ - "Both PEM file and CRT file (or path) must be readable" - exit 22 + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" + tcmd="$tcmd,cert='$tpem'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',capath='$tcert'" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" fi stagemsg="$stagemsg-OpenSSL-Encrypted-2" - wsrep_log_info "$action with cert=$tpem, ca=$tcert" + wsrep_log_info "$action with cert='$tpem', ca='$tcert', capath='$tcap'" elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then - wsrep_log_info "Using openssl based encryption with socat: with key and crt" + wsrep_log_info \ + "Using openssl based encryption with socat: with key and crt" if [ -z "$tpem" -o -z "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file are required" - exit 22 - fi - if [ ! -r "$tpem" -o ! -r "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file must be readable" + wsrep_log_error "Both the certificate file (or path) and" \ + "the key file are required" exit 22 fi verify_cert_matches_key "$tpem" "$tkey" stagemsg="$stagemsg-OpenSSL-Encrypted-3" - if [ -z "$tcert" ]; then + if [ -z "$tcert$tcap" ]; then if [ $encrypt -eq 4 ]; then wsrep_log_error \ "Peer certificate file (or path) required if encrypt=4" @@ -384,14 +381,11 @@ get_transfer() # no verification CN_option="" tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0" - wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0" + wsrep_log_info \ + "$action with cert='$tpem', key='$tkey', verify=0" else # CA verification - if [ ! -r "$tcert" ]; then - wsrep_log_error "Certificate file or path must be readable" - exit 22 - fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' -o $encrypt -eq 4 ] @@ -402,12 +396,15 @@ get_transfer() else CN_option=",commonname='$WSREP_SST_OPT_HOST_UNESCAPED'" fi - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',key='$tkey',capath='$tcert'" + tcmd="$tcmd,cert='$tpem',key='$tkey'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - wsrep_log_info "$action with cert=$tpem, key=$tkey, ca=$tcert" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" + fi + wsrep_log_info "$action with cert='$tpem', key='$tkey'," \ + "ca='$tcert', capath='$tcap'" fi else wsrep_log_info "Unknown encryption mode: encrypt=$encrypt" @@ -425,7 +422,9 @@ get_transfer() get_footprint() { pushd "$WSREP_SST_OPT_DATA" 1>/dev/null - payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }') + payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' \ + -type f -print0 | du --files0-from=- --block-size=1 -c -s | \ + awk 'END { print $1 }') if [ "$compress" != 'none' ]; then # QuickLZ has around 50% compression ratio # When compression/compaction used, the progress is only an approximate. @@ -438,7 +437,7 @@ get_footprint() adjust_progress() { - if [ -z "$(command -v pv)" ]; then + if [ -z "$(commandex pv)" ]; then wsrep_log_error "pv not found in path: $PATH" wsrep_log_error "Disabling all progress/rate-limiting" pcmd="" @@ -470,33 +469,42 @@ check_server_ssl_config() { # backward-compatible behavior: tcert=$(parse_cnf 'sst' 'tca') + tcap=$(parse_cnf 'sst' 'tcapath') tpem=$(parse_cnf 'sst' 'tcert') tkey=$(parse_cnf 'sst' 'tkey') # reading new ssl configuration options: local tcert2=$(parse_cnf "$encgroups" 'ssl-ca') + local tcap2=$(parse_cnf "$encgroups" 'ssl-capath') local tpem2=$(parse_cnf "$encgroups" 'ssl-cert') local tkey2=$(parse_cnf "$encgroups" 'ssl-key') # if there are no old options, then we take new ones: - if [ -z "$tcert" -a -z "$tpem" -a -z "$tkey" ]; then + if [ -z "$tcert" -a -z "$tcap" -a -z "$tpem" -a -z "$tkey" ]; then tcert="$tcert2" + tcap="$tcap2" tpem="$tpem2" tkey="$tkey2" # checking for presence of the new-style SSL configuration: - elif [ -n "$tcert2" -o -n "$tpem2" -o -n "$tkey2" ]; then + elif [ -n "$tcert2" -o -n "$tcap2" -o -n "$tpem2" -o -n "$tkey2" ]; then if [ "$tcert" != "$tcert2" -o \ + "$tcap" != "$tcap2" -o \ "$tpem" != "$tpem2" -o \ "$tkey" != "$tkey2" ] then - wsrep_log_info "new ssl configuration options (ssl-ca, ssl-cert " \ - "and ssl-key) are ignored by SST due to presence " \ - "of the tca, tcert and/or tkey in the [sst] section" + wsrep_log_info \ + "new ssl configuration options (ssl-ca[path], ssl-cert" \ + "and ssl-key) are ignored by SST due to presence" \ + "of the tca[path], tcert and/or tkey in the [sst] section" fi fi if [ -n "$tcert" ]; then - tcert=$(trim_string "$tcert") - if [ "${tcert%/}" != "$tcert" ]; then - tpath=1 - fi + tcert=$(trim_string "$tcert") + if [ "${tcert%/}" != "$tcert" ] || [ -d "$tcert" ]; then + tcap="$tcert" + tcert="" + fi + fi + if [ -n "$tcap" ]; then + tcap=$(trim_string "$tcap") fi } @@ -506,10 +514,10 @@ read_cnf() tfmt=$(parse_cnf sst transferfmt 'socat') encrypt=$(parse_cnf "$encgroups" 'encrypt' 0) - tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) + tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | \ + tr [:lower:] [:upper:]) - if [ $encrypt -eq 0 -o $encrypt -ge 2 ] - then + if [ $encrypt -eq 0 -o $encrypt -ge 2 ]; then if [ "$tmode" != 'DISABLED' -o $encrypt -ge 2 ]; then check_server_ssl_config fi @@ -517,11 +525,13 @@ read_cnf() if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] then encrypt=3 # enable cert/key SSL encyption - # avoid CA verification if not set explicitly: - # nodes may happen to have different CA if self-generated - # zeroing up tcert does the trick - [ "${tmode#VERIFY}" != "$tmode" ] || tcert="" + # nodes may happen to have different CA if self-generated, + # zeroing up tcert and tcap does the trick: + if [ "${tmode#VERIFY}" = "$tmode" ]; then + tcert="" + tcap="" + fi fi fi elif [ $encrypt -eq 1 ]; then @@ -535,8 +545,9 @@ read_cnf() fi fi - wsrep_log_info "SSL configuration: CA='$tcert', CERT='$tpem'," \ - "KEY='$tkey', MODE='$tmode', encrypt='$encrypt'" + wsrep_log_info "SSL configuration: CA='$tcert', CAPATH='$tcap'," \ + "CERT='$tpem', KEY='$tkey', MODE='$tmode'," \ + "encrypt='$encrypt'" sockopt=$(parse_cnf sst sockopt "") progress=$(parse_cnf sst progress "") @@ -561,7 +572,8 @@ read_cnf() sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir '/tmp/sst_log_archive') if [ $speciald -eq 0 ]; then - wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1" + wsrep_log_error \ + "sst-special-dirs equal to 0 is not supported, falling back to 1" speciald=1 fi @@ -589,7 +601,7 @@ get_stream() { if [ "$sfmt" = 'mbstream' -o "$sfmt" = 'xbstream' ]; then sfmt='mbstream' - STREAM_BIN="$(command -v mbstream)" + local STREAM_BIN=$(commandex "$sfmt") if [ -z "$STREAM_BIN" ]; then wsrep_log_error "Streaming with $sfmt, but $sfmt not found in path" exit 42 @@ -621,7 +633,7 @@ cleanup_at_exit() # Since this is invoked just after exit NNN local estatus=$? if [ $estatus -ne 0 ]; then - wsrep_log_error "Cleanup after exit with status:$estatus" + wsrep_log_error "Cleanup after exit with status: $estatus" fi if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then @@ -630,7 +642,8 @@ cleanup_at_exit() else if [ -n "$BACKUP_PID" ]; then if check_pid "$BACKUP_PID" 1; then - wsrep_log_error "mariabackup process is still running. Killing..." + wsrep_log_error \ + "mariabackup process is still running. Killing..." cleanup_pid $CHECK_PID "$BACKUP_PID" fi fi @@ -638,8 +651,8 @@ cleanup_at_exit() fi if [ -n "$progress" -a -p "$progress" ]; then - wsrep_log_info "Cleaning up fifo file $progress" - rm -f "$progress" || true + wsrep_log_info "Cleaning up fifo file: $progress" + rm -f "$progress" || : fi wsrep_log_info "Cleaning up temporary directories" @@ -649,8 +662,8 @@ cleanup_at_exit() [ -d "$STATDIR" ] && rm -rf "$STATDIR" fi else - [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true - [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true + [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || : + [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || : fi # Final cleanup @@ -662,7 +675,7 @@ cleanup_at_exit() # This means a signal was delivered to the process. # So, more cleanup. if [ $estatus -ge 128 ]; then - kill -KILL -- -$$ || true + kill -KILL -- -$$ || : fi fi @@ -738,7 +751,7 @@ recv_joiner() local ltcmd="$tcmd" if [ $tmt -gt 0 ]; then - if [ -n "$(command -v timeout)" ]; then + if [ -n "$(commandex timeout)" ]; then if timeout --help | grep -qw -- '-k'; then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" else @@ -760,14 +773,14 @@ recv_joiner() popd 1>/dev/null if [ ${RC[0]} -eq 124 ]; then - wsrep_log_error "Possible timeout in receiving first data from " \ + wsrep_log_error "Possible timeout in receiving first data from" \ "donor in gtid stage: exit codes: ${RC[@]}" exit 32 fi for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while getting data from donor node: " \ + wsrep_log_error "Error while getting data from donor node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -776,7 +789,7 @@ recv_joiner() if [ $checkf -eq 1 ]; then if [ ! -r "$MAGIC_FILE" ]; then # this message should cause joiner to abort - wsrep_log_error "receiving process ended without creating " \ + wsrep_log_error "receiving process ended without creating" \ "'$MAGIC_FILE'" wsrep_log_info "Contents of datadir" wsrep_log_info $(ls -l "$dir/"*) @@ -784,10 +797,11 @@ recv_joiner() fi # check donor supplied secret - SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | \ + cut -d ' ' -f 2) if [ "$SECRET" != "$MY_SECRET" ]; then wsrep_log_error "Donor does not know my secret!" - wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'" exit 32 fi @@ -810,7 +824,7 @@ send_donor() for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while sending data to joiner node: " \ + wsrep_log_error "Error while sending data to joiner node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -823,7 +837,9 @@ monitor_process() while true ; do if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1; then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error \ + "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." kill -- -"$WSREP_SST_OPT_PARENT" exit 32 fi @@ -845,7 +861,7 @@ read_cnf setup_ports if "$BACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then - disver='--no-version-check' + disver=' --no-version-check' fi # if no command line argument and INNODB_DATA_HOME_DIR environment variable @@ -867,7 +883,7 @@ INNODB_DATA_HOME_DIR=$(pwd -P) cd "$OLD_PWD" if [ $ssyslog -eq 1 ]; then - if [ -n "$(command -v logger)" ]; then + if [ -n "$(commandex logger)" ]; then wsrep_log_info "Logging all stderr of SST/mariabackup to syslog" exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE) @@ -898,10 +914,8 @@ else fi fi - if [ -e "$INNOAPPLYLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOAPPLYLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOAPPLYLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -912,10 +926,8 @@ else gzip "$newfile" fi - if [ -e "$INNOMOVELOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOMOVELOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOMOVELOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -926,10 +938,8 @@ else gzip "$newfile" fi - if [ -e "$INNOBACKUPLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOBACKUPLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOBACKUPLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -949,15 +959,15 @@ setup_commands() { local mysqld_args="" if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then - mysqld_args="--mysqld-args $WSREP_SST_OPT_MYSQLD" + mysqld_args=" --mysqld-args $WSREP_SST_OPT_MYSQLD" fi - if [ -z "$INNODB_FORCE_RECOVERY" ]; then - INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" - else - INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --innodb-force-recovery=$INNODB_FORCE_RECOVERY --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" + local recovery="" + if [ -n "$INNODB_FORCE_RECOVERY" ]; then + recovery=" --innodb-force-recovery=$INNODB_FORCE_RECOVERY" fi - INNOMOVE="$BACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" - INNOBACKUP="$BACKUP_BIN $WSREP_SST_OPT_CONF --backup $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA' $mysqld_args $INNOBACKUP" + INNOAPPLY="$BACKUP_BIN --prepare$disver$recovery${iapts:+ }$iapts$INNOEXTRA --target-dir='$DATA' --datadir='$DATA'$mysqld_args $INNOAPPLY" + INNOMOVE="$BACKUP_BIN$WSREP_SST_OPT_CONF --move-back$disver${impts:+ }$impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" + INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF --backup$disver${iopts:+ }$iopts $tmpopts$INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA'$mysqld_args $INNOBACKUP" } get_stream @@ -1055,27 +1065,28 @@ then tcmd="$ecmd | $tcmd" fi - iopts="--databases-exclude='lost+found' $iopts" + iopts="--databases-exclude='lost+found'${iopts:+ }$iopts" if [ ${FORCE_FTWRL:-0} -eq 1 ]; then - wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" - iopts="--no-backup-locks $iopts" + wsrep_log_info "Forcing FTWRL due to environment variable" \ + "FORCE_FTWRL equal to $FORCE_FTWRL" + iopts="--no-backup-locks${iopts:+ }$iopts" fi # if compression is enabled for backup files, then add the # appropriate options to the mariabackup command line: if [ "$compress" != 'none' ]; then - iopts="--compress${compress:+=$compress} $iopts" + iopts="--compress${compress:+=$compress}${iopts:+ }$iopts" if [ -n "$compress_threads" ]; then - iopts="--compress-threads=$compress_threads $iopts" + iopts="--compress-threads=$compress_threads${iopts:+ }$iopts" fi if [ -n "$compress_chunk" ]; then - iopts="--compress-chunk-size=$compress_chunk $iopts" + iopts="--compress-chunk-size=$compress_chunk${iopts:+ }$iopts" fi fi if [ -n "$backup_threads" ]; then - iopts="--parallel=$backup_threads $iopts" + iopts="--parallel=$backup_threads${iopts:+ }$iopts" fi setup_commands @@ -1084,7 +1095,7 @@ then set -e if [ ${RC[0]} -ne 0 ]; then - wsrep_log_error "mariabackup finished with error: ${RC[0]}. " \ + wsrep_log_error "mariabackup finished with error: ${RC[0]}." \ "Check syslog or '$INNOBACKUPLOG' for details" exit 22 elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then @@ -1125,7 +1136,8 @@ then elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ] then - [ -e "$SST_PROGRESS_FILE" ] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" + [ -e "$SST_PROGRESS_FILE" ] && \ + wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" [ -n "$SST_PROGRESS_FILE" ] && touch "$SST_PROGRESS_FILE" ib_home_dir="$INNODB_DATA_HOME_DIR" @@ -1146,7 +1158,7 @@ then ib_undo_dir="$INNODB_UNDO_DIR" if [ -n "$backup_threads" ]; then - impts="--parallel=$backup_threads $impts" + impts="--parallel=$backup_threads${impts:+ }$impts" fi stagemsg='Joiner-Recv' @@ -1165,15 +1177,15 @@ then ADDR="$WSREP_SST_OPT_ADDR" - if [ "${tmode#VERIFY}" != "$tmode" ] - then # backward-incompatible behavior + if [ "${tmode#VERIFY}" != "$tmode" ]; then + # backward-incompatible behavior: CN="" - if [ -n "$tpem" ] - then + if [ -n "$tpem" ]; then # find out my Common Name get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error 'openssl not found but it is required for authentication' + wsrep_log_error \ + 'openssl not found but it is required for authentication' exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ @@ -1213,15 +1225,17 @@ then if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1 then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." exit 32 fi - if [ ! -r "$STATDIR/$IST_FILE" ] - then + if [ ! -r "$STATDIR/$IST_FILE" ]; then if [ -d "$DATA/.sst" ]; then - wsrep_log_info "WARNING: Stale temporary SST directory: '$DATA/.sst' from previous state transfer. Removing" + wsrep_log_info \ + "WARNING: Stale temporary SST directory:" \ + "'$DATA/.sst' from previous state transfer, removing..." rm -rf "$DATA/.sst" fi mkdir -p "$DATA/.sst" @@ -1229,17 +1243,20 @@ then jpid=$! wsrep_log_info "Proceeding with SST" - wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories" + wsrep_log_info \ + "Cleaning the existing datadir and innodb-data/log directories" if [ "$OS" = 'FreeBSD' ]; then find -E ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ else find ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ fi get_binlog @@ -1248,9 +1265,9 @@ then binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") cd "$binlog_dir" wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" - rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || : [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ - rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || : cd "$OLD_PWD" fi @@ -1262,7 +1279,8 @@ then monitor_process $jpid if [ ! -s "$DATA/xtrabackup_checkpoints" ]; then - wsrep_log_error "xtrabackup_checkpoints missing, failed mariabackup/SST on donor" + wsrep_log_error "xtrabackup_checkpoints missing," \ + "failed mariabackup/SST on donor" exit 2 fi @@ -1277,7 +1295,7 @@ then if [ -n "$qpfiles" ]; then wsrep_log_info "Compressed qpress files found" - if [ -z "$(command -v qpress)" ]; then + if [ -z "$(commandex qpress)" ]; then wsrep_log_error "qpress utility not found in the path" exit 22 fi @@ -1300,14 +1318,17 @@ then # Decompress the qpress files wsrep_log_info "Decompression with $nproc threads" - timeit "Joiner-Decompression" "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" + timeit "Joiner-Decompression" \ + "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" extcode=$? if [ $extcode -eq 0 ]; then wsrep_log_info "Removing qpress files after decompression" find "$DATA" -type f -name '*.qp' -delete if [ $? -ne 0 ]; then - wsrep_log_error "Something went wrong with deletion of qpress files. Investigate" + wsrep_log_error \ + "Something went wrong with deletion of qpress files." \ + "Investigate" fi else wsrep_log_error "Decompression failed. Exit code: $extcode" @@ -1321,7 +1342,7 @@ then BINLOG_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG") # To avoid comparing data directory and BINLOG_DIRNAME - mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || true + mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || : cd "$BINLOG_DIRNAME" for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do @@ -1336,7 +1357,8 @@ then timeit "mariabackup prepare stage" "$INNOAPPLY" if [ $? -ne 0 ]; then - wsrep_log_error "mariabackup apply finished with errors. Check syslog or '$INNOAPPLYLOG' for details" + wsrep_log_error "mariabackup apply finished with errors." \ + "Check syslog or '$INNOAPPLYLOG' for details." exit 22 fi diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index 798bee1ac10..bed2cac0a9a 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -19,7 +19,6 @@ # This is a reference script for mysqldump-based state snapshot tansfer . $(dirname "$0")/wsrep_sst_common -PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin EINVAL=22 @@ -93,8 +92,7 @@ DROP PREPARE stmt;" SET_START_POSITION="SET GLOBAL wsrep_start_position='$WSREP_SST_OPT_GTID';" SET_WSREP_GTID_DOMAIN_ID="" -if [ -n $WSREP_SST_OPT_GTID_DOMAIN_ID ] -then +if [ -n $WSREP_SST_OPT_GTID_DOMAIN_ID ]; then SET_WSREP_GTID_DOMAIN_ID=" SET @val = (SELECT GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME = 'WSREP_GTID_STRICT_MODE' AND GLOBAL_VALUE > 0); SET @stmt = IF (@val IS NOT NULL, 'SET GLOBAL WSREP_GTID_DOMAIN_ID=$WSREP_SST_OPT_GTID_DOMAIN_ID', 'SET @dummy = 0'); @@ -103,7 +101,7 @@ then DROP PREPARE stmt;" fi -MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF_UNQUOTED "\ +MYSQL="$MYSQL_CLIENT$WSREP_SST_OPT_CONF_UNQUOTED "\ "$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\ "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" @@ -125,8 +123,7 @@ SET_GTID_BINLOG_STATE="" SQL_LOG_BIN_OFF="" # Safety check -if [ ${SERVER_VERSION%%.*} -gt 5 ] -then +if [ ${SERVER_VERSION%%.*} -gt 5 ]; then # If binary logging is enabled on the joiner node, we need to copy donor's # gtid_binlog_state to joiner. In order to do that, a RESET MASTER must be # executed to erase binary logs (if any). Binary logging should also be @@ -140,7 +137,7 @@ then fi # NOTE: we don't use --routines here because we're dumping mysql.proc table -MYSQLDUMP="$MYSQLDUMP $WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \ +MYSQLDUMP="$MYSQLDUMP$WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \ --add-drop-database --add-drop-table --skip-add-locks --create-options \ --disable-keys --extended-insert --skip-lock-tables --quick --set-charset \ --skip-comments --flush-privileges --all-databases --events" diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 29c9cd43470..b0cc8cb3066 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -25,9 +25,6 @@ STUNNEL_REAL_PID=0 # stunnel process id OS="$(uname)" [ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH -# Setting the path for lsof on CentOS -export PATH="/usr/sbin:/sbin:$PATH" - . $(dirname "$0")/wsrep_sst_common wsrep_check_datadir @@ -37,7 +34,8 @@ cleanup_joiner() { local failure=0 - wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID, stunnel PID=$STUNNEL_REAL_PID" + wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID," \ + "stunnel PID=$STUNNEL_REAL_PID" if [ -n "$STUNNEL" ]; then if cleanup_pid $STUNNEL_REAL_PID "$STUNNEL_PID" "$STUNNEL_CONF"; then @@ -87,7 +85,7 @@ check_pid_and_port() if [ $lsof_available -ne 0 ]; then port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \ - grep -F '(LISTEN)') + grep -F '(LISTEN)') echo "$port_info" | \ grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1 else @@ -124,7 +122,7 @@ check_pid_and_port() fi if ! check_port "$pid" "$port" "$utils"; then - wsrep_log_error "rsync or stunnel daemon port '$port' " \ + wsrep_log_error "rsync or stunnel daemon port '$port'" \ "has been taken by another program" exit 16 # EBUSY fi @@ -223,6 +221,7 @@ FILTER="-f '- /lost+found' SSTKEY=$(parse_cnf 'sst' 'tkey') SSTCERT=$(parse_cnf 'sst' 'tcert') SSTCA=$(parse_cnf 'sst' 'tca') +SSTCAP=$(parse_cnf 'sst' 'tcapath') SST_SECTIONS="--mysqld|sst" @@ -231,28 +230,34 @@ check_server_ssl_config() SSTKEY=$(parse_cnf "$SST_SECTIONS" 'ssl-key') SSTCERT=$(parse_cnf "$SST_SECTIONS" 'ssl-cert') SSTCA=$(parse_cnf "$SST_SECTIONS" 'ssl-ca') + SSTCAP=$(parse_cnf "$SST_SECTIONS" 'ssl-capath') } SSLMODE=$(parse_cnf "$SST_SECTIONS" 'ssl-mode' | tr [:lower:] [:upper:]) # no old-style SSL config in [sst], check for new one: -if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]; then +if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" -a -z "$SSTCAP" ]; then check_server_ssl_config fi -SSTPATH=0 if [ -n "$SSTCA" ]; then - SSTCA=$(trim_string "$SSTCA") - if [ "${SSTCA%/}" != "$SSTCA" ]; then - SSTPATH=1 - fi + SSTCA=$(trim_string "$SSTCA") + if [ "${SSTCA%/}" != "$SSTCA" ] || [ -d "$SSTCA" ]; then + SSTCAP="$SSTCA" + SSTCA="" + fi +fi + +if [ -n "$SSTCAP" ]; then + SSTCAP=$(trim_string "$SSTCAP") fi if [ -z "$SSLMODE" ]; then # Implicit verification if CA is set and the SSL mode # is not specified by user: - if [ -n "$SSTCA" ]; then - if [ -n "$(command -v stunnel)" ]; then + if [ -n "$SSTCA$SSTCAP" ]; then + STUNNEL_BIN=$(commandex 'stunnel') + if [ -n "$STUNNEL_BIN" ]; then SSLMODE='VERIFY_CA' fi # Require SSL by default if SSL key and cert are present: @@ -265,17 +270,18 @@ if [ -n "$SSTCERT" -a -n "$SSTKEY" ]; then verify_cert_matches_key "$SSTCERT" "$SSTKEY" fi -if [ -n "$SSTCA" ]; then - if [ $SSTPATH -eq 0 ]; then +CAFILE_OPT="" +CAPATH_OPT="" +if [ -n "$SSTCA$SSTCAP" ]; then + if [ -n "$SSTCA" ]; then CAFILE_OPT="CAfile = $SSTCA" - else - CAFILE_OPT="CApath = $SSTCA" + fi + if [ -n "$SSTCAP" ]; then + CAPATH_OPT="CApath = $SSTCAP" fi if [ -n "$SSTCERT" ]; then - verify_ca_matches_cert "$SSTCA" "$SSTCERT" $SSTPATH + verify_ca_matches_cert "$SSTCERT" "$SSTCA" "$SSTCAP" fi -else - CAFILE_OPT="" fi VERIFY_OPT="" @@ -295,7 +301,7 @@ then exit 22 # EINVAL ;; esac - if [ -z "$SSTCA" ]; then + if [ -z "$SSTCA$SSTCAP" ]; then wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file or path" exit 22 # EINVAL fi @@ -318,9 +324,12 @@ fi STUNNEL="" if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ]; then - STUNNEL_BIN="$(command -v stunnel)" + if [ -z "${STUNNEL_BIN+x}" ]; then + STUNNEL_BIN=$(commandex 'stunnel') + fi if [ -n "$STUNNEL_BIN" ]; then - wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA', ssl-mode='$SSLMODE'" + wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA'," \ + "CAPATH='$SSTCAP', ssl-mode='$SSLMODE'" STUNNEL="$STUNNEL_BIN $STUNNEL_CONF" fi fi @@ -340,6 +349,7 @@ then key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -392,8 +402,8 @@ EOF # Prepare binlog files cd "$BINLOG_DIRNAME" - binlog_files_full=$(tail -n $BINLOG_N_FILES "$WSREP_SST_OPT_BINLOG_INDEX") - + binlog_files_full=$(tail -n $BINLOG_N_FILES \ + "$WSREP_SST_OPT_BINLOG_INDEX") binlog_files="" for ii in $binlog_files_full do @@ -417,9 +427,10 @@ EOF WHOLE_FILE_OPT="--whole-file" fi - # first, the normal directories, so that we can detect incompatible protocol + # first, the normal directories, so that we can detect + # incompatible protocol: RC=0 - eval rsync ${STUNNEL:+"'--rsh=$STUNNEL'"} \ + eval rsync ${STUNNEL:+"--rsh='$STUNNEL'"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ $WHOLE_FILE_OPT $FILTER "'$WSREP_SST_OPT_DATA/'" \ @@ -430,8 +441,9 @@ EOF case $RC in 12) RC=71 # EPROTO wsrep_log_error \ - "rsync server on the other end has incompatible protocol. " \ - "Make sure you have the same version of rsync on all nodes." + "rsync server on the other end has incompatible" \ + "protocol. Make sure you have the same version of" \ + "rsync on all nodes." ;; 22) RC=12 # ENOMEM ;; @@ -481,9 +493,9 @@ EOF find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \ -not -name '.zfs' -print0 | xargs -I{} -0 -P $backup_threads \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \ - --owner --group --perms --links --specials \ - --ignore-times --inplace --recursive --delete --quiet \ - $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \ + --owner --group --perms --links --specials --ignore-times \ + --inplace --recursive --delete --quiet $WHOLE_FILE_OPT \ + --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \ --exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/{}/" \ "rsync://$WSREP_SST_OPT_ADDR/{}" >&2 || RC=$? @@ -514,7 +526,8 @@ EOF fi rsync ${STUNNEL:+--rsh="$STUNNEL"} \ - --archive --quiet --checksum "$MAGIC_FILE" "rsync://$WSREP_SST_OPT_ADDR" + --archive --quiet --checksum "$MAGIC_FILE" \ + "rsync://$WSREP_SST_OPT_ADDR" echo "done $STATE" @@ -546,7 +559,8 @@ then check_round=0 while check_pid "$STUNNEL_PID" 1 do - wsrep_log_info "lingering stunnel daemon found at startup, waiting for it to exit" + wsrep_log_info "Lingering stunnel daemon found at startup," \ + "waiting for it to exit" check_round=$(( check_round + 1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "stunnel daemon already running." @@ -563,7 +577,8 @@ then check_round=0 while check_pid "$RSYNC_PID" 1 do - wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit" + wsrep_log_info "Lingering rsync daemon found at startup," \ + "waiting for it to exit" check_round=$(( check_round + 1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "rsync daemon already running." @@ -575,9 +590,7 @@ then [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" [ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE" - if [ -z "$STUNNEL" ]; then - [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" - fi + [ -z "$STUNNEL" ] && [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" ADDR="$WSREP_SST_OPT_ADDR" RSYNC_PORT="$WSREP_SST_OPT_PORT" @@ -628,19 +641,21 @@ EOF echo $$ > "$SST_PID" - if [ -z "$STUNNEL" ] - then - rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & + if [ -z "$STUNNEL" ]; then + rsync --daemon --no-detach --port "$RSYNC_PORT" \ + --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & RSYNC_REAL_PID=$! TRANSFER_REAL_PID=$RSYNC_REAL_PID TRANSFER_PID="$RSYNC_PID" else # Let's check if the path to the config file contains a space? + RSYNC_BIN=$(commandex 'rsync') if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -650,17 +665,18 @@ ${CHECK_OPT} ${CHECK_OPT_LOCAL} [rsync] accept = $STUNNEL_ACCEPT -exec = $(command -v rsync) +exec = $RSYNC_BIN execargs = rsync --server --daemon --config=$RSYNC_CONF . EOF else # The path contains a space, so we will run it via # shell with "eval" command: - export RSYNC_CMD="eval $(command -v rsync) --server --daemon --config='$RSYNC_CONF' ." + export RSYNC_CMD="eval '$RSYNC_BIN' --server --daemon --config='$RSYNC_CONF' ." cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -688,7 +704,8 @@ EOF # find out my Common Name get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error 'openssl not found but it is required for authentication' + wsrep_log_error \ + 'openssl not found but it is required for authentication' exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \ @@ -703,7 +720,8 @@ EOF ADDR="$WSREP_SST_OPT_HOST" fi - until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT" + until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID \ + "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT" do sleep 0.2 done @@ -722,7 +740,7 @@ EOF if ! ps -p $MYSQLD_PID >/dev/null 2>&1 then wsrep_log_error \ - "Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly." + "Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly." kill -- -$MYSQLD_PID sleep 1 exit 32 @@ -768,10 +786,11 @@ EOF if [ -r "$MAGIC_FILE" ]; then if [ -n "$MY_SECRET" ]; then # check donor supplied secret - SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | \ + cut -d ' ' -f 2) if [ "$SECRET" != "$MY_SECRET" ]; then wsrep_log_error "Donor does not know my secret!" - wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'" exit 32 fi # remove secret from the magic file, and output diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh index 73f15e79a4c..d5c978c4147 100644 --- a/scripts/wsrep_sst_xtrabackup-v2.sh +++ b/scripts/wsrep_sst_xtrabackup-v2.sh @@ -17,13 +17,15 @@ # MA 02110-1335 USA. # Documentation: -# http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html +# https://mariadb.com/kb/en/mariabackup-overview/ +# https://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html # Make sure to read that before proceeding! +OS="$(uname)" + . $(dirname "$0")/wsrep_sst_common wsrep_check_datadir -OS="$(uname)" ealgo="" eformat="" ekey="" @@ -34,7 +36,7 @@ ssyslog="" ssystag="" BACKUP_PID="" tcert="" -tpath=0 +tcap="" tpem="" tkey="" tmode="DISABLED" @@ -88,14 +90,14 @@ readonly SECRET_TAG="secret" sst_ver=-1 -if [ -n "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then +if [ -n "$(commandex pv)" ] && pv --help | grep -qw -- '-F'; then pvopts="$pvopts $pvformat" fi pcmd="pv $pvopts" declare -a RC -BACKUP_BIN="$(command -v innobackupex)" -if [ ! -x "$BACKUP_BIN" ]; then +BACKUP_BIN=$(commandex 'innobackupex') +if [ -z "$BACKUP_BIN" ]; then wsrep_log_error 'innobackupex binary not found in path' exit 42 fi @@ -145,14 +147,14 @@ get_keys() if [ $encrypt -eq 0 ]; then if [ -n "$ealgo" -o -n "$ekey" -o -n "$ekeyfile" ]; then - wsrep_log_error "Options for encryption are specified, " \ + wsrep_log_error "Options for encryption are specified," \ "but encryption itself is disabled. SST may fail." fi return fi if [ $sfmt = 'tar' ]; then - wsrep_log_info "NOTE: key-based encryption (encrypt=1) " \ + wsrep_log_info "NOTE: key-based encryption (encrypt=1)" \ "cannot be enabled with tar format" encrypt=-1 return @@ -165,16 +167,18 @@ get_keys() exit 3 fi - if [ -z "$ekey" -a ! -r "$ekeyfile" ]; then - wsrep_log_error "FATAL: Either key must be specified " \ - "or keyfile must be readable" - exit 3 + if [ -z "$ekey" ]; then + if [ ! -r "$ekeyfile" ]; then + wsrep_log_error "FATAL: Either key must be specified" \ + "or keyfile must be readable" + exit 3 + fi fi if [ "$eformat" = 'openssl' ]; then get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error "If encryption using the openssl is enabled, " \ + wsrep_log_error "If encryption using the openssl is enabled," \ "then you need to install openssl" exit 2 fi @@ -192,19 +196,19 @@ get_keys() ecmd="$ecmd -k '$ekey'" fi elif [ "$eformat" = 'xbcrypt' ]; then - if [ -z "$(command -v xbcrypt)" ]; then - wsrep_log_error "If encryption using the xbcrypt is enabled, " \ + if [ -z "$(commandex xbcrypt)" ]; then + wsrep_log_error "If encryption using the xbcrypt is enabled," \ "then you need to install xbcrypt" exit 2 fi - wsrep_log_info "NOTE: xbcrypt-based encryption, " \ + wsrep_log_info "NOTE: xbcrypt-based encryption," \ "supported only from Xtrabackup 2.1.4" if [ -z "$ekey" ]; then ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'" else - wsrep_log_warning \ - "Using the 'encrypt-key' option causes the encryption key " \ - "to be set via the command-line and is considered insecure. " \ + wsrep_log_info \ + "Using the 'encrypt-key' option causes the encryption key" \ + "to be set via the command-line and is considered insecure." \ "It is recommended to use the 'encrypt-key-file' option instead." ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key='$ekey'" fi @@ -346,40 +350,34 @@ get_transfer() CN_option=",commonname=''" if [ $encrypt -eq 2 ]; then - wsrep_log_info "Using openssl based encryption with socat: with crt and pem" - if [ -z "$tpem" -o -z "$tcert" ]; then + wsrep_log_info \ + "Using openssl based encryption with socat: with crt and pem" + if [ -z "$tpem" -o -z "$tcert$tcap" ]; then wsrep_log_error \ "Both PEM file and CRT file (or path) are required" exit 22 fi - if [ ! -r "$tpem" -o ! -r "$tcert" ]; then - wsrep_log_error \ - "Both PEM file and CRT file (or path) must be readable" - exit 22 + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" + tcmd="$tcmd,cert='$tpem'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',capath='$tcert'" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" fi stagemsg="$stagemsg-OpenSSL-Encrypted-2" - wsrep_log_info "$action with cert=$tpem, ca=$tcert" + wsrep_log_info "$action with cert='$tpem', ca='$tcert', capath='$tcap'" elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then - wsrep_log_info "Using openssl based encryption with socat: with key and crt" + wsrep_log_info \ + "Using openssl based encryption with socat: with key and crt" if [ -z "$tpem" -o -z "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file are required" - exit 22 - fi - if [ ! -r "$tpem" -o ! -r "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file must be readable" + wsrep_log_error "Both the certificate file (or path) and" \ + "the key file are required" exit 22 fi verify_cert_matches_key "$tpem" "$tkey" stagemsg="$stagemsg-OpenSSL-Encrypted-3" - if [ -z "$tcert" ]; then + if [ -z "$tcert$tcap" ]; then if [ $encrypt -eq 4 ]; then wsrep_log_error \ "Peer certificate file (or path) required if encrypt=4" @@ -388,14 +386,11 @@ get_transfer() # no verification CN_option="" tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0" - wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0" + wsrep_log_info \ + "$action with cert='$tpem', key='$tkey', verify=0" else # CA verification - if [ ! -r "$tcert" ]; then - wsrep_log_error "Certificate file or path must be readable" - exit 22 - fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' -o $encrypt -eq 4 ] @@ -406,12 +401,15 @@ get_transfer() else CN_option=",commonname='$WSREP_SST_OPT_HOST_UNESCAPED'" fi - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',key='$tkey',capath='$tcert'" + tcmd="$tcmd,cert='$tpem',key='$tkey'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - wsrep_log_info "$action with cert=$tpem, key=$tkey, ca=$tcert" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" + fi + wsrep_log_info "$action with cert='$tpem', key='$tkey'," \ + "ca='$tcert', capath='$tcap'" fi else wsrep_log_info "Unknown encryption mode: encrypt=$encrypt" @@ -429,7 +427,9 @@ get_transfer() get_footprint() { pushd "$WSREP_SST_OPT_DATA" 1>/dev/null - payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }') + payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' \ + -type f -print0 | du --files0-from=- --block-size=1 -c -s | \ + awk 'END { print $1 }') if [ "$compress" != 'none' ]; then # QuickLZ has around 50% compression ratio # When compression/compaction used, the progress is only an approximate. @@ -442,7 +442,7 @@ get_footprint() adjust_progress() { - if [ -z "$(command -v pv)" ]; then + if [ -z "$(commandex pv)" ]; then wsrep_log_error "pv not found in path: $PATH" wsrep_log_error "Disabling all progress/rate-limiting" pcmd="" @@ -474,33 +474,42 @@ check_server_ssl_config() { # backward-compatible behavior: tcert=$(parse_cnf 'sst' 'tca') + tcap=$(parse_cnf 'sst' 'tcapath') tpem=$(parse_cnf 'sst' 'tcert') tkey=$(parse_cnf 'sst' 'tkey') # reading new ssl configuration options: local tcert2=$(parse_cnf "$encgroups" 'ssl-ca') + local tcap2=$(parse_cnf "$encgroups" 'ssl-capath') local tpem2=$(parse_cnf "$encgroups" 'ssl-cert') local tkey2=$(parse_cnf "$encgroups" 'ssl-key') # if there are no old options, then we take new ones: - if [ -z "$tcert" -a -z "$tpem" -a -z "$tkey" ]; then + if [ -z "$tcert" -a -z "$tcap" -a -z "$tpem" -a -z "$tkey" ]; then tcert="$tcert2" + tcap="$tcap2" tpem="$tpem2" tkey="$tkey2" # checking for presence of the new-style SSL configuration: - elif [ -n "$tcert2" -o -n "$tpem2" -o -n "$tkey2" ]; then + elif [ -n "$tcert2" -o -n "$tcap2" -o -n "$tpem2" -o -n "$tkey2" ]; then if [ "$tcert" != "$tcert2" -o \ + "$tcap" != "$tcap2" -o \ "$tpem" != "$tpem2" -o \ "$tkey" != "$tkey2" ] then - wsrep_log_info "new ssl configuration options (ssl-ca, ssl-cert " \ - "and ssl-key) are ignored by SST due to presence " \ - "of the tca, tcert and/or tkey in the [sst] section" + wsrep_log_info \ + "new ssl configuration options (ssl-ca[path], ssl-cert" \ + "and ssl-key) are ignored by SST due to presence" \ + "of the tca[path], tcert and/or tkey in the [sst] section" fi fi if [ -n "$tcert" ]; then - tcert=$(trim_string "$tcert") - if [ "${tcert%/}" != "$tcert" ]; then - tpath=1 - fi + tcert=$(trim_string "$tcert") + if [ "${tcert%/}" != "$tcert" ] || [ -d "$tcert" ]; then + tcap="$tcert" + tcert="" + fi + fi + if [ -n "$tcap" ]; then + tcap=$(trim_string "$tcap") fi } @@ -510,10 +519,10 @@ read_cnf() tfmt=$(parse_cnf sst transferfmt 'socat') encrypt=$(parse_cnf "$encgroups" 'encrypt' 0) - tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) + tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | \ + tr [:lower:] [:upper:]) - if [ $encrypt -eq 0 -o $encrypt -ge 2 ] - then + if [ $encrypt -eq 0 -o $encrypt -ge 2 ]; then if [ "$tmode" != 'DISABLED' -o $encrypt -ge 2 ]; then check_server_ssl_config fi @@ -521,11 +530,13 @@ read_cnf() if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] then encrypt=3 # enable cert/key SSL encyption - # avoid CA verification if not set explicitly: - # nodes may happen to have different CA if self-generated - # zeroing up tcert does the trick - [ "${tmode#VERIFY}" != "$tmode" ] || tcert="" + # nodes may happen to have different CA if self-generated, + # zeroing up tcert and tcap does the trick: + if [ "${tmode#VERIFY}" = "$tmode" ]; then + tcert="" + tcap="" + fi fi fi elif [ $encrypt -eq 1 ]; then @@ -539,8 +550,9 @@ read_cnf() fi fi - wsrep_log_info "SSL configuration: CA='$tcert', CERT='$tpem'," \ - "KEY='$tkey', MODE='$tmode', encrypt='$encrypt'" + wsrep_log_info "SSL configuration: CA='$tcert', CAPATH='$tcap'," \ + "CERT='$tpem', KEY='$tkey', MODE='$tmode'," \ + "encrypt='$encrypt'" sockopt=$(parse_cnf sst sockopt "") progress=$(parse_cnf sst progress "") @@ -566,7 +578,8 @@ read_cnf() sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir '/tmp/sst_log_archive') if [ $speciald -eq 0 ]; then - wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1" + wsrep_log_error \ + "sst-special-dirs equal to 0 is not supported, falling back to 1" speciald=1 fi @@ -593,12 +606,12 @@ read_cnf() get_stream() { if [ "$sfmt" = 'mbstream' -o "$sfmt" = 'xbstream' ]; then - STREAM_BIN=$(command -v "$sfmt") + local STREAM_BIN=$(commandex "$sfmt") if [ -z "$STREAM_BIN" ]; then if [ "$sfmt" = 'xbstream' ]; then - STREAM_BIN="$(command -v mbstream)" + STREAM_BIN=$(commandex 'mbstream') else - STREAM_BIN="$(command -v xbstream)" + STREAM_BIN=$(commandex 'xbstream') fi fi if [ -z "$STREAM_BIN" ]; then @@ -632,7 +645,7 @@ cleanup_at_exit() # Since this is invoked just after exit NNN local estatus=$? if [ $estatus -ne 0 ]; then - wsrep_log_error "Cleanup after exit with status:$estatus" + wsrep_log_error "Cleanup after exit with status: $estatus" fi if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then @@ -641,7 +654,8 @@ cleanup_at_exit() else if [ -n "$BACKUP_PID" ]; then if check_pid "$BACKUP_PID" 1; then - wsrep_log_error "xtrabackup process is still running. Killing..." + wsrep_log_error \ + "innobackupex process is still running. Killing..." cleanup_pid $CHECK_PID "$BACKUP_PID" fi fi @@ -649,8 +663,8 @@ cleanup_at_exit() fi if [ -n "$progress" -a -p "$progress" ]; then - wsrep_log_info "Cleaning up fifo file $progress" - rm -f "$progress" || true + wsrep_log_info "Cleaning up fifo file: $progress" + rm -f "$progress" || : fi wsrep_log_info "Cleaning up temporary directories" @@ -660,8 +674,8 @@ cleanup_at_exit() [ -d "$STATDIR" ] && rm -rf "$STATDIR" fi else - [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true - [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true + [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || : + [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || : fi # Final cleanup @@ -673,7 +687,7 @@ cleanup_at_exit() # This means a signal was delivered to the process. # So, more cleanup. if [ $estatus -ge 128 ]; then - kill -KILL -- -$$ || true + kill -KILL -- -$$ || : fi fi @@ -749,7 +763,7 @@ recv_joiner() local ltcmd="$tcmd" if [ $tmt -gt 0 ]; then - if [ -n "$(command -v timeout)" ]; then + if [ -n "$(commandex timeout)" ]; then if timeout --help | grep -qw -- '-k'; then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" else @@ -771,14 +785,14 @@ recv_joiner() popd 1>/dev/null if [ ${RC[0]} -eq 124 ]; then - wsrep_log_error "Possible timeout in receiving first data from " \ + wsrep_log_error "Possible timeout in receiving first data from" \ "donor in gtid stage: exit codes: ${RC[@]}" exit 32 fi for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while getting data from donor node: " \ + wsrep_log_error "Error while getting data from donor node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -787,7 +801,7 @@ recv_joiner() if [ $checkf -eq 1 ]; then if [ ! -r "$MAGIC_FILE" ]; then # this message should cause joiner to abort - wsrep_log_error "receiving process ended without creating " \ + wsrep_log_error "receiving process ended without creating" \ "'$MAGIC_FILE'" wsrep_log_info "Contents of datadir" wsrep_log_info $(ls -l "$dir/"*) @@ -795,10 +809,11 @@ recv_joiner() fi # check donor supplied secret - SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | \ + cut -d ' ' -f 2) if [ "$SECRET" != "$MY_SECRET" ]; then wsrep_log_error "Donor does not know my secret!" - wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'" exit 32 fi @@ -821,7 +836,7 @@ send_donor() for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while sending data to joiner node: " \ + wsrep_log_error "Error while sending data to joiner node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -834,7 +849,9 @@ monitor_process() while true ; do if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1; then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error \ + "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." kill -- -"$WSREP_SST_OPT_PARENT" exit 32 fi @@ -850,13 +867,17 @@ monitor_process() XB_REQUIRED_VERSION="2.3.5" XB_VERSION=`$BACKUP_BIN --version 2>&1 | grep -oe '[0-9]\.[0-9][\.0-9]*' | head -n1` -if [[ -z "$XB_VERSION" ]]; then - wsrep_log_error "FATAL: Cannot determine the $BACKUP_BIN version. Needs xtrabackup-$XB_REQUIRED_VERSION or higher to perform SST" +if [ -z "$XB_VERSION" ]; then + wsrep_log_error "FATAL: Cannot determine the $BACKUP_BIN version." \ + "Needs xtrabackup-$XB_REQUIRED_VERSION or higher to" \ + "perform SST" exit 2 fi if ! check_for_version "$XB_VERSION" "$XB_REQUIRED_VERSION"; then - wsrep_log_error "FATAL: The $BACKUP_BIN version is $XB_VERSION. Needs xtrabackup-$XB_REQUIRED_VERSION or higher to perform SST" + wsrep_log_error "FATAL: The $BACKUP_BIN version is $XB_VERSION." \ + "Needs xtrabackup-$XB_REQUIRED_VERSION or higher to" \ + "perform SST" exit 2 fi @@ -871,7 +892,7 @@ read_cnf setup_ports if "$BACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then - disver='--no-version-check' + disver=' --no-version-check' fi # if no command line argument and INNODB_DATA_HOME_DIR environment variable @@ -893,19 +914,19 @@ INNODB_DATA_HOME_DIR=$(pwd -P) cd "$OLD_PWD" if [ $ssyslog -eq 1 ]; then - if [ -n "$(command -v logger)" ]; then + if [ -n "$(commandex logger)" ]; then wsrep_log_info "Logging all stderr of SST/xtrabackup to syslog" exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE) wsrep_log_error() { - logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" + logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } wsrep_log_info() { - logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" + logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } else wsrep_log_error "logger not in path: $PATH. Ignoring" @@ -924,10 +945,8 @@ else fi fi - if [ -e "$INNOAPPLYLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOAPPLYLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOAPPLYLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -938,10 +957,8 @@ else gzip "$newfile" fi - if [ -e "$INNOMOVELOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOMOVELOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOMOVELOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -952,10 +969,8 @@ else gzip "$newfile" fi - if [ -e "$INNOBACKUPLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOBACKUPLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOBACKUPLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -973,17 +988,17 @@ fi setup_commands() { - if [ -z "$INNODB_FORCE_RECOVERY" ]; then - INNOAPPLY="$BACKUP_BIN $disver $iapts $INNOEXTRA --apply-log $rebuildcmd '$DATA' $INNOAPPLY" - else - INNOAPPLY="$BACKUP_BIN $disver $iapts $INNOEXTRA --innodb-force-recovery=$INNODB_FORCE_RECOVERY --apply-log $rebuildcmd '$DATA' $INNOAPPLY" + local recovery="" + if [ -n "$INNODB_FORCE_RECOVERY" ]; then + recovery=" --innodb-force-recovery=$INNODB_FORCE_RECOVERY" fi - INNOMOVE="$BACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories '$DATA' $INNOMOVE" - sfmt_work="$sfmt" + INNOAPPLY="$BACKUP_BIN$disver$recovery${iapts:+ }$iapts$INNOEXTRA --apply-log $rebuildcmd '$DATA' $INNOAPPLY" + INNOMOVE="$BACKUP_BIN$WSREP_SST_OPT_CONF --move-back$disver${impts:+ }$impts --force-non-empty-directories '$DATA' $INNOMOVE" + local sfmt_work="$sfmt" if [ "$sfmt" = 'mbstream' ]; then sfmt_work='xbstream' fi - INNOBACKUP="$BACKUP_BIN $WSREP_SST_OPT_CONF $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream=$sfmt_work '$itmpdir' $INNOBACKUP" + INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF$disver${iopts:+ }$iopts $tmpopts$INNOEXTRA --galera-info --stream=$sfmt_work '$itmpdir' $INNOBACKUP" } get_stream @@ -1081,27 +1096,28 @@ then tcmd="$ecmd | $tcmd" fi - iopts="--databases-exclude='lost+found' $iopts" + iopts="--databases-exclude='lost+found'${iopts:+ }$iopts" if [ ${FORCE_FTWRL:-0} -eq 1 ]; then - wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" - iopts="--no-backup-locks $iopts" + wsrep_log_info "Forcing FTWRL due to environment variable" \ + "FORCE_FTWRL equal to $FORCE_FTWRL" + iopts="--no-backup-locks${iopts:+ }$iopts" fi # if compression is enabled for backup files, then add the # appropriate options to the innobackupex command line: if [ "$compress" != 'none' ]; then - iopts="--compress${compress:+=$compress} $iopts" + iopts="--compress${compress:+=$compress}${iopts:+ }$iopts" if [ -n "$compress_threads" ]; then - iopts="--compress-threads=$compress_threads $iopts" + iopts="--compress-threads=$compress_threads${iopts:+ }$iopts" fi if [ -n "$compress_chunk" ]; then - iopts="--compress-chunk-size=$compress_chunk $iopts" + iopts="--compress-chunk-size=$compress_chunk${iopts:+ }$iopts" fi fi if [ -n "$backup_threads" ]; then - iopts="--parallel=$backup_threads $iopts" + iopts="--parallel=$backup_threads${iopts:+ }$iopts" fi setup_commands @@ -1110,7 +1126,7 @@ then set -e if [ ${RC[0]} -ne 0 ]; then - wsrep_log_error "innobackupex finished with error: ${RC[0]}. " \ + wsrep_log_error "innobackupex finished with error: ${RC[0]}." \ "Check syslog or '$INNOBACKUPLOG' for details" exit 22 elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then @@ -1151,7 +1167,8 @@ then elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ] then - [ -e "$SST_PROGRESS_FILE" ] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" + [ -e "$SST_PROGRESS_FILE" ] && \ + wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" [ -n "$SST_PROGRESS_FILE" ] && touch "$SST_PROGRESS_FILE" ib_home_dir="$INNODB_DATA_HOME_DIR" @@ -1172,7 +1189,7 @@ then ib_undo_dir="$INNODB_UNDO_DIR" if [ -n "$backup_threads" ]; then - impts="--parallel=$backup_threads $impts" + impts="--parallel=$backup_threads${impts:+ }$impts" fi stagemsg='Joiner-Recv' @@ -1191,15 +1208,15 @@ then ADDR="$WSREP_SST_OPT_ADDR" - if [ "${tmode#VERIFY}" != "$tmode" ] - then # backward-incompatible behavior + if [ "${tmode#VERIFY}" != "$tmode" ]; then + # backward-incompatible behavior: CN="" - if [ -n "$tpem" ] - then + if [ -n "$tpem" ]; then # find out my Common Name get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error 'openssl not found but it is required for authentication' + wsrep_log_error \ + 'openssl not found but it is required for authentication' exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ @@ -1239,15 +1256,17 @@ then if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1 then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." exit 32 fi - if [ ! -r "$STATDIR/$IST_FILE" ] - then + if [ ! -r "$STATDIR/$IST_FILE" ]; then if [ -d "$DATA/.sst" ]; then - wsrep_log_info "WARNING: Stale temporary SST directory: '$DATA/.sst' from previous state transfer. Removing" + wsrep_log_info \ + "WARNING: Stale temporary SST directory:" \ + "'$DATA/.sst' from previous state transfer, removing..." rm -rf "$DATA/.sst" fi mkdir -p "$DATA/.sst" @@ -1255,17 +1274,20 @@ then jpid=$! wsrep_log_info "Proceeding with SST" - wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories" + wsrep_log_info \ + "Cleaning the existing datadir and innodb-data/log directories" if [ "$OS" = 'FreeBSD' ]; then find -E ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ else find ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ fi get_binlog @@ -1274,9 +1296,9 @@ then binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") cd "$binlog_dir" wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" - rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || : [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ - rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || : cd "$OLD_PWD" fi @@ -1288,7 +1310,8 @@ then monitor_process $jpid if [ ! -s "$DATA/xtrabackup_checkpoints" ]; then - wsrep_log_error "xtrabackup_checkpoints missing, failed xtrabackup/SST on donor" + wsrep_log_error "xtrabackup_checkpoints missing," \ + "failed xtrabackup/SST on donor" exit 2 fi @@ -1305,7 +1328,7 @@ then if [ -n "$qpfiles" ]; then wsrep_log_info "Compressed qpress files found" - if [ -z "$(command -v qpress)" ]; then + if [ -z "$(commandex qpress)" ]; then wsrep_log_error "qpress utility not found in the path" exit 22 fi @@ -1328,14 +1351,17 @@ then # Decompress the qpress files wsrep_log_info "Decompression with $nproc threads" - timeit "Joiner-Decompression" "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" + timeit "Joiner-Decompression" \ + "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" extcode=$? if [ $extcode -eq 0 ]; then wsrep_log_info "Removing qpress files after decompression" find "$DATA" -type f -name '*.qp' -delete if [ $? -ne 0 ]; then - wsrep_log_error "Something went wrong with deletion of qpress files. Investigate" + wsrep_log_error \ + "Something went wrong with deletion of qpress files." \ + "Investigate" fi else wsrep_log_error "Decompression failed. Exit code: $extcode" @@ -1349,7 +1375,7 @@ then BINLOG_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG") # To avoid comparing data directory and BINLOG_DIRNAME - mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || true + mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || : cd "$BINLOG_DIRNAME" for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do @@ -1364,12 +1390,11 @@ then timeit "Xtrabackup prepare stage" "$INNOAPPLY" if [ $? -ne 0 ]; then - wsrep_log_error "xtrabackup apply finished with errors. Check '$INNOAPPLYLOG' for details" + wsrep_log_error "xtrabackup apply finished with errors." \ + "Check syslog or '$INNOAPPLYLOG' for details." exit 22 fi - # [ -f "$INNOAPPLYLOG" ] && rm "$INNOAPPLYLOG" - MAGIC_FILE="$TDATA/$INFO_FILE" wsrep_log_info "Moving the backup to $TDATA" diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh index b84aca4866e..de7b771bd2d 100644 --- a/scripts/wsrep_sst_xtrabackup.sh +++ b/scripts/wsrep_sst_xtrabackup.sh @@ -17,7 +17,7 @@ # MA 02110-1335 USA. # Optional dependencies and options documented here: -# http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html +# https://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html # Make sure to read that before proceeding! . $(dirname "$0")/wsrep_sst_common @@ -64,9 +64,6 @@ INFO_FILE="xtrabackup_galera_info" IST_FILE="xtrabackup_ist" MAGIC_FILE="${DATA}/${INFO_FILE}" -# Setting the path for ss and ip -export PATH="/usr/sbin:/sbin:$PATH" - timeit(){ local stage="$1" shift diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 8ab7565a666..08f0905e044 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -178,6 +178,12 @@ new_VioSSLFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; long ssl_ctx_options= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; DBUG_ENTER("new_VioSSLFd"); + + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + DBUG_PRINT("enter", ("key_file: '%s' cert_file: '%s' ca_file: '%s' ca_path: '%s' " "cipher: '%s' crl_file: '%s' crl_path: '%s' ", @@ -308,6 +314,11 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + /* Turn off verification of servers certificate if both ca_file and ca_path is set to NULL @@ -339,6 +350,12 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; + + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher, FALSE, error, crl_file, crl_path))) From 7bc629a5ce9e1edf2c27ddfba2a55c4341d55b4f Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Mon, 13 Dec 2021 02:15:57 +0100 Subject: [PATCH 15/52] MDEV-27181: Galera SST scripts should use ssl_capath for CA directory 1. Galera SST scripts should use ssl_capath (not ssl_ca) for CA directory. The current implementation tries to automatically detect the path using the trailing slash in the ssl_ca variable value, but this approach is not compatible with the server configuration. Now, by analogy with the server, SST scripts also use a separate ssl_capath variable. In addition, a similar tcapath variable has been added for the old-style configuration (in the "sst" section). 2. Openssl utility detection made more reliable. 3. Removed extra spaces in automatically generated command lines - to simplify debugging of the SST scripts. 4. In general, the code for detecting the presence or absence of auxiliary utilities has been improved - it is made more reliable in some configurations (and for shells other than bash). --- mysql-test/std_data/capath/3106f582.0 | 1 + mysql-test/std_data/capath/cacert.pem | 79 ++++ mysql-test/std_data/capath/ed1f42db.0 | 1 + mysql-test/suite/galera/disabled.def | 1 - ...alera_sst_rsync_encrypt_with_capath.result | 398 ++++++++++++++++++ .../galera_sst_rsync_encrypt_with_key.result | 2 - ...alera_sst_rsync_encrypt_with_server.result | 2 - .../galera_sst_mariabackup_table_options.test | 1 + .../galera_sst_rsync_encrypt_with_capath.cnf | 20 + .../galera_sst_rsync_encrypt_with_capath.test | 26 ++ .../t/galera_sst_rsync_encrypt_with_key.test | 3 - .../galera_sst_rsync_encrypt_with_server.test | 3 - .../t/galera_ipv6_mariabackup.test | 1 + .../t/galera_ipv6_mariabackup_section.test | 1 + scripts/wsrep_sst_common.sh | 142 ++++--- scripts/wsrep_sst_mariabackup.sh | 292 +++++++------ scripts/wsrep_sst_mysqldump.sh | 11 +- scripts/wsrep_sst_rsync.sh | 117 ++--- vio/viosslfactories.c | 17 + 19 files changed, 859 insertions(+), 259 deletions(-) create mode 120000 mysql-test/std_data/capath/3106f582.0 create mode 100644 mysql-test/std_data/capath/cacert.pem create mode 120000 mysql-test/std_data/capath/ed1f42db.0 create mode 100644 mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test diff --git a/mysql-test/std_data/capath/3106f582.0 b/mysql-test/std_data/capath/3106f582.0 new file mode 120000 index 00000000000..1310cfcff20 --- /dev/null +++ b/mysql-test/std_data/capath/3106f582.0 @@ -0,0 +1 @@ +cacert.pem \ No newline at end of file diff --git a/mysql-test/std_data/capath/cacert.pem b/mysql-test/std_data/capath/cacert.pem new file mode 100644 index 00000000000..23dda2318e1 --- /dev/null +++ b/mysql-test/std_data/capath/cacert.pem @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + d0:4d:23:85:ee:59:b3:fa + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Validity + Not Before: Jan 27 10:11:10 2019 GMT + Not After : Jan 22 10:11:10 2039 GMT + Subject: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e8:0e:a7:84:d3:75:30:06:30:b2:10:b9:d1:88: + 36:2b:5e:f8:c8:44:57:cb:67:72:ab:96:95:33:d5: + 88:d1:8f:23:50:98:ba:6d:20:00:80:bd:35:d5:c1: + bf:98:49:c4:0a:15:4a:34:a6:21:9b:2e:8c:15:09: + f0:63:81:02:c2:7c:e2:53:e0:f7:a1:1a:40:5e:8f: + 41:4a:4c:56:d4:20:f1:d5:a7:c1:53:2e:ff:7e:37: + 17:cc:7e:74:bd:e2:22:33:ce:8c:77:62:a4:c5:3f: + 44:35:7b:7e:b9:f5:7d:8c:7a:27:58:fd:2c:42:86: + 2e:e7:6b:01:99:7b:fe:7d:a7:a1:4f:3e:39:39:54: + 1f:61:de:74:66:d1:77:4f:43:1b:66:70:29:85:de: + fc:8f:8e:1b:7b:a2:66:48:26:7f:9b:a6:fd:4a:e4: + dc:eb:ed:bd:f8:e3:f1:57:98:13:6f:f1:a3:2a:e3: + 73:bd:8d:7c:6f:4b:59:35:bc:b5:42:3e:99:a7:13: + 8d:be:2e:5c:9a:c6:5b:ab:ae:bf:00:e9:c8:ee:05: + 22:8e:d5:67:1a:47:9a:6d:9c:f9:42:3e:15:34:f8: + 31:ec:b4:7e:d3:92:95:b0:b8:f9:66:f3:bd:1d:31: + 2c:b1:90:62:a1:f8:4e:a6:5d:26:22:f0:e1:fe:16: + 2b:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + X509v3 Authority Key Identifier: + keyid:CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + df:fd:74:29:5b:5e:9a:8b:09:02:40:59:73:cb:71:47:3f:97: + 3d:a9:fd:c4:8c:01:29:c9:86:b8:71:55:ff:72:0e:50:dc:c8: + b5:e6:91:41:52:47:21:30:cc:4d:e7:3b:4b:db:55:ea:7d:46: + eb:53:e0:b7:1b:80:7c:b1:0c:d3:d1:bc:a0:73:ae:96:1f:fd: + 05:52:7e:54:d5:03:52:69:7b:34:5f:27:d7:98:da:98:76:73: + e6:bb:50:59:2a:94:90:67:03:1c:a4:76:2f:ee:ef:59:60:09: + 48:33:03:2b:52:ed:83:42:f8:71:19:7f:d8:be:40:ed:20:01: + 90:3c:7e:1c:8b:d2:9f:f3:2f:09:1f:50:c8:10:e1:8a:d9:a5: + 49:9c:0b:74:17:b9:2b:68:f6:1e:73:c2:73:10:38:b3:35:e2: + 87:91:1b:a1:d1:9b:81:9d:1b:32:cc:03:6e:4c:82:95:81:11: + 42:56:e2:16:2b:22:65:db:40:2c:ca:dc:03:f4:d5:07:cf:f5: + 13:b2:cf:51:5b:24:cd:c7:d1:9b:42:8e:f9:df:5d:1e:5a:09: + a3:4f:a9:0b:f4:21:c5:bb:ff:02:93:67:e8:2d:ee:ab:d9:59: + 76:03:2c:a1:bd:fb:dc:af:b6:82:94:71:85:53:a8:18:0d:3a: + 9e:42:eb:59 +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIJANBNI4XuWbP6MA0GCSqGSIb3DQEBCwUAMFYxDzANBgNV +BAMMBmNhY2VydDELMAkGA1UEBhMCRkkxETAPBgNVBAgMCEhlbHNpbmtpMREwDwYD +VQQHDAhIZWxzaW5raTEQMA4GA1UECgwHTWFyaWFEQjAeFw0xOTAxMjcxMDExMTBa +Fw0zOTAxMjIxMDExMTBaMFYxDzANBgNVBAMMBmNhY2VydDELMAkGA1UEBhMCRkkx +ETAPBgNVBAgMCEhlbHNpbmtpMREwDwYDVQQHDAhIZWxzaW5raTEQMA4GA1UECgwH +TWFyaWFEQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOgOp4TTdTAG +MLIQudGINite+MhEV8tncquWlTPViNGPI1CYum0gAIC9NdXBv5hJxAoVSjSmIZsu +jBUJ8GOBAsJ84lPg96EaQF6PQUpMVtQg8dWnwVMu/343F8x+dL3iIjPOjHdipMU/ +RDV7frn1fYx6J1j9LEKGLudrAZl7/n2noU8+OTlUH2HedGbRd09DG2ZwKYXe/I+O +G3uiZkgmf5um/Urk3Ovtvfjj8VeYE2/xoyrjc72NfG9LWTW8tUI+macTjb4uXJrG +W6uuvwDpyO4FIo7VZxpHmm2c+UI+FTT4Mey0ftOSlbC4+WbzvR0xLLGQYqH4TqZd +JiLw4f4WK2kCAwEAAaNQME4wHQYDVR0OBBYEFMpxmYnwcqt1ZrtlagMEcqV7laaT +MB8GA1UdIwQYMBaAFMpxmYnwcqt1ZrtlagMEcqV7laaTMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBAN/9dClbXpqLCQJAWXPLcUc/lz2p/cSMASnJhrhx +Vf9yDlDcyLXmkUFSRyEwzE3nO0vbVep9RutT4LcbgHyxDNPRvKBzrpYf/QVSflTV +A1JpezRfJ9eY2ph2c+a7UFkqlJBnAxykdi/u71lgCUgzAytS7YNC+HEZf9i+QO0g +AZA8fhyL0p/zLwkfUMgQ4YrZpUmcC3QXuSto9h5zwnMQOLM14oeRG6HRm4GdGzLM +A25MgpWBEUJW4hYrImXbQCzK3AP01QfP9ROyz1FbJM3H0ZtCjvnfXR5aCaNPqQv0 +IcW7/wKTZ+gt7qvZWXYDLKG9+9yvtoKUcYVTqBgNOp5C61k= +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/capath/ed1f42db.0 b/mysql-test/std_data/capath/ed1f42db.0 new file mode 120000 index 00000000000..1310cfcff20 --- /dev/null +++ b/mysql-test/std_data/capath/ed1f42db.0 @@ -0,0 +1 @@ +cacert.pem \ No newline at end of file diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d92f3f7d6b8..955a2c82ebc 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -29,5 +29,4 @@ versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest galera_wsrep_provider_unset_set: wsrep_provider is read-only for security reasons pxc-421: wsrep_provider is read-only for security reasons galera_sst_xtrabackup-v2: Test fails due to innodb issues -galera_sst_xtrabackup-v2_encrypt_with_key: Test fails due to innodb issues galera_sst_xtrabackup-v2_data_dir: Test fails due to innodb issues diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result new file mode 100644 index 00000000000..170ba62dd12 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result @@ -0,0 +1,398 @@ +connection node_1; +connection node_2; +connection node_1; +Performing State Transfer on a server that has been shut down cleanly and restarted +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_shutdown_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that starts from a clean var directory +This is accomplished by shutting down node #2 and removing its var directory before restarting it +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +Cleaning var directory ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_clean_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_clean_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +while a DDL was in progress on it +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +connection node_2; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; +connection node_1; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +connection node_2; +SET wsrep_sync_wait = 0; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +connection node_2; +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave_ddl; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +SET GLOBAL debug_dbug = $debug_orig; +include/assert_grep.inc [Using stunnel for SSL encryption] diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result index 251c087412b..170ba62dd12 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result @@ -1,7 +1,5 @@ connection node_1; connection node_2; -connection node_2; -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); connection node_1; Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result index 251c087412b..170ba62dd12 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result @@ -1,7 +1,5 @@ connection node_1; connection node_2; -connection node_2; -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); connection node_1; Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test b/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test index 953a1635559..7a3a6c825c4 100644 --- a/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test @@ -66,6 +66,7 @@ COMMIT; --source include/wait_condition.inc --echo Cleaning var directory ... +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mtr --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/performance_schema --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/test diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf new file mode 100644 index 00000000000..3ab762df013 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf @@ -0,0 +1,20 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=rsync +ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem +ssl-key=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem +ssl-capath=@ENV.MYSQL_TEST_DIR/std_data/capath +# We need to turn off the default setting for the duration +# of the test (to test working with a directory instead of +# a file): +ssl-ca= + +[sst] +ssl-mode=VERIFY_CA + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test new file mode 100644 index 00000000000..a2d92723ec4 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test @@ -0,0 +1,26 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_debug.inc +--source include/have_stunnel.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--connection node_1 +--source suite/galera/include/galera_st_shutdown_slave.inc +--source suite/galera/include/galera_st_clean_slave.inc + +--source suite/galera/include/galera_st_kill_slave.inc +--source suite/galera/include/galera_st_kill_slave_ddl.inc + +# Confirm that transfer was SSL-encrypted +--let $assert_text = Using stunnel for SSL encryption +--let $assert_select = Using stunnel for SSL encryption +--let $assert_count = 5 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = CURRENT_TEST +--source include/assert_grep.inc + +--source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test index 838c473b9ce..a2d92723ec4 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test @@ -8,9 +8,6 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.inc ---connection node_2 -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); - --connection node_1 --source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_clean_slave.inc diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test index 838c473b9ce..a2d92723ec4 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test @@ -8,9 +8,6 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.inc ---connection node_2 -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); - --connection node_1 --source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_clean_slave.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test index dc3331d1be3..2bb2bb284e9 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/check_ipv6.inc --source include/have_innodb.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test index c88ff99790c..86607e61542 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/check_ipv6.inc --source include/have_innodb.inc diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index dbd639595df..5c84aa7c17f 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -19,6 +19,9 @@ set -u +# Setting the path for some utilities on CentOS +export PATH="$PATH:/usr/sbin:/usr/bin:/sbin:/bin" + WSREP_SST_OPT_BYPASS=0 WSREP_SST_OPT_BINLOG="" WSREP_SST_OPT_BINLOG_INDEX="" @@ -384,10 +387,8 @@ case "$1" in skip_mysqld_arg=1 ;; '--innodb-force-recovery') - if [ -n "$value" ]; then - if [ "$value" -ne 0 ]; then - INNODB_FORCE_RECOVERY="$value" - fi + if [ -n "$value" -a "$value" != "0" ]; then + INNODB_FORCE_RECOVERY="$value" fi skip_mysqld_arg=1 ;; @@ -584,7 +585,8 @@ get_binlog() if [ -n "$WSREP_SST_OPT_ADDR_PORT" ]; then if [ -n "$WSREP_SST_OPT_PORT" ]; then if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then - echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 + echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT" \ + "differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 exit 2 fi else @@ -616,8 +618,19 @@ fi readonly WSREP_SST_OPT_ADDR readonly WSREP_SST_OPT_ADDR_PORT -# try to use my_print_defaults, mysql and mysqldump that come with the sources -# (for MTR suite) +commandex() +{ + if [ -n "$BASH_VERSION" ]; then + command -v "$1" || : + elif [ -x "$1" ]; then + echo "$1" + else + which "$1" || : + fi +} + +# try to use my_print_defaults, mysql and mysqldump that come +# with the sources (for MTR suite): script_binary=$(dirname "$0") SCRIPTS_DIR=$(cd "$script_binary"; pwd -P) EXTRA_DIR="$SCRIPTS_DIR/../extra" @@ -626,13 +639,13 @@ CLIENT_DIR="$SCRIPTS_DIR/../client" if [ -x "$CLIENT_DIR/mysql" ]; then MYSQL_CLIENT="$CLIENT_DIR/mysql" else - MYSQL_CLIENT="$(command -v mysql)" + MYSQL_CLIENT=$(commandex 'mysql') fi if [ -x "$CLIENT_DIR/mysqldump" ]; then MYSQLDUMP="$CLIENT_DIR/mysqldump" else - MYSQLDUMP="$(command -v mysqldump)" + MYSQLDUMP=$(commandex 'mysqldump') fi wsrep_log() @@ -663,7 +676,7 @@ if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults" else - MY_PRINT_DEFAULTS="$(command -v my_print_defaults)" + MY_PRINT_DEFAULTS=$(commandex 'my_print_defaults') if [ -z "$MY_PRINT_DEFAULTS" ]; then wsrep_log_error "my_print_defaults not found in path" exit 2 @@ -673,16 +686,16 @@ fi readonly MY_PRINT_DEFAULTS wsrep_defaults="$WSREP_SST_OPT_DEFAULTS" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULTS:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" -readonly WSREP_SST_OPT_CONF="$wsrep_defaults" +readonly WSREP_SST_OPT_CONF="${wsrep_defaults:+ }$wsrep_defaults" wsrep_defaults="$WSREP_SST_OPT_DEFAULT" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULT" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULT:+ }$WSREP_SST_OPT_EXTRA_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" -readonly WSREP_SST_OPT_CONF_UNQUOTED="$wsrep_defaults" +readonly WSREP_SST_OPT_CONF_UNQUOTED="${wsrep_defaults:+ }$wsrep_defaults" # # User can specify mariabackup specific settings that will be used during sst @@ -819,8 +832,7 @@ if wsrep_auth_not_set; then fi # Splitting WSREP_SST_OPT_AUTH as "user:password" pair: -if ! wsrep_auth_not_set -then +if ! wsrep_auth_not_set; then # Extract username as shortest prefix up to first ':' character: WSREP_SST_OPT_AUTH_USER="${WSREP_SST_OPT_AUTH%%:*}" if [ -z "$WSREP_SST_OPT_USER" ]; then @@ -848,8 +860,7 @@ readonly WSREP_SST_OPT_USER readonly WSREP_SST_OPT_PSWD readonly WSREP_SST_OPT_AUTH -if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ] -then +if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ]; then # Split auth string at the last ':' readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%%:*}" readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH#*:}" @@ -860,8 +871,7 @@ fi readonly WSREP_SST_OPT_REMOTE_AUTH -if [ -n "$WSREP_SST_OPT_DATA" ] -then +if [ -n "$WSREP_SST_OPT_DATA" ]; then SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress" else SST_PROGRESS_FILE="" @@ -870,13 +880,14 @@ fi wsrep_cleanup_progress_file() { [ -n "$SST_PROGRESS_FILE" -a \ - -f "$SST_PROGRESS_FILE" ] && rm -f "$SST_PROGRESS_FILE" 2>/dev/null || true + -f "$SST_PROGRESS_FILE" ] && \ + rm -f "$SST_PROGRESS_FILE" 2>/dev/null || : } wsrep_check_program() { local prog="$1" - local cmd=$(command -v "$prog") + local cmd=$(commandex "$prog") if [ -z "$cmd" ]; then echo "'$prog' not found in PATH" return 2 # no such file or directory @@ -898,9 +909,9 @@ wsrep_check_programs() wsrep_check_datadir() { - if [ -z "$WSREP_SST_OPT_DATA" ] - then - wsrep_log_error "The '--datadir' parameter must be passed to the SST script" + if [ -z "$WSREP_SST_OPT_DATA" ]; then + wsrep_log_error \ + "The '--datadir' parameter must be passed to the SST script" exit 2 fi } @@ -912,10 +923,10 @@ get_openssl() return fi # Let's look for openssl: - OPENSSL_BINARY="$(command -v openssl)" + OPENSSL_BINARY=$(commandex 'openssl') if [ -z "$OPENSSL_BINARY" ]; then OPENSSL_BINARY='/usr/bin/openssl' - if [ -z "$OPENSSL_BINARY" ]; then + if [ ! -x "$OPENSSL_BINARY" ]; then OPENSSL_BINARY="" fi fi @@ -928,13 +939,12 @@ get_openssl() wsrep_gen_secret() { get_openssl - if [ -n "$OPENSSL_BINARY" ] - then + if [ -n "$OPENSSL_BINARY" ]; then echo $("$OPENSSL_BINARY" rand -hex 16) else printf "%04x%04x%04x%04x%04x%04x%04x%04x" \ - $RANDOM $RANDOM $RANDOM $RANDOM \ - $RANDOM $RANDOM $RANDOM $RANDOM + $RANDOM $RANDOM $RANDOM $RANDOM \ + $RANDOM $RANDOM $RANDOM $RANDOM fi } @@ -968,14 +978,14 @@ is_local_ip() fi # Now let's check if the given address is assigned to # one of the network cards: - local ip_util="$(command -v ip)" + local ip_util=$(commandex 'ip') if [ -n "$ip_util" ]; then # ip address show ouput format is " inet[6]
/": "$ip_util" address show \ | grep -E "^[[:space:]]*inet.? [^[:space:]]+/" -o \ | grep -F " $1/" >/dev/null && return 0 else - local ifconfig_util="$(command -v ifconfig)" + local ifconfig_util=$(commandex 'ifconfig') if [ -n "$ifconfig_util" ]; then # ifconfig output format is " inet[6]
...": "$ifconfig_util" \ @@ -992,15 +1002,15 @@ check_sockets_utils() sockstat_available=0 ss_available=0 - [ -n "$(command -v lsof)" ] && lsof_available=1 - [ -n "$(command -v sockstat)" ] && sockstat_available=1 - [ -n "$(command -v ss)" ] && ss_available=1 + [ -n "$(commandex lsof)" ] && lsof_available=1 + [ -n "$(commandex sockstat)" ] && sockstat_available=1 + [ -n "$(commandex ss)" ] && ss_available=1 if [ $lsof_available -eq 0 -a \ $sockstat_available -eq 0 -a \ $ss_available -eq 0 ] then - wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in " \ + wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in" \ "the PATH. Make sure you have it installed." exit 2 # ENOENT fi @@ -1085,26 +1095,38 @@ check_for_dhparams() # verify_ca_matches_cert() { - local ca="$1" - local cert="$2" - local path=${3:-0} + local cert="$1" + local ca="$2" + local cap="$3" # If the openssl utility is not installed, then # we will not do this certificate check: get_openssl if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_info "openssl utility not found" return fi - local not_match=0 + local readable=1; [ ! -r "$cert" ] && readable=0 + [ -n "$ca" ] && [ ! -r "$ca" ] && readable=0 + [ -n "$cap" ] && [ ! -r "$cap" ] && readable=0 - if [ $path -eq 0 ]; then - "$OPENSSL_BINARY" verify -verbose -CAfile "$ca" "$cert" >/dev/null 2>&1 || not_match=1 - else - "$OPENSSL_BINARY" verify -verbose -CApath "$ca" "$cert" >/dev/null 2>&1 || not_match=1 + if [ readable -eq 0 ]; then + wsrep_log_error \ + "Both PEM file and CA file (or path) must be readable" + exit 22 fi + local not_match=0 + local errmsg + errmsg=$("$OPENSSL_BINARY" verify -verbose \ + ${ca:+ -CAfile} ${ca:+ "$ca"} \ + ${cap:+ -CApath} ${cap:+ "$cap"} \ + "$cert" 2>&1) || not_match=1 + if [ $not_match -eq 1 ]; then + wsrep_log_info "run: \"$OPENSSL_BINARY\" verify -verbose${ca:+ -CAfile \"$ca\"}${cap:+ -CApath \"$cap\"} \"$cert\"" + wsrep_log_info "output: $errmsg" wsrep_log_error "******** FATAL ERROR ********************************************" wsrep_log_error "* The certifcate and CA (certificate authority) do not match. *" wsrep_log_error "* It does not appear that the certificate was issued by the CA. *" @@ -1124,12 +1146,18 @@ verify_ca_matches_cert() # verify_cert_matches_key() { - local cert_path="$1" - local key_path="$2" + local cert="$1" + local key="$2" + + if [ ! -r "$key" -o ! -r "$cert" ]; then + wsrep_log_error "Both the certificate file and the key file" \ + "must be readable" + exit 22 + fi # If the diff utility is not installed, then # we will not do this certificate check: - if [ -z "$(command -v diff)" ]; then + if [ -z "$(commandex diff)" ]; then return fi @@ -1142,13 +1170,13 @@ verify_cert_matches_key() # Generate the public key from the cert and the key. # They should match (otherwise we can't create an SSL connection). - if ! diff <("$OPENSSL_BINARY" x509 -in "$cert_path" -pubkey -noout 2>/dev/null) \ - <("$OPENSSL_BINARY" pkey -in "$key_path" -pubout 2>/dev/null) >/dev/null 2>&1 + if ! diff <("$OPENSSL_BINARY" x509 -in "$cert" -pubkey -noout 2>/dev/null) \ + <("$OPENSSL_BINARY" pkey -in "$key" -pubout 2>/dev/null) >/dev/null 2>&1 then - wsrep_log_error "******************* FATAL ERROR ****************" - wsrep_log_error "* The certifcate and private key do not match. *" - wsrep_log_error "* Please check your certificate and key files. *" - wsrep_log_error "************************************************" + wsrep_log_error "******************* FATAL ERROR *****************" + wsrep_log_error "* The certificate and private key do not match. *" + wsrep_log_error "* Please check your certificate and key files. *" + wsrep_log_error "*************************************************" exit 22 fi } @@ -1305,9 +1333,9 @@ get_proc() elif [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ]; then nproc=$(sysctl -n hw.ncpu) fi + set -e if [ -z "$nproc" ] || [ $nproc -eq 0 ]; then nproc=1 fi - set -e fi } diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index b429a9effd5..4bca785fcad 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -20,10 +20,11 @@ # https://mariadb.com/kb/en/mariabackup-overview/ # Make sure to read that before proceeding! +OS="$(uname)" + . $(dirname "$0")/wsrep_sst_common wsrep_check_datadir -OS="$(uname)" ealgo="" eformat="" ekey="" @@ -34,7 +35,7 @@ ssyslog="" ssystag="" BACKUP_PID="" tcert="" -tpath=0 +tcap="" tpem="" tkey="" tmode="DISABLED" @@ -88,14 +89,14 @@ readonly SECRET_TAG="secret" # For backup locks it is 1 sent by joiner sst_ver=1 -if [ -n "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then +if [ -n "$(commandex pv)" ] && pv --help | grep -qw -- '-F'; then pvopts="$pvopts $pvformat" fi pcmd="pv $pvopts" declare -a RC -BACKUP_BIN="$(command -v mariabackup)" -if [ ! -x "$BACKUP_BIN" ]; then +BACKUP_BIN=$(commandex 'mariabackup') +if [ -z "$BACKUP_BIN" ]; then wsrep_log_error 'mariabackup binary not found in path' exit 42 fi @@ -145,14 +146,14 @@ get_keys() if [ $encrypt -eq 0 ]; then if [ -n "$ealgo" -o -n "$ekey" -o -n "$ekeyfile" ]; then - wsrep_log_error "Options for encryption are specified, " \ + wsrep_log_error "Options for encryption are specified," \ "but encryption itself is disabled. SST may fail." fi return fi if [ $sfmt = 'tar' ]; then - wsrep_log_info "NOTE: key-based encryption (encrypt=1) " \ + wsrep_log_info "NOTE: key-based encryption (encrypt=1)" \ "cannot be enabled with tar format" encrypt=-1 return @@ -165,16 +166,18 @@ get_keys() exit 3 fi - if [ -z "$ekey" -a ! -r "$ekeyfile" ]; then - wsrep_log_error "FATAL: Either key must be specified " \ - "or keyfile must be readable" - exit 3 + if [ -z "$ekey" ]; then + if [ ! -r "$ekeyfile" ]; then + wsrep_log_error "FATAL: Either key must be specified" \ + "or keyfile must be readable" + exit 3 + fi fi if [ "$eformat" = 'openssl' ]; then get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error "If encryption using the openssl is enabled, " \ + wsrep_log_error "If encryption using the openssl is enabled," \ "then you need to install openssl" exit 2 fi @@ -192,12 +195,12 @@ get_keys() ecmd="$ecmd -k '$ekey'" fi elif [ "$eformat" = 'xbcrypt' ]; then - if [ -z "$(command -v xbcrypt)" ]; then - wsrep_log_error "If encryption using the xbcrypt is enabled, " \ + if [ -z "$(commandex xbcrypt)" ]; then + wsrep_log_error "If encryption using the xbcrypt is enabled," \ "then you need to install xbcrypt" exit 2 fi - wsrep_log_info "NOTE: xbcrypt-based encryption, " \ + wsrep_log_info "NOTE: xbcrypt-based encryption," \ "supported only from Xtrabackup 2.1.4" if [ -z "$ekey" ]; then ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'" @@ -342,40 +345,34 @@ get_transfer() CN_option=",commonname=''" if [ $encrypt -eq 2 ]; then - wsrep_log_info "Using openssl based encryption with socat: with crt and pem" - if [ -z "$tpem" -o -z "$tcert" ]; then + wsrep_log_info \ + "Using openssl based encryption with socat: with crt and pem" + if [ -z "$tpem" -o -z "$tcert$tcap" ]; then wsrep_log_error \ "Both PEM file and CRT file (or path) are required" exit 22 fi - if [ ! -r "$tpem" -o ! -r "$tcert" ]; then - wsrep_log_error \ - "Both PEM file and CRT file (or path) must be readable" - exit 22 + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" + tcmd="$tcmd,cert='$tpem'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',capath='$tcert'" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" fi stagemsg="$stagemsg-OpenSSL-Encrypted-2" - wsrep_log_info "$action with cert=$tpem, ca=$tcert" + wsrep_log_info "$action with cert='$tpem', ca='$tcert', capath='$tcap'" elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then - wsrep_log_info "Using openssl based encryption with socat: with key and crt" + wsrep_log_info \ + "Using openssl based encryption with socat: with key and crt" if [ -z "$tpem" -o -z "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file are required" - exit 22 - fi - if [ ! -r "$tpem" -o ! -r "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file must be readable" + wsrep_log_error "Both the certificate file (or path) and" \ + "the key file are required" exit 22 fi verify_cert_matches_key "$tpem" "$tkey" stagemsg="$stagemsg-OpenSSL-Encrypted-3" - if [ -z "$tcert" ]; then + if [ -z "$tcert$tcap" ]; then if [ $encrypt -eq 4 ]; then wsrep_log_error \ "Peer certificate file (or path) required if encrypt=4" @@ -384,14 +381,11 @@ get_transfer() # no verification CN_option="" tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0" - wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0" + wsrep_log_info \ + "$action with cert='$tpem', key='$tkey', verify=0" else # CA verification - if [ ! -r "$tcert" ]; then - wsrep_log_error "Certificate file or path must be readable" - exit 22 - fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' -o $encrypt -eq 4 ] @@ -402,12 +396,15 @@ get_transfer() else CN_option=",commonname='$WSREP_SST_OPT_HOST_UNESCAPED'" fi - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',key='$tkey',capath='$tcert'" + tcmd="$tcmd,cert='$tpem',key='$tkey'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - wsrep_log_info "$action with cert=$tpem, key=$tkey, ca=$tcert" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" + fi + wsrep_log_info "$action with cert='$tpem', key='$tkey'," \ + "ca='$tcert', capath='$tcap'" fi else wsrep_log_info "Unknown encryption mode: encrypt=$encrypt" @@ -425,7 +422,9 @@ get_transfer() get_footprint() { pushd "$WSREP_SST_OPT_DATA" 1>/dev/null - payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }') + payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' \ + -type f -print0 | du --files0-from=- --block-size=1 -c -s | \ + awk 'END { print $1 }') if [ "$compress" != 'none' ]; then # QuickLZ has around 50% compression ratio # When compression/compaction used, the progress is only an approximate. @@ -438,7 +437,7 @@ get_footprint() adjust_progress() { - if [ -z "$(command -v pv)" ]; then + if [ -z "$(commandex pv)" ]; then wsrep_log_error "pv not found in path: $PATH" wsrep_log_error "Disabling all progress/rate-limiting" pcmd="" @@ -470,33 +469,42 @@ check_server_ssl_config() { # backward-compatible behavior: tcert=$(parse_cnf 'sst' 'tca') + tcap=$(parse_cnf 'sst' 'tcapath') tpem=$(parse_cnf 'sst' 'tcert') tkey=$(parse_cnf 'sst' 'tkey') # reading new ssl configuration options: local tcert2=$(parse_cnf "$encgroups" 'ssl-ca') + local tcap2=$(parse_cnf "$encgroups" 'ssl-capath') local tpem2=$(parse_cnf "$encgroups" 'ssl-cert') local tkey2=$(parse_cnf "$encgroups" 'ssl-key') # if there are no old options, then we take new ones: - if [ -z "$tcert" -a -z "$tpem" -a -z "$tkey" ]; then + if [ -z "$tcert" -a -z "$tcap" -a -z "$tpem" -a -z "$tkey" ]; then tcert="$tcert2" + tcap="$tcap2" tpem="$tpem2" tkey="$tkey2" # checking for presence of the new-style SSL configuration: - elif [ -n "$tcert2" -o -n "$tpem2" -o -n "$tkey2" ]; then + elif [ -n "$tcert2" -o -n "$tcap2" -o -n "$tpem2" -o -n "$tkey2" ]; then if [ "$tcert" != "$tcert2" -o \ + "$tcap" != "$tcap2" -o \ "$tpem" != "$tpem2" -o \ "$tkey" != "$tkey2" ] then - wsrep_log_info "new ssl configuration options (ssl-ca, ssl-cert " \ - "and ssl-key) are ignored by SST due to presence " \ - "of the tca, tcert and/or tkey in the [sst] section" + wsrep_log_info \ + "new ssl configuration options (ssl-ca[path], ssl-cert" \ + "and ssl-key) are ignored by SST due to presence" \ + "of the tca[path], tcert and/or tkey in the [sst] section" fi fi if [ -n "$tcert" ]; then - tcert=$(trim_string "$tcert") - if [ "${tcert%/}" != "$tcert" ]; then - tpath=1 - fi + tcert=$(trim_string "$tcert") + if [ "${tcert%/}" != "$tcert" ] || [ -d "$tcert" ]; then + tcap="$tcert" + tcert="" + fi + fi + if [ -n "$tcap" ]; then + tcap=$(trim_string "$tcap") fi } @@ -506,10 +514,10 @@ read_cnf() tfmt=$(parse_cnf sst transferfmt 'socat') encrypt=$(parse_cnf "$encgroups" 'encrypt' 0) - tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) + tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | \ + tr [:lower:] [:upper:]) - if [ $encrypt -eq 0 -o $encrypt -ge 2 ] - then + if [ $encrypt -eq 0 -o $encrypt -ge 2 ]; then if [ "$tmode" != 'DISABLED' -o $encrypt -ge 2 ]; then check_server_ssl_config fi @@ -517,11 +525,13 @@ read_cnf() if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] then encrypt=3 # enable cert/key SSL encyption - # avoid CA verification if not set explicitly: - # nodes may happen to have different CA if self-generated - # zeroing up tcert does the trick - [ "${tmode#VERIFY}" != "$tmode" ] || tcert="" + # nodes may happen to have different CA if self-generated, + # zeroing up tcert and tcap does the trick: + if [ "${tmode#VERIFY}" = "$tmode" ]; then + tcert="" + tcap="" + fi fi fi elif [ $encrypt -eq 1 ]; then @@ -535,8 +545,9 @@ read_cnf() fi fi - wsrep_log_info "SSL configuration: CA='$tcert', CERT='$tpem'," \ - "KEY='$tkey', MODE='$tmode', encrypt='$encrypt'" + wsrep_log_info "SSL configuration: CA='$tcert', CAPATH='$tcap'," \ + "CERT='$tpem', KEY='$tkey', MODE='$tmode'," \ + "encrypt='$encrypt'" sockopt=$(parse_cnf sst sockopt "") progress=$(parse_cnf sst progress "") @@ -561,7 +572,8 @@ read_cnf() sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir '/tmp/sst_log_archive') if [ $speciald -eq 0 ]; then - wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1" + wsrep_log_error \ + "sst-special-dirs equal to 0 is not supported, falling back to 1" speciald=1 fi @@ -589,7 +601,7 @@ get_stream() { if [ "$sfmt" = 'mbstream' -o "$sfmt" = 'xbstream' ]; then sfmt='mbstream' - STREAM_BIN="$(command -v mbstream)" + local STREAM_BIN=$(commandex "$sfmt") if [ -z "$STREAM_BIN" ]; then wsrep_log_error "Streaming with $sfmt, but $sfmt not found in path" exit 42 @@ -621,7 +633,7 @@ cleanup_at_exit() # Since this is invoked just after exit NNN local estatus=$? if [ $estatus -ne 0 ]; then - wsrep_log_error "Cleanup after exit with status:$estatus" + wsrep_log_error "Cleanup after exit with status: $estatus" fi if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then @@ -630,7 +642,8 @@ cleanup_at_exit() else if [ -n "$BACKUP_PID" ]; then if check_pid "$BACKUP_PID" 1; then - wsrep_log_error "mariabackup process is still running. Killing..." + wsrep_log_error \ + "mariabackup process is still running. Killing..." cleanup_pid $CHECK_PID "$BACKUP_PID" fi fi @@ -638,8 +651,8 @@ cleanup_at_exit() fi if [ -n "$progress" -a -p "$progress" ]; then - wsrep_log_info "Cleaning up fifo file $progress" - rm -f "$progress" || true + wsrep_log_info "Cleaning up fifo file: $progress" + rm -f "$progress" || : fi wsrep_log_info "Cleaning up temporary directories" @@ -649,8 +662,8 @@ cleanup_at_exit() [ -d "$STATDIR" ] && rm -rf "$STATDIR" fi else - [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true - [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true + [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || : + [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || : fi # Final cleanup @@ -662,7 +675,7 @@ cleanup_at_exit() # This means a signal was delivered to the process. # So, more cleanup. if [ $estatus -ge 128 ]; then - kill -KILL -- -$$ || true + kill -KILL -- -$$ || : fi fi @@ -738,7 +751,7 @@ recv_joiner() local ltcmd="$tcmd" if [ $tmt -gt 0 ]; then - if [ -n "$(command -v timeout)" ]; then + if [ -n "$(commandex timeout)" ]; then if timeout --help | grep -qw -- '-k'; then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" else @@ -760,14 +773,14 @@ recv_joiner() popd 1>/dev/null if [ ${RC[0]} -eq 124 ]; then - wsrep_log_error "Possible timeout in receiving first data from " \ + wsrep_log_error "Possible timeout in receiving first data from" \ "donor in gtid stage: exit codes: ${RC[@]}" exit 32 fi for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while getting data from donor node: " \ + wsrep_log_error "Error while getting data from donor node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -776,7 +789,7 @@ recv_joiner() if [ $checkf -eq 1 ]; then if [ ! -r "$MAGIC_FILE" ]; then # this message should cause joiner to abort - wsrep_log_error "receiving process ended without creating " \ + wsrep_log_error "receiving process ended without creating" \ "'$MAGIC_FILE'" wsrep_log_info "Contents of datadir" wsrep_log_info $(ls -l "$dir/"*) @@ -784,10 +797,11 @@ recv_joiner() fi # check donor supplied secret - SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | \ + cut -d ' ' -f 2) if [ "$SECRET" != "$MY_SECRET" ]; then wsrep_log_error "Donor does not know my secret!" - wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'" exit 32 fi @@ -810,7 +824,7 @@ send_donor() for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while sending data to joiner node: " \ + wsrep_log_error "Error while sending data to joiner node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -823,7 +837,9 @@ monitor_process() while true ; do if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1; then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error \ + "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." kill -- -"$WSREP_SST_OPT_PARENT" exit 32 fi @@ -845,7 +861,7 @@ read_cnf setup_ports if "$BACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then - disver='--no-version-check' + disver=' --no-version-check' fi # if no command line argument and INNODB_DATA_HOME_DIR environment variable @@ -867,7 +883,7 @@ INNODB_DATA_HOME_DIR=$(pwd -P) cd "$OLD_PWD" if [ $ssyslog -eq 1 ]; then - if [ -n "$(command -v logger)" ]; then + if [ -n "$(commandex logger)" ]; then wsrep_log_info "Logging all stderr of SST/mariabackup to syslog" exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE) @@ -898,10 +914,8 @@ else fi fi - if [ -e "$INNOAPPLYLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOAPPLYLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOAPPLYLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -912,10 +926,8 @@ else gzip "$newfile" fi - if [ -e "$INNOMOVELOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOMOVELOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOMOVELOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -926,10 +938,8 @@ else gzip "$newfile" fi - if [ -e "$INNOBACKUPLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOBACKUPLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOBACKUPLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -949,15 +959,15 @@ setup_commands() { local mysqld_args="" if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then - mysqld_args="--mysqld-args $WSREP_SST_OPT_MYSQLD" + mysqld_args=" --mysqld-args $WSREP_SST_OPT_MYSQLD" fi - if [ -z "$INNODB_FORCE_RECOVERY" ]; then - INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" - else - INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --innodb-force-recovery=$INNODB_FORCE_RECOVERY --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" + local recovery="" + if [ -n "$INNODB_FORCE_RECOVERY" ]; then + recovery=" --innodb-force-recovery=$INNODB_FORCE_RECOVERY" fi - INNOMOVE="$BACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" - INNOBACKUP="$BACKUP_BIN $WSREP_SST_OPT_CONF --backup $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA' $mysqld_args $INNOBACKUP" + INNOAPPLY="$BACKUP_BIN --prepare$disver$recovery${iapts:+ }$iapts$INNOEXTRA --target-dir='$DATA' --datadir='$DATA'$mysqld_args $INNOAPPLY" + INNOMOVE="$BACKUP_BIN$WSREP_SST_OPT_CONF --move-back$disver${impts:+ }$impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" + INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF --backup$disver${iopts:+ }$iopts $tmpopts$INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA'$mysqld_args $INNOBACKUP" } get_stream @@ -1055,27 +1065,28 @@ then tcmd="$ecmd | $tcmd" fi - iopts="--databases-exclude='lost+found' $iopts" + iopts="--databases-exclude='lost+found'${iopts:+ }$iopts" if [ ${FORCE_FTWRL:-0} -eq 1 ]; then - wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" - iopts="--no-backup-locks $iopts" + wsrep_log_info "Forcing FTWRL due to environment variable" \ + "FORCE_FTWRL equal to $FORCE_FTWRL" + iopts="--no-backup-locks${iopts:+ }$iopts" fi # if compression is enabled for backup files, then add the # appropriate options to the mariabackup command line: if [ "$compress" != 'none' ]; then - iopts="--compress${compress:+=$compress} $iopts" + iopts="--compress${compress:+=$compress}${iopts:+ }$iopts" if [ -n "$compress_threads" ]; then - iopts="--compress-threads=$compress_threads $iopts" + iopts="--compress-threads=$compress_threads${iopts:+ }$iopts" fi if [ -n "$compress_chunk" ]; then - iopts="--compress-chunk-size=$compress_chunk $iopts" + iopts="--compress-chunk-size=$compress_chunk${iopts:+ }$iopts" fi fi if [ -n "$backup_threads" ]; then - iopts="--parallel=$backup_threads $iopts" + iopts="--parallel=$backup_threads${iopts:+ }$iopts" fi setup_commands @@ -1084,7 +1095,7 @@ then set -e if [ ${RC[0]} -ne 0 ]; then - wsrep_log_error "mariabackup finished with error: ${RC[0]}. " \ + wsrep_log_error "mariabackup finished with error: ${RC[0]}." \ "Check syslog or '$INNOBACKUPLOG' for details" exit 22 elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then @@ -1125,7 +1136,8 @@ then elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ] then - [ -e "$SST_PROGRESS_FILE" ] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" + [ -e "$SST_PROGRESS_FILE" ] && \ + wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" [ -n "$SST_PROGRESS_FILE" ] && touch "$SST_PROGRESS_FILE" ib_home_dir="$INNODB_DATA_HOME_DIR" @@ -1146,7 +1158,7 @@ then ib_undo_dir="$INNODB_UNDO_DIR" if [ -n "$backup_threads" ]; then - impts="--parallel=$backup_threads $impts" + impts="--parallel=$backup_threads${impts:+ }$impts" fi stagemsg='Joiner-Recv' @@ -1165,15 +1177,15 @@ then ADDR="$WSREP_SST_OPT_ADDR" - if [ "${tmode#VERIFY}" != "$tmode" ] - then # backward-incompatible behavior + if [ "${tmode#VERIFY}" != "$tmode" ]; then + # backward-incompatible behavior: CN="" - if [ -n "$tpem" ] - then + if [ -n "$tpem" ]; then # find out my Common Name get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error 'openssl not found but it is required for authentication' + wsrep_log_error \ + 'openssl not found but it is required for authentication' exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ @@ -1213,15 +1225,17 @@ then if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1 then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." exit 32 fi - if [ ! -r "$STATDIR/$IST_FILE" ] - then + if [ ! -r "$STATDIR/$IST_FILE" ]; then if [ -d "$DATA/.sst" ]; then - wsrep_log_info "WARNING: Stale temporary SST directory: '$DATA/.sst' from previous state transfer. Removing" + wsrep_log_info \ + "WARNING: Stale temporary SST directory:" \ + "'$DATA/.sst' from previous state transfer, removing..." rm -rf "$DATA/.sst" fi mkdir -p "$DATA/.sst" @@ -1229,17 +1243,20 @@ then jpid=$! wsrep_log_info "Proceeding with SST" - wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories" + wsrep_log_info \ + "Cleaning the existing datadir and innodb-data/log directories" if [ "$OS" = 'FreeBSD' ]; then find -E ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ else find ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ fi get_binlog @@ -1248,9 +1265,9 @@ then binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") cd "$binlog_dir" wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" - rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || : [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ - rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || : cd "$OLD_PWD" fi @@ -1262,7 +1279,8 @@ then monitor_process $jpid if [ ! -s "$DATA/xtrabackup_checkpoints" ]; then - wsrep_log_error "xtrabackup_checkpoints missing, failed mariabackup/SST on donor" + wsrep_log_error "xtrabackup_checkpoints missing," \ + "failed mariabackup/SST on donor" exit 2 fi @@ -1277,7 +1295,7 @@ then if [ -n "$qpfiles" ]; then wsrep_log_info "Compressed qpress files found" - if [ -z "$(command -v qpress)" ]; then + if [ -z "$(commandex qpress)" ]; then wsrep_log_error "qpress utility not found in the path" exit 22 fi @@ -1300,14 +1318,17 @@ then # Decompress the qpress files wsrep_log_info "Decompression with $nproc threads" - timeit "Joiner-Decompression" "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" + timeit "Joiner-Decompression" \ + "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" extcode=$? if [ $extcode -eq 0 ]; then wsrep_log_info "Removing qpress files after decompression" find "$DATA" -type f -name '*.qp' -delete if [ $? -ne 0 ]; then - wsrep_log_error "Something went wrong with deletion of qpress files. Investigate" + wsrep_log_error \ + "Something went wrong with deletion of qpress files." \ + "Investigate" fi else wsrep_log_error "Decompression failed. Exit code: $extcode" @@ -1321,7 +1342,7 @@ then BINLOG_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG") # To avoid comparing data directory and BINLOG_DIRNAME - mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || true + mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || : cd "$BINLOG_DIRNAME" for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do @@ -1336,7 +1357,8 @@ then timeit "mariabackup prepare stage" "$INNOAPPLY" if [ $? -ne 0 ]; then - wsrep_log_error "mariabackup apply finished with errors. Check syslog or '$INNOAPPLYLOG' for details" + wsrep_log_error "mariabackup apply finished with errors." \ + "Check syslog or '$INNOAPPLYLOG' for details." exit 22 fi diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index 798bee1ac10..bed2cac0a9a 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -19,7 +19,6 @@ # This is a reference script for mysqldump-based state snapshot tansfer . $(dirname "$0")/wsrep_sst_common -PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin EINVAL=22 @@ -93,8 +92,7 @@ DROP PREPARE stmt;" SET_START_POSITION="SET GLOBAL wsrep_start_position='$WSREP_SST_OPT_GTID';" SET_WSREP_GTID_DOMAIN_ID="" -if [ -n $WSREP_SST_OPT_GTID_DOMAIN_ID ] -then +if [ -n $WSREP_SST_OPT_GTID_DOMAIN_ID ]; then SET_WSREP_GTID_DOMAIN_ID=" SET @val = (SELECT GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME = 'WSREP_GTID_STRICT_MODE' AND GLOBAL_VALUE > 0); SET @stmt = IF (@val IS NOT NULL, 'SET GLOBAL WSREP_GTID_DOMAIN_ID=$WSREP_SST_OPT_GTID_DOMAIN_ID', 'SET @dummy = 0'); @@ -103,7 +101,7 @@ then DROP PREPARE stmt;" fi -MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF_UNQUOTED "\ +MYSQL="$MYSQL_CLIENT$WSREP_SST_OPT_CONF_UNQUOTED "\ "$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\ "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" @@ -125,8 +123,7 @@ SET_GTID_BINLOG_STATE="" SQL_LOG_BIN_OFF="" # Safety check -if [ ${SERVER_VERSION%%.*} -gt 5 ] -then +if [ ${SERVER_VERSION%%.*} -gt 5 ]; then # If binary logging is enabled on the joiner node, we need to copy donor's # gtid_binlog_state to joiner. In order to do that, a RESET MASTER must be # executed to erase binary logs (if any). Binary logging should also be @@ -140,7 +137,7 @@ then fi # NOTE: we don't use --routines here because we're dumping mysql.proc table -MYSQLDUMP="$MYSQLDUMP $WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \ +MYSQLDUMP="$MYSQLDUMP$WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \ --add-drop-database --add-drop-table --skip-add-locks --create-options \ --disable-keys --extended-insert --skip-lock-tables --quick --set-charset \ --skip-comments --flush-privileges --all-databases --events" diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 29c9cd43470..b0cc8cb3066 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -25,9 +25,6 @@ STUNNEL_REAL_PID=0 # stunnel process id OS="$(uname)" [ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH -# Setting the path for lsof on CentOS -export PATH="/usr/sbin:/sbin:$PATH" - . $(dirname "$0")/wsrep_sst_common wsrep_check_datadir @@ -37,7 +34,8 @@ cleanup_joiner() { local failure=0 - wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID, stunnel PID=$STUNNEL_REAL_PID" + wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID," \ + "stunnel PID=$STUNNEL_REAL_PID" if [ -n "$STUNNEL" ]; then if cleanup_pid $STUNNEL_REAL_PID "$STUNNEL_PID" "$STUNNEL_CONF"; then @@ -87,7 +85,7 @@ check_pid_and_port() if [ $lsof_available -ne 0 ]; then port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \ - grep -F '(LISTEN)') + grep -F '(LISTEN)') echo "$port_info" | \ grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1 else @@ -124,7 +122,7 @@ check_pid_and_port() fi if ! check_port "$pid" "$port" "$utils"; then - wsrep_log_error "rsync or stunnel daemon port '$port' " \ + wsrep_log_error "rsync or stunnel daemon port '$port'" \ "has been taken by another program" exit 16 # EBUSY fi @@ -223,6 +221,7 @@ FILTER="-f '- /lost+found' SSTKEY=$(parse_cnf 'sst' 'tkey') SSTCERT=$(parse_cnf 'sst' 'tcert') SSTCA=$(parse_cnf 'sst' 'tca') +SSTCAP=$(parse_cnf 'sst' 'tcapath') SST_SECTIONS="--mysqld|sst" @@ -231,28 +230,34 @@ check_server_ssl_config() SSTKEY=$(parse_cnf "$SST_SECTIONS" 'ssl-key') SSTCERT=$(parse_cnf "$SST_SECTIONS" 'ssl-cert') SSTCA=$(parse_cnf "$SST_SECTIONS" 'ssl-ca') + SSTCAP=$(parse_cnf "$SST_SECTIONS" 'ssl-capath') } SSLMODE=$(parse_cnf "$SST_SECTIONS" 'ssl-mode' | tr [:lower:] [:upper:]) # no old-style SSL config in [sst], check for new one: -if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]; then +if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" -a -z "$SSTCAP" ]; then check_server_ssl_config fi -SSTPATH=0 if [ -n "$SSTCA" ]; then - SSTCA=$(trim_string "$SSTCA") - if [ "${SSTCA%/}" != "$SSTCA" ]; then - SSTPATH=1 - fi + SSTCA=$(trim_string "$SSTCA") + if [ "${SSTCA%/}" != "$SSTCA" ] || [ -d "$SSTCA" ]; then + SSTCAP="$SSTCA" + SSTCA="" + fi +fi + +if [ -n "$SSTCAP" ]; then + SSTCAP=$(trim_string "$SSTCAP") fi if [ -z "$SSLMODE" ]; then # Implicit verification if CA is set and the SSL mode # is not specified by user: - if [ -n "$SSTCA" ]; then - if [ -n "$(command -v stunnel)" ]; then + if [ -n "$SSTCA$SSTCAP" ]; then + STUNNEL_BIN=$(commandex 'stunnel') + if [ -n "$STUNNEL_BIN" ]; then SSLMODE='VERIFY_CA' fi # Require SSL by default if SSL key and cert are present: @@ -265,17 +270,18 @@ if [ -n "$SSTCERT" -a -n "$SSTKEY" ]; then verify_cert_matches_key "$SSTCERT" "$SSTKEY" fi -if [ -n "$SSTCA" ]; then - if [ $SSTPATH -eq 0 ]; then +CAFILE_OPT="" +CAPATH_OPT="" +if [ -n "$SSTCA$SSTCAP" ]; then + if [ -n "$SSTCA" ]; then CAFILE_OPT="CAfile = $SSTCA" - else - CAFILE_OPT="CApath = $SSTCA" + fi + if [ -n "$SSTCAP" ]; then + CAPATH_OPT="CApath = $SSTCAP" fi if [ -n "$SSTCERT" ]; then - verify_ca_matches_cert "$SSTCA" "$SSTCERT" $SSTPATH + verify_ca_matches_cert "$SSTCERT" "$SSTCA" "$SSTCAP" fi -else - CAFILE_OPT="" fi VERIFY_OPT="" @@ -295,7 +301,7 @@ then exit 22 # EINVAL ;; esac - if [ -z "$SSTCA" ]; then + if [ -z "$SSTCA$SSTCAP" ]; then wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file or path" exit 22 # EINVAL fi @@ -318,9 +324,12 @@ fi STUNNEL="" if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ]; then - STUNNEL_BIN="$(command -v stunnel)" + if [ -z "${STUNNEL_BIN+x}" ]; then + STUNNEL_BIN=$(commandex 'stunnel') + fi if [ -n "$STUNNEL_BIN" ]; then - wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA', ssl-mode='$SSLMODE'" + wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA'," \ + "CAPATH='$SSTCAP', ssl-mode='$SSLMODE'" STUNNEL="$STUNNEL_BIN $STUNNEL_CONF" fi fi @@ -340,6 +349,7 @@ then key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -392,8 +402,8 @@ EOF # Prepare binlog files cd "$BINLOG_DIRNAME" - binlog_files_full=$(tail -n $BINLOG_N_FILES "$WSREP_SST_OPT_BINLOG_INDEX") - + binlog_files_full=$(tail -n $BINLOG_N_FILES \ + "$WSREP_SST_OPT_BINLOG_INDEX") binlog_files="" for ii in $binlog_files_full do @@ -417,9 +427,10 @@ EOF WHOLE_FILE_OPT="--whole-file" fi - # first, the normal directories, so that we can detect incompatible protocol + # first, the normal directories, so that we can detect + # incompatible protocol: RC=0 - eval rsync ${STUNNEL:+"'--rsh=$STUNNEL'"} \ + eval rsync ${STUNNEL:+"--rsh='$STUNNEL'"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ $WHOLE_FILE_OPT $FILTER "'$WSREP_SST_OPT_DATA/'" \ @@ -430,8 +441,9 @@ EOF case $RC in 12) RC=71 # EPROTO wsrep_log_error \ - "rsync server on the other end has incompatible protocol. " \ - "Make sure you have the same version of rsync on all nodes." + "rsync server on the other end has incompatible" \ + "protocol. Make sure you have the same version of" \ + "rsync on all nodes." ;; 22) RC=12 # ENOMEM ;; @@ -481,9 +493,9 @@ EOF find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \ -not -name '.zfs' -print0 | xargs -I{} -0 -P $backup_threads \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \ - --owner --group --perms --links --specials \ - --ignore-times --inplace --recursive --delete --quiet \ - $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \ + --owner --group --perms --links --specials --ignore-times \ + --inplace --recursive --delete --quiet $WHOLE_FILE_OPT \ + --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \ --exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/{}/" \ "rsync://$WSREP_SST_OPT_ADDR/{}" >&2 || RC=$? @@ -514,7 +526,8 @@ EOF fi rsync ${STUNNEL:+--rsh="$STUNNEL"} \ - --archive --quiet --checksum "$MAGIC_FILE" "rsync://$WSREP_SST_OPT_ADDR" + --archive --quiet --checksum "$MAGIC_FILE" \ + "rsync://$WSREP_SST_OPT_ADDR" echo "done $STATE" @@ -546,7 +559,8 @@ then check_round=0 while check_pid "$STUNNEL_PID" 1 do - wsrep_log_info "lingering stunnel daemon found at startup, waiting for it to exit" + wsrep_log_info "Lingering stunnel daemon found at startup," \ + "waiting for it to exit" check_round=$(( check_round + 1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "stunnel daemon already running." @@ -563,7 +577,8 @@ then check_round=0 while check_pid "$RSYNC_PID" 1 do - wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit" + wsrep_log_info "Lingering rsync daemon found at startup," \ + "waiting for it to exit" check_round=$(( check_round + 1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "rsync daemon already running." @@ -575,9 +590,7 @@ then [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" [ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE" - if [ -z "$STUNNEL" ]; then - [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" - fi + [ -z "$STUNNEL" ] && [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" ADDR="$WSREP_SST_OPT_ADDR" RSYNC_PORT="$WSREP_SST_OPT_PORT" @@ -628,19 +641,21 @@ EOF echo $$ > "$SST_PID" - if [ -z "$STUNNEL" ] - then - rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & + if [ -z "$STUNNEL" ]; then + rsync --daemon --no-detach --port "$RSYNC_PORT" \ + --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & RSYNC_REAL_PID=$! TRANSFER_REAL_PID=$RSYNC_REAL_PID TRANSFER_PID="$RSYNC_PID" else # Let's check if the path to the config file contains a space? + RSYNC_BIN=$(commandex 'rsync') if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -650,17 +665,18 @@ ${CHECK_OPT} ${CHECK_OPT_LOCAL} [rsync] accept = $STUNNEL_ACCEPT -exec = $(command -v rsync) +exec = $RSYNC_BIN execargs = rsync --server --daemon --config=$RSYNC_CONF . EOF else # The path contains a space, so we will run it via # shell with "eval" command: - export RSYNC_CMD="eval $(command -v rsync) --server --daemon --config='$RSYNC_CONF' ." + export RSYNC_CMD="eval '$RSYNC_BIN' --server --daemon --config='$RSYNC_CONF' ." cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -688,7 +704,8 @@ EOF # find out my Common Name get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error 'openssl not found but it is required for authentication' + wsrep_log_error \ + 'openssl not found but it is required for authentication' exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \ @@ -703,7 +720,8 @@ EOF ADDR="$WSREP_SST_OPT_HOST" fi - until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT" + until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID \ + "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT" do sleep 0.2 done @@ -722,7 +740,7 @@ EOF if ! ps -p $MYSQLD_PID >/dev/null 2>&1 then wsrep_log_error \ - "Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly." + "Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly." kill -- -$MYSQLD_PID sleep 1 exit 32 @@ -768,10 +786,11 @@ EOF if [ -r "$MAGIC_FILE" ]; then if [ -n "$MY_SECRET" ]; then # check donor supplied secret - SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | \ + cut -d ' ' -f 2) if [ "$SECRET" != "$MY_SECRET" ]; then wsrep_log_error "Donor does not know my secret!" - wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'" exit 32 fi # remove secret from the magic file, and output diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 8ab7565a666..08f0905e044 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -178,6 +178,12 @@ new_VioSSLFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; long ssl_ctx_options= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; DBUG_ENTER("new_VioSSLFd"); + + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + DBUG_PRINT("enter", ("key_file: '%s' cert_file: '%s' ca_file: '%s' ca_path: '%s' " "cipher: '%s' crl_file: '%s' crl_path: '%s' ", @@ -308,6 +314,11 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + /* Turn off verification of servers certificate if both ca_file and ca_path is set to NULL @@ -339,6 +350,12 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; + + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher, FALSE, error, crl_file, crl_path))) From 66b492f3e43e357951ee6b1c93f4afabcbfec9ba Mon Sep 17 00:00:00 2001 From: sjaakola Date: Mon, 13 Dec 2021 12:13:03 +0200 Subject: [PATCH 16/52] Fix for the test galera.galera_UK_conflict mtr test galera.galera_UK_conflict, has rather distorted logic in test scenario 2. The test would fail always with: CURRENT_TEST: galera.galera_UK_conflict mysqltest: In included file "./include/galera_wait_sync_point.inc": included from /home/seppo/work/wsrep/mariadb-server/mysql-test/suite/galera/t/galera_UK_conflict.test at line 216: At line 3: query 'SET SESSION wsrep_on = 0' failed: 1179: You are not allowed to execute this command in a transaction This happens because wait_condition is called in wrong connection (node_1, which is excuting MST transaction) This test is fixed by using contl connection for wait contdition check, and new result is recorded as well --- .../suite/galera/r/galera_UK_conflict.result | 57 +++++++++++++++++-- .../suite/galera/t/galera_UK_conflict.test | 8 ++- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_UK_conflict.result b/mysql-test/suite/galera/r/galera_UK_conflict.result index cc7e17d7c58..b0420d58ede 100644 --- a/mysql-test/suite/galera/r/galera_UK_conflict.result +++ b/mysql-test/suite/galera/r/galera_UK_conflict.result @@ -71,6 +71,31 @@ INSERT INTO t1 VALUES (8,8,8); SELECT COUNT(*) FROM t1; COUNT(*) 7 +SELECT * FROM t1; +f1 f2 f3 +1 1 0 +3 3 1 +4 4 2 +5 5 2 +7 7 7 +8 8 8 +10 10 0 +connection node_1; +SELECT COUNT(*) FROM t1; +COUNT(*) +7 +SELECT * FROM t1; +f1 f2 f3 +1 1 0 +3 3 1 +4 4 2 +5 5 2 +7 7 7 +8 8 8 +10 10 0 +DROP TABLE t1; +test scenario 2 +connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 int, f3 int, unique key keyj (f2)); INSERT INTO t1 VALUES (1, 1, 0); INSERT INTO t1 VALUES (3, 3, 0); @@ -92,9 +117,9 @@ SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'dbug='; SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync'; connection node_1; -SELECT COUNT(*) FROM t1; -COUNT(*) -7 +COMMIT; +connection node_1a; +SET SESSION wsrep_on = 0; SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'dbug='; SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_replay_cb"; @@ -125,8 +150,32 @@ f1 f2 f3 3 3 1 4 4 2 5 5 2 -8 8 8 10 10 0 INSERT INTO t1 VALUES (7,7,7); INSERT INTO t1 VALUES (8,8,8); +SELECT COUNT(*) FROM t1; +COUNT(*) +7 +SELECT * FROM t1; +f1 f2 f3 +1 1 0 +3 3 1 +4 4 2 +5 5 2 +7 7 7 +8 8 8 +10 10 0 +connection node_1; +SELECT COUNT(*) FROM t1; +COUNT(*) +7 +SELECT * FROM t1; +f1 f2 f3 +1 1 0 +3 3 1 +4 4 2 +5 5 2 +7 7 7 +8 8 8 +10 10 0 DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_UK_conflict.test b/mysql-test/suite/galera/t/galera_UK_conflict.test index 25f414a5764..7a14821cc32 100644 --- a/mysql-test/suite/galera/t/galera_UK_conflict.test +++ b/mysql-test/suite/galera/t/galera_UK_conflict.test @@ -207,14 +207,16 @@ INSERT INTO t1 VALUES (5, 5, 2); --source include/galera_set_sync_point.inc --connection node_1 ---let $wait_condition = SELECT COUNT(*) = 7 FROM t1 ---source include/wait_condition.inc -SELECT COUNT(*) FROM t1; +--send COMMIT + +--connection node_1a # wait for the local commit to enter in commit monitor wait state --let $galera_sync_point = apply_monitor_slave_enter_sync commit_monitor_master_enter_sync --source include/galera_wait_sync_point.inc --source include/galera_clear_sync_point.inc +# first applier is now waiting in before commit, and local trx in commit monitor + # set sync point before replaying SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_replay_cb"; From dda0bfaaecc898d7a4b1e1234e0f5083294ccf6e Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Tue, 14 Dec 2021 03:47:59 +0100 Subject: [PATCH 17/52] MDEV-27181: Galera SST scripts should use ssl_capath for CA directory 1. Galera SST scripts should use ssl_capath (not ssl_ca) for CA directory. The current implementation tries to automatically detect the path using the trailing slash in the ssl_ca variable value, but this approach is not compatible with the server configuration. Now, by analogy with the server, SST scripts also use a separate ssl_capath variable. In addition, a similar tcapath variable has been added for the old-style configuration (in the "sst" section). 2. Openssl utility detection made more reliable. 3. Removed extra spaces in automatically generated command lines - to simplify debugging of the SST scripts. 4. In general, the code for detecting the presence or absence of auxiliary utilities has been improved - it is made more reliable in some configurations (and for shells other than bash). --- mysql-test/std_data/capath/3106f582.0 | 1 + mysql-test/std_data/capath/cacert.pem | 79 +++ mysql-test/std_data/capath/ed1f42db.0 | 1 + ..._sst_rsync_encrypt_with_capath,debug.rdiff | 191 +++++++ ...alera_sst_rsync_encrypt_with_capath.result | 520 ++++++++++++++++++ .../galera_sst_rsync_encrypt_with_key.result | 2 - ...alera_sst_rsync_encrypt_with_server.result | 2 - .../galera_sst_mariabackup_table_options.test | 1 + .../galera_sst_rsync_encrypt_with_capath.cnf | 20 + .../galera_sst_rsync_encrypt_with_capath.test | 26 + .../t/galera_sst_rsync_encrypt_with_key.test | 3 - .../galera_sst_rsync_encrypt_with_server.test | 3 - .../t/galera_ipv6_mariabackup.test | 1 + .../t/galera_ipv6_mariabackup_section.test | 1 + scripts/wsrep_sst_common.sh | 142 +++-- scripts/wsrep_sst_mariabackup.sh | 292 +++++----- scripts/wsrep_sst_mysqldump.sh | 11 +- scripts/wsrep_sst_rsync.sh | 117 ++-- vio/viosslfactories.c | 17 + 19 files changed, 1172 insertions(+), 258 deletions(-) create mode 120000 mysql-test/std_data/capath/3106f582.0 create mode 100644 mysql-test/std_data/capath/cacert.pem create mode 120000 mysql-test/std_data/capath/ed1f42db.0 create mode 100644 mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath,debug.rdiff create mode 100644 mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test diff --git a/mysql-test/std_data/capath/3106f582.0 b/mysql-test/std_data/capath/3106f582.0 new file mode 120000 index 00000000000..1310cfcff20 --- /dev/null +++ b/mysql-test/std_data/capath/3106f582.0 @@ -0,0 +1 @@ +cacert.pem \ No newline at end of file diff --git a/mysql-test/std_data/capath/cacert.pem b/mysql-test/std_data/capath/cacert.pem new file mode 100644 index 00000000000..23dda2318e1 --- /dev/null +++ b/mysql-test/std_data/capath/cacert.pem @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + d0:4d:23:85:ee:59:b3:fa + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Validity + Not Before: Jan 27 10:11:10 2019 GMT + Not After : Jan 22 10:11:10 2039 GMT + Subject: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e8:0e:a7:84:d3:75:30:06:30:b2:10:b9:d1:88: + 36:2b:5e:f8:c8:44:57:cb:67:72:ab:96:95:33:d5: + 88:d1:8f:23:50:98:ba:6d:20:00:80:bd:35:d5:c1: + bf:98:49:c4:0a:15:4a:34:a6:21:9b:2e:8c:15:09: + f0:63:81:02:c2:7c:e2:53:e0:f7:a1:1a:40:5e:8f: + 41:4a:4c:56:d4:20:f1:d5:a7:c1:53:2e:ff:7e:37: + 17:cc:7e:74:bd:e2:22:33:ce:8c:77:62:a4:c5:3f: + 44:35:7b:7e:b9:f5:7d:8c:7a:27:58:fd:2c:42:86: + 2e:e7:6b:01:99:7b:fe:7d:a7:a1:4f:3e:39:39:54: + 1f:61:de:74:66:d1:77:4f:43:1b:66:70:29:85:de: + fc:8f:8e:1b:7b:a2:66:48:26:7f:9b:a6:fd:4a:e4: + dc:eb:ed:bd:f8:e3:f1:57:98:13:6f:f1:a3:2a:e3: + 73:bd:8d:7c:6f:4b:59:35:bc:b5:42:3e:99:a7:13: + 8d:be:2e:5c:9a:c6:5b:ab:ae:bf:00:e9:c8:ee:05: + 22:8e:d5:67:1a:47:9a:6d:9c:f9:42:3e:15:34:f8: + 31:ec:b4:7e:d3:92:95:b0:b8:f9:66:f3:bd:1d:31: + 2c:b1:90:62:a1:f8:4e:a6:5d:26:22:f0:e1:fe:16: + 2b:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + X509v3 Authority Key Identifier: + keyid:CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + df:fd:74:29:5b:5e:9a:8b:09:02:40:59:73:cb:71:47:3f:97: + 3d:a9:fd:c4:8c:01:29:c9:86:b8:71:55:ff:72:0e:50:dc:c8: + b5:e6:91:41:52:47:21:30:cc:4d:e7:3b:4b:db:55:ea:7d:46: + eb:53:e0:b7:1b:80:7c:b1:0c:d3:d1:bc:a0:73:ae:96:1f:fd: + 05:52:7e:54:d5:03:52:69:7b:34:5f:27:d7:98:da:98:76:73: + e6:bb:50:59:2a:94:90:67:03:1c:a4:76:2f:ee:ef:59:60:09: + 48:33:03:2b:52:ed:83:42:f8:71:19:7f:d8:be:40:ed:20:01: + 90:3c:7e:1c:8b:d2:9f:f3:2f:09:1f:50:c8:10:e1:8a:d9:a5: + 49:9c:0b:74:17:b9:2b:68:f6:1e:73:c2:73:10:38:b3:35:e2: + 87:91:1b:a1:d1:9b:81:9d:1b:32:cc:03:6e:4c:82:95:81:11: + 42:56:e2:16:2b:22:65:db:40:2c:ca:dc:03:f4:d5:07:cf:f5: + 13:b2:cf:51:5b:24:cd:c7:d1:9b:42:8e:f9:df:5d:1e:5a:09: + a3:4f:a9:0b:f4:21:c5:bb:ff:02:93:67:e8:2d:ee:ab:d9:59: + 76:03:2c:a1:bd:fb:dc:af:b6:82:94:71:85:53:a8:18:0d:3a: + 9e:42:eb:59 +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIJANBNI4XuWbP6MA0GCSqGSIb3DQEBCwUAMFYxDzANBgNV +BAMMBmNhY2VydDELMAkGA1UEBhMCRkkxETAPBgNVBAgMCEhlbHNpbmtpMREwDwYD +VQQHDAhIZWxzaW5raTEQMA4GA1UECgwHTWFyaWFEQjAeFw0xOTAxMjcxMDExMTBa +Fw0zOTAxMjIxMDExMTBaMFYxDzANBgNVBAMMBmNhY2VydDELMAkGA1UEBhMCRkkx +ETAPBgNVBAgMCEhlbHNpbmtpMREwDwYDVQQHDAhIZWxzaW5raTEQMA4GA1UECgwH +TWFyaWFEQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOgOp4TTdTAG +MLIQudGINite+MhEV8tncquWlTPViNGPI1CYum0gAIC9NdXBv5hJxAoVSjSmIZsu +jBUJ8GOBAsJ84lPg96EaQF6PQUpMVtQg8dWnwVMu/343F8x+dL3iIjPOjHdipMU/ +RDV7frn1fYx6J1j9LEKGLudrAZl7/n2noU8+OTlUH2HedGbRd09DG2ZwKYXe/I+O +G3uiZkgmf5um/Urk3Ovtvfjj8VeYE2/xoyrjc72NfG9LWTW8tUI+macTjb4uXJrG +W6uuvwDpyO4FIo7VZxpHmm2c+UI+FTT4Mey0ftOSlbC4+WbzvR0xLLGQYqH4TqZd +JiLw4f4WK2kCAwEAAaNQME4wHQYDVR0OBBYEFMpxmYnwcqt1ZrtlagMEcqV7laaT +MB8GA1UdIwQYMBaAFMpxmYnwcqt1ZrtlagMEcqV7laaTMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBAN/9dClbXpqLCQJAWXPLcUc/lz2p/cSMASnJhrhx +Vf9yDlDcyLXmkUFSRyEwzE3nO0vbVep9RutT4LcbgHyxDNPRvKBzrpYf/QVSflTV +A1JpezRfJ9eY2ph2c+a7UFkqlJBnAxykdi/u71lgCUgzAytS7YNC+HEZf9i+QO0g +AZA8fhyL0p/zLwkfUMgQ4YrZpUmcC3QXuSto9h5zwnMQOLM14oeRG6HRm4GdGzLM +A25MgpWBEUJW4hYrImXbQCzK3AP01QfP9ROyz1FbJM3H0ZtCjvnfXR5aCaNPqQv0 +IcW7/wKTZ+gt7qvZWXYDLKG9+9yvtoKUcYVTqBgNOp5C61k= +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/capath/ed1f42db.0 b/mysql-test/std_data/capath/ed1f42db.0 new file mode 120000 index 00000000000..1310cfcff20 --- /dev/null +++ b/mysql-test/std_data/capath/ed1f42db.0 @@ -0,0 +1 @@ +cacert.pem \ No newline at end of file diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath,debug.rdiff b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath,debug.rdiff new file mode 100644 index 00000000000..59417d4d6e4 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath,debug.rdiff @@ -0,0 +1,191 @@ +--- r/galera_sst_rsync_encrypt_with_server.result ++++ r/galera_sst_rsync_encrypt_with_server,debug.reject +@@ -519,4 +519,188 @@ + 1 + DROP TABLE t1; + COMMIT; ++Performing State Transfer on a server that has been killed and restarted ++while a DDL was in progress on it ++connection node_1; ++CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 VALUES (1,'node1_committed_before'); ++INSERT INTO t1 VALUES (2,'node1_committed_before'); ++INSERT INTO t1 VALUES (3,'node1_committed_before'); ++INSERT INTO t1 VALUES (4,'node1_committed_before'); ++INSERT INTO t1 VALUES (5,'node1_committed_before'); ++connection node_2; ++START TRANSACTION; ++INSERT INTO t1 VALUES (6,'node2_committed_before'); ++INSERT INTO t1 VALUES (7,'node2_committed_before'); ++INSERT INTO t1 VALUES (8,'node2_committed_before'); ++INSERT INTO t1 VALUES (9,'node2_committed_before'); ++INSERT INTO t1 VALUES (10,'node2_committed_before'); ++COMMIT; ++SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; ++connection node_1; ++ALTER TABLE t1 ADD COLUMN f2 INTEGER; ++connection node_2; ++SET wsrep_sync_wait = 0; ++Killing server ... ++connection node_1; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (11,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (12,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (13,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (14,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (15,'node1_committed_during'); ++COMMIT; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (16,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (17,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (18,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (19,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (20,'node1_to_be_committed_after'); ++connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (21,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (22,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (23,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (24,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (25,'node1_to_be_rollbacked_after'); ++connection node_2; ++Performing --wsrep-recover ... ++connection node_2; ++Starting server ... ++Using --wsrep-start-position when starting mysqld ... ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (26,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (27,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (28,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (29,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (30,'node2_committed_after'); ++COMMIT; ++connection node_1; ++INSERT INTO t1 (id,f1) VALUES (31,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (32,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (33,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (34,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (35,'node1_to_be_committed_after'); ++COMMIT; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (36,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (37,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (38,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (39,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (40,'node1_committed_after'); ++COMMIT; ++connection node_1a_galera_st_kill_slave_ddl; ++INSERT INTO t1 (id,f1) VALUES (41,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (42,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (43,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (44,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (45,'node1_to_be_rollbacked_after'); ++ROLLBACK; ++SET AUTOCOMMIT=ON; ++SET SESSION wsrep_sync_wait=15; ++SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; ++EXPECT_3 ++3 ++SELECT COUNT(*) AS EXPECT_35 FROM t1; ++EXPECT_35 ++35 ++SELECT * FROM t1; ++id f1 f2 ++1 node1_committed_before NULL ++2 node1_committed_before NULL ++3 node1_committed_before NULL ++4 node1_committed_before NULL ++5 node1_committed_before NULL ++6 node2_committed_before NULL ++7 node2_committed_before NULL ++8 node2_committed_before NULL ++9 node2_committed_before NULL ++10 node2_committed_before NULL ++11 node1_committed_during NULL ++12 node1_committed_during NULL ++13 node1_committed_during NULL ++14 node1_committed_during NULL ++15 node1_committed_during NULL ++16 node1_to_be_committed_after NULL ++17 node1_to_be_committed_after NULL ++18 node1_to_be_committed_after NULL ++19 node1_to_be_committed_after NULL ++20 node1_to_be_committed_after NULL ++26 node2_committed_after NULL ++27 node2_committed_after NULL ++28 node2_committed_after NULL ++29 node2_committed_after NULL ++30 node2_committed_after NULL ++31 node1_to_be_committed_after NULL ++32 node1_to_be_committed_after NULL ++33 node1_to_be_committed_after NULL ++34 node1_to_be_committed_after NULL ++35 node1_to_be_committed_after NULL ++36 node1_committed_after NULL ++37 node1_committed_after NULL ++38 node1_committed_after NULL ++39 node1_committed_after NULL ++40 node1_committed_after NULL ++SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; ++COUNT(*) = 0 ++1 ++COMMIT; ++connection node_1; ++SET AUTOCOMMIT=ON; ++SET SESSION wsrep_sync_wait=15; ++SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; ++EXPECT_3 ++3 ++SELECT COUNT(*) AS EXPECT_35 FROM t1; ++EXPECT_35 ++35 ++SELECT * FROM t1; ++id f1 f2 ++1 node1_committed_before NULL ++2 node1_committed_before NULL ++3 node1_committed_before NULL ++4 node1_committed_before NULL ++5 node1_committed_before NULL ++6 node2_committed_before NULL ++7 node2_committed_before NULL ++8 node2_committed_before NULL ++9 node2_committed_before NULL ++10 node2_committed_before NULL ++11 node1_committed_during NULL ++12 node1_committed_during NULL ++13 node1_committed_during NULL ++14 node1_committed_during NULL ++15 node1_committed_during NULL ++16 node1_to_be_committed_after NULL ++17 node1_to_be_committed_after NULL ++18 node1_to_be_committed_after NULL ++19 node1_to_be_committed_after NULL ++20 node1_to_be_committed_after NULL ++26 node2_committed_after NULL ++27 node2_committed_after NULL ++28 node2_committed_after NULL ++29 node2_committed_after NULL ++30 node2_committed_after NULL ++31 node1_to_be_committed_after NULL ++32 node1_to_be_committed_after NULL ++33 node1_to_be_committed_after NULL ++34 node1_to_be_committed_after NULL ++35 node1_to_be_committed_after NULL ++36 node1_committed_after NULL ++37 node1_committed_after NULL ++38 node1_committed_after NULL ++39 node1_committed_after NULL ++40 node1_committed_after NULL ++SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; ++COUNT(*) = 0 ++1 ++DROP TABLE t1; ++COMMIT; ++SET GLOBAL debug_dbug = $debug_orig; + include/assert_grep.inc [Using stunnel for SSL encryption] diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result new file mode 100644 index 00000000000..be8c845bdcf --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result @@ -0,0 +1,520 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connection node_1; +Performing State Transfer on a server that has been shut down cleanly and restarted +connection node_1; +CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'node1_committed_before'); +INSERT INTO t1 VALUES (2,'node1_committed_before'); +INSERT INTO t1 VALUES (3,'node1_committed_before'); +INSERT INTO t1 VALUES (4,'node1_committed_before'); +INSERT INTO t1 VALUES (5,'node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (6,'node2_committed_before'); +INSERT INTO t1 VALUES (7,'node2_committed_before'); +INSERT INTO t1 VALUES (8,'node2_committed_before'); +INSERT INTO t1 VALUES (9,'node2_committed_before'); +INSERT INTO t1 VALUES (10,'node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (11,'node1_committed_during'); +INSERT INTO t1 VALUES (12,'node1_committed_during'); +INSERT INTO t1 VALUES (13,'node1_committed_during'); +INSERT INTO t1 VALUES (14,'node1_committed_during'); +INSERT INTO t1 VALUES (15,'node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES (16,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (17,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (18,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (19,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (20,'node1_to_be_committed_after'); +connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (21,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (22,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (23,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (24,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (25,'node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (26,'node2_committed_after'); +INSERT INTO t1 VALUES (27,'node2_committed_after'); +INSERT INTO t1 VALUES (28,'node2_committed_after'); +INSERT INTO t1 VALUES (29,'node2_committed_after'); +INSERT INTO t1 VALUES (30,'node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES (31,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (32,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (33,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (34,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (35,'node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (36,'node1_committed_after'); +INSERT INTO t1 VALUES (37,'node1_committed_after'); +INSERT INTO t1 VALUES (38,'node1_committed_after'); +INSERT INTO t1 VALUES (39,'node1_committed_after'); +INSERT INTO t1 VALUES (40,'node1_committed_after'); +COMMIT; +connection node_1a_galera_st_shutdown_slave; +INSERT INTO t1 VALUES (41,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (42,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (43,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (44,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (45,'node1_to_be_rollbacked_after'); +ROLLBACK; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_15 FROM t1; +EXPECT_15 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +connection node_1; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_15 FROM t1; +EXPECT_15 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +Performing State Transfer on a server that starts from a clean var directory +This is accomplished by shutting down node #2 and removing its var directory before restarting it +connection node_1; +CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'node1_committed_before'); +INSERT INTO t1 VALUES (2,'node1_committed_before'); +INSERT INTO t1 VALUES (3,'node1_committed_before'); +INSERT INTO t1 VALUES (4,'node1_committed_before'); +INSERT INTO t1 VALUES (5,'node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (6,'node2_committed_before'); +INSERT INTO t1 VALUES (7,'node2_committed_before'); +INSERT INTO t1 VALUES (8,'node2_committed_before'); +INSERT INTO t1 VALUES (9,'node2_committed_before'); +INSERT INTO t1 VALUES (10,'node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +Cleaning var directory ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (11,'node1_committed_during'); +INSERT INTO t1 VALUES (12,'node1_committed_during'); +INSERT INTO t1 VALUES (13,'node1_committed_during'); +INSERT INTO t1 VALUES (14,'node1_committed_during'); +INSERT INTO t1 VALUES (15,'node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES (16,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (17,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (18,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (19,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (20,'node1_to_be_committed_after'); +connect node_1a_galera_st_clean_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (21,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (22,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (23,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (24,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (25,'node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (26,'node2_committed_after'); +INSERT INTO t1 VALUES (27,'node2_committed_after'); +INSERT INTO t1 VALUES (28,'node2_committed_after'); +INSERT INTO t1 VALUES (29,'node2_committed_after'); +INSERT INTO t1 VALUES (30,'node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES (31,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (32,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (33,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (34,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (35,'node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (36,'node1_committed_after'); +INSERT INTO t1 VALUES (37,'node1_committed_after'); +INSERT INTO t1 VALUES (38,'node1_committed_after'); +INSERT INTO t1 VALUES (39,'node1_committed_after'); +INSERT INTO t1 VALUES (40,'node1_committed_after'); +COMMIT; +connection node_1a_galera_st_clean_slave; +INSERT INTO t1 VALUES (41,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (42,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (43,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (44,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (45,'node1_to_be_rollbacked_after'); +ROLLBACK; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +connection node_1; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +Performing State Transfer on a server that has been killed and restarted +connection node_1; +CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'node1_committed_before'); +INSERT INTO t1 VALUES (2,'node1_committed_before'); +INSERT INTO t1 VALUES (3,'node1_committed_before'); +INSERT INTO t1 VALUES (4,'node1_committed_before'); +INSERT INTO t1 VALUES (5,'node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (6,'node2_committed_before'); +INSERT INTO t1 VALUES (7,'node2_committed_before'); +INSERT INTO t1 VALUES (8,'node2_committed_before'); +INSERT INTO t1 VALUES (9,'node2_committed_before'); +INSERT INTO t1 VALUES (10,'node2_committed_before'); +COMMIT; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (11,'node1_committed_during'); +INSERT INTO t1 VALUES (12,'node1_committed_during'); +INSERT INTO t1 VALUES (13,'node1_committed_during'); +INSERT INTO t1 VALUES (14,'node1_committed_during'); +INSERT INTO t1 VALUES (15,'node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES (16,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (17,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (18,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (19,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (20,'node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (21,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (22,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (23,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (24,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (25,'node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (26,'node2_committed_after'); +INSERT INTO t1 VALUES (27,'node2_committed_after'); +INSERT INTO t1 VALUES (28,'node2_committed_after'); +INSERT INTO t1 VALUES (29,'node2_committed_after'); +INSERT INTO t1 VALUES (30,'node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES (31,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (32,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (33,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (34,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (35,'node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (36,'node1_committed_after'); +INSERT INTO t1 VALUES (37,'node1_committed_after'); +INSERT INTO t1 VALUES (38,'node1_committed_after'); +INSERT INTO t1 VALUES (39,'node1_committed_after'); +INSERT INTO t1 VALUES (40,'node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave; +INSERT INTO t1 VALUES (41,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (42,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (43,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (45,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (46,'node1_to_be_rollbacked_after'); +ROLLBACK; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * FROM t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +connection node_1; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * FROM t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +include/assert_grep.inc [Using stunnel for SSL encryption] diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result index b791e580623..be8c845bdcf 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result @@ -2,8 +2,6 @@ connection node_2; connection node_1; connection node_1; connection node_2; -connection node_2; -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); connection node_1; Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result index b791e580623..be8c845bdcf 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result @@ -2,8 +2,6 @@ connection node_2; connection node_1; connection node_1; connection node_2; -connection node_2; -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); connection node_1; Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test b/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test index 953a1635559..7a3a6c825c4 100644 --- a/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test @@ -66,6 +66,7 @@ COMMIT; --source include/wait_condition.inc --echo Cleaning var directory ... +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mtr --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/performance_schema --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/test diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf new file mode 100644 index 00000000000..3ab762df013 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf @@ -0,0 +1,20 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=rsync +ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem +ssl-key=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem +ssl-capath=@ENV.MYSQL_TEST_DIR/std_data/capath +# We need to turn off the default setting for the duration +# of the test (to test working with a directory instead of +# a file): +ssl-ca= + +[sst] +ssl-mode=VERIFY_CA + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test new file mode 100644 index 00000000000..a2d92723ec4 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test @@ -0,0 +1,26 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_debug.inc +--source include/have_stunnel.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--connection node_1 +--source suite/galera/include/galera_st_shutdown_slave.inc +--source suite/galera/include/galera_st_clean_slave.inc + +--source suite/galera/include/galera_st_kill_slave.inc +--source suite/galera/include/galera_st_kill_slave_ddl.inc + +# Confirm that transfer was SSL-encrypted +--let $assert_text = Using stunnel for SSL encryption +--let $assert_select = Using stunnel for SSL encryption +--let $assert_count = 5 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = CURRENT_TEST +--source include/assert_grep.inc + +--source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test index 838c473b9ce..a2d92723ec4 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test @@ -8,9 +8,6 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.inc ---connection node_2 -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); - --connection node_1 --source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_clean_slave.inc diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test index 838c473b9ce..a2d92723ec4 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test @@ -8,9 +8,6 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.inc ---connection node_2 -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); - --connection node_1 --source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_clean_slave.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test index 31613454348..6e02350b12b 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/check_ipv6.inc --source include/have_innodb.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test index 3b2ca0892f1..453aa21988d 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/check_ipv6.inc --source include/have_innodb.inc diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index dbd639595df..5c84aa7c17f 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -19,6 +19,9 @@ set -u +# Setting the path for some utilities on CentOS +export PATH="$PATH:/usr/sbin:/usr/bin:/sbin:/bin" + WSREP_SST_OPT_BYPASS=0 WSREP_SST_OPT_BINLOG="" WSREP_SST_OPT_BINLOG_INDEX="" @@ -384,10 +387,8 @@ case "$1" in skip_mysqld_arg=1 ;; '--innodb-force-recovery') - if [ -n "$value" ]; then - if [ "$value" -ne 0 ]; then - INNODB_FORCE_RECOVERY="$value" - fi + if [ -n "$value" -a "$value" != "0" ]; then + INNODB_FORCE_RECOVERY="$value" fi skip_mysqld_arg=1 ;; @@ -584,7 +585,8 @@ get_binlog() if [ -n "$WSREP_SST_OPT_ADDR_PORT" ]; then if [ -n "$WSREP_SST_OPT_PORT" ]; then if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then - echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 + echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT" \ + "differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 exit 2 fi else @@ -616,8 +618,19 @@ fi readonly WSREP_SST_OPT_ADDR readonly WSREP_SST_OPT_ADDR_PORT -# try to use my_print_defaults, mysql and mysqldump that come with the sources -# (for MTR suite) +commandex() +{ + if [ -n "$BASH_VERSION" ]; then + command -v "$1" || : + elif [ -x "$1" ]; then + echo "$1" + else + which "$1" || : + fi +} + +# try to use my_print_defaults, mysql and mysqldump that come +# with the sources (for MTR suite): script_binary=$(dirname "$0") SCRIPTS_DIR=$(cd "$script_binary"; pwd -P) EXTRA_DIR="$SCRIPTS_DIR/../extra" @@ -626,13 +639,13 @@ CLIENT_DIR="$SCRIPTS_DIR/../client" if [ -x "$CLIENT_DIR/mysql" ]; then MYSQL_CLIENT="$CLIENT_DIR/mysql" else - MYSQL_CLIENT="$(command -v mysql)" + MYSQL_CLIENT=$(commandex 'mysql') fi if [ -x "$CLIENT_DIR/mysqldump" ]; then MYSQLDUMP="$CLIENT_DIR/mysqldump" else - MYSQLDUMP="$(command -v mysqldump)" + MYSQLDUMP=$(commandex 'mysqldump') fi wsrep_log() @@ -663,7 +676,7 @@ if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults" else - MY_PRINT_DEFAULTS="$(command -v my_print_defaults)" + MY_PRINT_DEFAULTS=$(commandex 'my_print_defaults') if [ -z "$MY_PRINT_DEFAULTS" ]; then wsrep_log_error "my_print_defaults not found in path" exit 2 @@ -673,16 +686,16 @@ fi readonly MY_PRINT_DEFAULTS wsrep_defaults="$WSREP_SST_OPT_DEFAULTS" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULTS:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" -readonly WSREP_SST_OPT_CONF="$wsrep_defaults" +readonly WSREP_SST_OPT_CONF="${wsrep_defaults:+ }$wsrep_defaults" wsrep_defaults="$WSREP_SST_OPT_DEFAULT" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULT" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULT:+ }$WSREP_SST_OPT_EXTRA_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" -readonly WSREP_SST_OPT_CONF_UNQUOTED="$wsrep_defaults" +readonly WSREP_SST_OPT_CONF_UNQUOTED="${wsrep_defaults:+ }$wsrep_defaults" # # User can specify mariabackup specific settings that will be used during sst @@ -819,8 +832,7 @@ if wsrep_auth_not_set; then fi # Splitting WSREP_SST_OPT_AUTH as "user:password" pair: -if ! wsrep_auth_not_set -then +if ! wsrep_auth_not_set; then # Extract username as shortest prefix up to first ':' character: WSREP_SST_OPT_AUTH_USER="${WSREP_SST_OPT_AUTH%%:*}" if [ -z "$WSREP_SST_OPT_USER" ]; then @@ -848,8 +860,7 @@ readonly WSREP_SST_OPT_USER readonly WSREP_SST_OPT_PSWD readonly WSREP_SST_OPT_AUTH -if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ] -then +if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ]; then # Split auth string at the last ':' readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%%:*}" readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH#*:}" @@ -860,8 +871,7 @@ fi readonly WSREP_SST_OPT_REMOTE_AUTH -if [ -n "$WSREP_SST_OPT_DATA" ] -then +if [ -n "$WSREP_SST_OPT_DATA" ]; then SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress" else SST_PROGRESS_FILE="" @@ -870,13 +880,14 @@ fi wsrep_cleanup_progress_file() { [ -n "$SST_PROGRESS_FILE" -a \ - -f "$SST_PROGRESS_FILE" ] && rm -f "$SST_PROGRESS_FILE" 2>/dev/null || true + -f "$SST_PROGRESS_FILE" ] && \ + rm -f "$SST_PROGRESS_FILE" 2>/dev/null || : } wsrep_check_program() { local prog="$1" - local cmd=$(command -v "$prog") + local cmd=$(commandex "$prog") if [ -z "$cmd" ]; then echo "'$prog' not found in PATH" return 2 # no such file or directory @@ -898,9 +909,9 @@ wsrep_check_programs() wsrep_check_datadir() { - if [ -z "$WSREP_SST_OPT_DATA" ] - then - wsrep_log_error "The '--datadir' parameter must be passed to the SST script" + if [ -z "$WSREP_SST_OPT_DATA" ]; then + wsrep_log_error \ + "The '--datadir' parameter must be passed to the SST script" exit 2 fi } @@ -912,10 +923,10 @@ get_openssl() return fi # Let's look for openssl: - OPENSSL_BINARY="$(command -v openssl)" + OPENSSL_BINARY=$(commandex 'openssl') if [ -z "$OPENSSL_BINARY" ]; then OPENSSL_BINARY='/usr/bin/openssl' - if [ -z "$OPENSSL_BINARY" ]; then + if [ ! -x "$OPENSSL_BINARY" ]; then OPENSSL_BINARY="" fi fi @@ -928,13 +939,12 @@ get_openssl() wsrep_gen_secret() { get_openssl - if [ -n "$OPENSSL_BINARY" ] - then + if [ -n "$OPENSSL_BINARY" ]; then echo $("$OPENSSL_BINARY" rand -hex 16) else printf "%04x%04x%04x%04x%04x%04x%04x%04x" \ - $RANDOM $RANDOM $RANDOM $RANDOM \ - $RANDOM $RANDOM $RANDOM $RANDOM + $RANDOM $RANDOM $RANDOM $RANDOM \ + $RANDOM $RANDOM $RANDOM $RANDOM fi } @@ -968,14 +978,14 @@ is_local_ip() fi # Now let's check if the given address is assigned to # one of the network cards: - local ip_util="$(command -v ip)" + local ip_util=$(commandex 'ip') if [ -n "$ip_util" ]; then # ip address show ouput format is " inet[6]
/": "$ip_util" address show \ | grep -E "^[[:space:]]*inet.? [^[:space:]]+/" -o \ | grep -F " $1/" >/dev/null && return 0 else - local ifconfig_util="$(command -v ifconfig)" + local ifconfig_util=$(commandex 'ifconfig') if [ -n "$ifconfig_util" ]; then # ifconfig output format is " inet[6]
...": "$ifconfig_util" \ @@ -992,15 +1002,15 @@ check_sockets_utils() sockstat_available=0 ss_available=0 - [ -n "$(command -v lsof)" ] && lsof_available=1 - [ -n "$(command -v sockstat)" ] && sockstat_available=1 - [ -n "$(command -v ss)" ] && ss_available=1 + [ -n "$(commandex lsof)" ] && lsof_available=1 + [ -n "$(commandex sockstat)" ] && sockstat_available=1 + [ -n "$(commandex ss)" ] && ss_available=1 if [ $lsof_available -eq 0 -a \ $sockstat_available -eq 0 -a \ $ss_available -eq 0 ] then - wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in " \ + wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in" \ "the PATH. Make sure you have it installed." exit 2 # ENOENT fi @@ -1085,26 +1095,38 @@ check_for_dhparams() # verify_ca_matches_cert() { - local ca="$1" - local cert="$2" - local path=${3:-0} + local cert="$1" + local ca="$2" + local cap="$3" # If the openssl utility is not installed, then # we will not do this certificate check: get_openssl if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_info "openssl utility not found" return fi - local not_match=0 + local readable=1; [ ! -r "$cert" ] && readable=0 + [ -n "$ca" ] && [ ! -r "$ca" ] && readable=0 + [ -n "$cap" ] && [ ! -r "$cap" ] && readable=0 - if [ $path -eq 0 ]; then - "$OPENSSL_BINARY" verify -verbose -CAfile "$ca" "$cert" >/dev/null 2>&1 || not_match=1 - else - "$OPENSSL_BINARY" verify -verbose -CApath "$ca" "$cert" >/dev/null 2>&1 || not_match=1 + if [ readable -eq 0 ]; then + wsrep_log_error \ + "Both PEM file and CA file (or path) must be readable" + exit 22 fi + local not_match=0 + local errmsg + errmsg=$("$OPENSSL_BINARY" verify -verbose \ + ${ca:+ -CAfile} ${ca:+ "$ca"} \ + ${cap:+ -CApath} ${cap:+ "$cap"} \ + "$cert" 2>&1) || not_match=1 + if [ $not_match -eq 1 ]; then + wsrep_log_info "run: \"$OPENSSL_BINARY\" verify -verbose${ca:+ -CAfile \"$ca\"}${cap:+ -CApath \"$cap\"} \"$cert\"" + wsrep_log_info "output: $errmsg" wsrep_log_error "******** FATAL ERROR ********************************************" wsrep_log_error "* The certifcate and CA (certificate authority) do not match. *" wsrep_log_error "* It does not appear that the certificate was issued by the CA. *" @@ -1124,12 +1146,18 @@ verify_ca_matches_cert() # verify_cert_matches_key() { - local cert_path="$1" - local key_path="$2" + local cert="$1" + local key="$2" + + if [ ! -r "$key" -o ! -r "$cert" ]; then + wsrep_log_error "Both the certificate file and the key file" \ + "must be readable" + exit 22 + fi # If the diff utility is not installed, then # we will not do this certificate check: - if [ -z "$(command -v diff)" ]; then + if [ -z "$(commandex diff)" ]; then return fi @@ -1142,13 +1170,13 @@ verify_cert_matches_key() # Generate the public key from the cert and the key. # They should match (otherwise we can't create an SSL connection). - if ! diff <("$OPENSSL_BINARY" x509 -in "$cert_path" -pubkey -noout 2>/dev/null) \ - <("$OPENSSL_BINARY" pkey -in "$key_path" -pubout 2>/dev/null) >/dev/null 2>&1 + if ! diff <("$OPENSSL_BINARY" x509 -in "$cert" -pubkey -noout 2>/dev/null) \ + <("$OPENSSL_BINARY" pkey -in "$key" -pubout 2>/dev/null) >/dev/null 2>&1 then - wsrep_log_error "******************* FATAL ERROR ****************" - wsrep_log_error "* The certifcate and private key do not match. *" - wsrep_log_error "* Please check your certificate and key files. *" - wsrep_log_error "************************************************" + wsrep_log_error "******************* FATAL ERROR *****************" + wsrep_log_error "* The certificate and private key do not match. *" + wsrep_log_error "* Please check your certificate and key files. *" + wsrep_log_error "*************************************************" exit 22 fi } @@ -1305,9 +1333,9 @@ get_proc() elif [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ]; then nproc=$(sysctl -n hw.ncpu) fi + set -e if [ -z "$nproc" ] || [ $nproc -eq 0 ]; then nproc=1 fi - set -e fi } diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index b429a9effd5..4bca785fcad 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -20,10 +20,11 @@ # https://mariadb.com/kb/en/mariabackup-overview/ # Make sure to read that before proceeding! +OS="$(uname)" + . $(dirname "$0")/wsrep_sst_common wsrep_check_datadir -OS="$(uname)" ealgo="" eformat="" ekey="" @@ -34,7 +35,7 @@ ssyslog="" ssystag="" BACKUP_PID="" tcert="" -tpath=0 +tcap="" tpem="" tkey="" tmode="DISABLED" @@ -88,14 +89,14 @@ readonly SECRET_TAG="secret" # For backup locks it is 1 sent by joiner sst_ver=1 -if [ -n "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then +if [ -n "$(commandex pv)" ] && pv --help | grep -qw -- '-F'; then pvopts="$pvopts $pvformat" fi pcmd="pv $pvopts" declare -a RC -BACKUP_BIN="$(command -v mariabackup)" -if [ ! -x "$BACKUP_BIN" ]; then +BACKUP_BIN=$(commandex 'mariabackup') +if [ -z "$BACKUP_BIN" ]; then wsrep_log_error 'mariabackup binary not found in path' exit 42 fi @@ -145,14 +146,14 @@ get_keys() if [ $encrypt -eq 0 ]; then if [ -n "$ealgo" -o -n "$ekey" -o -n "$ekeyfile" ]; then - wsrep_log_error "Options for encryption are specified, " \ + wsrep_log_error "Options for encryption are specified," \ "but encryption itself is disabled. SST may fail." fi return fi if [ $sfmt = 'tar' ]; then - wsrep_log_info "NOTE: key-based encryption (encrypt=1) " \ + wsrep_log_info "NOTE: key-based encryption (encrypt=1)" \ "cannot be enabled with tar format" encrypt=-1 return @@ -165,16 +166,18 @@ get_keys() exit 3 fi - if [ -z "$ekey" -a ! -r "$ekeyfile" ]; then - wsrep_log_error "FATAL: Either key must be specified " \ - "or keyfile must be readable" - exit 3 + if [ -z "$ekey" ]; then + if [ ! -r "$ekeyfile" ]; then + wsrep_log_error "FATAL: Either key must be specified" \ + "or keyfile must be readable" + exit 3 + fi fi if [ "$eformat" = 'openssl' ]; then get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error "If encryption using the openssl is enabled, " \ + wsrep_log_error "If encryption using the openssl is enabled," \ "then you need to install openssl" exit 2 fi @@ -192,12 +195,12 @@ get_keys() ecmd="$ecmd -k '$ekey'" fi elif [ "$eformat" = 'xbcrypt' ]; then - if [ -z "$(command -v xbcrypt)" ]; then - wsrep_log_error "If encryption using the xbcrypt is enabled, " \ + if [ -z "$(commandex xbcrypt)" ]; then + wsrep_log_error "If encryption using the xbcrypt is enabled," \ "then you need to install xbcrypt" exit 2 fi - wsrep_log_info "NOTE: xbcrypt-based encryption, " \ + wsrep_log_info "NOTE: xbcrypt-based encryption," \ "supported only from Xtrabackup 2.1.4" if [ -z "$ekey" ]; then ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'" @@ -342,40 +345,34 @@ get_transfer() CN_option=",commonname=''" if [ $encrypt -eq 2 ]; then - wsrep_log_info "Using openssl based encryption with socat: with crt and pem" - if [ -z "$tpem" -o -z "$tcert" ]; then + wsrep_log_info \ + "Using openssl based encryption with socat: with crt and pem" + if [ -z "$tpem" -o -z "$tcert$tcap" ]; then wsrep_log_error \ "Both PEM file and CRT file (or path) are required" exit 22 fi - if [ ! -r "$tpem" -o ! -r "$tcert" ]; then - wsrep_log_error \ - "Both PEM file and CRT file (or path) must be readable" - exit 22 + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" + tcmd="$tcmd,cert='$tpem'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',capath='$tcert'" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" fi stagemsg="$stagemsg-OpenSSL-Encrypted-2" - wsrep_log_info "$action with cert=$tpem, ca=$tcert" + wsrep_log_info "$action with cert='$tpem', ca='$tcert', capath='$tcap'" elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then - wsrep_log_info "Using openssl based encryption with socat: with key and crt" + wsrep_log_info \ + "Using openssl based encryption with socat: with key and crt" if [ -z "$tpem" -o -z "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file are required" - exit 22 - fi - if [ ! -r "$tpem" -o ! -r "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file must be readable" + wsrep_log_error "Both the certificate file (or path) and" \ + "the key file are required" exit 22 fi verify_cert_matches_key "$tpem" "$tkey" stagemsg="$stagemsg-OpenSSL-Encrypted-3" - if [ -z "$tcert" ]; then + if [ -z "$tcert$tcap" ]; then if [ $encrypt -eq 4 ]; then wsrep_log_error \ "Peer certificate file (or path) required if encrypt=4" @@ -384,14 +381,11 @@ get_transfer() # no verification CN_option="" tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0" - wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0" + wsrep_log_info \ + "$action with cert='$tpem', key='$tkey', verify=0" else # CA verification - if [ ! -r "$tcert" ]; then - wsrep_log_error "Certificate file or path must be readable" - exit 22 - fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' -o $encrypt -eq 4 ] @@ -402,12 +396,15 @@ get_transfer() else CN_option=",commonname='$WSREP_SST_OPT_HOST_UNESCAPED'" fi - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',key='$tkey',capath='$tcert'" + tcmd="$tcmd,cert='$tpem',key='$tkey'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - wsrep_log_info "$action with cert=$tpem, key=$tkey, ca=$tcert" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" + fi + wsrep_log_info "$action with cert='$tpem', key='$tkey'," \ + "ca='$tcert', capath='$tcap'" fi else wsrep_log_info "Unknown encryption mode: encrypt=$encrypt" @@ -425,7 +422,9 @@ get_transfer() get_footprint() { pushd "$WSREP_SST_OPT_DATA" 1>/dev/null - payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }') + payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' \ + -type f -print0 | du --files0-from=- --block-size=1 -c -s | \ + awk 'END { print $1 }') if [ "$compress" != 'none' ]; then # QuickLZ has around 50% compression ratio # When compression/compaction used, the progress is only an approximate. @@ -438,7 +437,7 @@ get_footprint() adjust_progress() { - if [ -z "$(command -v pv)" ]; then + if [ -z "$(commandex pv)" ]; then wsrep_log_error "pv not found in path: $PATH" wsrep_log_error "Disabling all progress/rate-limiting" pcmd="" @@ -470,33 +469,42 @@ check_server_ssl_config() { # backward-compatible behavior: tcert=$(parse_cnf 'sst' 'tca') + tcap=$(parse_cnf 'sst' 'tcapath') tpem=$(parse_cnf 'sst' 'tcert') tkey=$(parse_cnf 'sst' 'tkey') # reading new ssl configuration options: local tcert2=$(parse_cnf "$encgroups" 'ssl-ca') + local tcap2=$(parse_cnf "$encgroups" 'ssl-capath') local tpem2=$(parse_cnf "$encgroups" 'ssl-cert') local tkey2=$(parse_cnf "$encgroups" 'ssl-key') # if there are no old options, then we take new ones: - if [ -z "$tcert" -a -z "$tpem" -a -z "$tkey" ]; then + if [ -z "$tcert" -a -z "$tcap" -a -z "$tpem" -a -z "$tkey" ]; then tcert="$tcert2" + tcap="$tcap2" tpem="$tpem2" tkey="$tkey2" # checking for presence of the new-style SSL configuration: - elif [ -n "$tcert2" -o -n "$tpem2" -o -n "$tkey2" ]; then + elif [ -n "$tcert2" -o -n "$tcap2" -o -n "$tpem2" -o -n "$tkey2" ]; then if [ "$tcert" != "$tcert2" -o \ + "$tcap" != "$tcap2" -o \ "$tpem" != "$tpem2" -o \ "$tkey" != "$tkey2" ] then - wsrep_log_info "new ssl configuration options (ssl-ca, ssl-cert " \ - "and ssl-key) are ignored by SST due to presence " \ - "of the tca, tcert and/or tkey in the [sst] section" + wsrep_log_info \ + "new ssl configuration options (ssl-ca[path], ssl-cert" \ + "and ssl-key) are ignored by SST due to presence" \ + "of the tca[path], tcert and/or tkey in the [sst] section" fi fi if [ -n "$tcert" ]; then - tcert=$(trim_string "$tcert") - if [ "${tcert%/}" != "$tcert" ]; then - tpath=1 - fi + tcert=$(trim_string "$tcert") + if [ "${tcert%/}" != "$tcert" ] || [ -d "$tcert" ]; then + tcap="$tcert" + tcert="" + fi + fi + if [ -n "$tcap" ]; then + tcap=$(trim_string "$tcap") fi } @@ -506,10 +514,10 @@ read_cnf() tfmt=$(parse_cnf sst transferfmt 'socat') encrypt=$(parse_cnf "$encgroups" 'encrypt' 0) - tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) + tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | \ + tr [:lower:] [:upper:]) - if [ $encrypt -eq 0 -o $encrypt -ge 2 ] - then + if [ $encrypt -eq 0 -o $encrypt -ge 2 ]; then if [ "$tmode" != 'DISABLED' -o $encrypt -ge 2 ]; then check_server_ssl_config fi @@ -517,11 +525,13 @@ read_cnf() if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] then encrypt=3 # enable cert/key SSL encyption - # avoid CA verification if not set explicitly: - # nodes may happen to have different CA if self-generated - # zeroing up tcert does the trick - [ "${tmode#VERIFY}" != "$tmode" ] || tcert="" + # nodes may happen to have different CA if self-generated, + # zeroing up tcert and tcap does the trick: + if [ "${tmode#VERIFY}" = "$tmode" ]; then + tcert="" + tcap="" + fi fi fi elif [ $encrypt -eq 1 ]; then @@ -535,8 +545,9 @@ read_cnf() fi fi - wsrep_log_info "SSL configuration: CA='$tcert', CERT='$tpem'," \ - "KEY='$tkey', MODE='$tmode', encrypt='$encrypt'" + wsrep_log_info "SSL configuration: CA='$tcert', CAPATH='$tcap'," \ + "CERT='$tpem', KEY='$tkey', MODE='$tmode'," \ + "encrypt='$encrypt'" sockopt=$(parse_cnf sst sockopt "") progress=$(parse_cnf sst progress "") @@ -561,7 +572,8 @@ read_cnf() sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir '/tmp/sst_log_archive') if [ $speciald -eq 0 ]; then - wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1" + wsrep_log_error \ + "sst-special-dirs equal to 0 is not supported, falling back to 1" speciald=1 fi @@ -589,7 +601,7 @@ get_stream() { if [ "$sfmt" = 'mbstream' -o "$sfmt" = 'xbstream' ]; then sfmt='mbstream' - STREAM_BIN="$(command -v mbstream)" + local STREAM_BIN=$(commandex "$sfmt") if [ -z "$STREAM_BIN" ]; then wsrep_log_error "Streaming with $sfmt, but $sfmt not found in path" exit 42 @@ -621,7 +633,7 @@ cleanup_at_exit() # Since this is invoked just after exit NNN local estatus=$? if [ $estatus -ne 0 ]; then - wsrep_log_error "Cleanup after exit with status:$estatus" + wsrep_log_error "Cleanup after exit with status: $estatus" fi if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then @@ -630,7 +642,8 @@ cleanup_at_exit() else if [ -n "$BACKUP_PID" ]; then if check_pid "$BACKUP_PID" 1; then - wsrep_log_error "mariabackup process is still running. Killing..." + wsrep_log_error \ + "mariabackup process is still running. Killing..." cleanup_pid $CHECK_PID "$BACKUP_PID" fi fi @@ -638,8 +651,8 @@ cleanup_at_exit() fi if [ -n "$progress" -a -p "$progress" ]; then - wsrep_log_info "Cleaning up fifo file $progress" - rm -f "$progress" || true + wsrep_log_info "Cleaning up fifo file: $progress" + rm -f "$progress" || : fi wsrep_log_info "Cleaning up temporary directories" @@ -649,8 +662,8 @@ cleanup_at_exit() [ -d "$STATDIR" ] && rm -rf "$STATDIR" fi else - [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true - [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true + [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || : + [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || : fi # Final cleanup @@ -662,7 +675,7 @@ cleanup_at_exit() # This means a signal was delivered to the process. # So, more cleanup. if [ $estatus -ge 128 ]; then - kill -KILL -- -$$ || true + kill -KILL -- -$$ || : fi fi @@ -738,7 +751,7 @@ recv_joiner() local ltcmd="$tcmd" if [ $tmt -gt 0 ]; then - if [ -n "$(command -v timeout)" ]; then + if [ -n "$(commandex timeout)" ]; then if timeout --help | grep -qw -- '-k'; then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" else @@ -760,14 +773,14 @@ recv_joiner() popd 1>/dev/null if [ ${RC[0]} -eq 124 ]; then - wsrep_log_error "Possible timeout in receiving first data from " \ + wsrep_log_error "Possible timeout in receiving first data from" \ "donor in gtid stage: exit codes: ${RC[@]}" exit 32 fi for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while getting data from donor node: " \ + wsrep_log_error "Error while getting data from donor node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -776,7 +789,7 @@ recv_joiner() if [ $checkf -eq 1 ]; then if [ ! -r "$MAGIC_FILE" ]; then # this message should cause joiner to abort - wsrep_log_error "receiving process ended without creating " \ + wsrep_log_error "receiving process ended without creating" \ "'$MAGIC_FILE'" wsrep_log_info "Contents of datadir" wsrep_log_info $(ls -l "$dir/"*) @@ -784,10 +797,11 @@ recv_joiner() fi # check donor supplied secret - SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | \ + cut -d ' ' -f 2) if [ "$SECRET" != "$MY_SECRET" ]; then wsrep_log_error "Donor does not know my secret!" - wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'" exit 32 fi @@ -810,7 +824,7 @@ send_donor() for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while sending data to joiner node: " \ + wsrep_log_error "Error while sending data to joiner node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -823,7 +837,9 @@ monitor_process() while true ; do if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1; then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error \ + "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." kill -- -"$WSREP_SST_OPT_PARENT" exit 32 fi @@ -845,7 +861,7 @@ read_cnf setup_ports if "$BACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then - disver='--no-version-check' + disver=' --no-version-check' fi # if no command line argument and INNODB_DATA_HOME_DIR environment variable @@ -867,7 +883,7 @@ INNODB_DATA_HOME_DIR=$(pwd -P) cd "$OLD_PWD" if [ $ssyslog -eq 1 ]; then - if [ -n "$(command -v logger)" ]; then + if [ -n "$(commandex logger)" ]; then wsrep_log_info "Logging all stderr of SST/mariabackup to syslog" exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE) @@ -898,10 +914,8 @@ else fi fi - if [ -e "$INNOAPPLYLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOAPPLYLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOAPPLYLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -912,10 +926,8 @@ else gzip "$newfile" fi - if [ -e "$INNOMOVELOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOMOVELOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOMOVELOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -926,10 +938,8 @@ else gzip "$newfile" fi - if [ -e "$INNOBACKUPLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOBACKUPLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOBACKUPLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -949,15 +959,15 @@ setup_commands() { local mysqld_args="" if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then - mysqld_args="--mysqld-args $WSREP_SST_OPT_MYSQLD" + mysqld_args=" --mysqld-args $WSREP_SST_OPT_MYSQLD" fi - if [ -z "$INNODB_FORCE_RECOVERY" ]; then - INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" - else - INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --innodb-force-recovery=$INNODB_FORCE_RECOVERY --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" + local recovery="" + if [ -n "$INNODB_FORCE_RECOVERY" ]; then + recovery=" --innodb-force-recovery=$INNODB_FORCE_RECOVERY" fi - INNOMOVE="$BACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" - INNOBACKUP="$BACKUP_BIN $WSREP_SST_OPT_CONF --backup $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA' $mysqld_args $INNOBACKUP" + INNOAPPLY="$BACKUP_BIN --prepare$disver$recovery${iapts:+ }$iapts$INNOEXTRA --target-dir='$DATA' --datadir='$DATA'$mysqld_args $INNOAPPLY" + INNOMOVE="$BACKUP_BIN$WSREP_SST_OPT_CONF --move-back$disver${impts:+ }$impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" + INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF --backup$disver${iopts:+ }$iopts $tmpopts$INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA'$mysqld_args $INNOBACKUP" } get_stream @@ -1055,27 +1065,28 @@ then tcmd="$ecmd | $tcmd" fi - iopts="--databases-exclude='lost+found' $iopts" + iopts="--databases-exclude='lost+found'${iopts:+ }$iopts" if [ ${FORCE_FTWRL:-0} -eq 1 ]; then - wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" - iopts="--no-backup-locks $iopts" + wsrep_log_info "Forcing FTWRL due to environment variable" \ + "FORCE_FTWRL equal to $FORCE_FTWRL" + iopts="--no-backup-locks${iopts:+ }$iopts" fi # if compression is enabled for backup files, then add the # appropriate options to the mariabackup command line: if [ "$compress" != 'none' ]; then - iopts="--compress${compress:+=$compress} $iopts" + iopts="--compress${compress:+=$compress}${iopts:+ }$iopts" if [ -n "$compress_threads" ]; then - iopts="--compress-threads=$compress_threads $iopts" + iopts="--compress-threads=$compress_threads${iopts:+ }$iopts" fi if [ -n "$compress_chunk" ]; then - iopts="--compress-chunk-size=$compress_chunk $iopts" + iopts="--compress-chunk-size=$compress_chunk${iopts:+ }$iopts" fi fi if [ -n "$backup_threads" ]; then - iopts="--parallel=$backup_threads $iopts" + iopts="--parallel=$backup_threads${iopts:+ }$iopts" fi setup_commands @@ -1084,7 +1095,7 @@ then set -e if [ ${RC[0]} -ne 0 ]; then - wsrep_log_error "mariabackup finished with error: ${RC[0]}. " \ + wsrep_log_error "mariabackup finished with error: ${RC[0]}." \ "Check syslog or '$INNOBACKUPLOG' for details" exit 22 elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then @@ -1125,7 +1136,8 @@ then elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ] then - [ -e "$SST_PROGRESS_FILE" ] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" + [ -e "$SST_PROGRESS_FILE" ] && \ + wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" [ -n "$SST_PROGRESS_FILE" ] && touch "$SST_PROGRESS_FILE" ib_home_dir="$INNODB_DATA_HOME_DIR" @@ -1146,7 +1158,7 @@ then ib_undo_dir="$INNODB_UNDO_DIR" if [ -n "$backup_threads" ]; then - impts="--parallel=$backup_threads $impts" + impts="--parallel=$backup_threads${impts:+ }$impts" fi stagemsg='Joiner-Recv' @@ -1165,15 +1177,15 @@ then ADDR="$WSREP_SST_OPT_ADDR" - if [ "${tmode#VERIFY}" != "$tmode" ] - then # backward-incompatible behavior + if [ "${tmode#VERIFY}" != "$tmode" ]; then + # backward-incompatible behavior: CN="" - if [ -n "$tpem" ] - then + if [ -n "$tpem" ]; then # find out my Common Name get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error 'openssl not found but it is required for authentication' + wsrep_log_error \ + 'openssl not found but it is required for authentication' exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ @@ -1213,15 +1225,17 @@ then if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1 then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." exit 32 fi - if [ ! -r "$STATDIR/$IST_FILE" ] - then + if [ ! -r "$STATDIR/$IST_FILE" ]; then if [ -d "$DATA/.sst" ]; then - wsrep_log_info "WARNING: Stale temporary SST directory: '$DATA/.sst' from previous state transfer. Removing" + wsrep_log_info \ + "WARNING: Stale temporary SST directory:" \ + "'$DATA/.sst' from previous state transfer, removing..." rm -rf "$DATA/.sst" fi mkdir -p "$DATA/.sst" @@ -1229,17 +1243,20 @@ then jpid=$! wsrep_log_info "Proceeding with SST" - wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories" + wsrep_log_info \ + "Cleaning the existing datadir and innodb-data/log directories" if [ "$OS" = 'FreeBSD' ]; then find -E ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ else find ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ fi get_binlog @@ -1248,9 +1265,9 @@ then binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") cd "$binlog_dir" wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" - rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || : [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ - rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || : cd "$OLD_PWD" fi @@ -1262,7 +1279,8 @@ then monitor_process $jpid if [ ! -s "$DATA/xtrabackup_checkpoints" ]; then - wsrep_log_error "xtrabackup_checkpoints missing, failed mariabackup/SST on donor" + wsrep_log_error "xtrabackup_checkpoints missing," \ + "failed mariabackup/SST on donor" exit 2 fi @@ -1277,7 +1295,7 @@ then if [ -n "$qpfiles" ]; then wsrep_log_info "Compressed qpress files found" - if [ -z "$(command -v qpress)" ]; then + if [ -z "$(commandex qpress)" ]; then wsrep_log_error "qpress utility not found in the path" exit 22 fi @@ -1300,14 +1318,17 @@ then # Decompress the qpress files wsrep_log_info "Decompression with $nproc threads" - timeit "Joiner-Decompression" "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" + timeit "Joiner-Decompression" \ + "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" extcode=$? if [ $extcode -eq 0 ]; then wsrep_log_info "Removing qpress files after decompression" find "$DATA" -type f -name '*.qp' -delete if [ $? -ne 0 ]; then - wsrep_log_error "Something went wrong with deletion of qpress files. Investigate" + wsrep_log_error \ + "Something went wrong with deletion of qpress files." \ + "Investigate" fi else wsrep_log_error "Decompression failed. Exit code: $extcode" @@ -1321,7 +1342,7 @@ then BINLOG_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG") # To avoid comparing data directory and BINLOG_DIRNAME - mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || true + mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || : cd "$BINLOG_DIRNAME" for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do @@ -1336,7 +1357,8 @@ then timeit "mariabackup prepare stage" "$INNOAPPLY" if [ $? -ne 0 ]; then - wsrep_log_error "mariabackup apply finished with errors. Check syslog or '$INNOAPPLYLOG' for details" + wsrep_log_error "mariabackup apply finished with errors." \ + "Check syslog or '$INNOAPPLYLOG' for details." exit 22 fi diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index 798bee1ac10..bed2cac0a9a 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -19,7 +19,6 @@ # This is a reference script for mysqldump-based state snapshot tansfer . $(dirname "$0")/wsrep_sst_common -PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin EINVAL=22 @@ -93,8 +92,7 @@ DROP PREPARE stmt;" SET_START_POSITION="SET GLOBAL wsrep_start_position='$WSREP_SST_OPT_GTID';" SET_WSREP_GTID_DOMAIN_ID="" -if [ -n $WSREP_SST_OPT_GTID_DOMAIN_ID ] -then +if [ -n $WSREP_SST_OPT_GTID_DOMAIN_ID ]; then SET_WSREP_GTID_DOMAIN_ID=" SET @val = (SELECT GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME = 'WSREP_GTID_STRICT_MODE' AND GLOBAL_VALUE > 0); SET @stmt = IF (@val IS NOT NULL, 'SET GLOBAL WSREP_GTID_DOMAIN_ID=$WSREP_SST_OPT_GTID_DOMAIN_ID', 'SET @dummy = 0'); @@ -103,7 +101,7 @@ then DROP PREPARE stmt;" fi -MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF_UNQUOTED "\ +MYSQL="$MYSQL_CLIENT$WSREP_SST_OPT_CONF_UNQUOTED "\ "$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\ "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" @@ -125,8 +123,7 @@ SET_GTID_BINLOG_STATE="" SQL_LOG_BIN_OFF="" # Safety check -if [ ${SERVER_VERSION%%.*} -gt 5 ] -then +if [ ${SERVER_VERSION%%.*} -gt 5 ]; then # If binary logging is enabled on the joiner node, we need to copy donor's # gtid_binlog_state to joiner. In order to do that, a RESET MASTER must be # executed to erase binary logs (if any). Binary logging should also be @@ -140,7 +137,7 @@ then fi # NOTE: we don't use --routines here because we're dumping mysql.proc table -MYSQLDUMP="$MYSQLDUMP $WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \ +MYSQLDUMP="$MYSQLDUMP$WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \ --add-drop-database --add-drop-table --skip-add-locks --create-options \ --disable-keys --extended-insert --skip-lock-tables --quick --set-charset \ --skip-comments --flush-privileges --all-databases --events" diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 29c9cd43470..b0cc8cb3066 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -25,9 +25,6 @@ STUNNEL_REAL_PID=0 # stunnel process id OS="$(uname)" [ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH -# Setting the path for lsof on CentOS -export PATH="/usr/sbin:/sbin:$PATH" - . $(dirname "$0")/wsrep_sst_common wsrep_check_datadir @@ -37,7 +34,8 @@ cleanup_joiner() { local failure=0 - wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID, stunnel PID=$STUNNEL_REAL_PID" + wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID," \ + "stunnel PID=$STUNNEL_REAL_PID" if [ -n "$STUNNEL" ]; then if cleanup_pid $STUNNEL_REAL_PID "$STUNNEL_PID" "$STUNNEL_CONF"; then @@ -87,7 +85,7 @@ check_pid_and_port() if [ $lsof_available -ne 0 ]; then port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \ - grep -F '(LISTEN)') + grep -F '(LISTEN)') echo "$port_info" | \ grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1 else @@ -124,7 +122,7 @@ check_pid_and_port() fi if ! check_port "$pid" "$port" "$utils"; then - wsrep_log_error "rsync or stunnel daemon port '$port' " \ + wsrep_log_error "rsync or stunnel daemon port '$port'" \ "has been taken by another program" exit 16 # EBUSY fi @@ -223,6 +221,7 @@ FILTER="-f '- /lost+found' SSTKEY=$(parse_cnf 'sst' 'tkey') SSTCERT=$(parse_cnf 'sst' 'tcert') SSTCA=$(parse_cnf 'sst' 'tca') +SSTCAP=$(parse_cnf 'sst' 'tcapath') SST_SECTIONS="--mysqld|sst" @@ -231,28 +230,34 @@ check_server_ssl_config() SSTKEY=$(parse_cnf "$SST_SECTIONS" 'ssl-key') SSTCERT=$(parse_cnf "$SST_SECTIONS" 'ssl-cert') SSTCA=$(parse_cnf "$SST_SECTIONS" 'ssl-ca') + SSTCAP=$(parse_cnf "$SST_SECTIONS" 'ssl-capath') } SSLMODE=$(parse_cnf "$SST_SECTIONS" 'ssl-mode' | tr [:lower:] [:upper:]) # no old-style SSL config in [sst], check for new one: -if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]; then +if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" -a -z "$SSTCAP" ]; then check_server_ssl_config fi -SSTPATH=0 if [ -n "$SSTCA" ]; then - SSTCA=$(trim_string "$SSTCA") - if [ "${SSTCA%/}" != "$SSTCA" ]; then - SSTPATH=1 - fi + SSTCA=$(trim_string "$SSTCA") + if [ "${SSTCA%/}" != "$SSTCA" ] || [ -d "$SSTCA" ]; then + SSTCAP="$SSTCA" + SSTCA="" + fi +fi + +if [ -n "$SSTCAP" ]; then + SSTCAP=$(trim_string "$SSTCAP") fi if [ -z "$SSLMODE" ]; then # Implicit verification if CA is set and the SSL mode # is not specified by user: - if [ -n "$SSTCA" ]; then - if [ -n "$(command -v stunnel)" ]; then + if [ -n "$SSTCA$SSTCAP" ]; then + STUNNEL_BIN=$(commandex 'stunnel') + if [ -n "$STUNNEL_BIN" ]; then SSLMODE='VERIFY_CA' fi # Require SSL by default if SSL key and cert are present: @@ -265,17 +270,18 @@ if [ -n "$SSTCERT" -a -n "$SSTKEY" ]; then verify_cert_matches_key "$SSTCERT" "$SSTKEY" fi -if [ -n "$SSTCA" ]; then - if [ $SSTPATH -eq 0 ]; then +CAFILE_OPT="" +CAPATH_OPT="" +if [ -n "$SSTCA$SSTCAP" ]; then + if [ -n "$SSTCA" ]; then CAFILE_OPT="CAfile = $SSTCA" - else - CAFILE_OPT="CApath = $SSTCA" + fi + if [ -n "$SSTCAP" ]; then + CAPATH_OPT="CApath = $SSTCAP" fi if [ -n "$SSTCERT" ]; then - verify_ca_matches_cert "$SSTCA" "$SSTCERT" $SSTPATH + verify_ca_matches_cert "$SSTCERT" "$SSTCA" "$SSTCAP" fi -else - CAFILE_OPT="" fi VERIFY_OPT="" @@ -295,7 +301,7 @@ then exit 22 # EINVAL ;; esac - if [ -z "$SSTCA" ]; then + if [ -z "$SSTCA$SSTCAP" ]; then wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file or path" exit 22 # EINVAL fi @@ -318,9 +324,12 @@ fi STUNNEL="" if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ]; then - STUNNEL_BIN="$(command -v stunnel)" + if [ -z "${STUNNEL_BIN+x}" ]; then + STUNNEL_BIN=$(commandex 'stunnel') + fi if [ -n "$STUNNEL_BIN" ]; then - wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA', ssl-mode='$SSLMODE'" + wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA'," \ + "CAPATH='$SSTCAP', ssl-mode='$SSLMODE'" STUNNEL="$STUNNEL_BIN $STUNNEL_CONF" fi fi @@ -340,6 +349,7 @@ then key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -392,8 +402,8 @@ EOF # Prepare binlog files cd "$BINLOG_DIRNAME" - binlog_files_full=$(tail -n $BINLOG_N_FILES "$WSREP_SST_OPT_BINLOG_INDEX") - + binlog_files_full=$(tail -n $BINLOG_N_FILES \ + "$WSREP_SST_OPT_BINLOG_INDEX") binlog_files="" for ii in $binlog_files_full do @@ -417,9 +427,10 @@ EOF WHOLE_FILE_OPT="--whole-file" fi - # first, the normal directories, so that we can detect incompatible protocol + # first, the normal directories, so that we can detect + # incompatible protocol: RC=0 - eval rsync ${STUNNEL:+"'--rsh=$STUNNEL'"} \ + eval rsync ${STUNNEL:+"--rsh='$STUNNEL'"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ $WHOLE_FILE_OPT $FILTER "'$WSREP_SST_OPT_DATA/'" \ @@ -430,8 +441,9 @@ EOF case $RC in 12) RC=71 # EPROTO wsrep_log_error \ - "rsync server on the other end has incompatible protocol. " \ - "Make sure you have the same version of rsync on all nodes." + "rsync server on the other end has incompatible" \ + "protocol. Make sure you have the same version of" \ + "rsync on all nodes." ;; 22) RC=12 # ENOMEM ;; @@ -481,9 +493,9 @@ EOF find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \ -not -name '.zfs' -print0 | xargs -I{} -0 -P $backup_threads \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \ - --owner --group --perms --links --specials \ - --ignore-times --inplace --recursive --delete --quiet \ - $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \ + --owner --group --perms --links --specials --ignore-times \ + --inplace --recursive --delete --quiet $WHOLE_FILE_OPT \ + --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \ --exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/{}/" \ "rsync://$WSREP_SST_OPT_ADDR/{}" >&2 || RC=$? @@ -514,7 +526,8 @@ EOF fi rsync ${STUNNEL:+--rsh="$STUNNEL"} \ - --archive --quiet --checksum "$MAGIC_FILE" "rsync://$WSREP_SST_OPT_ADDR" + --archive --quiet --checksum "$MAGIC_FILE" \ + "rsync://$WSREP_SST_OPT_ADDR" echo "done $STATE" @@ -546,7 +559,8 @@ then check_round=0 while check_pid "$STUNNEL_PID" 1 do - wsrep_log_info "lingering stunnel daemon found at startup, waiting for it to exit" + wsrep_log_info "Lingering stunnel daemon found at startup," \ + "waiting for it to exit" check_round=$(( check_round + 1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "stunnel daemon already running." @@ -563,7 +577,8 @@ then check_round=0 while check_pid "$RSYNC_PID" 1 do - wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit" + wsrep_log_info "Lingering rsync daemon found at startup," \ + "waiting for it to exit" check_round=$(( check_round + 1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "rsync daemon already running." @@ -575,9 +590,7 @@ then [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" [ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE" - if [ -z "$STUNNEL" ]; then - [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" - fi + [ -z "$STUNNEL" ] && [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" ADDR="$WSREP_SST_OPT_ADDR" RSYNC_PORT="$WSREP_SST_OPT_PORT" @@ -628,19 +641,21 @@ EOF echo $$ > "$SST_PID" - if [ -z "$STUNNEL" ] - then - rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & + if [ -z "$STUNNEL" ]; then + rsync --daemon --no-detach --port "$RSYNC_PORT" \ + --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & RSYNC_REAL_PID=$! TRANSFER_REAL_PID=$RSYNC_REAL_PID TRANSFER_PID="$RSYNC_PID" else # Let's check if the path to the config file contains a space? + RSYNC_BIN=$(commandex 'rsync') if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -650,17 +665,18 @@ ${CHECK_OPT} ${CHECK_OPT_LOCAL} [rsync] accept = $STUNNEL_ACCEPT -exec = $(command -v rsync) +exec = $RSYNC_BIN execargs = rsync --server --daemon --config=$RSYNC_CONF . EOF else # The path contains a space, so we will run it via # shell with "eval" command: - export RSYNC_CMD="eval $(command -v rsync) --server --daemon --config='$RSYNC_CONF' ." + export RSYNC_CMD="eval '$RSYNC_BIN' --server --daemon --config='$RSYNC_CONF' ." cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -688,7 +704,8 @@ EOF # find out my Common Name get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error 'openssl not found but it is required for authentication' + wsrep_log_error \ + 'openssl not found but it is required for authentication' exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \ @@ -703,7 +720,8 @@ EOF ADDR="$WSREP_SST_OPT_HOST" fi - until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT" + until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID \ + "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT" do sleep 0.2 done @@ -722,7 +740,7 @@ EOF if ! ps -p $MYSQLD_PID >/dev/null 2>&1 then wsrep_log_error \ - "Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly." + "Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly." kill -- -$MYSQLD_PID sleep 1 exit 32 @@ -768,10 +786,11 @@ EOF if [ -r "$MAGIC_FILE" ]; then if [ -n "$MY_SECRET" ]; then # check donor supplied secret - SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | \ + cut -d ' ' -f 2) if [ "$SECRET" != "$MY_SECRET" ]; then wsrep_log_error "Donor does not know my secret!" - wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'" exit 32 fi # remove secret from the magic file, and output diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 80d1e55f358..a1fc14b9083 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -232,6 +232,12 @@ new_VioSSLFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; long ssl_ctx_options; DBUG_ENTER("new_VioSSLFd"); + + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + DBUG_PRINT("enter", ("key_file: '%s' cert_file: '%s' ca_file: '%s' ca_path: '%s' " "cipher: '%s' crl_file: '%s' crl_path: '%s'", @@ -378,6 +384,11 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + /* Turn off verification of servers certificate if both ca_file and ca_path is set to NULL @@ -410,6 +421,12 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; + + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher, FALSE, error, crl_file, crl_path, tls_version))) From 03678bcf55bf8a813a1d81c021d2ae085750aee2 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Tue, 14 Dec 2021 03:47:59 +0100 Subject: [PATCH 18/52] MDEV-27181: Galera SST scripts should use ssl_capath for CA directory 1. Galera SST scripts should use ssl_capath (not ssl_ca) for CA directory. The current implementation tries to automatically detect the path using the trailing slash in the ssl_ca variable value, but this approach is not compatible with the server configuration. Now, by analogy with the server, SST scripts also use a separate ssl_capath variable. In addition, a similar tcapath variable has been added for the old-style configuration (in the "sst" section). 2. Openssl utility detection made more reliable. 3. Removed extra spaces in automatically generated command lines - to simplify debugging of the SST scripts. 4. In general, the code for detecting the presence or absence of auxiliary utilities has been improved - it is made more reliable in some configurations (and for shells other than bash). --- mysql-test/std_data/capath/3106f582.0 | 1 + mysql-test/std_data/capath/cacert.pem | 79 +++ mysql-test/std_data/capath/ed1f42db.0 | 1 + ..._sst_rsync_encrypt_with_capath,debug.rdiff | 191 +++++++ ...alera_sst_rsync_encrypt_with_capath.result | 520 ++++++++++++++++++ .../galera_sst_rsync_encrypt_with_key.result | 2 - ...alera_sst_rsync_encrypt_with_server.result | 2 - .../galera_sst_mariabackup_table_options.test | 1 + .../galera_sst_rsync_encrypt_with_capath.cnf | 20 + .../galera_sst_rsync_encrypt_with_capath.test | 26 + .../t/galera_sst_rsync_encrypt_with_key.test | 3 - .../galera_sst_rsync_encrypt_with_server.test | 3 - .../t/galera_ipv6_mariabackup.test | 1 + .../t/galera_ipv6_mariabackup_section.test | 1 + scripts/wsrep_sst_common.sh | 142 +++-- scripts/wsrep_sst_mariabackup.sh | 292 +++++----- scripts/wsrep_sst_mysqldump.sh | 11 +- scripts/wsrep_sst_rsync.sh | 117 ++-- vio/viosslfactories.c | 17 + 19 files changed, 1172 insertions(+), 258 deletions(-) create mode 120000 mysql-test/std_data/capath/3106f582.0 create mode 100644 mysql-test/std_data/capath/cacert.pem create mode 120000 mysql-test/std_data/capath/ed1f42db.0 create mode 100644 mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath,debug.rdiff create mode 100644 mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test diff --git a/mysql-test/std_data/capath/3106f582.0 b/mysql-test/std_data/capath/3106f582.0 new file mode 120000 index 00000000000..1310cfcff20 --- /dev/null +++ b/mysql-test/std_data/capath/3106f582.0 @@ -0,0 +1 @@ +cacert.pem \ No newline at end of file diff --git a/mysql-test/std_data/capath/cacert.pem b/mysql-test/std_data/capath/cacert.pem new file mode 100644 index 00000000000..23dda2318e1 --- /dev/null +++ b/mysql-test/std_data/capath/cacert.pem @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + d0:4d:23:85:ee:59:b3:fa + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Validity + Not Before: Jan 27 10:11:10 2019 GMT + Not After : Jan 22 10:11:10 2039 GMT + Subject: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e8:0e:a7:84:d3:75:30:06:30:b2:10:b9:d1:88: + 36:2b:5e:f8:c8:44:57:cb:67:72:ab:96:95:33:d5: + 88:d1:8f:23:50:98:ba:6d:20:00:80:bd:35:d5:c1: + bf:98:49:c4:0a:15:4a:34:a6:21:9b:2e:8c:15:09: + f0:63:81:02:c2:7c:e2:53:e0:f7:a1:1a:40:5e:8f: + 41:4a:4c:56:d4:20:f1:d5:a7:c1:53:2e:ff:7e:37: + 17:cc:7e:74:bd:e2:22:33:ce:8c:77:62:a4:c5:3f: + 44:35:7b:7e:b9:f5:7d:8c:7a:27:58:fd:2c:42:86: + 2e:e7:6b:01:99:7b:fe:7d:a7:a1:4f:3e:39:39:54: + 1f:61:de:74:66:d1:77:4f:43:1b:66:70:29:85:de: + fc:8f:8e:1b:7b:a2:66:48:26:7f:9b:a6:fd:4a:e4: + dc:eb:ed:bd:f8:e3:f1:57:98:13:6f:f1:a3:2a:e3: + 73:bd:8d:7c:6f:4b:59:35:bc:b5:42:3e:99:a7:13: + 8d:be:2e:5c:9a:c6:5b:ab:ae:bf:00:e9:c8:ee:05: + 22:8e:d5:67:1a:47:9a:6d:9c:f9:42:3e:15:34:f8: + 31:ec:b4:7e:d3:92:95:b0:b8:f9:66:f3:bd:1d:31: + 2c:b1:90:62:a1:f8:4e:a6:5d:26:22:f0:e1:fe:16: + 2b:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + X509v3 Authority Key Identifier: + keyid:CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + df:fd:74:29:5b:5e:9a:8b:09:02:40:59:73:cb:71:47:3f:97: + 3d:a9:fd:c4:8c:01:29:c9:86:b8:71:55:ff:72:0e:50:dc:c8: + b5:e6:91:41:52:47:21:30:cc:4d:e7:3b:4b:db:55:ea:7d:46: + eb:53:e0:b7:1b:80:7c:b1:0c:d3:d1:bc:a0:73:ae:96:1f:fd: + 05:52:7e:54:d5:03:52:69:7b:34:5f:27:d7:98:da:98:76:73: + e6:bb:50:59:2a:94:90:67:03:1c:a4:76:2f:ee:ef:59:60:09: + 48:33:03:2b:52:ed:83:42:f8:71:19:7f:d8:be:40:ed:20:01: + 90:3c:7e:1c:8b:d2:9f:f3:2f:09:1f:50:c8:10:e1:8a:d9:a5: + 49:9c:0b:74:17:b9:2b:68:f6:1e:73:c2:73:10:38:b3:35:e2: + 87:91:1b:a1:d1:9b:81:9d:1b:32:cc:03:6e:4c:82:95:81:11: + 42:56:e2:16:2b:22:65:db:40:2c:ca:dc:03:f4:d5:07:cf:f5: + 13:b2:cf:51:5b:24:cd:c7:d1:9b:42:8e:f9:df:5d:1e:5a:09: + a3:4f:a9:0b:f4:21:c5:bb:ff:02:93:67:e8:2d:ee:ab:d9:59: + 76:03:2c:a1:bd:fb:dc:af:b6:82:94:71:85:53:a8:18:0d:3a: + 9e:42:eb:59 +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIJANBNI4XuWbP6MA0GCSqGSIb3DQEBCwUAMFYxDzANBgNV +BAMMBmNhY2VydDELMAkGA1UEBhMCRkkxETAPBgNVBAgMCEhlbHNpbmtpMREwDwYD +VQQHDAhIZWxzaW5raTEQMA4GA1UECgwHTWFyaWFEQjAeFw0xOTAxMjcxMDExMTBa +Fw0zOTAxMjIxMDExMTBaMFYxDzANBgNVBAMMBmNhY2VydDELMAkGA1UEBhMCRkkx +ETAPBgNVBAgMCEhlbHNpbmtpMREwDwYDVQQHDAhIZWxzaW5raTEQMA4GA1UECgwH +TWFyaWFEQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOgOp4TTdTAG +MLIQudGINite+MhEV8tncquWlTPViNGPI1CYum0gAIC9NdXBv5hJxAoVSjSmIZsu +jBUJ8GOBAsJ84lPg96EaQF6PQUpMVtQg8dWnwVMu/343F8x+dL3iIjPOjHdipMU/ +RDV7frn1fYx6J1j9LEKGLudrAZl7/n2noU8+OTlUH2HedGbRd09DG2ZwKYXe/I+O +G3uiZkgmf5um/Urk3Ovtvfjj8VeYE2/xoyrjc72NfG9LWTW8tUI+macTjb4uXJrG +W6uuvwDpyO4FIo7VZxpHmm2c+UI+FTT4Mey0ftOSlbC4+WbzvR0xLLGQYqH4TqZd +JiLw4f4WK2kCAwEAAaNQME4wHQYDVR0OBBYEFMpxmYnwcqt1ZrtlagMEcqV7laaT +MB8GA1UdIwQYMBaAFMpxmYnwcqt1ZrtlagMEcqV7laaTMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBAN/9dClbXpqLCQJAWXPLcUc/lz2p/cSMASnJhrhx +Vf9yDlDcyLXmkUFSRyEwzE3nO0vbVep9RutT4LcbgHyxDNPRvKBzrpYf/QVSflTV +A1JpezRfJ9eY2ph2c+a7UFkqlJBnAxykdi/u71lgCUgzAytS7YNC+HEZf9i+QO0g +AZA8fhyL0p/zLwkfUMgQ4YrZpUmcC3QXuSto9h5zwnMQOLM14oeRG6HRm4GdGzLM +A25MgpWBEUJW4hYrImXbQCzK3AP01QfP9ROyz1FbJM3H0ZtCjvnfXR5aCaNPqQv0 +IcW7/wKTZ+gt7qvZWXYDLKG9+9yvtoKUcYVTqBgNOp5C61k= +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/capath/ed1f42db.0 b/mysql-test/std_data/capath/ed1f42db.0 new file mode 120000 index 00000000000..1310cfcff20 --- /dev/null +++ b/mysql-test/std_data/capath/ed1f42db.0 @@ -0,0 +1 @@ +cacert.pem \ No newline at end of file diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath,debug.rdiff b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath,debug.rdiff new file mode 100644 index 00000000000..59417d4d6e4 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath,debug.rdiff @@ -0,0 +1,191 @@ +--- r/galera_sst_rsync_encrypt_with_server.result ++++ r/galera_sst_rsync_encrypt_with_server,debug.reject +@@ -519,4 +519,188 @@ + 1 + DROP TABLE t1; + COMMIT; ++Performing State Transfer on a server that has been killed and restarted ++while a DDL was in progress on it ++connection node_1; ++CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 VALUES (1,'node1_committed_before'); ++INSERT INTO t1 VALUES (2,'node1_committed_before'); ++INSERT INTO t1 VALUES (3,'node1_committed_before'); ++INSERT INTO t1 VALUES (4,'node1_committed_before'); ++INSERT INTO t1 VALUES (5,'node1_committed_before'); ++connection node_2; ++START TRANSACTION; ++INSERT INTO t1 VALUES (6,'node2_committed_before'); ++INSERT INTO t1 VALUES (7,'node2_committed_before'); ++INSERT INTO t1 VALUES (8,'node2_committed_before'); ++INSERT INTO t1 VALUES (9,'node2_committed_before'); ++INSERT INTO t1 VALUES (10,'node2_committed_before'); ++COMMIT; ++SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; ++connection node_1; ++ALTER TABLE t1 ADD COLUMN f2 INTEGER; ++connection node_2; ++SET wsrep_sync_wait = 0; ++Killing server ... ++connection node_1; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (11,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (12,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (13,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (14,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (15,'node1_committed_during'); ++COMMIT; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (16,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (17,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (18,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (19,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (20,'node1_to_be_committed_after'); ++connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (21,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (22,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (23,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (24,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (25,'node1_to_be_rollbacked_after'); ++connection node_2; ++Performing --wsrep-recover ... ++connection node_2; ++Starting server ... ++Using --wsrep-start-position when starting mysqld ... ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (26,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (27,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (28,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (29,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (30,'node2_committed_after'); ++COMMIT; ++connection node_1; ++INSERT INTO t1 (id,f1) VALUES (31,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (32,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (33,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (34,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (35,'node1_to_be_committed_after'); ++COMMIT; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (36,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (37,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (38,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (39,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (40,'node1_committed_after'); ++COMMIT; ++connection node_1a_galera_st_kill_slave_ddl; ++INSERT INTO t1 (id,f1) VALUES (41,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (42,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (43,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (44,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (45,'node1_to_be_rollbacked_after'); ++ROLLBACK; ++SET AUTOCOMMIT=ON; ++SET SESSION wsrep_sync_wait=15; ++SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; ++EXPECT_3 ++3 ++SELECT COUNT(*) AS EXPECT_35 FROM t1; ++EXPECT_35 ++35 ++SELECT * FROM t1; ++id f1 f2 ++1 node1_committed_before NULL ++2 node1_committed_before NULL ++3 node1_committed_before NULL ++4 node1_committed_before NULL ++5 node1_committed_before NULL ++6 node2_committed_before NULL ++7 node2_committed_before NULL ++8 node2_committed_before NULL ++9 node2_committed_before NULL ++10 node2_committed_before NULL ++11 node1_committed_during NULL ++12 node1_committed_during NULL ++13 node1_committed_during NULL ++14 node1_committed_during NULL ++15 node1_committed_during NULL ++16 node1_to_be_committed_after NULL ++17 node1_to_be_committed_after NULL ++18 node1_to_be_committed_after NULL ++19 node1_to_be_committed_after NULL ++20 node1_to_be_committed_after NULL ++26 node2_committed_after NULL ++27 node2_committed_after NULL ++28 node2_committed_after NULL ++29 node2_committed_after NULL ++30 node2_committed_after NULL ++31 node1_to_be_committed_after NULL ++32 node1_to_be_committed_after NULL ++33 node1_to_be_committed_after NULL ++34 node1_to_be_committed_after NULL ++35 node1_to_be_committed_after NULL ++36 node1_committed_after NULL ++37 node1_committed_after NULL ++38 node1_committed_after NULL ++39 node1_committed_after NULL ++40 node1_committed_after NULL ++SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; ++COUNT(*) = 0 ++1 ++COMMIT; ++connection node_1; ++SET AUTOCOMMIT=ON; ++SET SESSION wsrep_sync_wait=15; ++SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; ++EXPECT_3 ++3 ++SELECT COUNT(*) AS EXPECT_35 FROM t1; ++EXPECT_35 ++35 ++SELECT * FROM t1; ++id f1 f2 ++1 node1_committed_before NULL ++2 node1_committed_before NULL ++3 node1_committed_before NULL ++4 node1_committed_before NULL ++5 node1_committed_before NULL ++6 node2_committed_before NULL ++7 node2_committed_before NULL ++8 node2_committed_before NULL ++9 node2_committed_before NULL ++10 node2_committed_before NULL ++11 node1_committed_during NULL ++12 node1_committed_during NULL ++13 node1_committed_during NULL ++14 node1_committed_during NULL ++15 node1_committed_during NULL ++16 node1_to_be_committed_after NULL ++17 node1_to_be_committed_after NULL ++18 node1_to_be_committed_after NULL ++19 node1_to_be_committed_after NULL ++20 node1_to_be_committed_after NULL ++26 node2_committed_after NULL ++27 node2_committed_after NULL ++28 node2_committed_after NULL ++29 node2_committed_after NULL ++30 node2_committed_after NULL ++31 node1_to_be_committed_after NULL ++32 node1_to_be_committed_after NULL ++33 node1_to_be_committed_after NULL ++34 node1_to_be_committed_after NULL ++35 node1_to_be_committed_after NULL ++36 node1_committed_after NULL ++37 node1_committed_after NULL ++38 node1_committed_after NULL ++39 node1_committed_after NULL ++40 node1_committed_after NULL ++SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; ++COUNT(*) = 0 ++1 ++DROP TABLE t1; ++COMMIT; ++SET GLOBAL debug_dbug = $debug_orig; + include/assert_grep.inc [Using stunnel for SSL encryption] diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result new file mode 100644 index 00000000000..be8c845bdcf --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_capath.result @@ -0,0 +1,520 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connection node_1; +Performing State Transfer on a server that has been shut down cleanly and restarted +connection node_1; +CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'node1_committed_before'); +INSERT INTO t1 VALUES (2,'node1_committed_before'); +INSERT INTO t1 VALUES (3,'node1_committed_before'); +INSERT INTO t1 VALUES (4,'node1_committed_before'); +INSERT INTO t1 VALUES (5,'node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (6,'node2_committed_before'); +INSERT INTO t1 VALUES (7,'node2_committed_before'); +INSERT INTO t1 VALUES (8,'node2_committed_before'); +INSERT INTO t1 VALUES (9,'node2_committed_before'); +INSERT INTO t1 VALUES (10,'node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (11,'node1_committed_during'); +INSERT INTO t1 VALUES (12,'node1_committed_during'); +INSERT INTO t1 VALUES (13,'node1_committed_during'); +INSERT INTO t1 VALUES (14,'node1_committed_during'); +INSERT INTO t1 VALUES (15,'node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES (16,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (17,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (18,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (19,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (20,'node1_to_be_committed_after'); +connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (21,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (22,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (23,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (24,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (25,'node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (26,'node2_committed_after'); +INSERT INTO t1 VALUES (27,'node2_committed_after'); +INSERT INTO t1 VALUES (28,'node2_committed_after'); +INSERT INTO t1 VALUES (29,'node2_committed_after'); +INSERT INTO t1 VALUES (30,'node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES (31,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (32,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (33,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (34,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (35,'node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (36,'node1_committed_after'); +INSERT INTO t1 VALUES (37,'node1_committed_after'); +INSERT INTO t1 VALUES (38,'node1_committed_after'); +INSERT INTO t1 VALUES (39,'node1_committed_after'); +INSERT INTO t1 VALUES (40,'node1_committed_after'); +COMMIT; +connection node_1a_galera_st_shutdown_slave; +INSERT INTO t1 VALUES (41,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (42,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (43,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (44,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (45,'node1_to_be_rollbacked_after'); +ROLLBACK; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_15 FROM t1; +EXPECT_15 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +connection node_1; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_15 FROM t1; +EXPECT_15 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +Performing State Transfer on a server that starts from a clean var directory +This is accomplished by shutting down node #2 and removing its var directory before restarting it +connection node_1; +CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'node1_committed_before'); +INSERT INTO t1 VALUES (2,'node1_committed_before'); +INSERT INTO t1 VALUES (3,'node1_committed_before'); +INSERT INTO t1 VALUES (4,'node1_committed_before'); +INSERT INTO t1 VALUES (5,'node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (6,'node2_committed_before'); +INSERT INTO t1 VALUES (7,'node2_committed_before'); +INSERT INTO t1 VALUES (8,'node2_committed_before'); +INSERT INTO t1 VALUES (9,'node2_committed_before'); +INSERT INTO t1 VALUES (10,'node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +Cleaning var directory ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (11,'node1_committed_during'); +INSERT INTO t1 VALUES (12,'node1_committed_during'); +INSERT INTO t1 VALUES (13,'node1_committed_during'); +INSERT INTO t1 VALUES (14,'node1_committed_during'); +INSERT INTO t1 VALUES (15,'node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES (16,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (17,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (18,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (19,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (20,'node1_to_be_committed_after'); +connect node_1a_galera_st_clean_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (21,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (22,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (23,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (24,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (25,'node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (26,'node2_committed_after'); +INSERT INTO t1 VALUES (27,'node2_committed_after'); +INSERT INTO t1 VALUES (28,'node2_committed_after'); +INSERT INTO t1 VALUES (29,'node2_committed_after'); +INSERT INTO t1 VALUES (30,'node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES (31,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (32,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (33,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (34,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (35,'node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (36,'node1_committed_after'); +INSERT INTO t1 VALUES (37,'node1_committed_after'); +INSERT INTO t1 VALUES (38,'node1_committed_after'); +INSERT INTO t1 VALUES (39,'node1_committed_after'); +INSERT INTO t1 VALUES (40,'node1_committed_after'); +COMMIT; +connection node_1a_galera_st_clean_slave; +INSERT INTO t1 VALUES (41,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (42,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (43,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (44,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (45,'node1_to_be_rollbacked_after'); +ROLLBACK; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +connection node_1; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +Performing State Transfer on a server that has been killed and restarted +connection node_1; +CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'node1_committed_before'); +INSERT INTO t1 VALUES (2,'node1_committed_before'); +INSERT INTO t1 VALUES (3,'node1_committed_before'); +INSERT INTO t1 VALUES (4,'node1_committed_before'); +INSERT INTO t1 VALUES (5,'node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (6,'node2_committed_before'); +INSERT INTO t1 VALUES (7,'node2_committed_before'); +INSERT INTO t1 VALUES (8,'node2_committed_before'); +INSERT INTO t1 VALUES (9,'node2_committed_before'); +INSERT INTO t1 VALUES (10,'node2_committed_before'); +COMMIT; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (11,'node1_committed_during'); +INSERT INTO t1 VALUES (12,'node1_committed_during'); +INSERT INTO t1 VALUES (13,'node1_committed_during'); +INSERT INTO t1 VALUES (14,'node1_committed_during'); +INSERT INTO t1 VALUES (15,'node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES (16,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (17,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (18,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (19,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (20,'node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (21,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (22,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (23,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (24,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (25,'node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (26,'node2_committed_after'); +INSERT INTO t1 VALUES (27,'node2_committed_after'); +INSERT INTO t1 VALUES (28,'node2_committed_after'); +INSERT INTO t1 VALUES (29,'node2_committed_after'); +INSERT INTO t1 VALUES (30,'node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES (31,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (32,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (33,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (34,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (35,'node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (36,'node1_committed_after'); +INSERT INTO t1 VALUES (37,'node1_committed_after'); +INSERT INTO t1 VALUES (38,'node1_committed_after'); +INSERT INTO t1 VALUES (39,'node1_committed_after'); +INSERT INTO t1 VALUES (40,'node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave; +INSERT INTO t1 VALUES (41,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (42,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (43,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (45,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (46,'node1_to_be_rollbacked_after'); +ROLLBACK; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * FROM t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +connection node_1; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * FROM t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +include/assert_grep.inc [Using stunnel for SSL encryption] diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result index b791e580623..be8c845bdcf 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result @@ -2,8 +2,6 @@ connection node_2; connection node_1; connection node_1; connection node_2; -connection node_2; -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); connection node_1; Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result index b791e580623..be8c845bdcf 100644 --- a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result @@ -2,8 +2,6 @@ connection node_2; connection node_1; connection node_1; connection node_2; -connection node_2; -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); connection node_1; Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test b/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test index 953a1635559..7a3a6c825c4 100644 --- a/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_table_options.test @@ -66,6 +66,7 @@ COMMIT; --source include/wait_condition.inc --echo Cleaning var directory ... +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mtr --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/performance_schema --remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/test diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf new file mode 100644 index 00000000000..3ab762df013 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.cnf @@ -0,0 +1,20 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=rsync +ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem +ssl-key=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem +ssl-capath=@ENV.MYSQL_TEST_DIR/std_data/capath +# We need to turn off the default setting for the duration +# of the test (to test working with a directory instead of +# a file): +ssl-ca= + +[sst] +ssl-mode=VERIFY_CA + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test new file mode 100644 index 00000000000..a2d92723ec4 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_capath.test @@ -0,0 +1,26 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_debug.inc +--source include/have_stunnel.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--connection node_1 +--source suite/galera/include/galera_st_shutdown_slave.inc +--source suite/galera/include/galera_st_clean_slave.inc + +--source suite/galera/include/galera_st_kill_slave.inc +--source suite/galera/include/galera_st_kill_slave_ddl.inc + +# Confirm that transfer was SSL-encrypted +--let $assert_text = Using stunnel for SSL encryption +--let $assert_select = Using stunnel for SSL encryption +--let $assert_count = 5 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = CURRENT_TEST +--source include/assert_grep.inc + +--source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test index 838c473b9ce..a2d92723ec4 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test @@ -8,9 +8,6 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.inc ---connection node_2 -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); - --connection node_1 --source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_clean_slave.inc diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test index 838c473b9ce..a2d92723ec4 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test @@ -8,9 +8,6 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.inc ---connection node_2 -CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); - --connection node_1 --source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_clean_slave.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test index 31613454348..6e02350b12b 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/check_ipv6.inc --source include/have_innodb.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test index 3b2ca0892f1..453aa21988d 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup_section.test @@ -1,3 +1,4 @@ +--source include/big_test.inc --source include/galera_cluster.inc --source include/check_ipv6.inc --source include/have_innodb.inc diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index dbd639595df..5c84aa7c17f 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -19,6 +19,9 @@ set -u +# Setting the path for some utilities on CentOS +export PATH="$PATH:/usr/sbin:/usr/bin:/sbin:/bin" + WSREP_SST_OPT_BYPASS=0 WSREP_SST_OPT_BINLOG="" WSREP_SST_OPT_BINLOG_INDEX="" @@ -384,10 +387,8 @@ case "$1" in skip_mysqld_arg=1 ;; '--innodb-force-recovery') - if [ -n "$value" ]; then - if [ "$value" -ne 0 ]; then - INNODB_FORCE_RECOVERY="$value" - fi + if [ -n "$value" -a "$value" != "0" ]; then + INNODB_FORCE_RECOVERY="$value" fi skip_mysqld_arg=1 ;; @@ -584,7 +585,8 @@ get_binlog() if [ -n "$WSREP_SST_OPT_ADDR_PORT" ]; then if [ -n "$WSREP_SST_OPT_PORT" ]; then if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then - echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 + echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT" \ + "differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 exit 2 fi else @@ -616,8 +618,19 @@ fi readonly WSREP_SST_OPT_ADDR readonly WSREP_SST_OPT_ADDR_PORT -# try to use my_print_defaults, mysql and mysqldump that come with the sources -# (for MTR suite) +commandex() +{ + if [ -n "$BASH_VERSION" ]; then + command -v "$1" || : + elif [ -x "$1" ]; then + echo "$1" + else + which "$1" || : + fi +} + +# try to use my_print_defaults, mysql and mysqldump that come +# with the sources (for MTR suite): script_binary=$(dirname "$0") SCRIPTS_DIR=$(cd "$script_binary"; pwd -P) EXTRA_DIR="$SCRIPTS_DIR/../extra" @@ -626,13 +639,13 @@ CLIENT_DIR="$SCRIPTS_DIR/../client" if [ -x "$CLIENT_DIR/mysql" ]; then MYSQL_CLIENT="$CLIENT_DIR/mysql" else - MYSQL_CLIENT="$(command -v mysql)" + MYSQL_CLIENT=$(commandex 'mysql') fi if [ -x "$CLIENT_DIR/mysqldump" ]; then MYSQLDUMP="$CLIENT_DIR/mysqldump" else - MYSQLDUMP="$(command -v mysqldump)" + MYSQLDUMP=$(commandex 'mysqldump') fi wsrep_log() @@ -663,7 +676,7 @@ if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults" else - MY_PRINT_DEFAULTS="$(command -v my_print_defaults)" + MY_PRINT_DEFAULTS=$(commandex 'my_print_defaults') if [ -z "$MY_PRINT_DEFAULTS" ]; then wsrep_log_error "my_print_defaults not found in path" exit 2 @@ -673,16 +686,16 @@ fi readonly MY_PRINT_DEFAULTS wsrep_defaults="$WSREP_SST_OPT_DEFAULTS" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULTS:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" -readonly WSREP_SST_OPT_CONF="$wsrep_defaults" +readonly WSREP_SST_OPT_CONF="${wsrep_defaults:+ }$wsrep_defaults" wsrep_defaults="$WSREP_SST_OPT_DEFAULT" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULT" -wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULT:+ }$WSREP_SST_OPT_EXTRA_DEFAULT" +wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT" -readonly WSREP_SST_OPT_CONF_UNQUOTED="$wsrep_defaults" +readonly WSREP_SST_OPT_CONF_UNQUOTED="${wsrep_defaults:+ }$wsrep_defaults" # # User can specify mariabackup specific settings that will be used during sst @@ -819,8 +832,7 @@ if wsrep_auth_not_set; then fi # Splitting WSREP_SST_OPT_AUTH as "user:password" pair: -if ! wsrep_auth_not_set -then +if ! wsrep_auth_not_set; then # Extract username as shortest prefix up to first ':' character: WSREP_SST_OPT_AUTH_USER="${WSREP_SST_OPT_AUTH%%:*}" if [ -z "$WSREP_SST_OPT_USER" ]; then @@ -848,8 +860,7 @@ readonly WSREP_SST_OPT_USER readonly WSREP_SST_OPT_PSWD readonly WSREP_SST_OPT_AUTH -if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ] -then +if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ]; then # Split auth string at the last ':' readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%%:*}" readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH#*:}" @@ -860,8 +871,7 @@ fi readonly WSREP_SST_OPT_REMOTE_AUTH -if [ -n "$WSREP_SST_OPT_DATA" ] -then +if [ -n "$WSREP_SST_OPT_DATA" ]; then SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress" else SST_PROGRESS_FILE="" @@ -870,13 +880,14 @@ fi wsrep_cleanup_progress_file() { [ -n "$SST_PROGRESS_FILE" -a \ - -f "$SST_PROGRESS_FILE" ] && rm -f "$SST_PROGRESS_FILE" 2>/dev/null || true + -f "$SST_PROGRESS_FILE" ] && \ + rm -f "$SST_PROGRESS_FILE" 2>/dev/null || : } wsrep_check_program() { local prog="$1" - local cmd=$(command -v "$prog") + local cmd=$(commandex "$prog") if [ -z "$cmd" ]; then echo "'$prog' not found in PATH" return 2 # no such file or directory @@ -898,9 +909,9 @@ wsrep_check_programs() wsrep_check_datadir() { - if [ -z "$WSREP_SST_OPT_DATA" ] - then - wsrep_log_error "The '--datadir' parameter must be passed to the SST script" + if [ -z "$WSREP_SST_OPT_DATA" ]; then + wsrep_log_error \ + "The '--datadir' parameter must be passed to the SST script" exit 2 fi } @@ -912,10 +923,10 @@ get_openssl() return fi # Let's look for openssl: - OPENSSL_BINARY="$(command -v openssl)" + OPENSSL_BINARY=$(commandex 'openssl') if [ -z "$OPENSSL_BINARY" ]; then OPENSSL_BINARY='/usr/bin/openssl' - if [ -z "$OPENSSL_BINARY" ]; then + if [ ! -x "$OPENSSL_BINARY" ]; then OPENSSL_BINARY="" fi fi @@ -928,13 +939,12 @@ get_openssl() wsrep_gen_secret() { get_openssl - if [ -n "$OPENSSL_BINARY" ] - then + if [ -n "$OPENSSL_BINARY" ]; then echo $("$OPENSSL_BINARY" rand -hex 16) else printf "%04x%04x%04x%04x%04x%04x%04x%04x" \ - $RANDOM $RANDOM $RANDOM $RANDOM \ - $RANDOM $RANDOM $RANDOM $RANDOM + $RANDOM $RANDOM $RANDOM $RANDOM \ + $RANDOM $RANDOM $RANDOM $RANDOM fi } @@ -968,14 +978,14 @@ is_local_ip() fi # Now let's check if the given address is assigned to # one of the network cards: - local ip_util="$(command -v ip)" + local ip_util=$(commandex 'ip') if [ -n "$ip_util" ]; then # ip address show ouput format is " inet[6]
/": "$ip_util" address show \ | grep -E "^[[:space:]]*inet.? [^[:space:]]+/" -o \ | grep -F " $1/" >/dev/null && return 0 else - local ifconfig_util="$(command -v ifconfig)" + local ifconfig_util=$(commandex 'ifconfig') if [ -n "$ifconfig_util" ]; then # ifconfig output format is " inet[6]
...": "$ifconfig_util" \ @@ -992,15 +1002,15 @@ check_sockets_utils() sockstat_available=0 ss_available=0 - [ -n "$(command -v lsof)" ] && lsof_available=1 - [ -n "$(command -v sockstat)" ] && sockstat_available=1 - [ -n "$(command -v ss)" ] && ss_available=1 + [ -n "$(commandex lsof)" ] && lsof_available=1 + [ -n "$(commandex sockstat)" ] && sockstat_available=1 + [ -n "$(commandex ss)" ] && ss_available=1 if [ $lsof_available -eq 0 -a \ $sockstat_available -eq 0 -a \ $ss_available -eq 0 ] then - wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in " \ + wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in" \ "the PATH. Make sure you have it installed." exit 2 # ENOENT fi @@ -1085,26 +1095,38 @@ check_for_dhparams() # verify_ca_matches_cert() { - local ca="$1" - local cert="$2" - local path=${3:-0} + local cert="$1" + local ca="$2" + local cap="$3" # If the openssl utility is not installed, then # we will not do this certificate check: get_openssl if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_info "openssl utility not found" return fi - local not_match=0 + local readable=1; [ ! -r "$cert" ] && readable=0 + [ -n "$ca" ] && [ ! -r "$ca" ] && readable=0 + [ -n "$cap" ] && [ ! -r "$cap" ] && readable=0 - if [ $path -eq 0 ]; then - "$OPENSSL_BINARY" verify -verbose -CAfile "$ca" "$cert" >/dev/null 2>&1 || not_match=1 - else - "$OPENSSL_BINARY" verify -verbose -CApath "$ca" "$cert" >/dev/null 2>&1 || not_match=1 + if [ readable -eq 0 ]; then + wsrep_log_error \ + "Both PEM file and CA file (or path) must be readable" + exit 22 fi + local not_match=0 + local errmsg + errmsg=$("$OPENSSL_BINARY" verify -verbose \ + ${ca:+ -CAfile} ${ca:+ "$ca"} \ + ${cap:+ -CApath} ${cap:+ "$cap"} \ + "$cert" 2>&1) || not_match=1 + if [ $not_match -eq 1 ]; then + wsrep_log_info "run: \"$OPENSSL_BINARY\" verify -verbose${ca:+ -CAfile \"$ca\"}${cap:+ -CApath \"$cap\"} \"$cert\"" + wsrep_log_info "output: $errmsg" wsrep_log_error "******** FATAL ERROR ********************************************" wsrep_log_error "* The certifcate and CA (certificate authority) do not match. *" wsrep_log_error "* It does not appear that the certificate was issued by the CA. *" @@ -1124,12 +1146,18 @@ verify_ca_matches_cert() # verify_cert_matches_key() { - local cert_path="$1" - local key_path="$2" + local cert="$1" + local key="$2" + + if [ ! -r "$key" -o ! -r "$cert" ]; then + wsrep_log_error "Both the certificate file and the key file" \ + "must be readable" + exit 22 + fi # If the diff utility is not installed, then # we will not do this certificate check: - if [ -z "$(command -v diff)" ]; then + if [ -z "$(commandex diff)" ]; then return fi @@ -1142,13 +1170,13 @@ verify_cert_matches_key() # Generate the public key from the cert and the key. # They should match (otherwise we can't create an SSL connection). - if ! diff <("$OPENSSL_BINARY" x509 -in "$cert_path" -pubkey -noout 2>/dev/null) \ - <("$OPENSSL_BINARY" pkey -in "$key_path" -pubout 2>/dev/null) >/dev/null 2>&1 + if ! diff <("$OPENSSL_BINARY" x509 -in "$cert" -pubkey -noout 2>/dev/null) \ + <("$OPENSSL_BINARY" pkey -in "$key" -pubout 2>/dev/null) >/dev/null 2>&1 then - wsrep_log_error "******************* FATAL ERROR ****************" - wsrep_log_error "* The certifcate and private key do not match. *" - wsrep_log_error "* Please check your certificate and key files. *" - wsrep_log_error "************************************************" + wsrep_log_error "******************* FATAL ERROR *****************" + wsrep_log_error "* The certificate and private key do not match. *" + wsrep_log_error "* Please check your certificate and key files. *" + wsrep_log_error "*************************************************" exit 22 fi } @@ -1305,9 +1333,9 @@ get_proc() elif [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ]; then nproc=$(sysctl -n hw.ncpu) fi + set -e if [ -z "$nproc" ] || [ $nproc -eq 0 ]; then nproc=1 fi - set -e fi } diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index b429a9effd5..4bca785fcad 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -20,10 +20,11 @@ # https://mariadb.com/kb/en/mariabackup-overview/ # Make sure to read that before proceeding! +OS="$(uname)" + . $(dirname "$0")/wsrep_sst_common wsrep_check_datadir -OS="$(uname)" ealgo="" eformat="" ekey="" @@ -34,7 +35,7 @@ ssyslog="" ssystag="" BACKUP_PID="" tcert="" -tpath=0 +tcap="" tpem="" tkey="" tmode="DISABLED" @@ -88,14 +89,14 @@ readonly SECRET_TAG="secret" # For backup locks it is 1 sent by joiner sst_ver=1 -if [ -n "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then +if [ -n "$(commandex pv)" ] && pv --help | grep -qw -- '-F'; then pvopts="$pvopts $pvformat" fi pcmd="pv $pvopts" declare -a RC -BACKUP_BIN="$(command -v mariabackup)" -if [ ! -x "$BACKUP_BIN" ]; then +BACKUP_BIN=$(commandex 'mariabackup') +if [ -z "$BACKUP_BIN" ]; then wsrep_log_error 'mariabackup binary not found in path' exit 42 fi @@ -145,14 +146,14 @@ get_keys() if [ $encrypt -eq 0 ]; then if [ -n "$ealgo" -o -n "$ekey" -o -n "$ekeyfile" ]; then - wsrep_log_error "Options for encryption are specified, " \ + wsrep_log_error "Options for encryption are specified," \ "but encryption itself is disabled. SST may fail." fi return fi if [ $sfmt = 'tar' ]; then - wsrep_log_info "NOTE: key-based encryption (encrypt=1) " \ + wsrep_log_info "NOTE: key-based encryption (encrypt=1)" \ "cannot be enabled with tar format" encrypt=-1 return @@ -165,16 +166,18 @@ get_keys() exit 3 fi - if [ -z "$ekey" -a ! -r "$ekeyfile" ]; then - wsrep_log_error "FATAL: Either key must be specified " \ - "or keyfile must be readable" - exit 3 + if [ -z "$ekey" ]; then + if [ ! -r "$ekeyfile" ]; then + wsrep_log_error "FATAL: Either key must be specified" \ + "or keyfile must be readable" + exit 3 + fi fi if [ "$eformat" = 'openssl' ]; then get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error "If encryption using the openssl is enabled, " \ + wsrep_log_error "If encryption using the openssl is enabled," \ "then you need to install openssl" exit 2 fi @@ -192,12 +195,12 @@ get_keys() ecmd="$ecmd -k '$ekey'" fi elif [ "$eformat" = 'xbcrypt' ]; then - if [ -z "$(command -v xbcrypt)" ]; then - wsrep_log_error "If encryption using the xbcrypt is enabled, " \ + if [ -z "$(commandex xbcrypt)" ]; then + wsrep_log_error "If encryption using the xbcrypt is enabled," \ "then you need to install xbcrypt" exit 2 fi - wsrep_log_info "NOTE: xbcrypt-based encryption, " \ + wsrep_log_info "NOTE: xbcrypt-based encryption," \ "supported only from Xtrabackup 2.1.4" if [ -z "$ekey" ]; then ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'" @@ -342,40 +345,34 @@ get_transfer() CN_option=",commonname=''" if [ $encrypt -eq 2 ]; then - wsrep_log_info "Using openssl based encryption with socat: with crt and pem" - if [ -z "$tpem" -o -z "$tcert" ]; then + wsrep_log_info \ + "Using openssl based encryption with socat: with crt and pem" + if [ -z "$tpem" -o -z "$tcert$tcap" ]; then wsrep_log_error \ "Both PEM file and CRT file (or path) are required" exit 22 fi - if [ ! -r "$tpem" -o ! -r "$tcert" ]; then - wsrep_log_error \ - "Both PEM file and CRT file (or path) must be readable" - exit 22 + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" + tcmd="$tcmd,cert='$tpem'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',capath='$tcert'" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" fi stagemsg="$stagemsg-OpenSSL-Encrypted-2" - wsrep_log_info "$action with cert=$tpem, ca=$tcert" + wsrep_log_info "$action with cert='$tpem', ca='$tcert', capath='$tcap'" elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then - wsrep_log_info "Using openssl based encryption with socat: with key and crt" + wsrep_log_info \ + "Using openssl based encryption with socat: with key and crt" if [ -z "$tpem" -o -z "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file are required" - exit 22 - fi - if [ ! -r "$tpem" -o ! -r "$tkey" ]; then - wsrep_log_error "Both certificate file (or path) " \ - "and key file must be readable" + wsrep_log_error "Both the certificate file (or path) and" \ + "the key file are required" exit 22 fi verify_cert_matches_key "$tpem" "$tkey" stagemsg="$stagemsg-OpenSSL-Encrypted-3" - if [ -z "$tcert" ]; then + if [ -z "$tcert$tcap" ]; then if [ $encrypt -eq 4 ]; then wsrep_log_error \ "Peer certificate file (or path) required if encrypt=4" @@ -384,14 +381,11 @@ get_transfer() # no verification CN_option="" tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0" - wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0" + wsrep_log_info \ + "$action with cert='$tpem', key='$tkey', verify=0" else # CA verification - if [ ! -r "$tcert" ]; then - wsrep_log_error "Certificate file or path must be readable" - exit 22 - fi - verify_ca_matches_cert "$tcert" "$tpem" $tpath + verify_ca_matches_cert "$tpem" "$tcert" "$tcap" if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' -o $encrypt -eq 4 ] @@ -402,12 +396,15 @@ get_transfer() else CN_option=",commonname='$WSREP_SST_OPT_HOST_UNESCAPED'" fi - if [ $tpath -eq 0 ]; then - tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'" - else - tcmd="$tcmd,cert='$tpem',key='$tkey',capath='$tcert'" + tcmd="$tcmd,cert='$tpem',key='$tkey'" + if [ -n "$tcert" ]; then + tcmd="$tcmd,cafile='$tcert'" fi - wsrep_log_info "$action with cert=$tpem, key=$tkey, ca=$tcert" + if [ -n "$tcap" ]; then + tcmd="$tcmd,capath='$tcap'" + fi + wsrep_log_info "$action with cert='$tpem', key='$tkey'," \ + "ca='$tcert', capath='$tcap'" fi else wsrep_log_info "Unknown encryption mode: encrypt=$encrypt" @@ -425,7 +422,9 @@ get_transfer() get_footprint() { pushd "$WSREP_SST_OPT_DATA" 1>/dev/null - payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }') + payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' \ + -type f -print0 | du --files0-from=- --block-size=1 -c -s | \ + awk 'END { print $1 }') if [ "$compress" != 'none' ]; then # QuickLZ has around 50% compression ratio # When compression/compaction used, the progress is only an approximate. @@ -438,7 +437,7 @@ get_footprint() adjust_progress() { - if [ -z "$(command -v pv)" ]; then + if [ -z "$(commandex pv)" ]; then wsrep_log_error "pv not found in path: $PATH" wsrep_log_error "Disabling all progress/rate-limiting" pcmd="" @@ -470,33 +469,42 @@ check_server_ssl_config() { # backward-compatible behavior: tcert=$(parse_cnf 'sst' 'tca') + tcap=$(parse_cnf 'sst' 'tcapath') tpem=$(parse_cnf 'sst' 'tcert') tkey=$(parse_cnf 'sst' 'tkey') # reading new ssl configuration options: local tcert2=$(parse_cnf "$encgroups" 'ssl-ca') + local tcap2=$(parse_cnf "$encgroups" 'ssl-capath') local tpem2=$(parse_cnf "$encgroups" 'ssl-cert') local tkey2=$(parse_cnf "$encgroups" 'ssl-key') # if there are no old options, then we take new ones: - if [ -z "$tcert" -a -z "$tpem" -a -z "$tkey" ]; then + if [ -z "$tcert" -a -z "$tcap" -a -z "$tpem" -a -z "$tkey" ]; then tcert="$tcert2" + tcap="$tcap2" tpem="$tpem2" tkey="$tkey2" # checking for presence of the new-style SSL configuration: - elif [ -n "$tcert2" -o -n "$tpem2" -o -n "$tkey2" ]; then + elif [ -n "$tcert2" -o -n "$tcap2" -o -n "$tpem2" -o -n "$tkey2" ]; then if [ "$tcert" != "$tcert2" -o \ + "$tcap" != "$tcap2" -o \ "$tpem" != "$tpem2" -o \ "$tkey" != "$tkey2" ] then - wsrep_log_info "new ssl configuration options (ssl-ca, ssl-cert " \ - "and ssl-key) are ignored by SST due to presence " \ - "of the tca, tcert and/or tkey in the [sst] section" + wsrep_log_info \ + "new ssl configuration options (ssl-ca[path], ssl-cert" \ + "and ssl-key) are ignored by SST due to presence" \ + "of the tca[path], tcert and/or tkey in the [sst] section" fi fi if [ -n "$tcert" ]; then - tcert=$(trim_string "$tcert") - if [ "${tcert%/}" != "$tcert" ]; then - tpath=1 - fi + tcert=$(trim_string "$tcert") + if [ "${tcert%/}" != "$tcert" ] || [ -d "$tcert" ]; then + tcap="$tcert" + tcert="" + fi + fi + if [ -n "$tcap" ]; then + tcap=$(trim_string "$tcap") fi } @@ -506,10 +514,10 @@ read_cnf() tfmt=$(parse_cnf sst transferfmt 'socat') encrypt=$(parse_cnf "$encgroups" 'encrypt' 0) - tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) + tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | \ + tr [:lower:] [:upper:]) - if [ $encrypt -eq 0 -o $encrypt -ge 2 ] - then + if [ $encrypt -eq 0 -o $encrypt -ge 2 ]; then if [ "$tmode" != 'DISABLED' -o $encrypt -ge 2 ]; then check_server_ssl_config fi @@ -517,11 +525,13 @@ read_cnf() if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] then encrypt=3 # enable cert/key SSL encyption - # avoid CA verification if not set explicitly: - # nodes may happen to have different CA if self-generated - # zeroing up tcert does the trick - [ "${tmode#VERIFY}" != "$tmode" ] || tcert="" + # nodes may happen to have different CA if self-generated, + # zeroing up tcert and tcap does the trick: + if [ "${tmode#VERIFY}" = "$tmode" ]; then + tcert="" + tcap="" + fi fi fi elif [ $encrypt -eq 1 ]; then @@ -535,8 +545,9 @@ read_cnf() fi fi - wsrep_log_info "SSL configuration: CA='$tcert', CERT='$tpem'," \ - "KEY='$tkey', MODE='$tmode', encrypt='$encrypt'" + wsrep_log_info "SSL configuration: CA='$tcert', CAPATH='$tcap'," \ + "CERT='$tpem', KEY='$tkey', MODE='$tmode'," \ + "encrypt='$encrypt'" sockopt=$(parse_cnf sst sockopt "") progress=$(parse_cnf sst progress "") @@ -561,7 +572,8 @@ read_cnf() sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir '/tmp/sst_log_archive') if [ $speciald -eq 0 ]; then - wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1" + wsrep_log_error \ + "sst-special-dirs equal to 0 is not supported, falling back to 1" speciald=1 fi @@ -589,7 +601,7 @@ get_stream() { if [ "$sfmt" = 'mbstream' -o "$sfmt" = 'xbstream' ]; then sfmt='mbstream' - STREAM_BIN="$(command -v mbstream)" + local STREAM_BIN=$(commandex "$sfmt") if [ -z "$STREAM_BIN" ]; then wsrep_log_error "Streaming with $sfmt, but $sfmt not found in path" exit 42 @@ -621,7 +633,7 @@ cleanup_at_exit() # Since this is invoked just after exit NNN local estatus=$? if [ $estatus -ne 0 ]; then - wsrep_log_error "Cleanup after exit with status:$estatus" + wsrep_log_error "Cleanup after exit with status: $estatus" fi if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then @@ -630,7 +642,8 @@ cleanup_at_exit() else if [ -n "$BACKUP_PID" ]; then if check_pid "$BACKUP_PID" 1; then - wsrep_log_error "mariabackup process is still running. Killing..." + wsrep_log_error \ + "mariabackup process is still running. Killing..." cleanup_pid $CHECK_PID "$BACKUP_PID" fi fi @@ -638,8 +651,8 @@ cleanup_at_exit() fi if [ -n "$progress" -a -p "$progress" ]; then - wsrep_log_info "Cleaning up fifo file $progress" - rm -f "$progress" || true + wsrep_log_info "Cleaning up fifo file: $progress" + rm -f "$progress" || : fi wsrep_log_info "Cleaning up temporary directories" @@ -649,8 +662,8 @@ cleanup_at_exit() [ -d "$STATDIR" ] && rm -rf "$STATDIR" fi else - [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true - [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true + [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || : + [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || : fi # Final cleanup @@ -662,7 +675,7 @@ cleanup_at_exit() # This means a signal was delivered to the process. # So, more cleanup. if [ $estatus -ge 128 ]; then - kill -KILL -- -$$ || true + kill -KILL -- -$$ || : fi fi @@ -738,7 +751,7 @@ recv_joiner() local ltcmd="$tcmd" if [ $tmt -gt 0 ]; then - if [ -n "$(command -v timeout)" ]; then + if [ -n "$(commandex timeout)" ]; then if timeout --help | grep -qw -- '-k'; then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" else @@ -760,14 +773,14 @@ recv_joiner() popd 1>/dev/null if [ ${RC[0]} -eq 124 ]; then - wsrep_log_error "Possible timeout in receiving first data from " \ + wsrep_log_error "Possible timeout in receiving first data from" \ "donor in gtid stage: exit codes: ${RC[@]}" exit 32 fi for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while getting data from donor node: " \ + wsrep_log_error "Error while getting data from donor node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -776,7 +789,7 @@ recv_joiner() if [ $checkf -eq 1 ]; then if [ ! -r "$MAGIC_FILE" ]; then # this message should cause joiner to abort - wsrep_log_error "receiving process ended without creating " \ + wsrep_log_error "receiving process ended without creating" \ "'$MAGIC_FILE'" wsrep_log_info "Contents of datadir" wsrep_log_info $(ls -l "$dir/"*) @@ -784,10 +797,11 @@ recv_joiner() fi # check donor supplied secret - SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | \ + cut -d ' ' -f 2) if [ "$SECRET" != "$MY_SECRET" ]; then wsrep_log_error "Donor does not know my secret!" - wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'" exit 32 fi @@ -810,7 +824,7 @@ send_donor() for ecode in "${RC[@]}"; do if [ $ecode -ne 0 ]; then - wsrep_log_error "Error while sending data to joiner node: " \ + wsrep_log_error "Error while sending data to joiner node:" \ "exit codes: ${RC[@]}" exit 32 fi @@ -823,7 +837,9 @@ monitor_process() while true ; do if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1; then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error \ + "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." kill -- -"$WSREP_SST_OPT_PARENT" exit 32 fi @@ -845,7 +861,7 @@ read_cnf setup_ports if "$BACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then - disver='--no-version-check' + disver=' --no-version-check' fi # if no command line argument and INNODB_DATA_HOME_DIR environment variable @@ -867,7 +883,7 @@ INNODB_DATA_HOME_DIR=$(pwd -P) cd "$OLD_PWD" if [ $ssyslog -eq 1 ]; then - if [ -n "$(command -v logger)" ]; then + if [ -n "$(commandex logger)" ]; then wsrep_log_info "Logging all stderr of SST/mariabackup to syslog" exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE) @@ -898,10 +914,8 @@ else fi fi - if [ -e "$INNOAPPLYLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOAPPLYLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOAPPLYLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -912,10 +926,8 @@ else gzip "$newfile" fi - if [ -e "$INNOMOVELOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOMOVELOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOMOVELOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -926,10 +938,8 @@ else gzip "$newfile" fi - if [ -e "$INNOBACKUPLOG" ] - then - if [ -n "$sstlogarchivedir" ] - then + if [ -e "$INNOBACKUPLOG" ]; then + if [ -n "$sstlogarchivedir" ]; then newfile=$(basename "$INNOBACKUPLOG") newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else @@ -949,15 +959,15 @@ setup_commands() { local mysqld_args="" if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then - mysqld_args="--mysqld-args $WSREP_SST_OPT_MYSQLD" + mysqld_args=" --mysqld-args $WSREP_SST_OPT_MYSQLD" fi - if [ -z "$INNODB_FORCE_RECOVERY" ]; then - INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" - else - INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --innodb-force-recovery=$INNODB_FORCE_RECOVERY --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" + local recovery="" + if [ -n "$INNODB_FORCE_RECOVERY" ]; then + recovery=" --innodb-force-recovery=$INNODB_FORCE_RECOVERY" fi - INNOMOVE="$BACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" - INNOBACKUP="$BACKUP_BIN $WSREP_SST_OPT_CONF --backup $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA' $mysqld_args $INNOBACKUP" + INNOAPPLY="$BACKUP_BIN --prepare$disver$recovery${iapts:+ }$iapts$INNOEXTRA --target-dir='$DATA' --datadir='$DATA'$mysqld_args $INNOAPPLY" + INNOMOVE="$BACKUP_BIN$WSREP_SST_OPT_CONF --move-back$disver${impts:+ }$impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" + INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF --backup$disver${iopts:+ }$iopts $tmpopts$INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA'$mysqld_args $INNOBACKUP" } get_stream @@ -1055,27 +1065,28 @@ then tcmd="$ecmd | $tcmd" fi - iopts="--databases-exclude='lost+found' $iopts" + iopts="--databases-exclude='lost+found'${iopts:+ }$iopts" if [ ${FORCE_FTWRL:-0} -eq 1 ]; then - wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" - iopts="--no-backup-locks $iopts" + wsrep_log_info "Forcing FTWRL due to environment variable" \ + "FORCE_FTWRL equal to $FORCE_FTWRL" + iopts="--no-backup-locks${iopts:+ }$iopts" fi # if compression is enabled for backup files, then add the # appropriate options to the mariabackup command line: if [ "$compress" != 'none' ]; then - iopts="--compress${compress:+=$compress} $iopts" + iopts="--compress${compress:+=$compress}${iopts:+ }$iopts" if [ -n "$compress_threads" ]; then - iopts="--compress-threads=$compress_threads $iopts" + iopts="--compress-threads=$compress_threads${iopts:+ }$iopts" fi if [ -n "$compress_chunk" ]; then - iopts="--compress-chunk-size=$compress_chunk $iopts" + iopts="--compress-chunk-size=$compress_chunk${iopts:+ }$iopts" fi fi if [ -n "$backup_threads" ]; then - iopts="--parallel=$backup_threads $iopts" + iopts="--parallel=$backup_threads${iopts:+ }$iopts" fi setup_commands @@ -1084,7 +1095,7 @@ then set -e if [ ${RC[0]} -ne 0 ]; then - wsrep_log_error "mariabackup finished with error: ${RC[0]}. " \ + wsrep_log_error "mariabackup finished with error: ${RC[0]}." \ "Check syslog or '$INNOBACKUPLOG' for details" exit 22 elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then @@ -1125,7 +1136,8 @@ then elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ] then - [ -e "$SST_PROGRESS_FILE" ] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" + [ -e "$SST_PROGRESS_FILE" ] && \ + wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" [ -n "$SST_PROGRESS_FILE" ] && touch "$SST_PROGRESS_FILE" ib_home_dir="$INNODB_DATA_HOME_DIR" @@ -1146,7 +1158,7 @@ then ib_undo_dir="$INNODB_UNDO_DIR" if [ -n "$backup_threads" ]; then - impts="--parallel=$backup_threads $impts" + impts="--parallel=$backup_threads${impts:+ }$impts" fi stagemsg='Joiner-Recv' @@ -1165,15 +1177,15 @@ then ADDR="$WSREP_SST_OPT_ADDR" - if [ "${tmode#VERIFY}" != "$tmode" ] - then # backward-incompatible behavior + if [ "${tmode#VERIFY}" != "$tmode" ]; then + # backward-incompatible behavior: CN="" - if [ -n "$tpem" ] - then + if [ -n "$tpem" ]; then # find out my Common Name get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error 'openssl not found but it is required for authentication' + wsrep_log_error \ + 'openssl not found but it is required for authentication' exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ @@ -1213,15 +1225,17 @@ then if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1 then - wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT)" \ + "terminated unexpectedly." exit 32 fi - if [ ! -r "$STATDIR/$IST_FILE" ] - then + if [ ! -r "$STATDIR/$IST_FILE" ]; then if [ -d "$DATA/.sst" ]; then - wsrep_log_info "WARNING: Stale temporary SST directory: '$DATA/.sst' from previous state transfer. Removing" + wsrep_log_info \ + "WARNING: Stale temporary SST directory:" \ + "'$DATA/.sst' from previous state transfer, removing..." rm -rf "$DATA/.sst" fi mkdir -p "$DATA/.sst" @@ -1229,17 +1243,20 @@ then jpid=$! wsrep_log_info "Proceeding with SST" - wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories" + wsrep_log_info \ + "Cleaning the existing datadir and innodb-data/log directories" if [ "$OS" = 'FreeBSD' ]; then find -E ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ else find ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ - "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ + "$DATA" -mindepth 1 -prune -regex "$cpat" \ + -o -exec rm -rfv {} 1>&2 \+ fi get_binlog @@ -1248,9 +1265,9 @@ then binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") cd "$binlog_dir" wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" - rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || : [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ - rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || true + rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || : cd "$OLD_PWD" fi @@ -1262,7 +1279,8 @@ then monitor_process $jpid if [ ! -s "$DATA/xtrabackup_checkpoints" ]; then - wsrep_log_error "xtrabackup_checkpoints missing, failed mariabackup/SST on donor" + wsrep_log_error "xtrabackup_checkpoints missing," \ + "failed mariabackup/SST on donor" exit 2 fi @@ -1277,7 +1295,7 @@ then if [ -n "$qpfiles" ]; then wsrep_log_info "Compressed qpress files found" - if [ -z "$(command -v qpress)" ]; then + if [ -z "$(commandex qpress)" ]; then wsrep_log_error "qpress utility not found in the path" exit 22 fi @@ -1300,14 +1318,17 @@ then # Decompress the qpress files wsrep_log_info "Decompression with $nproc threads" - timeit "Joiner-Decompression" "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" + timeit "Joiner-Decompression" \ + "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" extcode=$? if [ $extcode -eq 0 ]; then wsrep_log_info "Removing qpress files after decompression" find "$DATA" -type f -name '*.qp' -delete if [ $? -ne 0 ]; then - wsrep_log_error "Something went wrong with deletion of qpress files. Investigate" + wsrep_log_error \ + "Something went wrong with deletion of qpress files." \ + "Investigate" fi else wsrep_log_error "Decompression failed. Exit code: $extcode" @@ -1321,7 +1342,7 @@ then BINLOG_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG") # To avoid comparing data directory and BINLOG_DIRNAME - mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || true + mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || : cd "$BINLOG_DIRNAME" for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do @@ -1336,7 +1357,8 @@ then timeit "mariabackup prepare stage" "$INNOAPPLY" if [ $? -ne 0 ]; then - wsrep_log_error "mariabackup apply finished with errors. Check syslog or '$INNOAPPLYLOG' for details" + wsrep_log_error "mariabackup apply finished with errors." \ + "Check syslog or '$INNOAPPLYLOG' for details." exit 22 fi diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index 798bee1ac10..bed2cac0a9a 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -19,7 +19,6 @@ # This is a reference script for mysqldump-based state snapshot tansfer . $(dirname "$0")/wsrep_sst_common -PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin EINVAL=22 @@ -93,8 +92,7 @@ DROP PREPARE stmt;" SET_START_POSITION="SET GLOBAL wsrep_start_position='$WSREP_SST_OPT_GTID';" SET_WSREP_GTID_DOMAIN_ID="" -if [ -n $WSREP_SST_OPT_GTID_DOMAIN_ID ] -then +if [ -n $WSREP_SST_OPT_GTID_DOMAIN_ID ]; then SET_WSREP_GTID_DOMAIN_ID=" SET @val = (SELECT GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME = 'WSREP_GTID_STRICT_MODE' AND GLOBAL_VALUE > 0); SET @stmt = IF (@val IS NOT NULL, 'SET GLOBAL WSREP_GTID_DOMAIN_ID=$WSREP_SST_OPT_GTID_DOMAIN_ID', 'SET @dummy = 0'); @@ -103,7 +101,7 @@ then DROP PREPARE stmt;" fi -MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF_UNQUOTED "\ +MYSQL="$MYSQL_CLIENT$WSREP_SST_OPT_CONF_UNQUOTED "\ "$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\ "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" @@ -125,8 +123,7 @@ SET_GTID_BINLOG_STATE="" SQL_LOG_BIN_OFF="" # Safety check -if [ ${SERVER_VERSION%%.*} -gt 5 ] -then +if [ ${SERVER_VERSION%%.*} -gt 5 ]; then # If binary logging is enabled on the joiner node, we need to copy donor's # gtid_binlog_state to joiner. In order to do that, a RESET MASTER must be # executed to erase binary logs (if any). Binary logging should also be @@ -140,7 +137,7 @@ then fi # NOTE: we don't use --routines here because we're dumping mysql.proc table -MYSQLDUMP="$MYSQLDUMP $WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \ +MYSQLDUMP="$MYSQLDUMP$WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \ --add-drop-database --add-drop-table --skip-add-locks --create-options \ --disable-keys --extended-insert --skip-lock-tables --quick --set-charset \ --skip-comments --flush-privileges --all-databases --events" diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 29c9cd43470..b0cc8cb3066 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -25,9 +25,6 @@ STUNNEL_REAL_PID=0 # stunnel process id OS="$(uname)" [ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH -# Setting the path for lsof on CentOS -export PATH="/usr/sbin:/sbin:$PATH" - . $(dirname "$0")/wsrep_sst_common wsrep_check_datadir @@ -37,7 +34,8 @@ cleanup_joiner() { local failure=0 - wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID, stunnel PID=$STUNNEL_REAL_PID" + wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID," \ + "stunnel PID=$STUNNEL_REAL_PID" if [ -n "$STUNNEL" ]; then if cleanup_pid $STUNNEL_REAL_PID "$STUNNEL_PID" "$STUNNEL_CONF"; then @@ -87,7 +85,7 @@ check_pid_and_port() if [ $lsof_available -ne 0 ]; then port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \ - grep -F '(LISTEN)') + grep -F '(LISTEN)') echo "$port_info" | \ grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1 else @@ -124,7 +122,7 @@ check_pid_and_port() fi if ! check_port "$pid" "$port" "$utils"; then - wsrep_log_error "rsync or stunnel daemon port '$port' " \ + wsrep_log_error "rsync or stunnel daemon port '$port'" \ "has been taken by another program" exit 16 # EBUSY fi @@ -223,6 +221,7 @@ FILTER="-f '- /lost+found' SSTKEY=$(parse_cnf 'sst' 'tkey') SSTCERT=$(parse_cnf 'sst' 'tcert') SSTCA=$(parse_cnf 'sst' 'tca') +SSTCAP=$(parse_cnf 'sst' 'tcapath') SST_SECTIONS="--mysqld|sst" @@ -231,28 +230,34 @@ check_server_ssl_config() SSTKEY=$(parse_cnf "$SST_SECTIONS" 'ssl-key') SSTCERT=$(parse_cnf "$SST_SECTIONS" 'ssl-cert') SSTCA=$(parse_cnf "$SST_SECTIONS" 'ssl-ca') + SSTCAP=$(parse_cnf "$SST_SECTIONS" 'ssl-capath') } SSLMODE=$(parse_cnf "$SST_SECTIONS" 'ssl-mode' | tr [:lower:] [:upper:]) # no old-style SSL config in [sst], check for new one: -if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]; then +if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" -a -z "$SSTCAP" ]; then check_server_ssl_config fi -SSTPATH=0 if [ -n "$SSTCA" ]; then - SSTCA=$(trim_string "$SSTCA") - if [ "${SSTCA%/}" != "$SSTCA" ]; then - SSTPATH=1 - fi + SSTCA=$(trim_string "$SSTCA") + if [ "${SSTCA%/}" != "$SSTCA" ] || [ -d "$SSTCA" ]; then + SSTCAP="$SSTCA" + SSTCA="" + fi +fi + +if [ -n "$SSTCAP" ]; then + SSTCAP=$(trim_string "$SSTCAP") fi if [ -z "$SSLMODE" ]; then # Implicit verification if CA is set and the SSL mode # is not specified by user: - if [ -n "$SSTCA" ]; then - if [ -n "$(command -v stunnel)" ]; then + if [ -n "$SSTCA$SSTCAP" ]; then + STUNNEL_BIN=$(commandex 'stunnel') + if [ -n "$STUNNEL_BIN" ]; then SSLMODE='VERIFY_CA' fi # Require SSL by default if SSL key and cert are present: @@ -265,17 +270,18 @@ if [ -n "$SSTCERT" -a -n "$SSTKEY" ]; then verify_cert_matches_key "$SSTCERT" "$SSTKEY" fi -if [ -n "$SSTCA" ]; then - if [ $SSTPATH -eq 0 ]; then +CAFILE_OPT="" +CAPATH_OPT="" +if [ -n "$SSTCA$SSTCAP" ]; then + if [ -n "$SSTCA" ]; then CAFILE_OPT="CAfile = $SSTCA" - else - CAFILE_OPT="CApath = $SSTCA" + fi + if [ -n "$SSTCAP" ]; then + CAPATH_OPT="CApath = $SSTCAP" fi if [ -n "$SSTCERT" ]; then - verify_ca_matches_cert "$SSTCA" "$SSTCERT" $SSTPATH + verify_ca_matches_cert "$SSTCERT" "$SSTCA" "$SSTCAP" fi -else - CAFILE_OPT="" fi VERIFY_OPT="" @@ -295,7 +301,7 @@ then exit 22 # EINVAL ;; esac - if [ -z "$SSTCA" ]; then + if [ -z "$SSTCA$SSTCAP" ]; then wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file or path" exit 22 # EINVAL fi @@ -318,9 +324,12 @@ fi STUNNEL="" if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ]; then - STUNNEL_BIN="$(command -v stunnel)" + if [ -z "${STUNNEL_BIN+x}" ]; then + STUNNEL_BIN=$(commandex 'stunnel') + fi if [ -n "$STUNNEL_BIN" ]; then - wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA', ssl-mode='$SSLMODE'" + wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA'," \ + "CAPATH='$SSTCAP', ssl-mode='$SSLMODE'" STUNNEL="$STUNNEL_BIN $STUNNEL_CONF" fi fi @@ -340,6 +349,7 @@ then key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -392,8 +402,8 @@ EOF # Prepare binlog files cd "$BINLOG_DIRNAME" - binlog_files_full=$(tail -n $BINLOG_N_FILES "$WSREP_SST_OPT_BINLOG_INDEX") - + binlog_files_full=$(tail -n $BINLOG_N_FILES \ + "$WSREP_SST_OPT_BINLOG_INDEX") binlog_files="" for ii in $binlog_files_full do @@ -417,9 +427,10 @@ EOF WHOLE_FILE_OPT="--whole-file" fi - # first, the normal directories, so that we can detect incompatible protocol + # first, the normal directories, so that we can detect + # incompatible protocol: RC=0 - eval rsync ${STUNNEL:+"'--rsh=$STUNNEL'"} \ + eval rsync ${STUNNEL:+"--rsh='$STUNNEL'"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ $WHOLE_FILE_OPT $FILTER "'$WSREP_SST_OPT_DATA/'" \ @@ -430,8 +441,9 @@ EOF case $RC in 12) RC=71 # EPROTO wsrep_log_error \ - "rsync server on the other end has incompatible protocol. " \ - "Make sure you have the same version of rsync on all nodes." + "rsync server on the other end has incompatible" \ + "protocol. Make sure you have the same version of" \ + "rsync on all nodes." ;; 22) RC=12 # ENOMEM ;; @@ -481,9 +493,9 @@ EOF find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \ -not -name '.zfs' -print0 | xargs -I{} -0 -P $backup_threads \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \ - --owner --group --perms --links --specials \ - --ignore-times --inplace --recursive --delete --quiet \ - $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \ + --owner --group --perms --links --specials --ignore-times \ + --inplace --recursive --delete --quiet $WHOLE_FILE_OPT \ + --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \ --exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/{}/" \ "rsync://$WSREP_SST_OPT_ADDR/{}" >&2 || RC=$? @@ -514,7 +526,8 @@ EOF fi rsync ${STUNNEL:+--rsh="$STUNNEL"} \ - --archive --quiet --checksum "$MAGIC_FILE" "rsync://$WSREP_SST_OPT_ADDR" + --archive --quiet --checksum "$MAGIC_FILE" \ + "rsync://$WSREP_SST_OPT_ADDR" echo "done $STATE" @@ -546,7 +559,8 @@ then check_round=0 while check_pid "$STUNNEL_PID" 1 do - wsrep_log_info "lingering stunnel daemon found at startup, waiting for it to exit" + wsrep_log_info "Lingering stunnel daemon found at startup," \ + "waiting for it to exit" check_round=$(( check_round + 1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "stunnel daemon already running." @@ -563,7 +577,8 @@ then check_round=0 while check_pid "$RSYNC_PID" 1 do - wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit" + wsrep_log_info "Lingering rsync daemon found at startup," \ + "waiting for it to exit" check_round=$(( check_round + 1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "rsync daemon already running." @@ -575,9 +590,7 @@ then [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" [ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE" - if [ -z "$STUNNEL" ]; then - [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" - fi + [ -z "$STUNNEL" ] && [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" ADDR="$WSREP_SST_OPT_ADDR" RSYNC_PORT="$WSREP_SST_OPT_PORT" @@ -628,19 +641,21 @@ EOF echo $$ > "$SST_PID" - if [ -z "$STUNNEL" ] - then - rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & + if [ -z "$STUNNEL" ]; then + rsync --daemon --no-detach --port "$RSYNC_PORT" \ + --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & RSYNC_REAL_PID=$! TRANSFER_REAL_PID=$RSYNC_REAL_PID TRANSFER_PID="$RSYNC_PID" else # Let's check if the path to the config file contains a space? + RSYNC_BIN=$(commandex 'rsync') if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -650,17 +665,18 @@ ${CHECK_OPT} ${CHECK_OPT_LOCAL} [rsync] accept = $STUNNEL_ACCEPT -exec = $(command -v rsync) +exec = $RSYNC_BIN execargs = rsync --server --daemon --config=$RSYNC_CONF . EOF else # The path contains a space, so we will run it via # shell with "eval" command: - export RSYNC_CMD="eval $(command -v rsync) --server --daemon --config='$RSYNC_CONF' ." + export RSYNC_CMD="eval '$RSYNC_BIN' --server --daemon --config='$RSYNC_CONF' ." cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT ${CAFILE_OPT} +${CAPATH_OPT} foreground = yes pid = $STUNNEL_PID debug = warning @@ -688,7 +704,8 @@ EOF # find out my Common Name get_openssl if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error 'openssl not found but it is required for authentication' + wsrep_log_error \ + 'openssl not found but it is required for authentication' exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \ @@ -703,7 +720,8 @@ EOF ADDR="$WSREP_SST_OPT_HOST" fi - until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT" + until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID \ + "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT" do sleep 0.2 done @@ -722,7 +740,7 @@ EOF if ! ps -p $MYSQLD_PID >/dev/null 2>&1 then wsrep_log_error \ - "Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly." + "Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly." kill -- -$MYSQLD_PID sleep 1 exit 32 @@ -768,10 +786,11 @@ EOF if [ -r "$MAGIC_FILE" ]; then if [ -n "$MY_SECRET" ]; then # check donor supplied secret - SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | \ + cut -d ' ' -f 2) if [ "$SECRET" != "$MY_SECRET" ]; then wsrep_log_error "Donor does not know my secret!" - wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'" exit 32 fi # remove secret from the magic file, and output diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index d9fcc942a71..fbf75729cc6 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -232,6 +232,12 @@ new_VioSSLFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; long ssl_ctx_options; DBUG_ENTER("new_VioSSLFd"); + + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + DBUG_PRINT("enter", ("key_file: '%s' cert_file: '%s' ca_file: '%s' ca_path: '%s' " "cipher: '%s' crl_file: '%s' crl_path: '%s'", @@ -379,6 +385,11 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + /* Turn off verification of servers certificate if both ca_file and ca_path is set to NULL @@ -411,6 +422,12 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; + + if (ca_file && ! ca_file[0]) ca_file = NULL; + if (ca_path && ! ca_path[0]) ca_path = NULL; + if (crl_file && ! crl_file[0]) crl_file = NULL; + if (crl_path && ! crl_path[0]) crl_path = NULL; + if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher, FALSE, error, crl_file, crl_path, tls_version))) From ef9517eb81cf6c278e88622b3fa4a668a8bcb13f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 15 Dec 2021 14:17:55 +0200 Subject: [PATCH 19/52] MDEV-27268 Failed InnoDB initialization leaves garbage files behind create_log_files(): Check log_set_capacity() before modifying or creating any log files. innobase_start_or_create_for_mysql(): If create_log_files() fails and we were initializing a new database, delete the system tablespace files before exiting. --- mysql-test/suite/innodb/r/log_file.result | 1 - mysql-test/suite/innodb/t/log_file.test | 3 --- storage/innobase/srv/srv0start.cc | 15 +++++++++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/innodb/r/log_file.result b/mysql-test/suite/innodb/r/log_file.result index b93bfc0d02b..952b9f3a3af 100644 --- a/mysql-test/suite/innodb/r/log_file.result +++ b/mysql-test/suite/innodb/r/log_file.result @@ -14,7 +14,6 @@ WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS FOUND 1 /File .path.to.non-existent.*ib_logfile101: 'create' returned OS error \d+/ in mysqld.1.err -# Remove ibdata1 & ibdata2 # Successfully let InnoDB create tablespaces SELECT COUNT(*) `1` FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb' diff --git a/mysql-test/suite/innodb/t/log_file.test b/mysql-test/suite/innodb/t/log_file.test index 8a82ab7f29f..7aca2336de6 100644 --- a/mysql-test/suite/innodb/t/log_file.test +++ b/mysql-test/suite/innodb/t/log_file.test @@ -67,9 +67,6 @@ eval $check_no_innodb; let SEARCH_PATTERN=File .path.to.non-existent.*ib_logfile101: 'create' returned OS error \d+; --source include/search_pattern_in_file.inc ---echo # Remove ibdata1 & ibdata2 ---remove_file $bugdir/ibdata1 ---remove_file $bugdir/ibdata2 --list_files $bugdir --echo # Successfully let InnoDB create tablespaces diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 9548730b359..9fc18272a2a 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -3,7 +3,7 @@ Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2021, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -426,6 +426,10 @@ create_log_files( return(DB_READ_ONLY); } + if (!log_set_capacity(srv_log_file_size_requested)) { + return(DB_ERROR); + } + /* Crashing after deleting the first file should be recoverable. The buffer pool was clean, and we can simply create all log files from the scratch. */ @@ -482,9 +486,6 @@ create_log_files( } log_init(srv_n_log_files); - if (!log_set_capacity(srv_log_file_size_requested)) { - return(DB_ERROR); - } fil_open_log_and_system_tablespace_files(); @@ -1936,6 +1937,12 @@ innobase_start_or_create_for_mysql() logfilename, dirnamelen, flushed_lsn, logfile0); if (err != DB_SUCCESS) { + for (Tablespace::const_iterator + i = srv_sys_space.begin(); + i != srv_sys_space.end(); i++) { + os_file_delete(innodb_data_file_key, + i->filepath()); + } return(srv_init_abort(err)); } } else { From 3691cc15751b01afaa807de1fb6f83b75668c479 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 15 Dec 2021 16:28:01 +0200 Subject: [PATCH 20/52] MDEV-18187 Aria engine: Redo phase failed with "error 192 when executing record redo_index_new_page" upon startup on a restored datadir The issue is that when recovery is about to create a new data or index page it check if the page already exits. If the page does not exists (file is too short) or contains wrong checksum, then the recovery code will recreate the page. The bug was that the code that checked if the page existed didn't take into account encrypted pages. Fixed by adding a check if page could not be encrypted solved the issue. I also added some code to silence decryption errors for new pages. Test case and some inspiration for how to solve this come from the pull request by alexandr.miloslavsky --- .../r/maria_recover_encrypted.result | 53 +++++++++++ .../t/maria_recover_encrypted.test | 90 +++++++++++++++++++ storage/maria/ma_blockrec.c | 10 ++- storage/maria/ma_check.c | 6 +- storage/maria/ma_crypt.c | 18 ++-- storage/maria/ma_key_recover.c | 3 +- storage/maria/maria_def.h | 1 + 7 files changed, 171 insertions(+), 10 deletions(-) create mode 100644 mysql-test/suite/large_tests/r/maria_recover_encrypted.result create mode 100644 mysql-test/suite/large_tests/t/maria_recover_encrypted.test diff --git a/mysql-test/suite/large_tests/r/maria_recover_encrypted.result b/mysql-test/suite/large_tests/r/maria_recover_encrypted.result new file mode 100644 index 00000000000..a7293d45db6 --- /dev/null +++ b/mysql-test/suite/large_tests/r/maria_recover_encrypted.result @@ -0,0 +1,53 @@ +DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS proc_insert_many; +CREATE TABLE t1 ( +field1 INTEGER NOT NULL, +field2 INTEGER NOT NULL, +field3 INTEGER NOT NULL, +KEY i_1 (field1), +KEY i_2 (field2), +KEY i_3 (field3), +KEY i_12 (field1, field2), +KEY i_13 (field1, field3), +KEY i_21 (field2, field1), +KEY i_23 (field2, field3), +KEY i_31 (field3, field1), +KEY i_32 (field3, field2), +KEY i_123 (field1, field2, field3), +KEY i_132 (field1, field3, field2), +KEY i_213 (field2, field1, field3), +KEY i_231 (field2, field3, field1), +KEY i_312 (field3, field1, field2), +KEY i_321 (field3, field2, field1) +) ENGINE=Aria; +CREATE PROCEDURE proc_insert_many() +BEGIN +DECLARE iRow INT DEFAULT 0; +insertRows: LOOP +IF (iRow = 70000) THEN +LEAVE insertRows; +END IF; +INSERT INTO t1 VALUES (1000000+iRow,2000000+iRow,3000000+iRow); +SET iRow = iRow + 1; +END LOOP insertRows; +END| +LOCK TABLES t1 WRITE; +CALL proc_insert_many(); +UNLOCK TABLES; +SET debug_dbug="d,crash_shutdown"; +shutdown; +ERROR HY000: Lost connection to MySQL server during query +SELECT * FROM t1 ORDER BY 1 DESC LIMIT 10; +field1 field2 field3 +1069999 2069999 3069999 +1069998 2069998 3069998 +1069997 2069997 3069997 +1069996 2069996 3069996 +1069995 2069995 3069995 +1069994 2069994 3069994 +1069993 2069993 3069993 +1069992 2069992 3069992 +1069991 2069991 3069991 +1069990 2069990 3069990 +DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS proc_insert_many; diff --git a/mysql-test/suite/large_tests/t/maria_recover_encrypted.test b/mysql-test/suite/large_tests/t/maria_recover_encrypted.test new file mode 100644 index 00000000000..4c590e5e1f9 --- /dev/null +++ b/mysql-test/suite/large_tests/t/maria_recover_encrypted.test @@ -0,0 +1,90 @@ +# MDEV-18187: If server crashes before flushing index pages in an +# encrypted Aria table, it could permanently fail to repair the table + +--source include/have_maria.inc +--source include/default_charset.inc + +# Cleanup +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS proc_insert_many; +--enable_warnings + +# -------- + +# Configure encryption +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc + +--write_file $MYSQLTEST_VARDIR/key.txt +1;76025E3ADC78D74819927DB02AAA4C35 +EOF + +--exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/key.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +# Create table with many indexes so that its index size grows quickly +# and it can be grown to needed size without too many inserts +CREATE TABLE t1 ( + field1 INTEGER NOT NULL, + field2 INTEGER NOT NULL, + field3 INTEGER NOT NULL, + KEY i_1 (field1), + KEY i_2 (field2), + KEY i_3 (field3), + KEY i_12 (field1, field2), + KEY i_13 (field1, field3), + KEY i_21 (field2, field1), + KEY i_23 (field2, field3), + KEY i_31 (field3, field1), + KEY i_32 (field3, field2), + KEY i_123 (field1, field2, field3), + KEY i_132 (field1, field3, field2), + KEY i_213 (field2, field1, field3), + KEY i_231 (field2, field3, field1), + KEY i_312 (field3, field1, field2), + KEY i_321 (field3, field2, field1) +) ENGINE=Aria; + +# Create procedures to insert many rows. +DELIMITER |; +CREATE PROCEDURE proc_insert_many() +BEGIN + DECLARE iRow INT DEFAULT 0; + insertRows: LOOP + IF (iRow = 70000) THEN + LEAVE insertRows; + END IF; + + INSERT INTO t1 VALUES (1000000+iRow,2000000+iRow,3000000+iRow); + SET iRow = iRow + 1; + END LOOP insertRows; +END| +DELIMITER ;| + +# Call the procedure to insert rows. +# Use 'LOCK TABLES' to make things a lot faster. +# Note that his code doesn't reproduce for some reason: +# INSERT INTO t1 SELECT 1000000+seq,2000000+seq,3000000+seq FROM seq_1_to_70000; +LOCK TABLES t1 WRITE; +CALL proc_insert_many(); +UNLOCK TABLES; + +# Crash and restart the server while it's still flushing index +--exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/key.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET debug_dbug="d,crash_shutdown"; +--error 2013 +shutdown; +--enable_reconnect +--source include/wait_until_connected_again.inc + +# Access the table to trigger repair; validate repaired data +SELECT * FROM t1 ORDER BY 1 DESC LIMIT 10; + +# -------- + +# Cleanup +DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS proc_insert_many; diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index 592aab6da41..667cc26758d 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -6379,16 +6379,19 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn, pin_method= PAGECACHE_PIN_LEFT_PINNED; share->pagecache->readwrite_flags&= ~MY_WME; + share->silence_encryption_errors= 1; buff= pagecache_read(share->pagecache, &info->dfile, page, 0, 0, PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE, &page_link.link); share->pagecache->readwrite_flags= share->pagecache->org_readwrite_flags; + share->silence_encryption_errors= 0; if (!buff) { /* Skip errors when reading outside of file and uninitialized pages */ if (!new_page || (my_errno != HA_ERR_FILE_TOO_SHORT && - my_errno != HA_ERR_WRONG_CRC)) + my_errno != HA_ERR_WRONG_CRC && + my_errno != HA_ERR_DECRYPTION_FAILED)) { DBUG_PRINT("error", ("Error %d when reading page", (int) my_errno)); goto err; @@ -6880,6 +6883,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, else { share->pagecache->readwrite_flags&= ~MY_WME; + share->silence_encryption_errors= 1; buff= pagecache_read(share->pagecache, &info->dfile, page, 0, 0, @@ -6887,10 +6891,12 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, PAGECACHE_LOCK_WRITE, &page_link.link); share->pagecache->readwrite_flags= share->pagecache-> org_readwrite_flags; + share->silence_encryption_errors= 0; if (!buff) { if (my_errno != HA_ERR_FILE_TOO_SHORT && - my_errno != HA_ERR_WRONG_CRC) + my_errno != HA_ERR_WRONG_CRC && + my_errno != HA_ERR_DECRYPTION_FAILED) { /* If not read outside of file */ pagecache_unlock_by_link(share->pagecache, page_link.link, diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 3a65cd61d08..98f9c49b9fa 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -4931,7 +4931,8 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) DBUG_RETURN(-1); } /* Retry only if wrong record, not if disk error */ - if (flag != HA_ERR_WRONG_IN_RECORD && flag != HA_ERR_WRONG_CRC) + if (flag != HA_ERR_WRONG_IN_RECORD && flag != HA_ERR_WRONG_CRC && + flag != HA_ERR_DECRYPTION_FAILED) { retry_if_quick(sort_param, flag); DBUG_RETURN(flag); @@ -6741,7 +6742,8 @@ read_next_page: PAGECACHE_READ_UNKNOWN_PAGE, PAGECACHE_LOCK_LEFT_UNLOCKED, 0))) { - if (my_errno == HA_ERR_WRONG_CRC) + if (my_errno == HA_ERR_WRONG_CRC || + my_errno == HA_ERR_DECRYPTION_FAILED) { /* Don't give errors for zero filled blocks. These can diff --git a/storage/maria/ma_crypt.c b/storage/maria/ma_crypt.c index 564edb4bbe8..33cf72b0b1e 100644 --- a/storage/maria/ma_crypt.c +++ b/storage/maria/ma_crypt.c @@ -345,7 +345,14 @@ static my_bool ma_crypt_index_post_read_hook(int res, const uint block_size= share->block_size; const uint page_used= _ma_get_page_used(share, args->page); - if (res == 0 && page_used <= block_size - CRC_SIZE) + if (res || + page_used < share->keypage_header || + page_used >= block_size - CRC_SIZE) + { + res= 1; + my_errno= HA_ERR_DECRYPTION_FAILED; + } + else { const uchar *src= args->page; uchar* dst= args->crypt_buf; @@ -506,10 +513,11 @@ static int ma_decrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data, if (! (rc == MY_AES_OK && dstlen == size)) { my_errno= HA_ERR_DECRYPTION_FAILED; - my_printf_error(HA_ERR_DECRYPTION_FAILED, - "failed to decrypt '%s' rc: %d dstlen: %u size: %u\n", - MYF(ME_FATAL|ME_ERROR_LOG), - share->open_file_name.str, rc, dstlen, size); + if (!share->silence_encryption_errors) + my_printf_error(HA_ERR_DECRYPTION_FAILED, + "failed to decrypt '%s' rc: %d dstlen: %u size: %u\n", + MYF(ME_FATAL|ME_ERROR_LOG), + share->open_file_name.str, rc, dstlen, size); return 1; } return 0; diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c index afa69fce444..2f28ec8d175 100644 --- a/storage/maria/ma_key_recover.c +++ b/storage/maria/ma_key_recover.c @@ -767,7 +767,8 @@ uint _ma_apply_redo_index_new_page(MARIA_HA *info, LSN lsn, &page_link.link))) { if (my_errno != HA_ERR_FILE_TOO_SHORT && - my_errno != HA_ERR_WRONG_CRC) + my_errno != HA_ERR_WRONG_CRC && + my_errno != HA_ERR_DECRYPTION_FAILED) { result= 1; goto err; diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 6c9649ede45..c51ae2b95f7 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -502,6 +502,7 @@ typedef struct st_maria_share my_bool key_del_used; /* != 0 if key_del is locked */ my_bool deleting; /* we are going to delete this table */ my_bool redo_error_given; /* Used during recovery */ + my_bool silence_encryption_errors; /* Used during recovery */ THR_LOCK lock; void (*lock_restore_status)(void *); /** From f1ca949f2bcb3a0bd32fbb2c0eed7ba7dd1e099f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 15 Dec 2021 13:16:29 +0200 Subject: [PATCH 21/52] Disable following tests from galera_3nodes suite * galera_pc_bootstrap * galera_ipv6_mariabackup * galera_ipv6_mariabackup_section * galera_ipv6_rsync * galera_ipv6_rsync_section * galera_ssl_reload * galera_toi_vote * galera_wsrep_schema_init because MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed --- mysql-test/suite/galera_3nodes/disabled.def | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index 9100db4d441..bbeddc8dcd8 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -15,6 +15,14 @@ galera_gtid_2_cluster : MDEV-23775 Galera test failure on galera_3nodes.galera_g galera_ist_gcache_rollover : MDEV-23578 WSREP: exception caused by message: {v=0,t=1,ut=255,o=4,s=0,sr=0,as=1,f=6,src=50524cfe,srcvid=view_id(REG,50524cfe,4),insvid=view_id(UNKNOWN,00000000,0),ru=00000000,r=[-1,-1],fs=75,nl=(} galera_load_data_ist : MDEV-24639 galera_3nodes.galera_load_data_ist MTR failed with SIGABRT: query 'reap' failed: 2013: Lost connection to MySQL server during query galera_load_data_ist : MDEV-24639 galera_3nodes.galera_load_data_ist MTR failed with SIGABRT: query 'reap' failed: 2013: Lost connection to MySQL server during query +galera_pc_bootstrap : MDEV-24097 MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed galera_safe_to_bootstrap : MDEV-24097 galera_3nodes.galera_safe_to_bootstrap MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed galera_slave_options_do : MDEV-8798 galera_slave_options_ignore : MDEV-8798 +galera_ipv6_mariabackup : MDEV-24097 MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed +galera_ipv6_mariabackup_section : MDEV-24097 MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed +galera_ipv6_rsync : MDEV-24097 MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed +galera_ipv6_rsync_section : MDEV-24097 MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed +galera_ssl_reload : MDEV-24097 MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed +galera_toi_vote : MDEV-24097 MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed +galera_wsrep_schema_init : MDEV-24097 MTR sporadaically fails: Failed to start mysqld or mysql_shutdown failed From 607b14c4dc3e052238ba58498607f70883f54a20 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 19 Oct 2021 16:41:45 +0300 Subject: [PATCH 22/52] Add --optimizer_trace option to mysqltest This enables optimizer_trace output for the next SQL command. Identical as if one would have done: - Store value of @@optimizer_trace - Set @optimizer_trace="enabled=on" - Run query - SELECT * from OPTIMIZER_TRACE - Restore value of @@optimizer_trace This is a great time saver when one wants to quickly check the optimizer trace for a query in a mtr test. --- client/mysqltest.cc | 102 ++++++++++++++++++++++++++++++- mysql-test/main/opt_trace.result | 2 - mysql-test/main/opt_trace.test | 4 +- 3 files changed, 102 insertions(+), 6 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 3ea279218eb..ad2eca21ec9 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -132,6 +132,7 @@ static my_bool disable_info= 1; static my_bool abort_on_error= 1, opt_continue_on_error= 0; static my_bool server_initialized= 0; static my_bool is_windows= 0; +static my_bool optimizer_trace_active= 0; static char **default_argv; static const char *load_default_groups[]= { "mysqltest", "mariadb-test", "client", "client-server", "client-mariadb", @@ -388,6 +389,7 @@ enum enum_commands { Q_MOVE_FILE, Q_REMOVE_FILES_WILDCARD, Q_SEND_EVAL, Q_ENABLE_PREPARE_WARNINGS, Q_DISABLE_PREPARE_WARNINGS, Q_RESET_CONNECTION, + Q_OPTIMIZER_TRACE, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ Q_COMMENT_WITH_COMMAND, @@ -498,7 +500,7 @@ const char *command_names[]= "enable_prepare_warnings", "disable_prepare_warnings", "reset_connection", - + "optimizer_trace", 0 }; @@ -643,6 +645,9 @@ void free_all_replace(){ } void var_set_int(const char* name, int value); +void enable_optimizer_trace(struct st_connection *con); +void display_optimizer_trace(struct st_connection *con, + DYNAMIC_STRING *ds); class LogFile { @@ -1541,6 +1546,8 @@ static void die(const char *fmt, ...) { char buff[DIE_BUFF_SIZE]; va_list args; + DBUG_ENTER("die"); + va_start(args, fmt); make_error_message(buff, sizeof(buff), fmt, args); really_die(buff); @@ -7841,7 +7848,7 @@ static void handle_no_active_connection(struct st_command *command, */ void run_query_normal(struct st_connection *cn, struct st_command *command, - int flags, char *query, size_t query_len, + int flags, const char *query, size_t query_len, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings) { MYSQL_RES *res= 0; @@ -7960,6 +7967,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, /* If we come here the query is both executed and read successfully */ handle_no_error(command); + display_optimizer_trace(cn, ds); revert_properties(); end: @@ -9580,6 +9588,9 @@ int main(int argc, char **argv) case Q_RESET_CONNECTION: do_reset_connection(); break; + case Q_OPTIMIZER_TRACE: + enable_optimizer_trace(cur_con); + break; case Q_SEND_SHUTDOWN: handle_command_error(command, mysql_shutdown(cur_con->mysql, @@ -11238,3 +11249,90 @@ char *mysql_authentication_dialog_ask(MYSQL *mysql, int type, return buf; } + +/* + Enable optimizer trace for the next command +*/ + +LEX_CSTRING enable_optimizer_trace_query= +{ + STRING_WITH_LEN("set @mysqltest_save_optimzer_trace=@@optimizer_trace,@@optimizer_trace=\"enabled=on\"") +}; + +LEX_CSTRING restore_optimizer_trace_query= +{ + STRING_WITH_LEN("set @@optimizer_trace=@mysqltest_save_optimzer_trace") +}; + + +LEX_CSTRING display_optimizer_trace_query +{ + STRING_WITH_LEN("SELECT * from information_schema.optimizer_trace") +}; + + +void enable_optimizer_trace(struct st_connection *con) +{ + MYSQL *mysql= con->mysql; + my_bool save_ps_protocol_enabled= ps_protocol_enabled; + my_bool save_view_protocol_enabled= view_protocol_enabled; + DYNAMIC_STRING ds_result; + DYNAMIC_STRING ds_warnings; + struct st_command command; + DBUG_ENTER("enable_optimizer_trace"); + + if (!mysql) + DBUG_VOID_RETURN; + ps_protocol_enabled= view_protocol_enabled= 0; + + init_dynamic_string(&ds_result, NULL, 0, 256); + init_dynamic_string(&ds_warnings, NULL, 0, 256); + bzero(&command, sizeof(command)); + + run_query_normal(con, &command, QUERY_SEND_FLAG | QUERY_REAP_FLAG, + enable_optimizer_trace_query.str, + enable_optimizer_trace_query.length, + &ds_result, &ds_warnings); + dynstr_free(&ds_result); + dynstr_free(&ds_warnings); + ps_protocol_enabled= save_ps_protocol_enabled; + view_protocol_enabled= save_view_protocol_enabled; + optimizer_trace_active= 1; + DBUG_VOID_RETURN; +} + + +void display_optimizer_trace(struct st_connection *con, + DYNAMIC_STRING *ds) +{ + my_bool save_ps_protocol_enabled= ps_protocol_enabled; + my_bool save_view_protocol_enabled= view_protocol_enabled; + DYNAMIC_STRING ds_result; + DYNAMIC_STRING ds_warnings; + struct st_command command; + DBUG_ENTER("display_optimizer_trace"); + + if (!optimizer_trace_active) + DBUG_VOID_RETURN; + + optimizer_trace_active= 0; + ps_protocol_enabled= view_protocol_enabled= 0; + + init_dynamic_string(&ds_result, NULL, 0, 256); + init_dynamic_string(&ds_warnings, NULL, 0, 256); + bzero(&command, sizeof(command)); + + run_query_normal(con, &command, QUERY_SEND_FLAG | QUERY_REAP_FLAG, + display_optimizer_trace_query.str, + display_optimizer_trace_query.length, + ds, &ds_warnings); + run_query_normal(con, &command, QUERY_SEND_FLAG | QUERY_REAP_FLAG, + restore_optimizer_trace_query.str, + restore_optimizer_trace_query.length, + ds, &ds_warnings); + dynstr_free(&ds_result); + dynstr_free(&ds_warnings); + ps_protocol_enabled= save_ps_protocol_enabled; + view_protocol_enabled= save_view_protocol_enabled; + DBUG_VOID_RETURN; +} diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index f2b69fb1eaa..0e4477e1fd9 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -571,7 +571,6 @@ create view v2 as select a from t2; explain select * from v2 ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 10 -select * from information_schema.OPTIMIZER_TRACE; QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES explain select * from v2 { "steps": [ @@ -685,7 +684,6 @@ explain select * from v1 ; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL NULL NULL NULL NULL 10 2 DERIVED t1 ALL NULL NULL NULL NULL 10 Using temporary; Using filesort -select * from information_schema.OPTIMIZER_TRACE; QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES explain select * from v1 { "steps": [ diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index 2084940fbc5..9d4794855e0 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -48,12 +48,12 @@ create view v1 as select a from t1 group by b; create view v2 as select a from t2; --echo # Mergeable view +--optimizer_trace explain select * from v2 ; -select * from information_schema.OPTIMIZER_TRACE; --echo # Non-Mergeable view +--optimizer_trace explain select * from v1 ; -select * from information_schema.OPTIMIZER_TRACE; drop table t1,t2; drop view v1,v2; From 136bcfdf7504092e7e49eba95e8be010da44c594 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 15 Dec 2021 15:12:06 +0300 Subject: [PATCH 23/52] MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT Followup to fix for MDEV-25858: When test_if_skip_sort_order() decides to use an index to satisfy ORDER BY ... LIMIT clause, it should disable "Range Checked for Each Record" optimization. Do this in all cases. --- mysql-test/r/order_by_innodb.result | 23 +++++++++++++++++++++++ mysql-test/t/order_by_innodb.test | 22 ++++++++++++++++++++++ sql/sql_select.cc | 8 ++++++++ 3 files changed, 53 insertions(+) diff --git a/mysql-test/r/order_by_innodb.result b/mysql-test/r/order_by_innodb.result index 14b9b861a14..28922ef65f2 100644 --- a/mysql-test/r/order_by_innodb.result +++ b/mysql-test/r/order_by_innodb.result @@ -198,5 +198,28 @@ id id 1 NULL 2 1 3 3 +# +# MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT +# +# This must NOT have "Range checked for each record" without any +# provisions to produce rows in the required ordering: +explain +select +t1.id,t2.id +from +t1 left join +t2 on t2.id2 = t1.id and +t2.id = (select dd.id +from t2 dd +where +dd.id2 = t1.id and +d1 > '2019-02-06 00:00:00' + order by +dd.d1, dd.d2, dd.id limit 1 +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL # Using index +1 PRIMARY t2 eq_ref PRIMARY,id2 PRIMARY 4 func # Using where +2 DEPENDENT SUBQUERY dd range id2,for_latest_sort for_latest_sort 6 NULL # Using where drop table t1,t2; # End of 10.2 tests diff --git a/mysql-test/t/order_by_innodb.test b/mysql-test/t/order_by_innodb.test index 97c043b8dbc..af12644c073 100644 --- a/mysql-test/t/order_by_innodb.test +++ b/mysql-test/t/order_by_innodb.test @@ -184,6 +184,28 @@ from order by dd.d1 desc, dd.d2 desc, dd.id desc limit 1 ); + +--echo # +--echo # MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT +--echo # + +--echo # This must NOT have "Range checked for each record" without any +--echo # provisions to produce rows in the required ordering: +--replace_column 9 # +explain +select + t1.id,t2.id +from + t1 left join + t2 on t2.id2 = t1.id and + t2.id = (select dd.id + from t2 dd + where + dd.id2 = t1.id and + d1 > '2019-02-06 00:00:00' + order by + dd.d1, dd.d2, dd.id limit 1 + ); drop table t1,t2; --echo # End of 10.2 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 47422116e38..3079145c1b9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -21986,7 +21986,15 @@ check_reverse_order: } } else if (select && select->quick) + { + /* Cancel "Range checked for each record" */ + if (tab->use_quick == 2) + { + tab->use_quick= 1; + tab->read_first_record= join_init_read_record; + } select->quick->need_sorted_output(); + } tab->read_record.unlock_row= (tab->type == JT_EQ_REF) ? join_read_key_unlock_row : rr_unlock_row; From 20f22dfa2f2d5bb5a1511d42a5bb18fbf469e812 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 15 Dec 2021 23:29:04 +0200 Subject: [PATCH 24/52] Fixed some tests that failes when built with valgrind Example build: ./BUILD/compile-pentium64-valgrind-max Fixes: - sp-no-valgrind failed if binary was built for valgrind as in this case mem_root is allocated in very small hunks which the test cannot handle. Fixed by testing of valgrind build - truncate_notembedded failed in reap because of more memory used. Fixed by allowing reap to fail too --- mysql-test/include/not_valgrind_build.inc | 4 ++++ mysql-test/main/sp-no-valgrind.test | 2 +- mysql-test/main/truncate_notembedded.test | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 mysql-test/include/not_valgrind_build.inc diff --git a/mysql-test/include/not_valgrind_build.inc b/mysql-test/include/not_valgrind_build.inc new file mode 100644 index 00000000000..2b60f11bfc7 --- /dev/null +++ b/mysql-test/include/not_valgrind_build.inc @@ -0,0 +1,4 @@ +if (`select version() like '%valgrind%'`) +{ + skip Does not run with binaries built with valgrind; +} diff --git a/mysql-test/main/sp-no-valgrind.test b/mysql-test/main/sp-no-valgrind.test index 89f8250bf72..21e52f2d3d5 100644 --- a/mysql-test/main/sp-no-valgrind.test +++ b/mysql-test/main/sp-no-valgrind.test @@ -1,5 +1,5 @@ ---source include/not_valgrind.inc +--source include/not_valgrind_build.inc --echo # MDEV-20699 do not cache SP in SHOW CREATE --echo # Warmup round, this might allocate some memory for session variable diff --git a/mysql-test/main/truncate_notembedded.test b/mysql-test/main/truncate_notembedded.test index c1fab2d3609..8b6d2becfa9 100644 --- a/mysql-test/main/truncate_notembedded.test +++ b/mysql-test/main/truncate_notembedded.test @@ -18,6 +18,7 @@ SELECT * FROM t1; UNLOCK TABLES; --connection con1 +--error 0,ER_OPTION_PREVENTS_STATEMENT --reap # This may work or fail as different servers uses different amount of # memory and the statement may work or not. What is important is that we From 2776635cb98d35867447d375fdc04a44ef11a697 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 19 May 2021 14:56:09 +1000 Subject: [PATCH 25/52] MDEV-24788: mariadbd --help Can't lock aria control file ... '/var/lib/mysql/aria_log_control' for exclusive use, error: 11 As such don't lock under aria_readonly (which is set by opt_help in the handler initialization. Fixes: 8eba777c2bbad7721c818936a3a0ced3b2fcd59c --- mysql-test/main/mysqld--help-aria.result | 4 ---- mysql-test/main/mysqld--help-aria.test | 7 +------ storage/maria/ma_control_file.c | 4 ++-- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/mysql-test/main/mysqld--help-aria.result b/mysql-test/main/mysqld--help-aria.result index 70e7d8930c4..fb44c3ea3ee 100644 --- a/mysql-test/main/mysqld--help-aria.result +++ b/mysql-test/main/mysqld--help-aria.result @@ -1,7 +1,3 @@ -[ERROR] mariadbd: Can't lock aria aria_log_control for exclusive use, error: #. Will retry for 0 seconds -[ERROR] Plugin 'Aria' init function returned error. -[ERROR] Plugin 'Aria' registration as a STORAGE ENGINE failed. -[Warning] Could not open mysql.plugin table: "Unknown storage engine 'Aria'". Some options may be missing from the help text # # Check that we don't write any data to wrong or not existing datadir # diff --git a/mysql-test/main/mysqld--help-aria.test b/mysql-test/main/mysqld--help-aria.test index 253a46492f0..55131e9e4eb 100644 --- a/mysql-test/main/mysqld--help-aria.test +++ b/mysql-test/main/mysqld--help-aria.test @@ -2,15 +2,10 @@ # Check errors from mysqld--help when providing different datadir # -# We can't run this test on windows as windows doesn't provide file locking -# which the first exec requires. - ---source include/not_windows.inc - --let $args=--table-cache=5 --max-connections=10 --log-warnings=1 --silent-startup --lower-case-table-names=1 --help --verbose --exec $MYSQLD_CMD $args > $MYSQL_TMP_DIR/mysqld--help2.txt 2> $MYSQL_TMP_DIR/mysqld--help2.err ---replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /control file '.*aria_log_control'/aria_log_control/ /error: \d+/error: #/ +--replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // --cat_file $MYSQL_TMP_DIR/mysqld--help2.err --echo # diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c index 65b8b0922aa..af1708c72b2 100644 --- a/storage/maria/ma_control_file.c +++ b/storage/maria/ma_control_file.c @@ -314,7 +314,7 @@ CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, errmsg= "Can't create file"; goto err; } - if (lock_control_file(name, wait_for_lock)) + if (!aria_readonly && lock_control_file(name, wait_for_lock)) { error= CONTROL_FILE_LOCKED; errmsg= lock_failed_errmsg; @@ -332,7 +332,7 @@ CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, } /* lock it before reading content */ - if (lock_control_file(name, wait_for_lock)) + if (!aria_readonly && lock_control_file(name, wait_for_lock)) { error= CONTROL_FILE_LOCKED; errmsg= lock_failed_errmsg; From fff8ac2e966ac123a091a3e1be22b59cbc1c7e9b Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Mon, 8 Nov 2021 15:22:06 +0700 Subject: [PATCH 26/52] MDEV-21866: Assertion `!result' failed in convert_const_to_int upon 2nd execution of PS Consider the following use case: MariaDB [test]> CREATE TABLE t1 (field1 BIGINT DEFAULT -1); MariaDB [test]> CREATE VIEW v1 AS SELECT DISTINCT field1 FROM t1; Repeated execution of the following query as a Prepared Statement MariaDB [test]> PREPARE stmt FROM 'SELECT * FROM v1 WHERE field1 <=> NULL'; MariaDB [test]> EXECUTE stmt; results in a crash for a server built with DEBUG. MariaDB [test]> EXECUTE stmt; ERROR 2013 (HY000): Lost connection to MySQL server during query Assertion failed: (!result), function convert_const_to_int, file item_cmpfunc.cc, line 476. Abort trap: 6 (core dumped) The crash inside the function convert_const_to_int() happens by the reason that the value -1 is stored in an instance of the class Field_longlong on restoring its original value in the statement result= field->store(orig_field_val, TRUE); that leads to assigning the value 1 to the variable 'result' with subsequent crash in the DBUG_ASSERT statement following it DBUG_ASSERT(!result); The main matter here is why this assertion failure happens on the second execution of the prepared statement and doens't on the first one. On first handling of the statement 'EXECUTE stmt;' a temporary table is created for serving the query involving the view 'v1'. The table is created by the function create_tmp_table() in the following calls trace: (trace #1) JOIN::prepare (at sql_select.cc:725) st_select_lex::handle_derived LEX::handle_list_of_derived TABLE_LIST::handle_derived mysql_handle_single_derived mysql_derived_prepare select_union::create_result_table create_tmp_table Note, that the data member TABLE::status of a TABLE instance returned by the function create_tmp_table() has the value 0. Later the function setup_table_map() is called on the TABLE instance just created for the sake of the temporary table (calls trace #2 is below): JOIN::prepare (at sql_select.cc:737) setup_tables_and_check_access setup_tables setup_table_map where the data member TABLE::status is set to the value STATUS_NO_RECORD. After that when execution of the method JOIN::prepare reaches calling of the function setup_without_group() the following calls trace is invoked JOIN::prepare setup_without_group setup_conds Item_func::fix_fields Item_func_equal::fix_length_and_dec Item_bool_rowready_func2::fix_length_and_dec Item_func::setup_args_and_comparator Item_func::convert_const_compared_to_int_field convert_const_to_int There is the following code snippet in the function convert_const_to_int() at the line item_cmpfunc.cc:448 bool save_field_value= (field_item->const_item() || !(field->table->status & STATUS_NO_RECORD)); Since field->table->status has bits STATUS_NO_RECORD set the variable save_field_value is false and therefore neither the method Field_longlong::val_int() nor the method Field_longlong::store is called on the Field instance that has the numeric value -1. That is the reason why first execution of the Prepared Statement for the query 'SELECT * FROM v1 WHERE field1 <=> NULL' is successful. On second running of the statement 'EXECUTE stmt' a new temporary tables is also created by running the calls trace #1 but the trace #2 is not executed by the reason that data member SELECT_LEX::first_cond_optimization has been set to false on first execution of the prepared statemet (in the method JOIN::optimize_inner()). As a consequence, the data member TABLE::status for a temporary table just created doesn't have the flags STATUS_NO_RECORD set and therefore on re-execution of the prepared statement the methods Field_longlong::val_int() and Field_longlong::store() are called for the field having the value -1 and the DBUG_ASSERT(!result) is fired. To fix the issue the data member TABLE::status has to be assigned the value STATUS_NO_RECORD in every place where the macros empty_record() is called to emptify a record for just instantiated TABLE object created on behalf the new temporary table. --- mysql-test/r/ps.result | 13 +++++++++++++ mysql-test/t/ps.test | 16 ++++++++++++++++ sql/sql_select.cc | 3 ++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f1f779ef03f..1cd41e5b3a4 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -5474,5 +5474,18 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables DEALLOCATE PREPARE stmt; DROP TABLE t1, t2, t3; +# +# MDEV-21866: Assertion `!result' failed in convert_const_to_int upon 2nd execution of PS +# +CREATE TABLE t1 (a BIGINT DEFAULT -1); +CREATE VIEW v1 AS SELECT DISTINCT a FROM t1; +PREPARE stmt FROM 'SELECT * FROM v1 WHERE a <=> NULL'; +EXECUTE stmt; +a +EXECUTE stmt; +a +DEALLOCATE PREPARE stmt; +DROP VIEW v1; +DROP TABLE t1; # End of 10.2 tests # diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 2e7b43ad748..4097d28a949 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -4961,5 +4961,21 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; DROP TABLE t1, t2, t3; +--echo # +--echo # MDEV-21866: Assertion `!result' failed in convert_const_to_int upon 2nd execution of PS +--echo # + +CREATE TABLE t1 (a BIGINT DEFAULT -1); +CREATE VIEW v1 AS SELECT DISTINCT a FROM t1; +PREPARE stmt FROM 'SELECT * FROM v1 WHERE a <=> NULL'; +EXECUTE stmt; +EXECUTE stmt; + +# Cleanup +DEALLOCATE PREPARE stmt; +DROP VIEW v1; +DROP TABLE t1; + + --echo # End of 10.2 tests --echo # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3079145c1b9..a331f4f3dbc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -17556,7 +17556,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List &fields, // Make empty record so random data is not written to disk empty_record(table); - + table->status= STATUS_NO_RECORD; thd->mem_root= mem_root_save; DBUG_RETURN(table); @@ -18557,6 +18557,7 @@ bool instantiate_tmp_table(TABLE *table, KEY *keyinfo, return TRUE; // Make empty record so random data is not written to disk empty_record(table); + table->status= STATUS_NO_RECORD; } if (open_tmp_table(table)) return TRUE; From a65d01a4cf04c744f9355bec186430540ce6ba08 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Wed, 20 Oct 2021 19:24:31 +0700 Subject: [PATCH 27/52] MDEV-23182: Server crashes in Item::fix_fields_if_needed / table_value_constr::prepare upon 2nd execution of PS Repeating execution of a query containing the clause IN with string literals in environment where the server variable in_predicate_conversion_threshold is set results in server abnormal termination in case the query is run as a Prepared Statement and conversion of charsets for string values in the query are required. The reason for server abnormal termination is that instances of the class Item_string created on transforming the IN clause into subquery were created on runtime memory root that is deallocated on finishing execution of Prepared statement. On the other hand, references to Items placed on deallocated memory root still exist in objects of the class table_value_constr. Subsequent running of the same prepared statement leads to dereferencing of pointers to already deallocated memory that could lead to undefined behaviour. To fix the issue the values being pushed into a values list for TVC are created by cloning their original items. This way the cloned items are allocate on the PS memroot and as consequences no dangling pointer does more exist. --- mysql-test/main/table_value_constr.result | 42 +++++++++++++++++++++ mysql-test/main/table_value_constr.test | 46 +++++++++++++++++++++++ sql/sql_tvc.cc | 8 +++- 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result index 1d1cd054556..7ff5fb7fa5e 100644 --- a/mysql-test/main/table_value_constr.result +++ b/mysql-test/main/table_value_constr.result @@ -3100,4 +3100,46 @@ select * from (values (3),(7),(1) union values (2),(4) order by 1 limit 2) as dt 1 2 drop table t1; +# +# MDEV-23182: Server crashes in +# Item::fix_fields_if_needed / table_value_constr::prepare upon 2nd execution of PS +# +SET @save_in_predicate_conversion_threshold=@@in_predicate_conversion_threshold; +SET in_predicate_conversion_threshold=2; +CREATE TABLE t1 (c VARCHAR(10)) DEFAULT CHARSET=utf8; +PREPARE stmt FROM "SELECT * FROM t1 WHERE c IN ('10','20')"; +EXECUTE stmt; +c +# Without the patch second execution of the prepared statement 'stmt' +# results in crash. +EXECUTE stmt; +c +DEALLOCATE PREPARE stmt; +DROP TABLE t1; +# Check that the query without conversion doesn't crash server +CREATE TABLE t1 (c VARCHAR(10)); +PREPARE stmt FROM "SELECT * FROM t1 WHERE c IN ('10','20')"; +EXECUTE stmt; +c +EXECUTE stmt; +c +DEALLOCATE PREPARE stmt; +DROP TABLE t1; +# Test case for a row expression in the left part of the IN clause +CREATE TABLE t1 (a VARCHAR(3), b VARCHAR(3)) DEFAULT CHARSET=utf8; +PREPARE stmt FROM "SELECT * FROM t1 WHERE (a, b) IN (('10', '10'), ('20', '20'))"; +EXECUTE stmt; +a b +EXECUTE stmt; +a b +DROP TABLE t1; +# Check that the query without conversion is handled successfully +CREATE TABLE t1 (a VARCHAR(3), b VARCHAR(3)); +PREPARE stmt FROM "SELECT * FROM t1 WHERE (a, b) IN (('10', '10'), ('20', '20'))"; +EXECUTE stmt; +a b +EXECUTE stmt; +a b +DROP TABLE t1; +SET @@in_predicate_conversion_threshold = @save_in_predicate_conversion_threshold; End of 10.3 tests diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test index d13962579cc..673e7dcdc6e 100644 --- a/mysql-test/main/table_value_constr.test +++ b/mysql-test/main/table_value_constr.test @@ -1650,4 +1650,50 @@ select * from (values (3),(7),(1) union values (2),(4) order by 1 limit 2) as dt drop table t1; +--echo # +--echo # MDEV-23182: Server crashes in +--echo # Item::fix_fields_if_needed / table_value_constr::prepare upon 2nd execution of PS +--echo # +SET @save_in_predicate_conversion_threshold=@@in_predicate_conversion_threshold; +SET in_predicate_conversion_threshold=2; + +CREATE TABLE t1 (c VARCHAR(10)) DEFAULT CHARSET=utf8; +PREPARE stmt FROM "SELECT * FROM t1 WHERE c IN ('10','20')"; +EXECUTE stmt; +--echo # Without the patch second execution of the prepared statement 'stmt' +--echo # results in crash. +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +DROP TABLE t1; + +--echo # Check that the query without conversion doesn't crash server +CREATE TABLE t1 (c VARCHAR(10)); +PREPARE stmt FROM "SELECT * FROM t1 WHERE c IN ('10','20')"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +DROP TABLE t1; + +--echo # Test case for a row expression in the left part of the IN clause +CREATE TABLE t1 (a VARCHAR(3), b VARCHAR(3)) DEFAULT CHARSET=utf8; +PREPARE stmt FROM "SELECT * FROM t1 WHERE (a, b) IN (('10', '10'), ('20', '20'))"; + +EXECUTE stmt; +EXECUTE stmt; + +DROP TABLE t1; + +--echo # Check that the query without conversion is handled successfully +CREATE TABLE t1 (a VARCHAR(3), b VARCHAR(3)); +PREPARE stmt FROM "SELECT * FROM t1 WHERE (a, b) IN (('10', '10'), ('20', '20'))"; + +EXECUTE stmt; +EXECUTE stmt; + +DROP TABLE t1; + +SET @@in_predicate_conversion_threshold = @save_in_predicate_conversion_threshold; + --echo End of 10.3 tests diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 96c5223ee6a..3866b7c9352 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -539,7 +539,10 @@ bool Item_func_in::create_value_list_for_tvc(THD *thd, if (is_list_of_rows) { - Item_row *row_list= (Item_row *)(args[i]); + Item_row *row_list= (Item_row *)(args[i]->build_clone(thd)); + + if (!row_list) + return true; for (uint j=0; j < row_list->cols(); j++) { @@ -561,7 +564,8 @@ bool Item_func_in::create_value_list_for_tvc(THD *thd, sprintf(col_name, "_col_%i", 1); args[i]->set_name(thd, col_name, strlen(col_name), thd->charset()); } - if (tvc_value->push_back(args[i]->real_item())) + Item *arg_clone= args[i]->build_clone(thd); + if (!arg_clone || tvc_value->push_back(arg_clone)) return true; } From 3fd80d08740d3ad2426bfb8eb9debc40d96e2a20 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 16 Dec 2021 23:13:45 +0300 Subject: [PATCH 28/52] MDEV-27244 Table corruption upon adding serial data type MDEV-25803 excluded some cases from key sort upon alter table. That particularly depends on ALTER_ADD_INDEX flag. Creating a column of SERIAL data type missed that flag. Though equivalent operation alter table t1 add x bigint unsigned not null auto_increment unique; has ALTER_ADD_INDEX flag. --- mysql-test/suite/versioning/r/partition.result | 9 +++++++++ mysql-test/suite/versioning/t/partition.test | 10 ++++++++++ sql/sql_yacc.yy | 1 + sql/sql_yacc_ora.yy | 1 + 4 files changed, 21 insertions(+) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 6472c0480c3..8344e91a34f 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -746,4 +746,13 @@ explain partitions select * from t1; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pn # NULL NULL NULL NULL # # drop table t1; +# +# MDEV-27244 Table corruption upon adding serial data type +# +create table t1 (f int, key(f)) with system versioning +partition by system_time limit 10 (partition p0 history, partition pn current); +alter table t1 add x serial; +alter table t1 add partition (partition p1 history); +alter table t1 add partition (partition p2 history); +drop table t1; # End of 10.3 tests diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index c5f6b242b53..6eeb305c218 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -727,6 +727,16 @@ explain partitions select * from t1 for system_time as of '2000-01-01 02:00:00'; explain partitions select * from t1; drop table t1; +--echo # +--echo # MDEV-27244 Table corruption upon adding serial data type +--echo # +create table t1 (f int, key(f)) with system versioning +partition by system_time limit 10 (partition p0 history, partition pn current); +alter table t1 add x serial; +alter table t1 add partition (partition p1 history); +alter table t1 add partition (partition p2 history); +drop table t1; + --echo # End of 10.3 tests --source suite/versioning/common_finish.inc diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b26ddcbb9e5..01e3922040b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6783,6 +6783,7 @@ field_type_or_serial: Lex->last_field->set_handler(&type_handler_longlong); Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | UNIQUE_KEY_FLAG; + Lex->alter_info.flags|= ALTER_ADD_INDEX; } opt_serial_attribute ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 93315add399..5e17e41a940 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -6625,6 +6625,7 @@ field_type_or_serial: Lex->last_field->set_handler(&type_handler_longlong); Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | UNIQUE_KEY_FLAG; + Lex->alter_info.flags|= ALTER_ADD_INDEX; } opt_serial_attribute ; From 85defc4764860613742af23acf954cfdd9397553 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Fri, 17 Dec 2021 04:44:43 +0100 Subject: [PATCH 29/52] MDEV-27181 fixup: compatibility with Windows + small corrections 1) Removed symlinks that are not very well supported in tar under Windows. 2) Added comment + changed code formatting in viosslfactories.c 3) Fixed a small bug in the yassl code. 4) Fixed a typo in the script code. --- extra/yassl/src/ssl.cpp | 2 +- mysql-test/std_data/capath/3106f582.0 | 80 +++++++++++++++++++++++++- mysql-test/std_data/capath/cacert.pem | 79 -------------------------- mysql-test/std_data/capath/ed1f42db.0 | 80 +++++++++++++++++++++++++- scripts/wsrep_sst_common.sh | 2 +- vio/viosslfactories.c | 81 +++++++++++++++++++++++---- 6 files changed, 229 insertions(+), 95 deletions(-) mode change 120000 => 100644 mysql-test/std_data/capath/3106f582.0 delete mode 100644 mysql-test/std_data/capath/cacert.pem mode change 120000 => 100644 mysql-test/std_data/capath/ed1f42db.0 diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index c4adb4692be..eac691315b7 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -773,7 +773,7 @@ void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback vc) int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file, const char* path) { - int ret = SSL_FAILURE; + int ret = SSL_SUCCESS; if (file) ret = read_file(ctx, file, SSL_FILETYPE_PEM, CA); diff --git a/mysql-test/std_data/capath/3106f582.0 b/mysql-test/std_data/capath/3106f582.0 deleted file mode 120000 index 1310cfcff20..00000000000 --- a/mysql-test/std_data/capath/3106f582.0 +++ /dev/null @@ -1 +0,0 @@ -cacert.pem \ No newline at end of file diff --git a/mysql-test/std_data/capath/3106f582.0 b/mysql-test/std_data/capath/3106f582.0 new file mode 100644 index 00000000000..23dda2318e1 --- /dev/null +++ b/mysql-test/std_data/capath/3106f582.0 @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + d0:4d:23:85:ee:59:b3:fa + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Validity + Not Before: Jan 27 10:11:10 2019 GMT + Not After : Jan 22 10:11:10 2039 GMT + Subject: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e8:0e:a7:84:d3:75:30:06:30:b2:10:b9:d1:88: + 36:2b:5e:f8:c8:44:57:cb:67:72:ab:96:95:33:d5: + 88:d1:8f:23:50:98:ba:6d:20:00:80:bd:35:d5:c1: + bf:98:49:c4:0a:15:4a:34:a6:21:9b:2e:8c:15:09: + f0:63:81:02:c2:7c:e2:53:e0:f7:a1:1a:40:5e:8f: + 41:4a:4c:56:d4:20:f1:d5:a7:c1:53:2e:ff:7e:37: + 17:cc:7e:74:bd:e2:22:33:ce:8c:77:62:a4:c5:3f: + 44:35:7b:7e:b9:f5:7d:8c:7a:27:58:fd:2c:42:86: + 2e:e7:6b:01:99:7b:fe:7d:a7:a1:4f:3e:39:39:54: + 1f:61:de:74:66:d1:77:4f:43:1b:66:70:29:85:de: + fc:8f:8e:1b:7b:a2:66:48:26:7f:9b:a6:fd:4a:e4: + dc:eb:ed:bd:f8:e3:f1:57:98:13:6f:f1:a3:2a:e3: + 73:bd:8d:7c:6f:4b:59:35:bc:b5:42:3e:99:a7:13: + 8d:be:2e:5c:9a:c6:5b:ab:ae:bf:00:e9:c8:ee:05: + 22:8e:d5:67:1a:47:9a:6d:9c:f9:42:3e:15:34:f8: + 31:ec:b4:7e:d3:92:95:b0:b8:f9:66:f3:bd:1d:31: + 2c:b1:90:62:a1:f8:4e:a6:5d:26:22:f0:e1:fe:16: + 2b:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + X509v3 Authority Key Identifier: + keyid:CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + df:fd:74:29:5b:5e:9a:8b:09:02:40:59:73:cb:71:47:3f:97: + 3d:a9:fd:c4:8c:01:29:c9:86:b8:71:55:ff:72:0e:50:dc:c8: + b5:e6:91:41:52:47:21:30:cc:4d:e7:3b:4b:db:55:ea:7d:46: + eb:53:e0:b7:1b:80:7c:b1:0c:d3:d1:bc:a0:73:ae:96:1f:fd: + 05:52:7e:54:d5:03:52:69:7b:34:5f:27:d7:98:da:98:76:73: + e6:bb:50:59:2a:94:90:67:03:1c:a4:76:2f:ee:ef:59:60:09: + 48:33:03:2b:52:ed:83:42:f8:71:19:7f:d8:be:40:ed:20:01: + 90:3c:7e:1c:8b:d2:9f:f3:2f:09:1f:50:c8:10:e1:8a:d9:a5: + 49:9c:0b:74:17:b9:2b:68:f6:1e:73:c2:73:10:38:b3:35:e2: + 87:91:1b:a1:d1:9b:81:9d:1b:32:cc:03:6e:4c:82:95:81:11: + 42:56:e2:16:2b:22:65:db:40:2c:ca:dc:03:f4:d5:07:cf:f5: + 13:b2:cf:51:5b:24:cd:c7:d1:9b:42:8e:f9:df:5d:1e:5a:09: + a3:4f:a9:0b:f4:21:c5:bb:ff:02:93:67:e8:2d:ee:ab:d9:59: + 76:03:2c:a1:bd:fb:dc:af:b6:82:94:71:85:53:a8:18:0d:3a: + 9e:42:eb:59 +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIJANBNI4XuWbP6MA0GCSqGSIb3DQEBCwUAMFYxDzANBgNV +BAMMBmNhY2VydDELMAkGA1UEBhMCRkkxETAPBgNVBAgMCEhlbHNpbmtpMREwDwYD +VQQHDAhIZWxzaW5raTEQMA4GA1UECgwHTWFyaWFEQjAeFw0xOTAxMjcxMDExMTBa +Fw0zOTAxMjIxMDExMTBaMFYxDzANBgNVBAMMBmNhY2VydDELMAkGA1UEBhMCRkkx +ETAPBgNVBAgMCEhlbHNpbmtpMREwDwYDVQQHDAhIZWxzaW5raTEQMA4GA1UECgwH +TWFyaWFEQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOgOp4TTdTAG +MLIQudGINite+MhEV8tncquWlTPViNGPI1CYum0gAIC9NdXBv5hJxAoVSjSmIZsu +jBUJ8GOBAsJ84lPg96EaQF6PQUpMVtQg8dWnwVMu/343F8x+dL3iIjPOjHdipMU/ +RDV7frn1fYx6J1j9LEKGLudrAZl7/n2noU8+OTlUH2HedGbRd09DG2ZwKYXe/I+O +G3uiZkgmf5um/Urk3Ovtvfjj8VeYE2/xoyrjc72NfG9LWTW8tUI+macTjb4uXJrG +W6uuvwDpyO4FIo7VZxpHmm2c+UI+FTT4Mey0ftOSlbC4+WbzvR0xLLGQYqH4TqZd +JiLw4f4WK2kCAwEAAaNQME4wHQYDVR0OBBYEFMpxmYnwcqt1ZrtlagMEcqV7laaT +MB8GA1UdIwQYMBaAFMpxmYnwcqt1ZrtlagMEcqV7laaTMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBAN/9dClbXpqLCQJAWXPLcUc/lz2p/cSMASnJhrhx +Vf9yDlDcyLXmkUFSRyEwzE3nO0vbVep9RutT4LcbgHyxDNPRvKBzrpYf/QVSflTV +A1JpezRfJ9eY2ph2c+a7UFkqlJBnAxykdi/u71lgCUgzAytS7YNC+HEZf9i+QO0g +AZA8fhyL0p/zLwkfUMgQ4YrZpUmcC3QXuSto9h5zwnMQOLM14oeRG6HRm4GdGzLM +A25MgpWBEUJW4hYrImXbQCzK3AP01QfP9ROyz1FbJM3H0ZtCjvnfXR5aCaNPqQv0 +IcW7/wKTZ+gt7qvZWXYDLKG9+9yvtoKUcYVTqBgNOp5C61k= +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/capath/cacert.pem b/mysql-test/std_data/capath/cacert.pem deleted file mode 100644 index 23dda2318e1..00000000000 --- a/mysql-test/std_data/capath/cacert.pem +++ /dev/null @@ -1,79 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - d0:4d:23:85:ee:59:b3:fa - Signature Algorithm: sha256WithRSAEncryption - Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB - Validity - Not Before: Jan 27 10:11:10 2019 GMT - Not After : Jan 22 10:11:10 2039 GMT - Subject: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:e8:0e:a7:84:d3:75:30:06:30:b2:10:b9:d1:88: - 36:2b:5e:f8:c8:44:57:cb:67:72:ab:96:95:33:d5: - 88:d1:8f:23:50:98:ba:6d:20:00:80:bd:35:d5:c1: - bf:98:49:c4:0a:15:4a:34:a6:21:9b:2e:8c:15:09: - f0:63:81:02:c2:7c:e2:53:e0:f7:a1:1a:40:5e:8f: - 41:4a:4c:56:d4:20:f1:d5:a7:c1:53:2e:ff:7e:37: - 17:cc:7e:74:bd:e2:22:33:ce:8c:77:62:a4:c5:3f: - 44:35:7b:7e:b9:f5:7d:8c:7a:27:58:fd:2c:42:86: - 2e:e7:6b:01:99:7b:fe:7d:a7:a1:4f:3e:39:39:54: - 1f:61:de:74:66:d1:77:4f:43:1b:66:70:29:85:de: - fc:8f:8e:1b:7b:a2:66:48:26:7f:9b:a6:fd:4a:e4: - dc:eb:ed:bd:f8:e3:f1:57:98:13:6f:f1:a3:2a:e3: - 73:bd:8d:7c:6f:4b:59:35:bc:b5:42:3e:99:a7:13: - 8d:be:2e:5c:9a:c6:5b:ab:ae:bf:00:e9:c8:ee:05: - 22:8e:d5:67:1a:47:9a:6d:9c:f9:42:3e:15:34:f8: - 31:ec:b4:7e:d3:92:95:b0:b8:f9:66:f3:bd:1d:31: - 2c:b1:90:62:a1:f8:4e:a6:5d:26:22:f0:e1:fe:16: - 2b:69 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Subject Key Identifier: - CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 - X509v3 Authority Key Identifier: - keyid:CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 - - X509v3 Basic Constraints: - CA:TRUE - Signature Algorithm: sha256WithRSAEncryption - df:fd:74:29:5b:5e:9a:8b:09:02:40:59:73:cb:71:47:3f:97: - 3d:a9:fd:c4:8c:01:29:c9:86:b8:71:55:ff:72:0e:50:dc:c8: - b5:e6:91:41:52:47:21:30:cc:4d:e7:3b:4b:db:55:ea:7d:46: - eb:53:e0:b7:1b:80:7c:b1:0c:d3:d1:bc:a0:73:ae:96:1f:fd: - 05:52:7e:54:d5:03:52:69:7b:34:5f:27:d7:98:da:98:76:73: - e6:bb:50:59:2a:94:90:67:03:1c:a4:76:2f:ee:ef:59:60:09: - 48:33:03:2b:52:ed:83:42:f8:71:19:7f:d8:be:40:ed:20:01: - 90:3c:7e:1c:8b:d2:9f:f3:2f:09:1f:50:c8:10:e1:8a:d9:a5: - 49:9c:0b:74:17:b9:2b:68:f6:1e:73:c2:73:10:38:b3:35:e2: - 87:91:1b:a1:d1:9b:81:9d:1b:32:cc:03:6e:4c:82:95:81:11: - 42:56:e2:16:2b:22:65:db:40:2c:ca:dc:03:f4:d5:07:cf:f5: - 13:b2:cf:51:5b:24:cd:c7:d1:9b:42:8e:f9:df:5d:1e:5a:09: - a3:4f:a9:0b:f4:21:c5:bb:ff:02:93:67:e8:2d:ee:ab:d9:59: - 76:03:2c:a1:bd:fb:dc:af:b6:82:94:71:85:53:a8:18:0d:3a: - 9e:42:eb:59 ------BEGIN CERTIFICATE----- -MIIDfzCCAmegAwIBAgIJANBNI4XuWbP6MA0GCSqGSIb3DQEBCwUAMFYxDzANBgNV -BAMMBmNhY2VydDELMAkGA1UEBhMCRkkxETAPBgNVBAgMCEhlbHNpbmtpMREwDwYD -VQQHDAhIZWxzaW5raTEQMA4GA1UECgwHTWFyaWFEQjAeFw0xOTAxMjcxMDExMTBa -Fw0zOTAxMjIxMDExMTBaMFYxDzANBgNVBAMMBmNhY2VydDELMAkGA1UEBhMCRkkx -ETAPBgNVBAgMCEhlbHNpbmtpMREwDwYDVQQHDAhIZWxzaW5raTEQMA4GA1UECgwH -TWFyaWFEQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOgOp4TTdTAG -MLIQudGINite+MhEV8tncquWlTPViNGPI1CYum0gAIC9NdXBv5hJxAoVSjSmIZsu -jBUJ8GOBAsJ84lPg96EaQF6PQUpMVtQg8dWnwVMu/343F8x+dL3iIjPOjHdipMU/ -RDV7frn1fYx6J1j9LEKGLudrAZl7/n2noU8+OTlUH2HedGbRd09DG2ZwKYXe/I+O -G3uiZkgmf5um/Urk3Ovtvfjj8VeYE2/xoyrjc72NfG9LWTW8tUI+macTjb4uXJrG -W6uuvwDpyO4FIo7VZxpHmm2c+UI+FTT4Mey0ftOSlbC4+WbzvR0xLLGQYqH4TqZd -JiLw4f4WK2kCAwEAAaNQME4wHQYDVR0OBBYEFMpxmYnwcqt1ZrtlagMEcqV7laaT -MB8GA1UdIwQYMBaAFMpxmYnwcqt1ZrtlagMEcqV7laaTMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQELBQADggEBAN/9dClbXpqLCQJAWXPLcUc/lz2p/cSMASnJhrhx -Vf9yDlDcyLXmkUFSRyEwzE3nO0vbVep9RutT4LcbgHyxDNPRvKBzrpYf/QVSflTV -A1JpezRfJ9eY2ph2c+a7UFkqlJBnAxykdi/u71lgCUgzAytS7YNC+HEZf9i+QO0g -AZA8fhyL0p/zLwkfUMgQ4YrZpUmcC3QXuSto9h5zwnMQOLM14oeRG6HRm4GdGzLM -A25MgpWBEUJW4hYrImXbQCzK3AP01QfP9ROyz1FbJM3H0ZtCjvnfXR5aCaNPqQv0 -IcW7/wKTZ+gt7qvZWXYDLKG9+9yvtoKUcYVTqBgNOp5C61k= ------END CERTIFICATE----- diff --git a/mysql-test/std_data/capath/ed1f42db.0 b/mysql-test/std_data/capath/ed1f42db.0 deleted file mode 120000 index 1310cfcff20..00000000000 --- a/mysql-test/std_data/capath/ed1f42db.0 +++ /dev/null @@ -1 +0,0 @@ -cacert.pem \ No newline at end of file diff --git a/mysql-test/std_data/capath/ed1f42db.0 b/mysql-test/std_data/capath/ed1f42db.0 new file mode 100644 index 00000000000..23dda2318e1 --- /dev/null +++ b/mysql-test/std_data/capath/ed1f42db.0 @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + d0:4d:23:85:ee:59:b3:fa + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Validity + Not Before: Jan 27 10:11:10 2019 GMT + Not After : Jan 22 10:11:10 2039 GMT + Subject: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e8:0e:a7:84:d3:75:30:06:30:b2:10:b9:d1:88: + 36:2b:5e:f8:c8:44:57:cb:67:72:ab:96:95:33:d5: + 88:d1:8f:23:50:98:ba:6d:20:00:80:bd:35:d5:c1: + bf:98:49:c4:0a:15:4a:34:a6:21:9b:2e:8c:15:09: + f0:63:81:02:c2:7c:e2:53:e0:f7:a1:1a:40:5e:8f: + 41:4a:4c:56:d4:20:f1:d5:a7:c1:53:2e:ff:7e:37: + 17:cc:7e:74:bd:e2:22:33:ce:8c:77:62:a4:c5:3f: + 44:35:7b:7e:b9:f5:7d:8c:7a:27:58:fd:2c:42:86: + 2e:e7:6b:01:99:7b:fe:7d:a7:a1:4f:3e:39:39:54: + 1f:61:de:74:66:d1:77:4f:43:1b:66:70:29:85:de: + fc:8f:8e:1b:7b:a2:66:48:26:7f:9b:a6:fd:4a:e4: + dc:eb:ed:bd:f8:e3:f1:57:98:13:6f:f1:a3:2a:e3: + 73:bd:8d:7c:6f:4b:59:35:bc:b5:42:3e:99:a7:13: + 8d:be:2e:5c:9a:c6:5b:ab:ae:bf:00:e9:c8:ee:05: + 22:8e:d5:67:1a:47:9a:6d:9c:f9:42:3e:15:34:f8: + 31:ec:b4:7e:d3:92:95:b0:b8:f9:66:f3:bd:1d:31: + 2c:b1:90:62:a1:f8:4e:a6:5d:26:22:f0:e1:fe:16: + 2b:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + X509v3 Authority Key Identifier: + keyid:CA:71:99:89:F0:72:AB:75:66:BB:65:6A:03:04:72:A5:7B:95:A6:93 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + df:fd:74:29:5b:5e:9a:8b:09:02:40:59:73:cb:71:47:3f:97: + 3d:a9:fd:c4:8c:01:29:c9:86:b8:71:55:ff:72:0e:50:dc:c8: + b5:e6:91:41:52:47:21:30:cc:4d:e7:3b:4b:db:55:ea:7d:46: + eb:53:e0:b7:1b:80:7c:b1:0c:d3:d1:bc:a0:73:ae:96:1f:fd: + 05:52:7e:54:d5:03:52:69:7b:34:5f:27:d7:98:da:98:76:73: + e6:bb:50:59:2a:94:90:67:03:1c:a4:76:2f:ee:ef:59:60:09: + 48:33:03:2b:52:ed:83:42:f8:71:19:7f:d8:be:40:ed:20:01: + 90:3c:7e:1c:8b:d2:9f:f3:2f:09:1f:50:c8:10:e1:8a:d9:a5: + 49:9c:0b:74:17:b9:2b:68:f6:1e:73:c2:73:10:38:b3:35:e2: + 87:91:1b:a1:d1:9b:81:9d:1b:32:cc:03:6e:4c:82:95:81:11: + 42:56:e2:16:2b:22:65:db:40:2c:ca:dc:03:f4:d5:07:cf:f5: + 13:b2:cf:51:5b:24:cd:c7:d1:9b:42:8e:f9:df:5d:1e:5a:09: + a3:4f:a9:0b:f4:21:c5:bb:ff:02:93:67:e8:2d:ee:ab:d9:59: + 76:03:2c:a1:bd:fb:dc:af:b6:82:94:71:85:53:a8:18:0d:3a: + 9e:42:eb:59 +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIJANBNI4XuWbP6MA0GCSqGSIb3DQEBCwUAMFYxDzANBgNV +BAMMBmNhY2VydDELMAkGA1UEBhMCRkkxETAPBgNVBAgMCEhlbHNpbmtpMREwDwYD +VQQHDAhIZWxzaW5raTEQMA4GA1UECgwHTWFyaWFEQjAeFw0xOTAxMjcxMDExMTBa +Fw0zOTAxMjIxMDExMTBaMFYxDzANBgNVBAMMBmNhY2VydDELMAkGA1UEBhMCRkkx +ETAPBgNVBAgMCEhlbHNpbmtpMREwDwYDVQQHDAhIZWxzaW5raTEQMA4GA1UECgwH +TWFyaWFEQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOgOp4TTdTAG +MLIQudGINite+MhEV8tncquWlTPViNGPI1CYum0gAIC9NdXBv5hJxAoVSjSmIZsu +jBUJ8GOBAsJ84lPg96EaQF6PQUpMVtQg8dWnwVMu/343F8x+dL3iIjPOjHdipMU/ +RDV7frn1fYx6J1j9LEKGLudrAZl7/n2noU8+OTlUH2HedGbRd09DG2ZwKYXe/I+O +G3uiZkgmf5um/Urk3Ovtvfjj8VeYE2/xoyrjc72NfG9LWTW8tUI+macTjb4uXJrG +W6uuvwDpyO4FIo7VZxpHmm2c+UI+FTT4Mey0ftOSlbC4+WbzvR0xLLGQYqH4TqZd +JiLw4f4WK2kCAwEAAaNQME4wHQYDVR0OBBYEFMpxmYnwcqt1ZrtlagMEcqV7laaT +MB8GA1UdIwQYMBaAFMpxmYnwcqt1ZrtlagMEcqV7laaTMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBAN/9dClbXpqLCQJAWXPLcUc/lz2p/cSMASnJhrhx +Vf9yDlDcyLXmkUFSRyEwzE3nO0vbVep9RutT4LcbgHyxDNPRvKBzrpYf/QVSflTV +A1JpezRfJ9eY2ph2c+a7UFkqlJBnAxykdi/u71lgCUgzAytS7YNC+HEZf9i+QO0g +AZA8fhyL0p/zLwkfUMgQ4YrZpUmcC3QXuSto9h5zwnMQOLM14oeRG6HRm4GdGzLM +A25MgpWBEUJW4hYrImXbQCzK3AP01QfP9ROyz1FbJM3H0ZtCjvnfXR5aCaNPqQv0 +IcW7/wKTZ+gt7qvZWXYDLKG9+9yvtoKUcYVTqBgNOp5C61k= +-----END CERTIFICATE----- diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 5c84aa7c17f..040cd31caa9 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -1111,7 +1111,7 @@ verify_ca_matches_cert() [ -n "$ca" ] && [ ! -r "$ca" ] && readable=0 [ -n "$cap" ] && [ ! -r "$cap" ] && readable=0 - if [ readable -eq 0 ]; then + if [ $readable -eq 0 ]; then wsrep_log_error \ "Both PEM file and CA file (or path) must be readable" exit 22 diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 08f0905e044..fe980322736 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -179,10 +179,29 @@ new_VioSSLFd(const char *key_file, const char *cert_file, long ssl_ctx_options= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; DBUG_ENTER("new_VioSSLFd"); - if (ca_file && ! ca_file[0]) ca_file = NULL; - if (ca_path && ! ca_path[0]) ca_path = NULL; - if (crl_file && ! crl_file[0]) crl_file = NULL; - if (crl_path && ! crl_path[0]) crl_path = NULL; + /* + If some optional parameters indicate empty strings, then + for compatibility with SSL libraries, replace them with NULL, + otherwise these libraries will try to open files with an empty + name, etc., and they will return an error code instead performing + the necessary operations: + */ + if (ca_file && !ca_file[0]) + { + ca_file = NULL; + } + if (ca_path && !ca_path[0]) + { + ca_path = NULL; + } + if (crl_file && !crl_file[0]) + { + crl_file = NULL; + } + if (crl_path && !crl_path[0]) + { + crl_path = NULL; + } DBUG_PRINT("enter", ("key_file: '%s' cert_file: '%s' ca_file: '%s' ca_path: '%s' " @@ -314,10 +333,29 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; - if (ca_file && ! ca_file[0]) ca_file = NULL; - if (ca_path && ! ca_path[0]) ca_path = NULL; - if (crl_file && ! crl_file[0]) crl_file = NULL; - if (crl_path && ! crl_path[0]) crl_path = NULL; + /* + If some optional parameters indicate empty strings, then + for compatibility with SSL libraries, replace them with NULL, + otherwise these libraries will try to open files with an empty + name, etc., and they will return an error code instead performing + the necessary operations: + */ + if (ca_file && !ca_file[0]) + { + ca_file = NULL; + } + if (ca_path && !ca_path[0]) + { + ca_path = NULL; + } + if (crl_file && !crl_file[0]) + { + crl_file = NULL; + } + if (crl_path && !crl_path[0]) + { + crl_path = NULL; + } /* Turn off verification of servers certificate if both @@ -351,10 +389,29 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; - if (ca_file && ! ca_file[0]) ca_file = NULL; - if (ca_path && ! ca_path[0]) ca_path = NULL; - if (crl_file && ! crl_file[0]) crl_file = NULL; - if (crl_path && ! crl_path[0]) crl_path = NULL; + /* + If some optional parameters indicate empty strings, then + for compatibility with SSL libraries, replace them with NULL, + otherwise these libraries will try to open files with an empty + name, etc., and they will return an error code instead performing + the necessary operations: + */ + if (ca_file && !ca_file[0]) + { + ca_file = NULL; + } + if (ca_path && !ca_path[0]) + { + ca_path = NULL; + } + if (crl_file && !crl_file[0]) + { + crl_file = NULL; + } + if (crl_path && !crl_path[0]) + { + crl_path = NULL; + } if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher, FALSE, error, From c1846c4fcfb04cb628c73b95516deefeb8ee0e19 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Thu, 9 Dec 2021 18:12:20 +0200 Subject: [PATCH 30/52] MDEV-26803 PA unsafety with FK cascade delete operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit has a mtr test where two two transactions delete a row from two separate tables, which will cascade a FK delete for the same row in a third table. Second replica node is configured with 2 applier threads, and the test will fail if these two transactions are applied in parallel. The actual fix, in this commit, is to mark a transaction as unsafe for parallel applying when it traverses into cascade delete operation. Reviewed-by: Jan Lindström --- include/mysql/service_wsrep.h | 4 + .../galera/r/galera_fk_cascade_delete.result | 110 +++++++++++ .../galera/t/galera_fk_cascade_delete.test | 186 ++++++++++++++++++ sql/service_wsrep.cc | 8 + sql/sql_plugin_services.ic | 3 +- sql/wsrep_dummy.cc | 4 + sql/wsrep_thd.h | 2 - storage/innobase/handler/ha_innodb.cc | 29 ++- storage/innobase/row/row0ins.cc | 39 ++-- 9 files changed, 354 insertions(+), 31 deletions(-) diff --git a/include/mysql/service_wsrep.h b/include/mysql/service_wsrep.h index 10c70c790e9..1e6aaa1b9b9 100644 --- a/include/mysql/service_wsrep.h +++ b/include/mysql/service_wsrep.h @@ -88,6 +88,7 @@ extern struct wsrep_service_st { unsigned long long trx_id); void (*wsrep_thd_kill_LOCK_func)(const MYSQL_THD thd); void (*wsrep_thd_kill_UNLOCK_func)(const MYSQL_THD thd); + void (*wsrep_thd_set_wsrep_PA_unsafe_func)(MYSQL_THD thd); } *wsrep_service; #define MYSQL_SERVICE_WSREP_INCLUDED @@ -131,6 +132,7 @@ extern struct wsrep_service_st { #define wsrep_thd_is_applying(T) wsrep_service->wsrep_thd_is_applying_func(T) #define wsrep_thd_set_wsrep_aborter(T) wsrep_service->wsrep_thd_set_wsrep_aborter_func(T1, T2) #define wsrep_report_bf_lock_wait(T,I) wsrep_service->wsrep_report_bf_lock_wait(T,I) +#define wsrep_thd_set_PA_unsafe(T) wsrep_service->wsrep_thd_set_PA_unsafe_func(T) #else #define MYSQL_SERVICE_WSREP_STATIC_INCLUDED @@ -229,5 +231,7 @@ extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd); extern "C" bool wsrep_thd_set_wsrep_aborter(MYSQL_THD bf_thd, MYSQL_THD victim_thd); extern "C" void wsrep_report_bf_lock_wait(const THD *thd, unsigned long long trx_id); +/* declare parallel applying unsafety for the THD */ +extern "C" void wsrep_thd_set_PA_unsafe(MYSQL_THD thd); #endif #endif /* MYSQL_SERVICE_WSREP_INCLUDED */ diff --git a/mysql-test/suite/galera/r/galera_fk_cascade_delete.result b/mysql-test/suite/galera/r/galera_fk_cascade_delete.result index 808e32b8cb2..9bb004d0ed8 100644 --- a/mysql-test/suite/galera/r/galera_fk_cascade_delete.result +++ b/mysql-test/suite/galera/r/galera_fk_cascade_delete.result @@ -48,3 +48,113 @@ id parent_id DROP TABLE child; DROP TABLE parent; DROP TABLE grandparent; + +Scenario 2, testing PA applying with FK cascade delete + +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) +ON DELETE CASCADE, +CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1) +ON DELETE CASCADE); +connection node_2; +set global wsrep_slave_threads=DEFAULT; +SELECT * FROM p1; +f1 f2 +SELECT * FROM p2; +f1 f2 +SELECT * FROM c; +f1 p1_id p2_id f2 +connection node_1; +DROP TABLE c; +DROP TABLE p1,p2; + +Scenario 4, testing PA applying with FK cascade delete on +more than one level + +CREATE TABLE gp1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE gp2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT pfk_3 FOREIGN KEY (p1_id) REFERENCES gp1 (f1) +ON DELETE CASCADE +) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY,p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT pfk_4 FOREIGN KEY (p1_id) REFERENCES gp2 (f1) +ON DELETE CASCADE +) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) +ON DELETE CASCADE, +CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1) +ON DELETE CASCADE) ENGINE=INNODB; +connection node_2; +set global wsrep_slave_threads=DEFAULT; +SELECT * FROM gp1; +f1 f2 +SELECT * FROM gp2; +f1 f2 +SELECT * FROM p1; +f1 p1_id p2_id f2 +SELECT * FROM p2; +f1 p1_id p2_id f2 +SELECT * FROM c; +f1 p1_id p2_id f2 +connection node_1; +DROP TABLE c; +DROP TABLE p1,p2; +DROP TABLE gp1,gp2; + +Scenario 3, testing PA applying with FK cascade delete on +more than one level in a diamond topology + +CREATE TABLE ggp1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE gp1 (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT pfk_6 FOREIGN KEY (p1_id) REFERENCES ggp1 (f1) +ON DELETE CASCADE +) ENGINE=INNODB; +CREATE TABLE gp2 (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT pfk_5 FOREIGN KEY (p1_id) REFERENCES ggp1 (f1) +ON DELETE CASCADE +) ENGINE=INNODB; +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT pfk_3 FOREIGN KEY (p1_id) REFERENCES gp1 (f1) +ON DELETE CASCADE +) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY,p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT pfk_4 FOREIGN KEY (p1_id) REFERENCES gp2 (f1) +ON DELETE CASCADE +) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) +ON DELETE CASCADE, +CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1) +ON DELETE CASCADE) ENGINE=INNODB; +connection node_2; +set global wsrep_slave_threads=DEFAULT; +SELECT * FROM ggp1; +f1 f2 +SELECT * FROM gp2; +f1 p1_id p2_id f2 +SELECT * FROM gp1; +f1 p1_id p2_id f2 +SELECT * FROM p1; +f1 p1_id p2_id f2 +SELECT * FROM p2; +f1 p1_id p2_id f2 +SELECT * FROM c; +f1 p1_id p2_id f2 +connection node_1; +DROP TABLE c; +DROP TABLE p1,p2; +DROP TABLE gp1,gp2; +DROP TABLE ggp1; diff --git a/mysql-test/suite/galera/t/galera_fk_cascade_delete.test b/mysql-test/suite/galera/t/galera_fk_cascade_delete.test index 49b54f0f7f0..901fc1fc6d1 100644 --- a/mysql-test/suite/galera/t/galera_fk_cascade_delete.test +++ b/mysql-test/suite/galera/t/galera_fk_cascade_delete.test @@ -68,3 +68,189 @@ SELECT * FROM child; DROP TABLE child; DROP TABLE parent; DROP TABLE grandparent; + +--echo +--echo Scenario 2, testing PA applying with FK cascade delete +--echo + +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) + ON DELETE CASCADE, + CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1) + ON DELETE CASCADE); + +--let $count = 100 +--disable_query_log +while ($count) +{ + --eval INSERT INTO p1 VALUES ($count, 0); + --eval INSERT INTO p2 VALUES ($count, 0); + --eval INSERT INTO c VALUES ($count, $count, $count, 0); + --dec $count +} + +--connection node_2 +set global wsrep_slave_threads=2; + +--connection node_1 +--let $count = 100 +while ($count) +{ + --eval DELETE FROM p2 WHERE f1=$count; + --eval DELETE FROM p1 WHERE f1=$count; + +--dec $count +} +--enable_query_log + +--connection node_2 +set global wsrep_slave_threads=DEFAULT; + + +SELECT * FROM p1; +SELECT * FROM p2; +SELECT * FROM c; + +--connection node_1 +DROP TABLE c; +DROP TABLE p1,p2; + +--echo +--echo Scenario 4, testing PA applying with FK cascade delete on +--echo more than one level +--echo +CREATE TABLE gp1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE gp2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT pfk_3 FOREIGN KEY (p1_id) REFERENCES gp1 (f1) + ON DELETE CASCADE + ) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY,p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT pfk_4 FOREIGN KEY (p1_id) REFERENCES gp2 (f1) + ON DELETE CASCADE + ) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) + ON DELETE CASCADE, + CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1) + ON DELETE CASCADE) ENGINE=INNODB; + +--let $count = 100 +--disable_query_log +while ($count) +{ + --eval INSERT INTO gp1 VALUES ($count, 0); + --eval INSERT INTO gp2 VALUES ($count, 0); + --eval INSERT INTO p1 VALUES ($count, $count, $count, 0); + --eval INSERT INTO p2 VALUES ($count, $count, $count, 0); + --eval INSERT INTO c VALUES ($count, $count, $count, 0); + --dec $count +} + +--connection node_2 +set global wsrep_slave_threads=2; + +--connection node_1 +--let $count = 100 +while ($count) +{ + --eval DELETE FROM gp1 WHERE f1=$count; + --eval DELETE FROM gp2 WHERE f1=$count; + +--dec $count +} +--enable_query_log + +--connection node_2 +set global wsrep_slave_threads=DEFAULT; + +SELECT * FROM gp1; +SELECT * FROM gp2; +SELECT * FROM p1; +SELECT * FROM p2; +SELECT * FROM c; + +--connection node_1 +DROP TABLE c; +DROP TABLE p1,p2; +DROP TABLE gp1,gp2; + +--echo +--echo Scenario 3, testing PA applying with FK cascade delete on +--echo more than one level in a diamond topology +--echo +CREATE TABLE ggp1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE gp1 (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT pfk_6 FOREIGN KEY (p1_id) REFERENCES ggp1 (f1) + ON DELETE CASCADE + ) ENGINE=INNODB; +CREATE TABLE gp2 (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT pfk_5 FOREIGN KEY (p1_id) REFERENCES ggp1 (f1) + ON DELETE CASCADE + ) ENGINE=INNODB; +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT pfk_3 FOREIGN KEY (p1_id) REFERENCES gp1 (f1) + ON DELETE CASCADE + ) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY,p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT pfk_4 FOREIGN KEY (p1_id) REFERENCES gp2 (f1) + ON DELETE CASCADE + ) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) + ON DELETE CASCADE, + CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1) + ON DELETE CASCADE) ENGINE=INNODB; + +--let $count = 100 +--disable_query_log +while ($count) +{ + --eval INSERT INTO ggp1 VALUES ($count, 0); + --eval INSERT INTO gp1 VALUES ($count, $count, $count, 0); + --eval INSERT INTO gp2 VALUES ($count, $count, $count, 0); + --eval INSERT INTO p1 VALUES ($count, $count, $count, 0); + --eval INSERT INTO p2 VALUES ($count, $count, $count, 0); + --eval INSERT INTO c VALUES ($count, $count, $count, 0); + --dec $count +} + +--connection node_2 +set global wsrep_slave_threads=2; + +--connection node_1 +--let $count = 100 +while ($count) +{ + --eval DELETE FROM ggp1 WHERE f1=$count; + +--dec $count +} +--enable_query_log + +--connection node_2 +set global wsrep_slave_threads=DEFAULT; + +SELECT * FROM ggp1; +SELECT * FROM gp2; +SELECT * FROM gp1; +SELECT * FROM p1; +SELECT * FROM p2; +SELECT * FROM c; + +--connection node_1 +DROP TABLE c; +DROP TABLE p1,p2; +DROP TABLE gp1,gp2; +DROP TABLE ggp1; diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index 18067a4d0ec..fd2a5c301f2 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -381,3 +381,11 @@ extern "C" void wsrep_report_bf_lock_wait(const THD *thd, wsrep_thd_query(thd)); } } + +extern "C" void wsrep_thd_set_PA_unsafe(THD *thd) +{ + if (thd && thd->wsrep_cs().mark_transaction_pa_unsafe()) + { + WSREP_DEBUG("session does not have active transaction, can not mark as PA unsafe"); + } +} diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic index 740569dc76e..60ba38eae61 100644 --- a/sql/sql_plugin_services.ic +++ b/sql/sql_plugin_services.ic @@ -176,7 +176,8 @@ static struct wsrep_service_st wsrep_handler = { wsrep_thd_set_wsrep_aborter, wsrep_report_bf_lock_wait, wsrep_thd_kill_LOCK, - wsrep_thd_kill_UNLOCK + wsrep_thd_kill_UNLOCK, + wsrep_thd_set_PA_unsafe }; static struct thd_specifics_service_st thd_specifics_handler= diff --git a/sql/wsrep_dummy.cc b/sql/wsrep_dummy.cc index 129df8e1577..83bf4778d10 100644 --- a/sql/wsrep_dummy.cc +++ b/sql/wsrep_dummy.cc @@ -147,3 +147,7 @@ bool wsrep_thd_set_wsrep_aborter(THD*, THD*) void wsrep_report_bf_lock_wait(const THD*, unsigned long long) {} + +void wsrep_thd_set_PA_unsafe(THD*) +{} + diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h index 560dbbdab44..40e5ed98e9b 100644 --- a/sql/wsrep_thd.h +++ b/sql/wsrep_thd.h @@ -90,8 +90,6 @@ void wsrep_create_rollbacker(); bool wsrep_bf_abort(THD* bf_thd, THD* victim_thd); int wsrep_abort_thd(THD *bf_thd_ptr, THD *victim_thd_ptr, my_bool signal); -extern void wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe); - /* Helper methods to deal with thread local storage. The purpose of these methods is to hide the details of thread diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 23df38c64ab..257074ae56d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -10220,12 +10220,20 @@ wsrep_append_foreign_key( dict_foreign_t* foreign, /*!< in: foreign key constraint */ const rec_t* rec, /*!is_wsrep() || !wsrep_thd_is_local(trx->mysql_thd)) { + ut_ad(trx->is_wsrep()); + + if (!wsrep_thd_is_local(trx->mysql_thd)) return DB_SUCCESS; + + if (upd_node && wsrep_protocol_version < 4) { + key_type = WSREP_SERVICE_KEY_SHARED; } THD* thd = trx->mysql_thd; @@ -10286,8 +10294,7 @@ wsrep_append_foreign_key( WSREP_WARN("FK: %s missing in query: %s", (!foreign->referenced_table) ? "referenced table" : "foreign table", - (wsrep_thd_query(thd)) ? - wsrep_thd_query(thd) : "void"); + wsrep_thd_query(thd)); return DB_ERROR; } @@ -10365,20 +10372,24 @@ wsrep_append_foreign_key( wkey_part, (size_t*)&wkey.key_parts_num)) { WSREP_WARN("key prepare failed for cascaded FK: %s", - (wsrep_thd_query(thd)) ? - wsrep_thd_query(thd) : "void"); + wsrep_thd_query(thd)); return DB_ERROR; } + rcode = wsrep_thd_append_key(thd, &wkey, 1, key_type); + if (rcode) { - DBUG_PRINT("wsrep", ("row key failed: " ULINTPF, rcode)); WSREP_ERROR("Appending cascaded fk row key failed: %s, " ULINTPF, - (wsrep_thd_query(thd)) ? - wsrep_thd_query(thd) : "void", rcode); + wsrep_thd_query(thd), + rcode); return DB_ERROR; } + if (pa_disable) { + wsrep_thd_set_PA_unsafe(trx->mysql_thd); + } + return DB_SUCCESS; } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index a63dd90e9c2..a1f5e55d8f4 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -970,7 +970,9 @@ dberr_t wsrep_append_foreign_key(trx_t *trx, dict_foreign_t* foreign, const rec_t* clust_rec, dict_index_t* clust_index, - ibool referenced, + bool referenced, + upd_node_t* upd_node, + bool pa_disable, Wsrep_service_key_type key_type); #endif /* WITH_WSREP */ @@ -1322,11 +1324,13 @@ row_ins_foreign_check_on_constraint( } #ifdef WITH_WSREP - err = wsrep_append_foreign_key(trx, foreign, clust_rec, clust_index, - FALSE, WSREP_SERVICE_KEY_EXCLUSIVE); - if (err != DB_SUCCESS) { - ib::info() << "WSREP: foreign key append failed: " << err; - goto nonstandard_exit_func; + if (trx->is_wsrep()) { + err = wsrep_append_foreign_key(trx, foreign, clust_rec, clust_index, + false, NULL, true, + WSREP_SERVICE_KEY_EXCLUSIVE); + if (err != DB_SUCCESS) { + goto nonstandard_exit_func; + } } #endif /* WITH_WSREP */ mtr_commit(mtr); @@ -1722,19 +1726,16 @@ row_ins_check_foreign_constraint( if (check_ref) { err = DB_SUCCESS; #ifdef WITH_WSREP - err = wsrep_append_foreign_key( - thr_get_trx(thr), - foreign, - rec, - check_index, - check_ref, - (upd_node != NULL - && wsrep_protocol_version < 4) - ? WSREP_SERVICE_KEY_SHARED - : WSREP_SERVICE_KEY_REFERENCE); - if (err != DB_SUCCESS) { - fprintf(stderr, - "WSREP: foreign key append failed: %d\n", err); + if (trx->is_wsrep()) { + err = wsrep_append_foreign_key( + thr_get_trx(thr), + foreign, + rec, + check_index, + check_ref, + upd_node, + false, + WSREP_SERVICE_KEY_REFERENCE); } #endif /* WITH_WSREP */ goto end_scan; From 53de922ae5185b71fdb52e813ac5fb0c51079361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 17 Dec 2021 09:55:01 +0200 Subject: [PATCH 31/52] Enable galera_sr.GCF-1060 test case as it is now fixed. --- mysql-test/suite/galera_sr/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/suite/galera_sr/disabled.def b/mysql-test/suite/galera_sr/disabled.def index d52ee32f610..932b48eaae4 100644 --- a/mysql-test/suite/galera_sr/disabled.def +++ b/mysql-test/suite/galera_sr/disabled.def @@ -10,5 +10,4 @@ # ############################################################################## -GCF-1060 : MDEV-20848 galera_sr.GCF_1060 galera-features#56 : MDEV-24896 From 4b25790eb3d09404230bb873d3e963b1eb600974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 20 Dec 2021 08:32:11 +0200 Subject: [PATCH 32/52] Update wsrep-lib submodule --- wsrep-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsrep-lib b/wsrep-lib index 14b3612a308..6fd1fdf6904 160000 --- a/wsrep-lib +++ b/wsrep-lib @@ -1 +1 @@ -Subproject commit 14b3612a308132d819237bba322f3373ac5a5135 +Subproject commit 6fd1fdf69044bb6a08c488cec52668bbb31dd8aa From 49791cbc6f76c4f4c1bb436dbe26cec6177ee279 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Wed, 15 Dec 2021 22:29:32 +0200 Subject: [PATCH 33/52] 10.4-MDEV-27275 CREATE TABLE with FK not safe for PA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit contains a fix, where the replication write set for a CREATE TABLE will contain, as certification keys, table names for all FK references. With this, all DML for the FK parent tables will conflict with the CREATE TABLE statement. There is also new test galera.MDEV-27276 to verify the fix. Reviewed-by: Jan Lindström --- include/wsrep.h | 2 +- mysql-test/suite/galera/r/MDEV-22051.result | 1 + mysql-test/suite/galera/r/MDEV-27276.result | 36 +++++++++++++++ .../suite/galera/r/galera_split_brain.result | 1 + mysql-test/suite/galera/t/MDEV-22051.test | 1 + mysql-test/suite/galera/t/MDEV-27276.test | 44 +++++++++++++++++++ .../suite/galera/t/galera_split_brain.test | 1 + .../suite/galera/t/mysql-wsrep#332.test | 1 + sql/sql_table.cc | 14 +++--- sql/wsrep_mysqld.cc | 5 +-- 10 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-27276.result create mode 100644 mysql-test/suite/galera/t/MDEV-27276.test diff --git a/include/wsrep.h b/include/wsrep.h index 2a9036956cc..1b645207f00 100644 --- a/include/wsrep.h +++ b/include/wsrep.h @@ -68,7 +68,7 @@ //#define WSREP_WARN(...) #define WSREP_ERROR(...) #define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) do { } while(0) -#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_) +#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_, fk_tables_) #define WSREP_TO_ISOLATION_END #define WSREP_TO_ISOLATION_BEGIN_WRTCHK(db_, table_, table_list_) #define WSREP_SYNC_WAIT(thd_, before_) diff --git a/mysql-test/suite/galera/r/MDEV-22051.result b/mysql-test/suite/galera/r/MDEV-22051.result index 0e9756dd20e..229e26fd32a 100644 --- a/mysql-test/suite/galera/r/MDEV-22051.result +++ b/mysql-test/suite/galera/r/MDEV-22051.result @@ -18,3 +18,4 @@ INSERT INTO t1 VALUES (1); ERROR HY000: Can't execute the query because you have a conflicting read lock UNLOCK TABLES; DROP TABLE t1; +CALL mtr.add_suppression("CREATE TABLE isolation failure"); diff --git a/mysql-test/suite/galera/r/MDEV-27276.result b/mysql-test/suite/galera/r/MDEV-27276.result new file mode 100644 index 00000000000..7e5b29fad7e --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-27276.result @@ -0,0 +1,36 @@ +connection node_2; +connection node_1; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1; +CREATE TABLE p (id INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +connection node_1; +SET AUTOCOMMIT=ON; +START TRANSACTION; +INSERT INTO p VALUES(1,0); +connection node_1a; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +CREATE TABLE c(id INT NOT NULL PRIMARY KEY, p_id INT, FOREIGN KEY (p_id) REFERENCES p(id) ON DELETE CASCADE) ENGINE=InnoDB; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +connection node_1; +COMMIT; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +connection node_2; +SELECT * FROM p; +id f2 +SELECT * FROM c; +id p_id +DROP TABLE c; +DROP TABLE p; diff --git a/mysql-test/suite/galera/r/galera_split_brain.result b/mysql-test/suite/galera/r/galera_split_brain.result index 08f9060d2a9..374fb31afd1 100644 --- a/mysql-test/suite/galera/r/galera_split_brain.result +++ b/mysql-test/suite/galera/r/galera_split_brain.result @@ -4,6 +4,7 @@ connection node_1; connection node_2; call mtr.add_suppression("WSREP: TO isolation failed for: "); connection node_1; +call mtr.add_suppression("CREATE TABLE isolation failure"); connection node_2; Killing server ... connection node_1; diff --git a/mysql-test/suite/galera/t/MDEV-22051.test b/mysql-test/suite/galera/t/MDEV-22051.test index b7332c47d69..a5f05f5cf3b 100644 --- a/mysql-test/suite/galera/t/MDEV-22051.test +++ b/mysql-test/suite/galera/t/MDEV-22051.test @@ -31,3 +31,4 @@ INSERT INTO t1 VALUES (1); UNLOCK TABLES; DROP TABLE t1; +CALL mtr.add_suppression("CREATE TABLE isolation failure"); diff --git a/mysql-test/suite/galera/t/MDEV-27276.test b/mysql-test/suite/galera/t/MDEV-27276.test new file mode 100644 index 00000000000..1c589c9e85b --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-27276.test @@ -0,0 +1,44 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/galera_have_debug_sync.inc + +# +# Testing CREATE TABLE statement having foreign key constraint, +# while having concurrent DML for the referenced parent table. +# +# The replication of CREATE TABLE should have all referenced table names +# appended in the key set, and DML on the parent table should be considered as +# conflicting. +# +# There are related test scenarios in test mysql-wsrep#332, where a regular table +# is altered by adding new foreign key reference. +# +# We use concurrency facility of test MW-369 to setup the conflict between DDL and DML +# + +# Open connection node_1a here, MW-369.inc will use it later +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 + +# create FK parent table +--connection node_1 +CREATE TABLE p (id INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; + +# setup conflicting queries +--let $mw_369_parent_query = INSERT INTO p VALUES(1,0) +--let $mw_369_child_query = CREATE TABLE c(id INT NOT NULL PRIMARY KEY, p_id INT, FOREIGN KEY (p_id) REFERENCES p(id) ON DELETE CASCADE) ENGINE=InnoDB + +# execute above queries through separate nodes +--source MW-369.inc + +# Expect certification failure +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p; diff --git a/mysql-test/suite/galera/t/galera_split_brain.test b/mysql-test/suite/galera/t/galera_split_brain.test index ccdfd3fd506..b1ea9c9b4ab 100644 --- a/mysql-test/suite/galera/t/galera_split_brain.test +++ b/mysql-test/suite/galera/t/galera_split_brain.test @@ -17,6 +17,7 @@ call mtr.add_suppression("WSREP: TO isolation failed for: "); --connection node_1 --let $wsrep_cluster_address_orig = `SELECT @@wsrep_cluster_address` +call mtr.add_suppression("CREATE TABLE isolation failure"); --connection node_2 --source include/kill_galera.inc diff --git a/mysql-test/suite/galera/t/mysql-wsrep#332.test b/mysql-test/suite/galera/t/mysql-wsrep#332.test index 674a5c3de52..e216dfe79d4 100644 --- a/mysql-test/suite/galera/t/mysql-wsrep#332.test +++ b/mysql-test/suite/galera/t/mysql-wsrep#332.test @@ -111,3 +111,4 @@ SELECT * FROM c; DROP TABLE c; DROP TABLE p1; DROP TABLE p2; + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4409360cd8f..9a51ce49248 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -11624,7 +11624,14 @@ bool Sql_cmd_create_table_like::execute(THD *thd) (!thd->is_current_stmt_binlog_format_row() || !create_info.tmp_table())) { - WSREP_TO_ISOLATION_BEGIN(create_table->db.str, create_table->table_name.str, NULL); +#ifdef WITH_WSREP + WSREP_TO_ISOLATION_BEGIN_ALTER(create_table->db.str, create_table->table_name.str, + first_table, &alter_info, NULL) + { + WSREP_WARN("CREATE TABLE isolation failure"); + DBUG_RETURN(true); + } +#endif /* WITH_WSREP */ } /* Regular CREATE TABLE */ res= mysql_create_table(thd, create_table, &create_info, &alter_info); @@ -11646,9 +11653,4 @@ bool Sql_cmd_create_table_like::execute(THD *thd) end_with_restore_list: DBUG_RETURN(res); - -#ifdef WITH_WSREP -wsrep_error_label: - DBUG_RETURN(true); -#endif } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index a2856b5034d..1e4eff831c2 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1405,7 +1405,7 @@ static bool wsrep_prepare_keys_for_isolation(THD* thd, goto err; } - if (alter_info && (alter_info->flags & (ALTER_ADD_FOREIGN_KEY))) + if (alter_info) { if (!wsrep_prepare_keys_for_alter_add_fk(table_list->db.str, alter_info, ka)) goto err; @@ -1538,7 +1538,7 @@ wsrep::key_array wsrep_prepare_keys_for_toi(const char* db, ret.push_back(wsrep_prepare_key_for_toi(table->db.str, table->table_name.str, wsrep::key::exclusive)); } - if (alter_info && (alter_info->flags & ALTER_ADD_FOREIGN_KEY)) + if (alter_info) { wsrep::key_array fk(wsrep_prepare_keys_for_alter_add_fk(table_list->db.str, alter_info)); if (!fk.empty()) @@ -1803,7 +1803,6 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, switch (lex->sql_command) { case SQLCOM_CREATE_TABLE: - DBUG_ASSERT(!table_list); if (thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) { return false; From 3b33593f80442214640eefb2ce75c34698c8043b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 21 Dec 2021 11:07:25 +0200 Subject: [PATCH 34/52] MDEV-27332 SIGSEGV in fetch_data_into_cache() Since commit fb335b48b5e3263698b7d9a74ff3f20ef406df9f we may have a null pointer in purge_sys.query when fetch_data_into_cache() is invoked and innodb_force_recovery>4. This is because the call to purge_sys.create() would be skipped. fetch_data_into_cache(): Load the purge_sys pseudo transaction pointer to a local variable (null pointer if purge_sys is not initialized). --- .../suite/innodb/r/read_only_recover_committed.result | 7 +++++++ mysql-test/suite/innodb/t/read_only_recover_committed.test | 7 +++++++ storage/innobase/trx/trx0i_s.cc | 4 +++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/r/read_only_recover_committed.result b/mysql-test/suite/innodb/r/read_only_recover_committed.result index 278905a976b..0bfba662c15 100644 --- a/mysql-test/suite/innodb/r/read_only_recover_committed.result +++ b/mysql-test/suite/innodb/r/read_only_recover_committed.result @@ -63,6 +63,13 @@ SELECT * FROM t; a 3 20 +# +# MDEV-27332 SIGSEGV in fetch_data_into_cache +# +BEGIN; +SELECT trx_state FROM information_schema.innodb_trx; +trx_state +COMMIT; SELECT * FROM t; a 3 diff --git a/mysql-test/suite/innodb/t/read_only_recover_committed.test b/mysql-test/suite/innodb/t/read_only_recover_committed.test index 9ad09bb9b3a..439f57e9fad 100644 --- a/mysql-test/suite/innodb/t/read_only_recover_committed.test +++ b/mysql-test/suite/innodb/t/read_only_recover_committed.test @@ -78,6 +78,13 @@ SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT * FROM t; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT * FROM t; + +--echo # +--echo # MDEV-27332 SIGSEGV in fetch_data_into_cache +--echo # +BEGIN; +SELECT trx_state FROM information_schema.innodb_trx; +COMMIT; --let $restart_parameters= --source include/restart_mysqld.inc SELECT * FROM t; diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index afd644f3c70..951770e5bb7 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -1275,6 +1275,8 @@ static void fetch_data_into_cache_low(trx_i_s_cache_t *cache, const trx_t *trx) static void fetch_data_into_cache(trx_i_s_cache_t *cache) { + const trx_t *const purge_trx= purge_sys.query ? purge_sys.query->trx : NULL; + ut_ad(lock_mutex_own()); trx_i_s_cache_clear(cache); @@ -1284,7 +1286,7 @@ static void fetch_data_into_cache(trx_i_s_cache_t *cache) trx != NULL; trx= UT_LIST_GET_NEXT(trx_list, trx)) { - if (trx->state != TRX_STATE_NOT_STARTED && trx != purge_sys.query->trx) + if (trx != purge_trx && trx->state != TRX_STATE_NOT_STARTED) { mutex_enter(&trx->mutex); if (trx->state != TRX_STATE_NOT_STARTED) From 61a66d81b2bfc3a7c8c9a07d8c82d921eacba284 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Mon, 20 Dec 2021 12:07:20 +0200 Subject: [PATCH 35/52] MDEV-27297 wsrep error log messages drop last character MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vsnprintf takes the space need for trailing '\0' in consideration, and copies only n-1 characters to destination buffer. With the old code, only sizeof(buf)-2 characters were copied, this caused that last character of message could be lost. Reviewed-by: Jan Lindström --- sql/wsrep_mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 1e4eff831c2..f2b04393340 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -288,7 +288,7 @@ void WSREP_LOG(void (*fun)(const char* fmt, ...), const char* fmt, ...) char msg[128] = {'\0'}; va_list arglist; va_start(arglist, fmt); - int n= vsnprintf(msg, sizeof(msg) - 1, fmt, arglist); + int n= vsnprintf(msg, sizeof(msg), fmt, arglist); va_end(arglist); if (n < 0) { From 6487b8e33060b54612981e81b663aff15724fbdf Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 21 Dec 2021 11:59:08 +0400 Subject: [PATCH 36/52] MDEV-27307 main.ctype_utf8mb4_uca_allkeys tests fail with Valgrind/MSAN In case when filesort does not use addon field packing (because of too small potential savings) and uses fixed width addon fields instead, the field->pack() call can store less bytes when the field maximum possible field length, e.g. in case of VARCHAR(). The memory between the packed length and addonf->length (the maximum length) stayed uninitialized, which was reported by Valgrind/MSAN. The problem was introduced by f52bf92014efae6a1da9c2f26a7e3792ed5f5396 in 10.5, which removed the tail initialization (probably unintentionally). Restoring the bzero() in the fixed length branch, so in case when pack() stores less bytes than addonf->length says, the trailing bytes gets initialized. Note, before f52bf92014efae6a1da9c2f26a7e3792ed5f5396, the bzero() was under HAVE_valgrind conditional compilation. Now it's being added unconditionally: - MSAN also reported the problem, so it's not only Valgrind specific. - As Serg proposed, conditional initialization is bad - it can have potentional security problems as the non-initialized memory fragments can store various pieces of essential information, e.g. passwords. --- mysql-test/main/filesort_pack.result | 29 ++++++++++++++++ mysql-test/main/filesort_pack.test | 51 ++++++++++++++++++++++++++++ sql/filesort.cc | 7 +++- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 mysql-test/main/filesort_pack.result create mode 100644 mysql-test/main/filesort_pack.test diff --git a/mysql-test/main/filesort_pack.result b/mysql-test/main/filesort_pack.result new file mode 100644 index 00000000000..c067e0620b9 --- /dev/null +++ b/mysql-test/main/filesort_pack.result @@ -0,0 +1,29 @@ +# +# Start of 10.5 tests +# +# +# MDEV-27307 main.ctype_utf8mb4_uca_allkeys tests fail with Valgrind/MSAN +# +# In this scenario packing is fully disabled: +# - The sortkey is of a fixed width data type +# - The addon fields have too small potential savings +SET NAMES latin1; +CREATE TABLE t1 ( +code INT NOT NULL, +str VARCHAR(5) CHARACTER SET latin1 NOT NULL +) ENGINE=MyISAM; +FOR i IN 0..50 +DO +INSERT INTO t1 VALUES (i, REPEAT('a',1)); +END FOR; +$$ +SELECT COUNT(*) FROM t1; +COUNT(*) +51 +SET sort_buffer_size=1024; +SELECT HEX(code), HEX(str) FROM t1 ORDER BY HEX(str); +SET sort_buffer_size=DEFAULT; +DROP TABLE t1; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/filesort_pack.test b/mysql-test/main/filesort_pack.test new file mode 100644 index 00000000000..6765778904e --- /dev/null +++ b/mysql-test/main/filesort_pack.test @@ -0,0 +1,51 @@ +# +# Tests related to pack modes of the sortkey and addon fields. +# Fields can be either packed or fixed length. +# +# See the comment in filesort.cc: +# +# Heuristic: skip packing if potential savings are less than 10 bytes. +# + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-27307 main.ctype_utf8mb4_uca_allkeys tests fail with Valgrind/MSAN +--echo # +--echo # In this scenario packing is fully disabled: +--echo # - The sortkey is of a fixed width data type +--echo # - The addon fields have too small potential savings + +SET NAMES latin1; + +CREATE TABLE t1 ( + code INT NOT NULL, + str VARCHAR(5) CHARACTER SET latin1 NOT NULL +) ENGINE=MyISAM; + +DELIMITER $$; +FOR i IN 0..50 +DO + INSERT INTO t1 VALUES (i, REPEAT('a',1)); +END FOR; +$$ +DELIMITER ;$$ +SELECT COUNT(*) FROM t1; + +# The result is not very interesting, let's suppress it. +# We just make sure there are no Valgrind/MSAN warnings about +# not initialized memory being written to disk. + +SET sort_buffer_size=1024; +--disable_result_log +SELECT HEX(code), HEX(str) FROM t1 ORDER BY HEX(str); +--enable_result_log +SET sort_buffer_size=DEFAULT; + +DROP TABLE t1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/filesort.cc b/sql/filesort.cc index 766415f58fb..4e5aeccb78e 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1376,12 +1376,17 @@ static uint make_sortkey(Sort_param *param, uchar *to, uchar *ref_pos, else { uchar *end= field->pack(to, field->ptr); - int sz= static_cast(end - to); + DBUG_ASSERT(end >= to); + uint sz= static_cast(end - to); res_len += sz; if (packed_addon_fields) to+= sz; else + { + if (addonf->length > sz) + bzero(end, addonf->length - sz); // Make Valgrind/MSAN happy to+= addonf->length; + } } } if (packed_addon_fields) From a5ef74e7eb4bab09c9bda4fcd7fab12302526ea4 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 22 Dec 2021 13:12:40 +0400 Subject: [PATCH 37/52] MDEV-27195 SIGSEGV in Table_scope_and_contents_source_st::vers_check_system_fields The old code erroneously used default_charset_info to compare field names. default_charset_info can point to any arbitrary collation, including ucs2*, utf16*, utf32*, including those that do not support strcasecmp(). my_charset_utf8mb4_unicode_ci, which is used in this scenario: CREATE TABLE t1 ENGINE=InnoDB WITH SYSTEM VERSIONING AS SELECT 0; does not support strcasecmp(). Fixing the code to use Lex_ident::streq(), which uses system_charset_info instead of default_charset_info. --- mysql-test/main/ctype_utf8mb4_unicode_ci_def.opt | 1 + .../main/ctype_utf8mb4_unicode_ci_def.result | 11 +++++++++++ mysql-test/main/ctype_utf8mb4_unicode_ci_def.test | 15 +++++++++++++++ sql/handler.cc | 3 +-- 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 mysql-test/main/ctype_utf8mb4_unicode_ci_def.opt create mode 100644 mysql-test/main/ctype_utf8mb4_unicode_ci_def.result create mode 100644 mysql-test/main/ctype_utf8mb4_unicode_ci_def.test diff --git a/mysql-test/main/ctype_utf8mb4_unicode_ci_def.opt b/mysql-test/main/ctype_utf8mb4_unicode_ci_def.opt new file mode 100644 index 00000000000..e430a45c10e --- /dev/null +++ b/mysql-test/main/ctype_utf8mb4_unicode_ci_def.opt @@ -0,0 +1 @@ +--character-set-server=utf8mb4,latin1 --collation-server=utf8mb4_unicode_ci diff --git a/mysql-test/main/ctype_utf8mb4_unicode_ci_def.result b/mysql-test/main/ctype_utf8mb4_unicode_ci_def.result new file mode 100644 index 00000000000..2e15931248b --- /dev/null +++ b/mysql-test/main/ctype_utf8mb4_unicode_ci_def.result @@ -0,0 +1,11 @@ +# +# Start of 10.3 tests +# +# +# MDEV-27195 SIGSEGV in Table_scope_and_contents_source_st::vers_check_system_fields +# +CREATE TABLE t1 ENGINE=MyISAM WITH SYSTEM VERSIONING AS SELECT 0; +DROP TABLE t1; +# +# End of 10.3 tests +# diff --git a/mysql-test/main/ctype_utf8mb4_unicode_ci_def.test b/mysql-test/main/ctype_utf8mb4_unicode_ci_def.test new file mode 100644 index 00000000000..fb7fbe04e3b --- /dev/null +++ b/mysql-test/main/ctype_utf8mb4_unicode_ci_def.test @@ -0,0 +1,15 @@ +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-27195 SIGSEGV in Table_scope_and_contents_source_st::vers_check_system_fields +--echo # + +CREATE TABLE t1 ENGINE=MyISAM WITH SYSTEM VERSIONING AS SELECT 0; +DROP TABLE t1; + + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/sql/handler.cc b/sql/handler.cc index 11a387fb4e3..f8702c27a39 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7264,8 +7264,7 @@ bool Table_scope_and_contents_source_st::vers_check_system_fields( { List_iterator dup_it(alter_info->create_list); for (Create_field *dup= dup_it++; !is_dup && dup != f; dup= dup_it++) - is_dup= my_strcasecmp(default_charset_info, - dup->field_name.str, f->field_name.str) == 0; + is_dup= Lex_ident(dup->field_name).streq(f->field_name); } if (!(f->flags & VERS_UPDATE_UNVERSIONED_FLAG) && !is_dup) From 12087d67579e641cfc07ee6b8c46b75171e9708c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 22 Dec 2021 01:05:18 +0100 Subject: [PATCH 38/52] MDEV-23175: my_timer_milliseconds clock_gettime for multiple platfomrs Small postfix to MDEV-23175 to ensure faster option on FreeBSD and compatibility to Solaris that isn't high resolution. ftime is left as a backup in case an implementation doesn't contain any of these clocks. FreeBSD $ ./unittest/mysys/my_rdtsc-t 1..11 # ----- Routine --------------- # myt.cycles.routine : 5 # myt.nanoseconds.routine : 11 # myt.microseconds.routine : 13 # myt.milliseconds.routine : 11 # myt.ticks.routine : 17 # ----- Frequency ------------- # myt.cycles.frequency : 3610295566 # myt.nanoseconds.frequency : 1000000000 # myt.microseconds.frequency : 1000000 # myt.milliseconds.frequency : 899 # myt.ticks.frequency : 136 # ----- Resolution ------------ # myt.cycles.resolution : 1 # myt.nanoseconds.resolution : 1 # myt.microseconds.resolution : 1 # myt.milliseconds.resolution : 7 # myt.ticks.resolution : 1 # ----- Overhead -------------- # myt.cycles.overhead : 26 # myt.nanoseconds.overhead : 19140 # myt.microseconds.overhead : 19036 # myt.milliseconds.overhead : 578 # myt.ticks.overhead : 21544 ok 1 - my_timer_init() did not crash ok 2 - The cycle timer is strictly increasing ok 3 - The cycle timer is implemented ok 4 - The nanosecond timer is increasing ok 5 - The nanosecond timer is implemented ok 6 - The microsecond timer is increasing ok 7 - The microsecond timer is implemented ok 8 - The millisecond timer is increasing ok 9 - The millisecond timer is implemented ok 10 - The tick timer is increasing ok 11 - The tick timer is implemented --- mysys/my_rdtsc.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/mysys/my_rdtsc.c b/mysys/my_rdtsc.c index b020e224a59..605ac20350c 100644 --- a/mysys/my_rdtsc.c +++ b/mysys/my_rdtsc.c @@ -356,9 +356,29 @@ ulonglong my_timer_microseconds(void) milliseconds. */ +#if defined(HAVE_CLOCK_GETTIME) +#if defined(CLOCK_MONOTONIC_FAST) +/* FreeBSD */ +#define MY_CLOCK_ID CLOCK_MONOTONIC_FAST +#elif defined(CLOCK_MONOTONIC_COARSE) +/* Linux */ +#define MY_CLOCK_ID CLOCK_MONOTONIC_COARSE +#elif defined(CLOCK_MONOTONIC) +/* POSIX (includes OSX) */ +#define MY_CLOCK_ID CLOCK_MONOTONIC +#elif defined(CLOCK_REALTIME) +/* Solaris (which doesn't seem to have MONOTONIC) */ +#define MY_CLOCK_ID CLOCK_REALTIME +#endif +#endif + ulonglong my_timer_milliseconds(void) { -#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME) +#if defined(MY_CLOCK_ID) + struct timespec tp; + clock_gettime(MY_CLOCK_ID, &tp); + return (ulonglong)tp.tv_sec * 1000 + (ulonglong)tp.tv_nsec / 1000000; +#elif defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME) /* ftime() is obsolete but maybe the platform is old */ struct timeb ft; ftime(&ft); @@ -631,7 +651,9 @@ void my_timer_init(MY_TIMER_INFO *mti) /* milliseconds */ mti->milliseconds.frequency= 1000; /* initial assumption */ -#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME) +#ifdef MY_CLOCK_ID + mti->milliseconds.routine= MY_TIMER_ROUTINE_CLOCK_GETTIME; +#elif defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME) mti->milliseconds.routine= MY_TIMER_ROUTINE_FTIME; #elif defined(_WIN32) mti->milliseconds.routine= MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME; From 4eec6b99e177a644650057f2c14d2f10ddd0ada4 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 15 Jul 2020 11:23:19 +1000 Subject: [PATCH 39/52] MDEV-23175: my_timer_milliseconds clock_gettime for multiple platfomrs Small postfix to MDEV-23175 to ensure faster option on FreeBSD and compatibility to Solaris that isn't high resolution. ftime is left as a backup in case an implementation doesn't contain any of these clocks. FreeBSD $ ./unittest/mysys/my_rdtsc-t 1..11 # ----- Routine --------------- # myt.cycles.routine : 5 # myt.nanoseconds.routine : 11 # myt.microseconds.routine : 13 # myt.milliseconds.routine : 11 # myt.ticks.routine : 17 # ----- Frequency ------------- # myt.cycles.frequency : 3610295566 # myt.nanoseconds.frequency : 1000000000 # myt.microseconds.frequency : 1000000 # myt.milliseconds.frequency : 899 # myt.ticks.frequency : 136 # ----- Resolution ------------ # myt.cycles.resolution : 1 # myt.nanoseconds.resolution : 1 # myt.microseconds.resolution : 1 # myt.milliseconds.resolution : 7 # myt.ticks.resolution : 1 # ----- Overhead -------------- # myt.cycles.overhead : 26 # myt.nanoseconds.overhead : 19140 # myt.microseconds.overhead : 19036 # myt.milliseconds.overhead : 578 # myt.ticks.overhead : 21544 ok 1 - my_timer_init() did not crash ok 2 - The cycle timer is strictly increasing ok 3 - The cycle timer is implemented ok 4 - The nanosecond timer is increasing ok 5 - The nanosecond timer is implemented ok 6 - The microsecond timer is increasing ok 7 - The microsecond timer is implemented ok 8 - The millisecond timer is increasing ok 9 - The millisecond timer is implemented ok 10 - The tick timer is increasing ok 11 - The tick timer is implemented --- mysys/my_rdtsc.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/mysys/my_rdtsc.c b/mysys/my_rdtsc.c index c707588da01..1503a5db442 100644 --- a/mysys/my_rdtsc.c +++ b/mysys/my_rdtsc.c @@ -173,9 +173,29 @@ ulonglong my_timer_microseconds(void) milliseconds. */ +#if defined(HAVE_CLOCK_GETTIME) +#if defined(CLOCK_MONOTONIC_FAST) +/* FreeBSD */ +#define MY_CLOCK_ID CLOCK_MONOTONIC_FAST +#elif defined(CLOCK_MONOTONIC_COARSE) +/* Linux */ +#define MY_CLOCK_ID CLOCK_MONOTONIC_COARSE +#elif defined(CLOCK_MONOTONIC) +/* POSIX (includes OSX) */ +#define MY_CLOCK_ID CLOCK_MONOTONIC +#elif defined(CLOCK_REALTIME) +/* Solaris (which doesn't seem to have MONOTONIC) */ +#define MY_CLOCK_ID CLOCK_REALTIME +#endif +#endif + ulonglong my_timer_milliseconds(void) { -#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME) +#if defined(MY_CLOCK_ID) + struct timespec tp; + clock_gettime(MY_CLOCK_ID, &tp); + return (ulonglong)tp.tv_sec * 1000 + (ulonglong)tp.tv_nsec / 1000000; +#elif defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME) /* ftime() is obsolete but maybe the platform is old */ struct timeb ft; ftime(&ft); @@ -428,7 +448,9 @@ void my_timer_init(MY_TIMER_INFO *mti) /* milliseconds */ mti->milliseconds.frequency= 1000; /* initial assumption */ -#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME) +#ifdef MY_CLOCK_ID + mti->milliseconds.routine= MY_TIMER_ROUTINE_CLOCK_GETTIME; +#elif defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME) mti->milliseconds.routine= MY_TIMER_ROUTINE_FTIME; #elif defined(_WIN32) mti->milliseconds.routine= MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME; From be20b3b03f9c522d17b3454214981506549063eb Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Tue, 21 Dec 2021 16:22:33 -0700 Subject: [PATCH 40/52] MDEV-26919: binlog.binlog_truncate_active_log fails in bb with valgrind, Conditional jump or move depends on uninitialised value Problem: ======== When writing an XA based event to the binary log, an assert was always referencing thd->lex->xa_opt. This variable, however, is only set when using XA START, XA END, and XA COMMIT. When an XA PREPARE statement is being processed, it is not guaranteed that the xa_opt variable will be set (e.g. if existing within a stored procedure). This caused valgrind to complain about accessing an uninitialized variable. Solution: ======== Before referencing xa_opt, ensure the context is valid such that it is set. Reviewed By: ============ Andrei Elkin --- sql/log_event_server.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 093adebf536..7c4ea488f9e 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -3281,7 +3281,8 @@ Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg, (thd->lex->sql_command == SQLCOM_XA_PREPARE || xid_state.get_state_code() == XA_PREPARED)) { - DBUG_ASSERT(thd->lex->xa_opt != XA_ONE_PHASE); + DBUG_ASSERT(!(thd->lex->sql_command == SQLCOM_XA_COMMIT && + thd->lex->xa_opt == XA_ONE_PHASE)); flags2|= thd->lex->sql_command == SQLCOM_XA_PREPARE ? FL_PREPARED_XA : FL_COMPLETED_XA; From ca2ea4ff4178d097ac2d939b8fd88ea658ed64dc Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 19 May 2020 20:15:00 +0300 Subject: [PATCH 41/52] Only apply wsrep_trx_fragment_size to InnoDB tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MDEV-22617 Galera node crashes when trying to log to slow_log table in streaming replication mode Other things: - Changed name of wsrep_after_row(two arguments) to wsrep_after_row_internal(one argument) to not depended on the function signature with unused arguments. Reviewed-by: Jan Lindström Added test case --- mysql-test/suite/galera_sr/r/galera_sr_slow.result | 13 +++++++++++++ mysql-test/suite/galera_sr/t/galera_sr_slow.test | 11 +++++++++++ sql/handler.cc | 11 +++++++---- sql/wsrep_trans_observer.h | 2 +- 4 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/galera_sr/r/galera_sr_slow.result create mode 100644 mysql-test/suite/galera_sr/t/galera_sr_slow.test diff --git a/mysql-test/suite/galera_sr/r/galera_sr_slow.result b/mysql-test/suite/galera_sr/r/galera_sr_slow.result new file mode 100644 index 00000000000..a03aac0d085 --- /dev/null +++ b/mysql-test/suite/galera_sr/r/galera_sr_slow.result @@ -0,0 +1,13 @@ +connection node_2; +connection node_1; +connection node_1; +SET GLOBAL wsrep_trx_fragment_unit='bytes'; +SET GLOBAL wsrep_trx_fragment_size=10240000; +SET GLOBAL slow_query_log=ON; +SET GLOBAL log_output='TABLE'; +SELECT SLEEP(10); +SLEEP(10) +0 +SET GLOBAL wsrep_trx_fragment_unit=DEFAULT; +SET GLOBAL wsrep_trx_fragment_size=DEFAULT; +SET GLOBAL log_output=DEFAULT; diff --git a/mysql-test/suite/galera_sr/t/galera_sr_slow.test b/mysql-test/suite/galera_sr/t/galera_sr_slow.test new file mode 100644 index 00000000000..d98305102fc --- /dev/null +++ b/mysql-test/suite/galera_sr/t/galera_sr_slow.test @@ -0,0 +1,11 @@ +--source include/galera_cluster.inc + +--connection node_1 +SET GLOBAL wsrep_trx_fragment_unit='bytes'; +SET GLOBAL wsrep_trx_fragment_size=10240000; +SET GLOBAL slow_query_log=ON; +SET GLOBAL log_output='TABLE'; +SELECT SLEEP(10); +SET GLOBAL wsrep_trx_fragment_unit=DEFAULT; +SET GLOBAL wsrep_trx_fragment_size=DEFAULT; +SET GLOBAL log_output=DEFAULT; diff --git a/sql/handler.cc b/sql/handler.cc index 812de48fa68..82472bcadde 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6579,7 +6579,7 @@ static int wsrep_after_row(THD *thd) my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0)); DBUG_RETURN(ER_ERROR_DURING_COMMIT); } - else if (wsrep_after_row(thd, false)) + else if (wsrep_after_row_internal(thd)) { DBUG_RETURN(ER_LOCK_DEADLOCK); } @@ -6778,7 +6778,8 @@ int handler::ha_write_row(const uchar *buf) error= binlog_log_row(table, 0, buf, log_func); #ifdef WITH_WSREP if (table_share->tmp_table == NO_TMP_TABLE && - WSREP(ha_thd()) && (error= wsrep_after_row(ha_thd()))) + WSREP(ha_thd()) && ht->flags & HTON_WSREP_REPLICATION && + !error && (error= wsrep_after_row(ha_thd()))) { DBUG_RETURN(error); } @@ -6836,7 +6837,8 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data) } } if (table_share->tmp_table == NO_TMP_TABLE && - is_wsrep && (error= wsrep_after_row(thd))) + is_wsrep && ht->flags & HTON_WSREP_REPLICATION && + !error && (error= wsrep_after_row(thd))) { return error; } @@ -6911,7 +6913,8 @@ int handler::ha_delete_row(const uchar *buf) } } if (table_share->tmp_table == NO_TMP_TABLE && - is_wsrep && (error= wsrep_after_row(thd))) + is_wsrep && ht->flags & HTON_WSREP_REPLICATION && + !error && (error= wsrep_after_row(thd))) { return error; } diff --git a/sql/wsrep_trans_observer.h b/sql/wsrep_trans_observer.h index 55beb6ebe7c..837bad4c50f 100644 --- a/sql/wsrep_trans_observer.h +++ b/sql/wsrep_trans_observer.h @@ -158,7 +158,7 @@ static inline int wsrep_start_trx_if_not_started(THD* thd) Return zero on succes, non-zero on failure. */ -static inline int wsrep_after_row(THD* thd, bool) +static inline int wsrep_after_row_internal(THD* thd) { if (thd->wsrep_cs().state() != wsrep::client_state::s_none && wsrep_thd_is_local(thd)) From 0165a0632256a30fcb5b55b677ca5927478d1212 Mon Sep 17 00:00:00 2001 From: Leandro Pacheco Date: Mon, 13 Sep 2021 11:20:22 -0300 Subject: [PATCH 42/52] result of wsrep logic in queue_for_group_commit was being ignored MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This could cause out of order wsrep checkpoints due wsrep specific leader code not being executed in `MYSQL_BIN_LOG::write_transaction_to_binlog_events`. Move original result assignment to before wsrep logic to prevent that. Reviewed-by: Jan Lindström --- sql/log.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/log.cc b/sql/log.cc index fbe7c78c4ac..c5a192d56d3 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -7768,6 +7768,8 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry) cur= entry->thd->wait_for_commit_ptr; } + result= orig_queue == NULL; + #ifdef WITH_WSREP if (wsrep_is_active(entry->thd) && wsrep_run_commit_hook(entry->thd, entry->all)) @@ -7791,7 +7793,6 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry) DBUG_PRINT("info", ("Queued for group commit as %s", (orig_queue == NULL) ? "leader" : "participant")); - result= orig_queue == NULL; end: if (backup_lock_released) From 397f5cf71ee9424373febe0cb8fb0bce1e02e504 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Thu, 23 Dec 2021 12:00:05 +0300 Subject: [PATCH 43/52] MDEV-27238: Assertion `got_name == named_item_expected()' failed in Json_writer make_join_select() calls const_cond->val_int(). There are edge cases where const_cond may have a not-yet optimized subquery. (The subquery will have used_tables() covered by join->const_tables. It will still have const_item()==false, so other parts of the optimizer will not try to evaluate it. We should probably mark such subqueries as constant but that is outside the scope of this MDEV) --- mysql-test/main/opt_trace.result | 27 +++++++++++++++++++++------ mysql-test/main/opt_trace.test | 10 ++++++++++ sql/sql_select.cc | 6 +++++- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index 0e4477e1fd9..34683d037ea 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -2393,7 +2393,8 @@ select t1.a from t1 left join t2 on t1.a=t2.a { "best_join_order": ["t2", "t1"] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -2550,7 +2551,8 @@ explain select * from t1 left join t2 on t2.a=t1.a { "best_join_order": ["t1", "t2"] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -2708,7 +2710,8 @@ explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and "best_join_order": ["t3", "t2", "t1"] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -3021,7 +3024,8 @@ explain extended select * from t1 where a in (select pk from t10) { "best_join_order": ["t1", ""] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -4719,7 +4723,8 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ "best_join_order": ["t1", ""] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -7365,7 +7370,8 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -8632,5 +8638,14 @@ SELECT 'a\0' LIMIT 0 { } SET optimizer_trace=DEFAULT; # +# MDEV-27238: Assertion `got_name == named_item_expected()' failed in Json_writer::on_start_object +# +CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=MEMORY; +SET optimizer_trace=1; +INSERT INTO t1 VALUES (0,0); +SELECT a FROM t1 WHERE (a,b) in (SELECT @c,@d); +a +DROP TABLE t1; +# # End of 10.4 tests # diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index 9d4794855e0..855ce11aaf5 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -643,6 +643,16 @@ SELECT 'a\0' LIMIT 0; SELECT query, trace FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; SET optimizer_trace=DEFAULT; +--echo # +--echo # MDEV-27238: Assertion `got_name == named_item_expected()' failed in Json_writer::on_start_object +--echo # + +CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=MEMORY; +SET optimizer_trace=1; +INSERT INTO t1 VALUES (0,0); +SELECT a FROM t1 WHERE (a,b) in (SELECT @c,@d); +DROP TABLE t1; + --echo # --echo # End of 10.4 tests --echo # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 27fc27f242a..35925c0cd44 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11409,7 +11409,11 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } else { - const bool const_cond_result = const_cond->val_int() != 0; + bool const_cond_result; + { + Json_writer_array a(thd, "computing_condition"); + const_cond_result= const_cond->val_int() != 0; + } if (!const_cond_result) { DBUG_PRINT("info",("Found impossible WHERE condition")); From 4b020bfd9a10f991845b995780db4879f8c9f61d Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Thu, 23 Dec 2021 12:03:09 +0300 Subject: [PATCH 44/52] Fix typos in optimizer trace output --- sql/sql_select.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 35925c0cd44..cfd1fbb3275 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11404,7 +11404,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) trace_const_cond.add("condition_on_constant_tables", const_cond); if (const_cond->is_expensive()) { - trace_const_cond.add("evalualted", "false") + trace_const_cond.add("evaluated", "false") .add("cause", "expensive cond"); } else @@ -11417,7 +11417,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (!const_cond_result) { DBUG_PRINT("info",("Found impossible WHERE condition")); - trace_const_cond.add("evalualted", "true") + trace_const_cond.add("evaluated", "true") .add("found", "impossible where"); join->exec_const_cond= NULL; DBUG_RETURN(1); From b5cbe50604046647b52c1ed6b5af596483a120be Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Thu, 23 Dec 2021 14:19:45 +0100 Subject: [PATCH 45/52] MDEV-24097: galera[_3nodes] suite tests in MTR sporadically fails This is the first part of the fixes for MDEV-24097. This commit contains the fixes for instability when testing Galera and when restarting nodes quickly: 1) Protection against a "stuck" old SST process during the execution of the new SST (after restarting the node) is now implemented for mariabackup / xtrabackup, which should help to avoid almost all conflicts due to the use of the same ports - both during testing with mtr, so and when restarting nodes quickly in a production environment. 2) Added more protection to scripts against unexpected return of the rc != 0 (in the commands for deleting temporary files, etc). 3) Added protection against unexpected crashes during binlog transfer (in SST scripts for rsync). 4) Spaces and some special characters in binlog filenames shouldn't be a problem now (at the script level). 5) Daemon process termination tracking has been made more robust against crashes due to unexpected termination of the previous SST process while new scripts are running. 6) Reading ssl encryption parameters has been moved from specific SST scripts to a common wsrep_sst_common.sh script, which allows unified error handling, unified diagnostics and simplifies script revisions in the future. 7) Improved diagnostics of errors related to the use of openssl. 8) Corrections have been made for xtrabackup-v2 (both in tests and in the script code) that restore the work of xtrabackup with updated versions of innodb. 9) Fixed some tests for galera_3nodes, although the complete solution for the problem of starting three nodes at the same time on fast machines will be done in a separate commit. No additional tests are required as this commit fixes problems with existing tests. --- mysql-test/suite/galera/disabled.def | 2 - .../galera_sst_xtrabackup-v2_data_dir.result | 26 +++ .../t/galera_autoinc_sst_xtrabackup.cnf | 1 + .../galera/t/galera_ist_xtrabackup-v2.cnf | 1 + .../t/galera_sst_xtrabackup-v2-options.cnf | 1 + .../galera/t/galera_sst_xtrabackup-v2.cnf | 1 + .../t/galera_sst_xtrabackup-v2_data_dir.cnf | 1 + ...era_sst_xtrabackup-v2_encrypt_with_key.cnf | 1 + .../r/galera_ist_gcache_rollover.result | 4 +- .../t/galera_ist_gcache_rollover.test | 10 +- scripts/wsrep_sst_common.sh | 142 ++++++++++----- scripts/wsrep_sst_mariabackup.sh | 109 +++++------- scripts/wsrep_sst_rsync.sh | 161 ++++++++---------- scripts/wsrep_sst_xtrabackup-v2.sh | 117 +++++-------- 14 files changed, 292 insertions(+), 285 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 955a2c82ebc..84babda2fa0 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -28,5 +28,3 @@ query_cache: MDEV-15805 Test failure on galera.query_cache versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch galera_wsrep_provider_unset_set: wsrep_provider is read-only for security reasons pxc-421: wsrep_provider is read-only for security reasons -galera_sst_xtrabackup-v2: Test fails due to innodb issues -galera_sst_xtrabackup-v2_data_dir: Test fails due to innodb issues diff --git a/mysql-test/suite/galera/r/galera_sst_xtrabackup-v2_data_dir.result b/mysql-test/suite/galera/r/galera_sst_xtrabackup-v2_data_dir.result index cec0f21ee22..ff85a7d6c0f 100644 --- a/mysql-test/suite/galera/r/galera_sst_xtrabackup-v2_data_dir.result +++ b/mysql-test/suite/galera/r/galera_sst_xtrabackup-v2_data_dir.result @@ -1,4 +1,7 @@ +connection node_1; +connection node_2; Performing State Transfer on a server that has been shut down cleanly and restarted +connection node_1; CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -8,6 +11,7 @@ INSERT INTO t1 VALUES ('node1_committed_before'); INSERT INTO t1 VALUES ('node1_committed_before'); INSERT INTO t1 VALUES ('node1_committed_before'); COMMIT; +connection node_2; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node2_committed_before'); @@ -17,6 +21,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; Shutting down server ... +connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node1_committed_during'); @@ -31,6 +36,7 @@ INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -38,6 +44,7 @@ INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; Starting server ... SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -47,6 +54,7 @@ INSERT INTO t1 VALUES ('node2_committed_after'); INSERT INTO t1 VALUES ('node2_committed_after'); INSERT INTO t1 VALUES ('node2_committed_after'); COMMIT; +connection node_1; INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); @@ -61,6 +69,7 @@ INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); COMMIT; +connection node_1a_galera_st_shutdown_slave; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -75,6 +84,7 @@ COUNT(*) = 0 1 COMMIT; SET AUTOCOMMIT=ON; +connection node_1; SELECT COUNT(*) = 35 FROM t1; COUNT(*) = 35 1 @@ -86,6 +96,7 @@ COMMIT; SET AUTOCOMMIT=ON; Performing State Transfer on a server that starts from a clean var directory This is accomplished by shutting down node #2 and removing its var directory before restarting it +connection node_1; CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -95,6 +106,7 @@ INSERT INTO t1 VALUES ('node1_committed_before'); INSERT INTO t1 VALUES ('node1_committed_before'); INSERT INTO t1 VALUES ('node1_committed_before'); COMMIT; +connection node_2; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node2_committed_before'); @@ -104,6 +116,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; Shutting down server ... +connection node_1; Cleaning var directory ... SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -119,6 +132,7 @@ INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_clean_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -126,6 +140,7 @@ INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; Starting server ... SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -135,6 +150,7 @@ INSERT INTO t1 VALUES ('node2_committed_after'); INSERT INTO t1 VALUES ('node2_committed_after'); INSERT INTO t1 VALUES ('node2_committed_after'); COMMIT; +connection node_1; INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); @@ -149,6 +165,7 @@ INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); COMMIT; +connection node_1a_galera_st_clean_slave; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -163,6 +180,7 @@ COUNT(*) = 0 1 COMMIT; SET AUTOCOMMIT=ON; +connection node_1; SELECT COUNT(*) = 35 FROM t1; COUNT(*) = 35 1 @@ -173,6 +191,7 @@ DROP TABLE t1; COMMIT; SET AUTOCOMMIT=ON; Performing State Transfer on a server that has been killed and restarted +connection node_1; CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -182,6 +201,7 @@ INSERT INTO t1 VALUES ('node1_committed_before'); INSERT INTO t1 VALUES ('node1_committed_before'); INSERT INTO t1 VALUES ('node1_committed_before'); COMMIT; +connection node_2; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node2_committed_before'); @@ -191,6 +211,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; Killing server ... +connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node1_committed_during'); @@ -205,6 +226,7 @@ INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -212,6 +234,7 @@ INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; Performing --wsrep-recover ... Starting server ... Using --wsrep-start-position when starting mysqld ... @@ -223,6 +246,7 @@ INSERT INTO t1 VALUES ('node2_committed_after'); INSERT INTO t1 VALUES ('node2_committed_after'); INSERT INTO t1 VALUES ('node2_committed_after'); COMMIT; +connection node_1; INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); @@ -237,6 +261,7 @@ INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); COMMIT; +connection node_1a_galera_st_kill_slave; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -251,6 +276,7 @@ COUNT(*) = 0 1 COMMIT; SET AUTOCOMMIT=ON; +connection node_1; SELECT COUNT(*) = 35 FROM t1; COUNT(*) = 35 1 diff --git a/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.cnf b/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.cnf index 2e25ecae317..f6ee3c56e5e 100644 --- a/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.cnf +++ b/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.cnf @@ -4,6 +4,7 @@ wsrep_sst_method=xtrabackup-v2 wsrep_sst_auth="root:" innodb_safe_truncate=OFF +# innodb_undo_logs=1 [mysqld.1] wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_ist_xtrabackup-v2.cnf b/mysql-test/suite/galera/t/galera_ist_xtrabackup-v2.cnf index 5b35701aeab..7242606fe05 100644 --- a/mysql-test/suite/galera/t/galera_ist_xtrabackup-v2.cnf +++ b/mysql-test/suite/galera/t/galera_ist_xtrabackup-v2.cnf @@ -4,6 +4,7 @@ wsrep_sst_method=xtrabackup-v2 wsrep_sst_auth=root: innodb_safe_truncate=OFF +innodb_undo_logs=1 [mysqld.1] wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2-options.cnf b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2-options.cnf index af3a7aecec4..ec836592965 100644 --- a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2-options.cnf +++ b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2-options.cnf @@ -5,6 +5,7 @@ wsrep_sst_method=xtrabackup-v2 wsrep_sst_auth="root:" wsrep_debug=ON innodb_safe_truncate=OFF +innodb_undo_logs=1 [xtrabackup] backup-locks diff --git a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2.cnf b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2.cnf index e347e259897..ad99bd909b8 100644 --- a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2.cnf +++ b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2.cnf @@ -5,6 +5,7 @@ wsrep_sst_method=xtrabackup-v2 wsrep_sst_auth="root:" wsrep_debug=ON innodb_safe_truncate=OFF +innodb_undo_logs=1 [mysqld.1] wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_data_dir.cnf b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_data_dir.cnf index 43180173425..8665c517629 100644 --- a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_data_dir.cnf +++ b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_data_dir.cnf @@ -5,6 +5,7 @@ wsrep_sst_method=xtrabackup-v2 wsrep_sst_auth="root:" wsrep_debug=ON innodb_safe_truncate=OFF +innodb_undo_logs=1 [mysqld.1] wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_encrypt_with_key.cnf b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_encrypt_with_key.cnf index 7a98fd2aa58..984d040c6ab 100644 --- a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_encrypt_with_key.cnf +++ b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_encrypt_with_key.cnf @@ -5,6 +5,7 @@ wsrep_sst_method=xtrabackup-v2 wsrep_sst_auth="root:" wsrep_debug=ON innodb_safe_truncate=OFF +innodb_undo_logs=1 [SST] tkey=@ENV.MYSQL_TEST_DIR/std_data/cakey.pem diff --git a/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result b/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result index aa3e349eda7..996363a1ea8 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result +++ b/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result @@ -6,10 +6,10 @@ CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); INSERT INTO t1 VALUES (01), (02), (03), (04), (05); connection node_2; Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +SET GLOBAL wsrep_cluster_address = ''; connection node_3; Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +SET GLOBAL wsrep_cluster_address = ''; connection node_1; INSERT INTO t1 VALUES (11), (12), (13), (14), (15); INSERT INTO t1 VALUES (21), (22), (23), (24), (25); diff --git a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test index 0032f8d6ee1..2719316fb84 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test @@ -29,9 +29,11 @@ INSERT INTO t1 VALUES (01), (02), (03), (04), (05); # Disconnect nodes #2 and #3 --connection node_2 +--let $wsrep_cluster_address_orig2 = `select @@wsrep_cluster_address` --source suite/galera/include/galera_stop_replication.inc --connection node_3 +--let $wsrep_cluster_address_orig3 = `select @@wsrep_cluster_address` --source suite/galera/include/galera_stop_replication.inc --connection node_1 @@ -51,8 +53,8 @@ INSERT INTO t1 VALUES (21), (22), (23), (24), (25); # ... and restart providers to force IST --connection node_2 --disable_query_log ---eval SET GLOBAL wsrep_provider = '$wsrep_provider_orig'; ---eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig'; +SET GLOBAL wsrep_cluster_address=''; +--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig2'; --enable_query_log --connection node_1 @@ -60,8 +62,8 @@ INSERT INTO t1 VALUES (31), (32), (33), (34), (35); --connection node_3 --disable_query_log ---eval SET GLOBAL wsrep_provider = '$wsrep_provider_orig'; ---eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig'; +SET GLOBAL wsrep_cluster_address=''; +--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig3'; --enable_query_log --connection node_1 diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 040cd31caa9..deebe7cf820 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -17,7 +17,7 @@ # This is a common command line parser to be sourced by other SST scripts -set -u +set -ue # Setting the path for some utilities on CentOS export PATH="$PATH:/usr/sbin:/usr/bin:/sbin:/bin" @@ -879,9 +879,9 @@ fi wsrep_cleanup_progress_file() { - [ -n "$SST_PROGRESS_FILE" -a \ - -f "$SST_PROGRESS_FILE" ] && \ - rm -f "$SST_PROGRESS_FILE" 2>/dev/null || : + if [ -n "$SST_PROGRESS_FILE" -a -f "$SST_PROGRESS_FILE" ]; then + rm -f "$SST_PROGRESS_FILE" 2>/dev/null || : + fi } wsrep_check_program() @@ -897,13 +897,10 @@ wsrep_check_program() wsrep_check_programs() { local ret=0 - - while [ $# -gt 0 ] - do + while [ $# -gt 0 ]; do wsrep_check_program "$1" || ret=$? shift done - return $ret } @@ -1028,11 +1025,11 @@ check_sockets_utils() # check_port() { - local pid="$1" + local pid="${1:-0}" local port="$2" local utils="$3" - [ -z "$pid" ] || [ $pid -eq 0 ] && pid='[0-9]+' + [ $pid -le 0 ] && pid='[0-9]+' local rc=1 @@ -1070,14 +1067,20 @@ check_for_dhparams() if [ ! -r "$ssl_dhparams" ]; then get_openssl if [ -n "$OPENSSL_BINARY" ]; then - wsrep_log_info "Could not find dhparams file, creating $ssl_dhparams" - if ! "$OPENSSL_BINARY" dhparam -out "$ssl_dhparams" 2048 >/dev/null 2>&1 - then + wsrep_log_info \ + "Could not find dhparams file, creating $ssl_dhparams" + local bug=0 + local errmsg + errmsg=$("$OPENSSL_BINARY" \ + dhparam -out "$ssl_dhparams" 2048 2>&1) || bug=1 + if [ $bug -ne 0 ]; then + wsrep_log_info "run: \"$OPENSSL_BINARY\" dhparam -out \"$ssl_dhparams\" 2048" + wsrep_log_info "output: $errmsg" wsrep_log_error "******** ERROR *****************************************" wsrep_log_error "* Could not create the dhparams.pem file with OpenSSL. *" wsrep_log_error "********************************************************" ssl_dhparams="" - fi + fi else # Rollback: if openssl is not installed, then use # the default parameters: @@ -1099,6 +1102,16 @@ verify_ca_matches_cert() local ca="$2" local cap="$3" + local readable=1; [ ! -r "$cert" ] && readable=0 + [ -n "$ca" -a ! -r "$ca" ] && readable=0 + [ -n "$cap" -a ! -r "$cap" ] && readable=0 + + if [ $readable -eq 0 ]; then + wsrep_log_error \ + "Both PEM file and CA file (or path) must be readable" + exit 22 + fi + # If the openssl utility is not installed, then # we will not do this certificate check: get_openssl @@ -1107,22 +1120,12 @@ verify_ca_matches_cert() return fi - local readable=1; [ ! -r "$cert" ] && readable=0 - [ -n "$ca" ] && [ ! -r "$ca" ] && readable=0 - [ -n "$cap" ] && [ ! -r "$cap" ] && readable=0 - - if [ $readable -eq 0 ]; then - wsrep_log_error \ - "Both PEM file and CA file (or path) must be readable" - exit 22 - fi - local not_match=0 local errmsg errmsg=$("$OPENSSL_BINARY" verify -verbose \ - ${ca:+ -CAfile} ${ca:+ "$ca"} \ - ${cap:+ -CApath} ${cap:+ "$cap"} \ - "$cert" 2>&1) || not_match=1 + ${ca:+ -CAfile} ${ca:+ "$ca"} \ + ${cap:+ -CApath} ${cap:+ "$cap"} \ + "$cert" 2>&1) || not_match=1 if [ $not_match -eq 1 ]; then wsrep_log_info "run: \"$OPENSSL_BINARY\" verify -verbose${ca:+ -CAfile \"$ca\"}${cap:+ -CApath \"$cap\"} \"$cert\"" @@ -1158,6 +1161,7 @@ verify_cert_matches_key() # If the diff utility is not installed, then # we will not do this certificate check: if [ -z "$(commandex diff)" ]; then + wsrep_log_info "diff utility not found" return fi @@ -1165,6 +1169,7 @@ verify_cert_matches_key() # we will not do this certificate check: get_openssl if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_info "openssl utility not found" return fi @@ -1253,18 +1258,18 @@ check_pid() { local pid_file="$1" if [ -r "$pid_file" ]; then - local pid=$(cat "$pid_file" 2>/dev/null) + local pid=$(cat "$pid_file" 2>/dev/null || :) if [ -n "$pid" ]; then - if [ $pid -ne 0 ]; then - if ps -p "$pid" >/dev/null 2>&1; then + if [ $pid -gt 0 ]; then + if ps -p $pid >/dev/null 2>&1; then CHECK_PID=$pid return 0 fi fi fi local remove=${2:-0} - if [ $remove -eq 1 ]; then - rm -f "$pid_file" + if [ $remove -ne 0 ]; then + rm -f "$pid_file" || : fi fi CHECK_PID=0 @@ -1289,25 +1294,25 @@ cleanup_pid() local pid_file="${2:-}" local config="${3:-}" - if [ $pid -ne 0 ]; then + if [ $pid -gt 0 ]; then if ps -p $pid >/dev/null 2>&1; then if kill $pid >/dev/null 2>&1; then sleep 0.5 local round=0 local force=0 while ps -p $pid >/dev/null 2>&1; do - sleep 1 - round=$(( round+1 )) - if [ $round -eq 16 ]; then - if [ $force -eq 0 ]; then - round=8 - force=1 - kill -9 $pid >/dev/null 2>&1 - sleep 0.5 - else - return 1 - fi - fi + sleep 1 + round=$(( round+1 )) + if [ $round -eq 16 ]; then + if [ $force -eq 0 ]; then + round=8 + force=1 + kill -9 $pid >/dev/null 2>&1 || : + sleep 0.5 + else + return 1 + fi + fi done elif ps -p $pid >/dev/null 2>&1; then wsrep_log_warning "Unable to kill PID=$pid ($pid_file)" @@ -1316,8 +1321,8 @@ cleanup_pid() fi fi - [ -n "$pid_file" ] && [ -f "$pid_file" ] && rm -f "$pid_file" - [ -n "$config" ] && [ -f "$config" ] && rm -f "$config" + [ -n "$pid_file" -a -f "$pid_file" ] && rm -f "$pid_file" || : + [ -n "$config" -a -f "$config" ] && rm -f "$config" || : return 0 } @@ -1339,3 +1344,46 @@ get_proc() fi fi } + +check_server_ssl_config() +{ + # backward-compatible behavior: + tcert=$(parse_cnf 'sst' 'tca') + tcap=$(parse_cnf 'sst' 'tcapath') + tpem=$(parse_cnf 'sst' 'tcert') + tkey=$(parse_cnf 'sst' 'tkey') + # reading new ssl configuration options: + local tcert2=$(parse_cnf "$encgroups" 'ssl-ca') + local tcap2=$(parse_cnf "$encgroups" 'ssl-capath') + local tpem2=$(parse_cnf "$encgroups" 'ssl-cert') + local tkey2=$(parse_cnf "$encgroups" 'ssl-key') + # if there are no old options, then we take new ones: + if [ -z "$tcert" -a -z "$tcap" -a -z "$tpem" -a -z "$tkey" ]; then + tcert="$tcert2" + tcap="$tcap2" + tpem="$tpem2" + tkey="$tkey2" + # checking for presence of the new-style SSL configuration: + elif [ -n "$tcert2" -o -n "$tcap2" -o -n "$tpem2" -o -n "$tkey2" ]; then + if [ "$tcert" != "$tcert2" -o \ + "$tcap" != "$tcap2" -o \ + "$tpem" != "$tpem2" -o \ + "$tkey" != "$tkey2" ] + then + wsrep_log_info \ + "new ssl configuration options (ssl-ca[path], ssl-cert" \ + "and ssl-key) are ignored by SST due to presence" \ + "of the tca[path], tcert and/or tkey in the [sst] section" + fi + fi + if [ -n "$tcert" ]; then + tcert=$(trim_string "$tcert") + if [ "${tcert%/}" != "$tcert" -o -d "$tcert" ]; then + tcap="$tcert" + tcert="" + fi + fi + if [ -n "$tcap" ]; then + tcap=$(trim_string "$tcap") + fi +} diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 4bca785fcad..aa9442b0601 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -30,7 +30,6 @@ eformat="" ekey="" ekeyfile="" encrypt=0 -ecode=0 ssyslog="" ssystag="" BACKUP_PID="" @@ -465,49 +464,6 @@ adjust_progress() encgroups='--mysqld|sst|xtrabackup' -check_server_ssl_config() -{ - # backward-compatible behavior: - tcert=$(parse_cnf 'sst' 'tca') - tcap=$(parse_cnf 'sst' 'tcapath') - tpem=$(parse_cnf 'sst' 'tcert') - tkey=$(parse_cnf 'sst' 'tkey') - # reading new ssl configuration options: - local tcert2=$(parse_cnf "$encgroups" 'ssl-ca') - local tcap2=$(parse_cnf "$encgroups" 'ssl-capath') - local tpem2=$(parse_cnf "$encgroups" 'ssl-cert') - local tkey2=$(parse_cnf "$encgroups" 'ssl-key') - # if there are no old options, then we take new ones: - if [ -z "$tcert" -a -z "$tcap" -a -z "$tpem" -a -z "$tkey" ]; then - tcert="$tcert2" - tcap="$tcap2" - tpem="$tpem2" - tkey="$tkey2" - # checking for presence of the new-style SSL configuration: - elif [ -n "$tcert2" -o -n "$tcap2" -o -n "$tpem2" -o -n "$tkey2" ]; then - if [ "$tcert" != "$tcert2" -o \ - "$tcap" != "$tcap2" -o \ - "$tpem" != "$tpem2" -o \ - "$tkey" != "$tkey2" ] - then - wsrep_log_info \ - "new ssl configuration options (ssl-ca[path], ssl-cert" \ - "and ssl-key) are ignored by SST due to presence" \ - "of the tca[path], tcert and/or tkey in the [sst] section" - fi - fi - if [ -n "$tcert" ]; then - tcert=$(trim_string "$tcert") - if [ "${tcert%/}" != "$tcert" ] || [ -d "$tcert" ]; then - tcap="$tcert" - tcert="" - fi - fi - if [ -n "$tcap" ]; then - tcap=$(trim_string "$tcap") - fi -} - read_cnf() { sfmt=$(parse_cnf sst streamfmt 'mbstream') @@ -647,7 +603,7 @@ cleanup_at_exit() cleanup_pid $CHECK_PID "$BACKUP_PID" fi fi - [ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE" + [ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE" || : fi if [ -n "$progress" -a -p "$progress" ]; then @@ -658,27 +614,31 @@ cleanup_at_exit() wsrep_log_info "Cleaning up temporary directories" if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then - if [ -n "$STATDIR" ]; then - [ -d "$STATDIR" ] && rm -rf "$STATDIR" - fi + [ -n "$STATDIR" -a -d "$STATDIR" ] && rm -rf "$STATDIR" || : else [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || : [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || : fi # Final cleanup - pgid=$(ps -o pgid= $$ | grep -o '[0-9]*') + pgid=$(ps -o pgid= $$ 2>/dev/null | grep -o '[0-9]*' || :) # This means no setsid done in mysqld. # We don't want to kill mysqld here otherwise. - if [ $$ -eq $pgid ]; then - # This means a signal was delivered to the process. - # So, more cleanup. - if [ $estatus -ge 128 ]; then - kill -KILL -- -$$ || : + if [ -n "$pgid" ]; then + if [ $$ -eq $pgid ]; then + # This means a signal was delivered to the process. + # So, more cleanup. + if [ $estatus -ge 128 ]; then + kill -KILL -- -$$ || : + fi fi fi + if [ -n "${SST_PID:-}" ]; then + [ -f "$SST_PID" ] && rm -f "$SST_PID" || : + fi + exit $estatus } @@ -967,7 +927,7 @@ setup_commands() fi INNOAPPLY="$BACKUP_BIN --prepare$disver$recovery${iapts:+ }$iapts$INNOEXTRA --target-dir='$DATA' --datadir='$DATA'$mysqld_args $INNOAPPLY" INNOMOVE="$BACKUP_BIN$WSREP_SST_OPT_CONF --move-back$disver${impts:+ }$impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" - INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF --backup$disver${iopts:+ }$iopts $tmpopts$INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA'$mysqld_args $INNOBACKUP" + INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF --backup$disver${iopts:+ }$iopts$tmpopts$INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA'$mysqld_args $INNOBACKUP" } get_stream @@ -995,7 +955,7 @@ then fi wsrep_log_info "Using '$xtmpdir' as mariabackup temporary directory" - tmpopts="--tmpdir='$xtmpdir'" + tmpopts=" --tmpdir='$xtmpdir'" itmpdir="$(mktemp -d)" wsrep_log_info "Using '$itmpdir' as mariabackup working directory" @@ -1161,10 +1121,23 @@ then impts="--parallel=$backup_threads${impts:+ }$impts" fi - stagemsg='Joiner-Recv' + SST_PID="$WSREP_SST_OPT_DATA/wsrep_sst.pid" - sencrypted=1 - nthreads=1 + # give some time for previous SST to complete: + check_round=0 + while check_pid "$SST_PID" 0; do + wsrep_log_info "previous SST is not completed, waiting for it to exit" + check_round=$(( check_round + 1 )) + if [ $check_round -eq 10 ]; then + wsrep_log_error "previous SST script still running." + exit 114 # EALREADY + fi + sleep 1 + done + + echo $$ > "$SST_PID" + + stagemsg='Joiner-Recv' MODULE="xtrabackup_sst" @@ -1208,7 +1181,7 @@ then fi get_keys - if [ $encrypt -eq 1 -a $sencrypted -eq 1 ]; then + if [ $encrypt -eq 1 ]; then strmcmd="$ecmd | $strmcmd" fi @@ -1263,12 +1236,14 @@ then if [ -n "$WSREP_SST_OPT_BINLOG" ]; then binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") - cd "$binlog_dir" - wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" - rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || : - [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ - rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || : - cd "$OLD_PWD" + if [ -d "$binlog_dir" ]; then + cd "$binlog_dir" + wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" + rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || : + [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ + rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ + cd "$OLD_PWD" + fi fi TDATA="$DATA" @@ -1285,7 +1260,7 @@ then fi # Compact backups are not supported by mariabackup - if grep -q -F 'compact = 1' "$DATA/xtrabackup_checkpoints"; then + if grep -qw -F 'compact = 1' "$DATA/xtrabackup_checkpoints"; then wsrep_log_info "Index compaction detected" wsrel_log_error "Compact backups are not supported by mariabackup" exit 2 diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index b0cc8cb3066..28dfed18218 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -17,7 +17,7 @@ # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston # MA 02110-1335 USA. -# This is a reference script for rsync-based state snapshot tansfer +# This is a reference script for rsync-based state snapshot transfer RSYNC_REAL_PID=0 # rsync process id STUNNEL_REAL_PID=0 # stunnel process id @@ -41,7 +41,7 @@ cleanup_joiner() if cleanup_pid $STUNNEL_REAL_PID "$STUNNEL_PID" "$STUNNEL_CONF"; then if [ $RSYNC_REAL_PID -eq 0 ]; then if [ -r "$RSYNC_PID" ]; then - RSYNC_REAL_PID=$(cat "$RSYNC_PID" 2>/dev/null) + RSYNC_REAL_PID=$(cat "$RSYNC_PID" 2>/dev/null || :) if [ -z "$RSYNC_REAL_PID" ]; then RSYNC_REAL_PID=0 fi @@ -79,7 +79,7 @@ check_pid_and_port() local utils='rsync|stunnel' - if ! check_port "$pid" "$port" "$utils"; then + if ! check_port $pid "$port" "$utils"; then local port_info local busy=0 @@ -90,7 +90,7 @@ check_pid_and_port() grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1 else local filter='([^[:space:]]+[[:space:]]+){4}[^[:space:]]+' - if [ $sockstat_available -eq 1 ]; then + if [ $sockstat_available -ne 0 ]; then local opts='-p' if [ "$OS" = 'FreeBSD' ]; then # sockstat on FreeBSD requires the "-s" option @@ -110,18 +110,20 @@ check_pid_and_port() fi if [ $busy -eq 0 ]; then - if echo "$port_info" | grep -qw -F "[$addr]:$port" || \ - echo "$port_info" | grep -qw -F -- "$addr:$port" + if ! echo "$port_info" | grep -qw -F "[$addr]:$port" && \ + ! echo "$port_info" | grep -qw -F -- "$addr:$port" then - busy=1 + if ! ps -p $pid >/dev/null 2>&1; then + wsrep_log_error \ + "rsync or stunnel daemon (PID: $pid)" \ + "terminated unexpectedly." + exit 16 # EBUSY + fi + return 1 fi fi - if [ $busy -eq 0 ]; then - return 1 - fi - - if ! check_port "$pid" "$port" "$utils"; then + if ! check_port $pid "$port" "$utils"; then wsrep_log_error "rsync or stunnel daemon port '$port'" \ "has been taken by another program" exit 16 # EBUSY @@ -197,60 +199,16 @@ INNODB_UNDO_DIR=$(pwd -P) cd "$OLD_PWD" -# Old filter - include everything except selected -# FILTER=(--exclude '*.err' --exclude '*.pid' --exclude '*.sock' \ -# --exclude '*.conf' --exclude core --exclude 'galera.*' \ -# --exclude grastate.txt --exclude '*.pem' \ -# --exclude '*.[0-9][0-9][0-9][0-9][0-9][0-9]' --exclude '*.index') +encgroups='--mysqld|sst' -# New filter - exclude everything except dirs (schemas) and innodb files -FILTER="-f '- /lost+found' - -f '- /.zfs' - -f '- /.fseventsd' - -f '- /.Trashes' - -f '- /.pid' - -f '- /.conf' - -f '+ /wsrep_sst_binlog.tar' - -f '- $INNODB_DATA_HOME_DIR/ib_lru_dump' - -f '- $INNODB_DATA_HOME_DIR/ibdata*' - -f '+ $INNODB_UNDO_DIR/undo*' - -f '+ /*/' - -f '- /*'" +check_server_ssl_config -# old-style SSL config -SSTKEY=$(parse_cnf 'sst' 'tkey') -SSTCERT=$(parse_cnf 'sst' 'tcert') -SSTCA=$(parse_cnf 'sst' 'tca') -SSTCAP=$(parse_cnf 'sst' 'tcapath') +SSTKEY="$tkey" +SSTCERT="$tpem" +SSTCA="$tcert" +SSTCAP="$tcap" -SST_SECTIONS="--mysqld|sst" - -check_server_ssl_config() -{ - SSTKEY=$(parse_cnf "$SST_SECTIONS" 'ssl-key') - SSTCERT=$(parse_cnf "$SST_SECTIONS" 'ssl-cert') - SSTCA=$(parse_cnf "$SST_SECTIONS" 'ssl-ca') - SSTCAP=$(parse_cnf "$SST_SECTIONS" 'ssl-capath') -} - -SSLMODE=$(parse_cnf "$SST_SECTIONS" 'ssl-mode' | tr [:lower:] [:upper:]) - -# no old-style SSL config in [sst], check for new one: -if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" -a -z "$SSTCAP" ]; then - check_server_ssl_config -fi - -if [ -n "$SSTCA" ]; then - SSTCA=$(trim_string "$SSTCA") - if [ "${SSTCA%/}" != "$SSTCA" ] || [ -d "$SSTCA" ]; then - SSTCAP="$SSTCA" - SSTCA="" - fi -fi - -if [ -n "$SSTCAP" ]; then - SSTCAP=$(trim_string "$SSTCAP") -fi +SSLMODE=$(parse_cnf "$encgroups" 'ssl-mode' | tr [:lower:] [:upper:]) if [ -z "$SSLMODE" ]; then # Implicit verification if CA is set and the SSL mode @@ -266,7 +224,7 @@ if [ -z "$SSLMODE" ]; then fi fi -if [ -n "$SSTCERT" -a -n "$SSTKEY" ]; then +if [ -n "$SSTKEY" -a -n "$SSTCERT" ]; then verify_cert_matches_key "$SSTCERT" "$SSTKEY" fi @@ -287,8 +245,7 @@ fi VERIFY_OPT="" CHECK_OPT="" CHECK_OPT_LOCAL="" -if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ] -then +if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]; then case "$SSLMODE" in 'VERIFY_IDENTITY') VERIFY_OPT='verifyPeer = yes' @@ -364,8 +321,9 @@ EOF [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" fi - if [ $WSREP_SST_OPT_BYPASS -eq 0 ] - then + RC=0 + + if [ $WSREP_SST_OPT_BYPASS -eq 0 ]; then FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed" ERROR="$WSREP_SST_OPT_DATA/sst_error" @@ -380,11 +338,11 @@ EOF # (b) Cluster state ID & wsrep_gtid_domain_id to be written to the file, OR # (c) ERROR file, in case flush tables operation failed. - while [ ! -r "$FLUSHED" ] && ! grep -q -F ':' "$FLUSHED" >/dev/null 2>&1 + while [ ! -r "$FLUSHED" ] && \ + ! grep -q -F ':' '--' "$FLUSHED" >/dev/null 2>&1 do # Check whether ERROR file exists. - if [ -f "$ERROR" ] - then + if [ -f "$ERROR" ]; then # Flush tables operation failed. rm -f "$ERROR" exit 255 @@ -397,7 +355,7 @@ EOF sync - if [ -n "$WSREP_SST_OPT_BINLOG" ] + if [ -n "$WSREP_SST_OPT_BINLOG" -a -d "${BINLOG_DIRNAME:-}" ] then # Prepare binlog files cd "$BINLOG_DIRNAME" @@ -405,16 +363,14 @@ EOF binlog_files_full=$(tail -n $BINLOG_N_FILES \ "$WSREP_SST_OPT_BINLOG_INDEX") binlog_files="" - for ii in $binlog_files_full - do - binlog_file=$(basename "$ii") - binlog_files="$binlog_files $binlog_file" + for file in $binlog_files_full; do + binlog_file=$(basename "$file") + binlog_files="$binlog_files${binlog_files:+ }'$binlog_file'" done - if [ -n "$binlog_files" ] - then + if [ -n "$binlog_files" ]; then wsrep_log_info "Preparing binlog files for transfer:" - tar -cvf "$BINLOG_TAR_FILE" $binlog_files >&2 + eval tar -cvf "'$BINLOG_TAR_FILE'" $binlog_files >&2 fi cd "$OLD_PWD" @@ -427,9 +383,28 @@ EOF WHOLE_FILE_OPT="--whole-file" fi +# Old filter - include everything except selected +# FILTER=(--exclude '*.err' --exclude '*.pid' --exclude '*.sock' \ +# --exclude '*.conf' --exclude core --exclude 'galera.*' \ +# --exclude grastate.txt --exclude '*.pem' \ +# --exclude '*.[0-9][0-9][0-9][0-9][0-9][0-9]' --exclude '*.index') + +# New filter - exclude everything except dirs (schemas) and innodb files +FILTER="-f '- /lost+found' + -f '- /.zfs' + -f '- /.fseventsd' + -f '- /.Trashes' + -f '- /.pid' + -f '- /.conf' + -f '+ /wsrep_sst_binlog.tar' + -f '- $INNODB_DATA_HOME_DIR/ib_lru_dump' + -f '- $INNODB_DATA_HOME_DIR/ibdata*' + -f '+ $INNODB_UNDO_DIR/undo*' + -f '+ /*/' + -f '- /*'" + # first, the normal directories, so that we can detect # incompatible protocol: - RC=0 eval rsync ${STUNNEL:+"--rsh='$STUNNEL'"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ @@ -484,7 +459,7 @@ EOF cd "$WSREP_SST_OPT_DATA" - backup_threads=$(parse_cnf "--mysqld|sst" 'backup-threads') + backup_threads=$(parse_cnf '--mysqld|sst' 'backup-threads') if [ -z "$backup_threads" ]; then get_proc backup_threads=$nproc @@ -527,7 +502,12 @@ EOF rsync ${STUNNEL:+--rsh="$STUNNEL"} \ --archive --quiet --checksum "$MAGIC_FILE" \ - "rsync://$WSREP_SST_OPT_ADDR" + "rsync://$WSREP_SST_OPT_ADDR" >&2 || RC=$? + + if [ $RC -ne 0 ]; then + wsrep_log_error "rsync $MAGIC_FILE returned code $RC:" + exit 255 # unknown error + fi echo "done $STATE" @@ -540,12 +520,11 @@ elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ] then check_sockets_utils - SST_PID="$WSREP_SST_OPT_DATA/wsrep_rsync_sst.pid" + SST_PID="$WSREP_SST_OPT_DATA/wsrep_sst.pid" # give some time for previous SST to complete: check_round=0 - while check_pid "$SST_PID" 0 - do + while check_pid "$SST_PID" 0 'wsrep_sst_'; do wsrep_log_info "previous SST is not completed, waiting for it to exit" check_round=$(( check_round + 1 )) if [ $check_round -eq 10 ]; then @@ -555,10 +534,11 @@ then sleep 1 done + echo $$ > "$SST_PID" + # give some time for stunnel from the previous SST to complete: check_round=0 - while check_pid "$STUNNEL_PID" 1 - do + while check_pid "$STUNNEL_PID" 1; do wsrep_log_info "Lingering stunnel daemon found at startup," \ "waiting for it to exit" check_round=$(( check_round + 1 )) @@ -575,8 +555,7 @@ then # give some time for rsync from the previous SST to complete: check_round=0 - while check_pid "$RSYNC_PID" 1 - do + while check_pid "$RSYNC_PID" 1; do wsrep_log_info "Lingering rsync daemon found at startup," \ "waiting for it to exit" check_round=$(( check_round + 1 )) @@ -590,7 +569,7 @@ then [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" [ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE" - [ -z "$STUNNEL" ] && [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" + [ -z "$STUNNEL" -a -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" ADDR="$WSREP_SST_OPT_ADDR" RSYNC_PORT="$WSREP_SST_OPT_PORT" @@ -639,8 +618,6 @@ EOF RSYNC_ADDR="*" fi - echo $$ > "$SST_PID" - if [ -z "$STUNNEL" ]; then rsync --daemon --no-detach --port "$RSYNC_PORT" \ --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh index d5c978c4147..569d5084c98 100644 --- a/scripts/wsrep_sst_xtrabackup-v2.sh +++ b/scripts/wsrep_sst_xtrabackup-v2.sh @@ -31,7 +31,6 @@ eformat="" ekey="" ekeyfile="" encrypt=0 -ecode=0 ssyslog="" ssystag="" BACKUP_PID="" @@ -160,7 +159,7 @@ get_keys() return fi - wsrep_log_info "Key based encryption enabled in my.cnf - supported only from Xtrabackup 2.1.4" + wsrep_log_info "Key based encryption enabled in my.cnf" if [ -z "$ealgo" ]; then wsrep_log_error "FATAL: Encryption algorithm empty from my.cnf, bailing out" @@ -470,49 +469,6 @@ adjust_progress() encgroups='--mysqld|sst|xtrabackup' -check_server_ssl_config() -{ - # backward-compatible behavior: - tcert=$(parse_cnf 'sst' 'tca') - tcap=$(parse_cnf 'sst' 'tcapath') - tpem=$(parse_cnf 'sst' 'tcert') - tkey=$(parse_cnf 'sst' 'tkey') - # reading new ssl configuration options: - local tcert2=$(parse_cnf "$encgroups" 'ssl-ca') - local tcap2=$(parse_cnf "$encgroups" 'ssl-capath') - local tpem2=$(parse_cnf "$encgroups" 'ssl-cert') - local tkey2=$(parse_cnf "$encgroups" 'ssl-key') - # if there are no old options, then we take new ones: - if [ -z "$tcert" -a -z "$tcap" -a -z "$tpem" -a -z "$tkey" ]; then - tcert="$tcert2" - tcap="$tcap2" - tpem="$tpem2" - tkey="$tkey2" - # checking for presence of the new-style SSL configuration: - elif [ -n "$tcert2" -o -n "$tcap2" -o -n "$tpem2" -o -n "$tkey2" ]; then - if [ "$tcert" != "$tcert2" -o \ - "$tcap" != "$tcap2" -o \ - "$tpem" != "$tpem2" -o \ - "$tkey" != "$tkey2" ] - then - wsrep_log_info \ - "new ssl configuration options (ssl-ca[path], ssl-cert" \ - "and ssl-key) are ignored by SST due to presence" \ - "of the tca[path], tcert and/or tkey in the [sst] section" - fi - fi - if [ -n "$tcert" ]; then - tcert=$(trim_string "$tcert") - if [ "${tcert%/}" != "$tcert" ] || [ -d "$tcert" ]; then - tcap="$tcert" - tcert="" - fi - fi - if [ -n "$tcap" ]; then - tcap=$(trim_string "$tcap") - fi -} - read_cnf() { sfmt=$(parse_cnf sst streamfmt 'xbstream') @@ -659,7 +615,7 @@ cleanup_at_exit() cleanup_pid $CHECK_PID "$BACKUP_PID" fi fi - [ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE" + [ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE" || : fi if [ -n "$progress" -a -p "$progress" ]; then @@ -670,27 +626,31 @@ cleanup_at_exit() wsrep_log_info "Cleaning up temporary directories" if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then - if [ -n "$STATDIR" ]; then - [ -d "$STATDIR" ] && rm -rf "$STATDIR" - fi + [ -n "$STATDIR" -a -d "$STATDIR" ] && rm -rf "$STATDIR" || : else [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || : [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || : fi # Final cleanup - pgid=$(ps -o pgid= $$ | grep -o '[0-9]*') + pgid=$(ps -o pgid= $$ 2>/dev/null | grep -o '[0-9]*' || :) # This means no setsid done in mysqld. # We don't want to kill mysqld here otherwise. - if [ $$ -eq $pgid ]; then - # This means a signal was delivered to the process. - # So, more cleanup. - if [ $estatus -ge 128 ]; then - kill -KILL -- -$$ || : + if [ -n "$pgid" ]; then + if [ $$ -eq $pgid ]; then + # This means a signal was delivered to the process. + # So, more cleanup. + if [ $estatus -ge 128 ]; then + kill -KILL -- -$$ || : + fi fi fi + if [ -n "${SST_PID:-}" ]; then + [ -f "$SST_PID" ] && rm -f "$SST_PID" || : + fi + exit $estatus } @@ -862,7 +822,7 @@ monitor_process() done } -# check the version, we require XB-2.4 to ensure that we can pass the +# check the version, we require XB-2.3.5 to ensure that we can pass the # datadir via the command-line option XB_REQUIRED_VERSION="2.3.5" @@ -992,13 +952,13 @@ setup_commands() if [ -n "$INNODB_FORCE_RECOVERY" ]; then recovery=" --innodb-force-recovery=$INNODB_FORCE_RECOVERY" fi - INNOAPPLY="$BACKUP_BIN$disver$recovery${iapts:+ }$iapts$INNOEXTRA --apply-log $rebuildcmd '$DATA' $INNOAPPLY" - INNOMOVE="$BACKUP_BIN$WSREP_SST_OPT_CONF --move-back$disver${impts:+ }$impts --force-non-empty-directories '$DATA' $INNOMOVE" + INNOAPPLY="$BACKUP_BIN$disver$recovery${iapts:+ }$iapts$INNOEXTRA --apply-log${rebuildcmd:+ }$rebuildcmd --datadir='$DATA' '$DATA' $INNOAPPLY" + INNOMOVE="$BACKUP_BIN$WSREP_SST_OPT_CONF --move-back$disver${impts:+ }$impts --force-non-empty-directories --datadir='${TDATA:-$DATA}' '$DATA' $INNOMOVE" local sfmt_work="$sfmt" if [ "$sfmt" = 'mbstream' ]; then sfmt_work='xbstream' fi - INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF$disver${iopts:+ }$iopts $tmpopts$INNOEXTRA --galera-info --stream=$sfmt_work '$itmpdir' $INNOBACKUP" + INNOBACKUP="$BACKUP_BIN$WSREP_SST_OPT_CONF$disver${iopts:+ }$iopts$tmpopts$INNOEXTRA --galera-info --stream=$sfmt_work --datadir='$DATA' '$itmpdir' $INNOBACKUP" } get_stream @@ -1026,7 +986,7 @@ then fi wsrep_log_info "Using '$xtmpdir' as xtrabackup temporary directory" - tmpopts="--tmpdir='$xtmpdir'" + tmpopts=" --tmpdir='$xtmpdir'" itmpdir="$(mktemp -d)" wsrep_log_info "Using '$itmpdir' as xtrabackup working directory" @@ -1192,10 +1152,23 @@ then impts="--parallel=$backup_threads${impts:+ }$impts" fi - stagemsg='Joiner-Recv' + SST_PID="$WSREP_SST_OPT_DATA/wsrep_sst.pid" - sencrypted=1 - nthreads=1 + # give some time for previous SST to complete: + check_round=0 + while check_pid "$SST_PID" 0; do + wsrep_log_info "previous SST is not completed, waiting for it to exit" + check_round=$(( check_round + 1 )) + if [ $check_round -eq 10 ]; then + wsrep_log_error "previous SST script still running." + exit 114 # EALREADY + fi + sleep 1 + done + + echo $$ > "$SST_PID" + + stagemsg='Joiner-Recv' MODULE="xtrabackup_sst" @@ -1239,7 +1212,7 @@ then fi get_keys - if [ $encrypt -eq 1 -a $sencrypted -eq 1 ]; then + if [ $encrypt -eq 1 ]; then strmcmd="$ecmd | $strmcmd" fi @@ -1294,12 +1267,14 @@ then if [ -n "$WSREP_SST_OPT_BINLOG" ]; then binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") - cd "$binlog_dir" - wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" - rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || : - [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ - rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || : - cd "$OLD_PWD" + if [ -d "$binlog_dir" ]; then + cd "$binlog_dir" + wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" + rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || : + [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ + rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ + cd "$OLD_PWD" + fi fi TDATA="$DATA" @@ -1316,7 +1291,7 @@ then fi # Rebuild indexes for compact backups - if grep -q -F 'compact = 1' "$DATA/xtrabackup_checkpoints"; then + if grep -qw -F 'compact = 1' "$DATA/xtrabackup_checkpoints"; then wsrep_log_info "Index compaction detected" get_proc nthreads=$(parse_cnf "$encgroups" 'rebuild-threads' $nproc) From 5045509b724cbfe0311366fd2bbc36c7753e0852 Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Thu, 23 Dec 2021 21:07:28 +0900 Subject: [PATCH 46/52] MDEV-27184 Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed, Assertion `str.alloced_length() >= str.length() + data_len' failed Spider crashes on a query that inserts some rows including float. This is because Spider allocates a string of insufficient length. --- .../spider/bugfix/r/mdev_27184.result | 21 +++++++++++++ .../mysql-test/spider/bugfix/t/mdev_27184.cnf | 2 ++ .../spider/bugfix/t/mdev_27184.test | 31 +++++++++++++++++++ storage/spider/spd_db_mysql.cc | 2 +- 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_27184.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27184.cnf create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27184.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27184.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27184.result new file mode 100644 index 00000000000..8a3d9da1dc4 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27184.result @@ -0,0 +1,21 @@ +# +# MDEV-27184 Assertion `(old_top == initial_top (av) && old_size == 0) || +# ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && +# ((unsigned long) old_end & (pagesize - 1)) == 0)' failed, +# Assertion `str.alloced_length() >= str.length() + data_len' failed +# +for master_1 +for child2 +for child3 +connection master_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a (a FLOAT) ENGINE=SPIDER; +INSERT INTO tbl_a VALUES +(0xF5A7),(0xF5A8),(0xF5A9),(0xF5AA),(0xF5AB),(0xF5AC),(0xF5AD),(0xF5AE), +(0xF5A7),(0xF5A8),(0xF5A9),(0xF5AA),(0xF5AB),(0xF5AC),(0xF5AD),(0xF5AE); +ERROR HY000: Unable to connect to foreign data source: localhost +DROP DATABASE auto_test_remote; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.cnf new file mode 100644 index 00000000000..b0853e32654 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.cnf @@ -0,0 +1,2 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.test new file mode 100644 index 00000000000..9d3922b2c48 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.test @@ -0,0 +1,31 @@ +--echo # +--echo # MDEV-27184 Assertion `(old_top == initial_top (av) && old_size == 0) || +--echo # ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && +--echo # ((unsigned long) old_end & (pagesize - 1)) == 0)' failed, +--echo # Assertion `str.alloced_length() >= str.length() + data_len' failed +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection master_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +CREATE TABLE tbl_a (a FLOAT) ENGINE=SPIDER; + +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +INSERT INTO tbl_a VALUES + (0xF5A7),(0xF5A8),(0xF5A9),(0xF5AA),(0xF5AB),(0xF5AC),(0xF5AD),(0xF5AE), + (0xF5A7),(0xF5A8),(0xF5A9),(0xF5AA),(0xF5AB),(0xF5AC),(0xF5AD),(0xF5AE); + +DROP DATABASE auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index ee3c25d914c..3425a97049f 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -4243,7 +4243,7 @@ int spider_db_mariadb_util::append_column_value( } else if (float_value) { if (str->reserve(SPIDER_SQL_CAST_LEN + ptr->length() + - SPIDER_SQL_AS_FLOAT_LEN, SPIDER_SQL_CLOSE_PAREN_LEN)) + SPIDER_SQL_AS_FLOAT_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } From 89a0364fc88efa7d91d02839a25fa22e4b276995 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 24 Dec 2021 22:16:10 +0100 Subject: [PATCH 47/52] MDEV-27304 SHOW ... result columns are right-aligned --version=value was setting sys_var::CONFIG (meaning, the value came from the config file), but the filename was left as NULL. --- mysql-test/suite/sys_vars/r/version.result | 16 ++++++++++++++++ mysql-test/suite/sys_vars/t/version.test | 1 + sql/mysqld.cc | 3 ++- sql/set_var.cc | 4 +++- sql/set_var.h | 3 ++- storage/perfschema/unittest/pfs_server_stubs.cc | 2 +- 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/version.result b/mysql-test/suite/sys_vars/r/version.result index 29a2fb8c7e9..5dafd8e0d93 100644 --- a/mysql-test/suite/sys_vars/r/version.result +++ b/mysql-test/suite/sys_vars/r/version.result @@ -2,3 +2,19 @@ SELECT @@version; @@version my_favorite_version 1 +select * from information_schema.system_variables where variable_name='version'; +VARIABLE_NAME VERSION +SESSION_VALUE NULL +GLOBAL_VALUE my_favorite_version +GLOBAL_VALUE_ORIGIN COMMAND-LINE +DEFAULT_VALUE NULL +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE VARCHAR +VARIABLE_COMMENT Server version number. It may also include a suffix with configuration or build information. -debug indicates debugging support was enabled on the server, and -log indicates at least one of the binary log, general log or slow query log are enabled, for example 10.1.1-MariaDB-mariadb1precise-log. +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY YES +COMMAND_LINE_ARGUMENT NULL +GLOBAL_VALUE_PATH NULL diff --git a/mysql-test/suite/sys_vars/t/version.test b/mysql-test/suite/sys_vars/t/version.test index daa95386fd4..35067a43406 100644 --- a/mysql-test/suite/sys_vars/t/version.test +++ b/mysql-test/suite/sys_vars/t/version.test @@ -4,3 +4,4 @@ perl; grep /my_favorite_version/, `$ENV{MYSQL} -e status`; print "$cnt\n"; EOF +query_vertical select * from information_schema.system_variables where variable_name='version'; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5775902c476..80aa87a5410 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7967,7 +7967,8 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument, if (argument) { strmake(server_version, argument, sizeof(server_version) - 1); - set_sys_var_value_origin(&server_version_ptr, sys_var::CONFIG); + set_sys_var_value_origin(&server_version_ptr, + *filename ? sys_var::CONFIG : sys_var::COMMAND_LINE, filename); using_custom_server_version= true; } #ifndef EMBEDDED_LIBRARY diff --git a/sql/set_var.cc b/sql/set_var.cc index 9744f0f6f39..861db2c1b8d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1278,7 +1278,8 @@ end: and update it directly. */ -void set_sys_var_value_origin(void *ptr, enum sys_var::where here) +void set_sys_var_value_origin(void *ptr, enum sys_var::where here, + const char *filename) { bool found __attribute__((unused))= false; DBUG_ASSERT(!mysqld_server_started); // only to be used during startup @@ -1289,6 +1290,7 @@ void set_sys_var_value_origin(void *ptr, enum sys_var::where here) if (var->option.value == ptr) { found= true; + var->origin_filename= filename; var->value_origin= here; /* don't break early, search for all matches */ } diff --git a/sql/set_var.h b/sql/set_var.h index 2d538624825..611f16e8bbb 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -450,7 +450,8 @@ int sql_set_variables(THD *thd, List *var_list, bool free); } \ } while(0) -void set_sys_var_value_origin(void *ptr, enum sys_var::where here); +void set_sys_var_value_origin(void *ptr, enum sys_var::where here, + const char *filename= NULL); enum sys_var::where get_sys_var_value_origin(void *ptr); inline bool IS_SYSVAR_AUTOSIZE(void *ptr) diff --git a/storage/perfschema/unittest/pfs_server_stubs.cc b/storage/perfschema/unittest/pfs_server_stubs.cc index 5a855b2c147..ca7b2300797 100644 --- a/storage/perfschema/unittest/pfs_server_stubs.cc +++ b/storage/perfschema/unittest/pfs_server_stubs.cc @@ -51,7 +51,7 @@ void sql_print_warning(const char *format, ...) } class sys_var { public: enum where { AUTO }; }; -void set_sys_var_value_origin(void *ptr, enum sys_var::where here) +void set_sys_var_value_origin(void *, enum sys_var::where, const char *) { } From a48d2ec866751e9da76066bf3a30f99da9031ab0 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 28 Dec 2021 16:37:14 +0200 Subject: [PATCH 48/52] Add --valgrind to VERSION() string for valgrind builds Fixes main.sp-no-valgrind for valgrind builds not done with BUILD scripts --- sql/mysqld.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index af68d28dd9f..310dcada671 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -9038,10 +9038,12 @@ void set_server_version(char *buf, size_t size) { bool is_log= opt_log || global_system_variables.sql_log_slow || opt_bin_log; bool is_debug= IF_DBUG(!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"), 0); + bool is_valgrind= IF_VALGRIND(!strstr(MYSQL_SERVER_SUFFIX_STR, "-valgrind"), 0); strxnmov(buf, size - 1, MYSQL_SERVER_VERSION, MYSQL_SERVER_SUFFIX_STR, IF_EMBEDDED("-embedded", ""), + is_valgrind ? "-valgrind" : "", is_debug ? "-debug" : "", is_log ? "-log" : "", NullS); From c14dd0d19d95460ad48f2657cf35c0cf26596ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 3 Jan 2022 07:23:18 +0200 Subject: [PATCH 49/52] Cleanup: Remove RECV_READ_AHEAD_AREA Let us directly use the constant 32 in recv_read_in_area(). --- storage/innobase/log/log0recv.cc | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index dfadd9df37f..b600817b25d 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2,7 +2,7 @@ Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -56,9 +56,6 @@ Created 9/20/1997 Heikki Tuuri #include "srv0start.h" #include "fil0pagecompress.h" -/** Read-ahead area in applying log records to file pages */ -#define RECV_READ_AHEAD_AREA 32U - /** The recovery system */ recv_sys_t recv_sys; /** TRUE when recv_init_crash_recovery() has been called. */ @@ -2519,11 +2516,9 @@ page number. @param[in] page_id page id */ static void recv_read_in_area(page_id_t page_id) { - uint32_t page_nos[RECV_READ_AHEAD_AREA]; - compile_time_assert(ut_is_2pow(RECV_READ_AHEAD_AREA)); - page_id.set_page_no(ut_2pow_round(page_id.page_no(), - RECV_READ_AHEAD_AREA)); - const ulint up_limit = page_id.page_no() + RECV_READ_AHEAD_AREA; + uint32_t page_nos[32]; + page_id.set_page_no(ut_2pow_round(page_id.page_no(), 32U)); + const uint32_t up_limit = page_id.page_no() + 32; uint32_t* p = page_nos; for (recv_sys_t::map::iterator i= recv_sys.pages.lower_bound(page_id); From 1df05a0854bcde53fb8f73f9348ab54330e812e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 3 Jan 2022 07:23:39 +0200 Subject: [PATCH 50/52] Correct some copyright messages Most of the Facebook contribution mysql/mysql-server@72d656acdf082d5ead1cc1be84f2fd68ab6a65a9 was removed in commit 5bea43f5e03225327cd04e0c302f613600f06081 (MDEV-12353). Mainly the configuration parameter innodb_compression_level remains. It had been renamed to page_zip_level in mysql/mysql-server@5b38f2a712a7077c994c00787b891a7d4ee328df. --- storage/innobase/include/mtr0mtr.h | 3 +-- storage/innobase/include/page0zip.ic | 3 +-- storage/innobase/log/log0recv.cc | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index e253038e1ee..263c9945e65 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -1,8 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/storage/innobase/include/page0zip.ic b/storage/innobase/include/page0zip.ic index ede61283f33..b0622ba79c3 100644 --- a/storage/innobase/include/page0zip.ic +++ b/storage/innobase/include/page0zip.ic @@ -1,8 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2012, Facebook Inc. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index b600817b25d..68bbf06ca49 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1,7 +1,6 @@ /***************************************************************************** Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2012, Facebook Inc. Copyright (c) 2013, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under From eab89f14ab0069a3f74e80bdf13aa70d85738c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Kek=C3=A4l=C3=A4inen?= Date: Fri, 31 Dec 2021 23:12:54 +0200 Subject: [PATCH 51/52] Deb: Adapt custom build steps to be compatible with latest Salsa-CI Upstream Salsa-CI refactored the build process in https://salsa.debian.org/salsa-ci-team/pipeline/-/commit/58880fcef5b742cb9c661121a8c8707bf392b3b5 This broke our custom direct invocation of install-build-deps.sh as the Salsa-CI images no longer contain them. Adapt the .build-script equivalent to follow new Salsa-CI method so builds work again. --- debian/salsa-ci.yml | 49 +++++---------------------------------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml index c95efe0de3a..60fdc3d6544 100644 --- a/debian/salsa-ci.yml +++ b/debian/salsa-ci.yml @@ -32,11 +32,11 @@ build: # Run Salsa-CI .build-before-script equivalent - mkdir -p ${WORKING_DIR} ${CCACHE_WORK_DIR} - mv ${CCACHE_WORK_DIR} ${CCACHE_TMP_DIR} - # Run Salsa-CI .build-script equivalent - - export CCACHE_DIR="${CCACHE_TMP_DIR}" - - apt-get update && eatmydata apt-get install --yes --no-install-recommends aptitude devscripts ccache equivs + # Run Salsa-CI .build-script equivalent, with extra devscripts so autobake-deb.sh can run 'dch' + - export CCACHE_DIR=${CCACHE_TMP_DIR} + - apt-get update && eatmydata apt-get install --no-install-recommends -y ccache fakeroot build-essential devscripts - cd ${WORKING_DIR}/${SOURCE_DIR} - - eatmydata install-build-deps.sh . + - eatmydata apt-get build-dep --no-install-recommends -y . - update-ccache-symlinks; ccache -z # Zero out ccache counters - while true; do sleep 600; echo "10 minutes passed" >&2; done & # Progress keeper since build is long and silent - debian/autobake-deb.sh |& tail -n 10000 # Keep Gitlab-CI output under 4 MB @@ -44,7 +44,7 @@ build: - rm -rf ${WORKING_DIR}/${SOURCE_DIR} - du -shc ${WORKING_DIR}/* # Show total file size of artifacts. Must stay are under 100 MB. - ccache -s # Show ccache stats to validate it worked - - mv ${CCACHE_TMP_DIR} ${CCACHE_WORK_DIR} || true + - mv ${CCACHE_TMP_DIR} ${CCACHE_WORK_DIR} build bullseye-backports: extends: .build-package @@ -77,45 +77,6 @@ build i386: build native deb: extends: .build-package - script: &buildpackage-script | - mkdir -p ${WORKING_DIR} ${CCACHE_WORK_DIR} - mv ${CCACHE_WORK_DIR} ${CCACHE_TMP_DIR} - export CCACHE_DIR=${CCACHE_TMP_DIR} - # Add deb-src entries - sed -n '/^deb\s/s//deb-src /p' /etc/apt/sources.list > /etc/apt/sources.list.d/deb-src.list - apt-get update && eatmydata apt-get install --no-install-recommends -y \ - aptitude \ - devscripts \ - ccache \ - equivs \ - build-essential \ - python3 - # Enter source package dir - cd ${WORKING_DIR}/${SOURCE_DIR} - # Install package build dependencies - eatmydata install-build-deps.sh . - # Generate ccache links - dpkg-reconfigure ccache - PATH="/usr/lib/ccache/:${PATH}" - # Reset ccache stats - ccache -z - # Create salsaci user and fix permissions - useradd salsaci - chown -R salsaci. ${WORKING_DIR} ${CCACHE_DIR} - # Define buildlog filename - BUILD_LOGFILE_SOURCE=$(dpkg-parsechangelog -S Source) - BUILD_LOGFILE_VERSION=$(dpkg-parsechangelog -S Version) - BUILD_LOGFILE_VERSION=${BUILD_LOGFILE_VERSION#*:} - BUILD_LOGFILE_ARCH=$(dpkg --print-architecture) - BUILD_LOGFILE="${WORKING_DIR}/${BUILD_LOGFILE_SOURCE}_${BUILD_LOGFILE_VERSION}_${BUILD_LOGFILE_ARCH}.build" - # Build package as user salsaci - su salsaci -c "eatmydata dpkg-buildpackage ${DB_BUILD_PARAM}" |& OUTPUT_FILENAME=${BUILD_LOGFILE} filter-output - # Restore PWD to ${WORKING_DIR} - cd ${WORKING_DIR} - rm -rf ${WORKING_DIR}/${SOURCE_DIR} - # Print ccache stats on job log - ccache -s - mv ${CCACHE_TMP_DIR} ${CCACHE_WORK_DIR} piuparts: extends: .test-piuparts From 4c3ad24413f234599eda27f4958dd3ff21df3203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 4 Jan 2022 07:40:31 +0200 Subject: [PATCH 52/52] MDEV-27416 InnoDB hang in buf_flush_wait_flushed(), on log checkpoint InnoDB could sometimes hang when triggering a log checkpoint. This is due to commit 7b1252c03d7131754d9503560fe507b33ca1f8b4 (MDEV-24278), which introduced an untimed wait to buf_flush_page_cleaner(). The hang was noticed by occasional failures of IMPORT TABLESPACE tests, such as innodb.innodb-wl5522, which would (unnecessarily) invoke log_make_checkpoint() from row_import_cleanup(). The reason of the hang was that buf_flush_page_cleaner() would enter untimed sleep despite buf_flush_sync_lsn being set. The exact failure scenario is unclear, because buf_flush_sync_lsn should actually be protected by buf_pool.flush_list_mutex. We prevent the hang by invoking buf_pool.page_cleaner_set_idle(false) whenever we are setting buf_flush_sync_lsn and signaling buf_pool.do_flush_list. The bulk of these changes was originally developed as a preparation for MDEV-26827, to invoke buf_flush_list() from fewer threads, and tested on 10.6 by Matthias Leich. This fix was tested by running 100 repetitions of 100 concurrent instances of the test innodb.innodb-wl5522 on a RelWithDebInfo build, using ext4fs and innodb_flush_method=O_DIRECT on a SATA SSD with 4096-byte block size. During the test, the call to log_make_checkpoint() in row_import_cleanup() was present. buf_flush_list(): Make static. buf_flush_wait(): Wait for buf_pool.get_oldest_modification() to reach a target, by work done in the buf_flush_page_cleaner. If buf_flush_sync_lsn is going to be set, we will invoke buf_pool.page_cleaner_set_idle(false). buf_flush_ahead(): If buf_flush_sync_lsn or buf_flush_async_lsn is going to be set and the page cleaner woken up, we will invoke buf_pool.page_cleaner_set_idle(false). buf_flush_wait_flushed(): Invoke buf_flush_wait(). buf_flush_sync(): Invoke recv_sys.apply() at the start in case crash recovery is active. Invoke buf_flush_wait(). buf_flush_sync_batch(): A lower-level variant of buf_flush_sync() that is only called by recv_sys_t::apply(). buf_flush_sync_for_checkpoint(): Do not trigger log apply or checkpoint during recovery. buf_dblwr_t::create(): Only initiate a buffer pool flush, not a checkpoint. row_import_cleanup(): Do not unnecessarily invoke log_make_checkpoint(). Invoking buf_flush_list_space() before starting to generate redo log for the imported tablespace should suffice. srv_prepare_to_delete_redo_log_file(): Set recv_sys.recovery_on in order to prevent buf_flush_sync_for_checkpoint() from initiating a checkpoint while the log is inaccessible. Remove a wait loop that is already part of buf_flush_sync(). Do not invoke fil_names_clear() if the log is being upgraded, because the FILE_MODIFY record is specific to the latest format. create_log_file(): Clear recv_sys.recovery_on only after calling log_make_checkpoint(), to prevent buf_flush_page_cleaner from invoking a checkpoint. innodb_shutdown(): Simplify the logic in mariadb-backup --prepare. os_aio_wait_until_no_pending_writes(): Update the function comment. Apart from row_quiesce_table_start() during FLUSH TABLES...FOR EXPORT, this is being called by buf_flush_list_space(), which is invoked by ALTER TABLE...IMPORT TABLESPACE as well as some encryption operations. --- storage/innobase/buf/buf0buf.cc | 5 +- storage/innobase/buf/buf0dblwr.cc | 3 +- storage/innobase/buf/buf0flu.cc | 114 ++++++++++++++-------- storage/innobase/include/buf0flu.h | 11 +-- storage/innobase/include/os0file.h | 3 +- storage/innobase/include/srv0srv.h | 2 +- storage/innobase/log/log0recv.cc | 2 +- storage/innobase/os/os0file.cc | 3 +- storage/innobase/row/row0import.cc | 2 - storage/innobase/srv/srv0srv.cc | 2 +- storage/innobase/srv/srv0start.cc | 147 +++++++++++++---------------- 11 files changed, 155 insertions(+), 139 deletions(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 1c126191df3..37f99a94cee 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -3300,10 +3300,7 @@ re_evict: fix_block->fix(); mysql_mutex_unlock(&buf_pool.mutex); - buf_flush_list(); - buf_flush_wait_batch_end_acquiring_mutex(false); - while (buf_flush_list_space(space)); - os_aio_wait_until_no_pending_writes(); + buf_flush_sync(); if (fix_block->page.buf_fix_count() == 1 && !fix_block->page.oldest_modification()) { diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 52e947b7c5e..1d582b6cfbf 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -219,8 +219,7 @@ too_small: trx_sys_block->frame, TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N); mtr.commit(); - /* Flush the modified pages to disk and make a checkpoint */ - log_make_checkpoint(); + buf_flush_wait_flushed(mtr.commit_lsn()); /* Remove doublewrite pages from LRU */ buf_pool_invalidate(); diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 3c234228771..4b3e6e6e77e 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -1538,7 +1538,7 @@ void buf_flush_wait_batch_end(bool lru) @param lsn buf_pool.get_oldest_modification(LSN_MAX) target @return the number of processed pages @retval 0 if a buf_pool.flush_list batch is already running */ -ulint buf_flush_list(ulint max_n, lsn_t lsn) +static ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, lsn_t lsn= LSN_MAX) { ut_ad(lsn); @@ -1833,6 +1833,30 @@ ATTRIBUTE_COLD void log_make_checkpoint() while (!log_checkpoint()); } +/** Wait for all dirty pages up to an LSN to be written out. +NOTE: The calling thread is not allowed to hold any buffer page latches! */ +static void buf_flush_wait(lsn_t lsn) +{ + ut_ad(lsn <= log_sys.get_lsn()); + + while (buf_pool.get_oldest_modification(lsn) < lsn) + { + if (buf_flush_sync_lsn < lsn) + { + buf_flush_sync_lsn= lsn; + buf_pool.page_cleaner_set_idle(false); + pthread_cond_signal(&buf_pool.do_flush_list); + } + my_cond_wait(&buf_pool.done_flush_list, + &buf_pool.flush_list_mutex.m_mutex); + } + + /* Wait for the checkpoint. */ + while (buf_flush_sync_lsn) + my_cond_wait(&buf_pool.done_flush_list, + &buf_pool.flush_list_mutex.m_mutex); +} + /** Wait until all persistent pages are flushed up to a limit. @param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) @@ -1849,9 +1873,9 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) if (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn) { + MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS); #if 1 /* FIXME: remove this, and guarantee that the page cleaner serves us */ - if (UNIV_UNLIKELY(!buf_page_cleaner_is_active) - ut_d(|| innodb_page_cleaner_disabled_debug)) + if (UNIV_UNLIKELY(!buf_page_cleaner_is_active)) { do { @@ -1864,35 +1888,21 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) MONITOR_FLUSH_SYNC_COUNT, MONITOR_FLUSH_SYNC_PAGES, n_pages); } - MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS); mysql_mutex_lock(&buf_pool.flush_list_mutex); } while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn); - - goto try_checkpoint; } + else #endif - if (buf_flush_sync_lsn < sync_lsn) { - buf_flush_sync_lsn= sync_lsn; - pthread_cond_signal(&buf_pool.do_flush_list); - } - - do - { - tpool::tpool_wait_begin(); thd_wait_begin(nullptr, THD_WAIT_DISKIO); - my_cond_wait(&buf_pool.done_flush_list, - &buf_pool.flush_list_mutex.m_mutex); - thd_wait_end(nullptr); + tpool::tpool_wait_begin(); + buf_flush_wait(sync_lsn); tpool::tpool_wait_end(); - - MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS); + thd_wait_end(nullptr); } - while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn); } -try_checkpoint: mysql_mutex_unlock(&buf_pool.flush_list_mutex); if (UNIV_UNLIKELY(log_sys.last_checkpoint_lsn < sync_lsn)) @@ -1925,8 +1935,11 @@ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) { mysql_mutex_lock(&buf_pool.flush_list_mutex); if (limit < lsn) + { limit= lsn; - pthread_cond_signal(&buf_pool.do_flush_list); + buf_pool.page_cleaner_set_idle(false); + pthread_cond_signal(&buf_pool.do_flush_list); + } mysql_mutex_unlock(&buf_pool.flush_list_mutex); } } @@ -1960,10 +1973,6 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn) MONITOR_FLUSH_SYNC_PAGES, n_flushed); } - /* Attempt to perform a log checkpoint upon completing each batch. */ - if (recv_recovery_is_on()) - recv_sys.apply(true); - switch (srv_file_flush_method) { case SRV_NOSYNC: case SRV_O_DIRECT_NO_FSYNC: @@ -1980,7 +1989,8 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn) mysql_mutex_unlock(&log_sys.flush_order_mutex); const lsn_t checkpoint_lsn= measure ? measure : newest_lsn; - if (checkpoint_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT) + if (!recv_recovery_is_on() && + checkpoint_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT) { mysql_mutex_unlock(&buf_pool.flush_list_mutex); log_checkpoint_low(checkpoint_lsn, newest_lsn); @@ -2004,7 +2014,7 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn) else if (measure >= buf_flush_async_lsn) buf_flush_async_lsn= 0; - /* wake up buf_flush_wait_flushed() */ + /* wake up buf_flush_wait() */ pthread_cond_broadcast(&buf_pool.done_flush_list); lsn= std::max(lsn, target); @@ -2264,7 +2274,7 @@ furious_flush: if (UNIV_UNLIKELY(lsn_limit != 0)) { buf_flush_sync_lsn= 0; - /* wake up buf_flush_wait_flushed() */ + /* wake up buf_flush_wait() */ pthread_cond_broadcast(&buf_pool.done_flush_list); } unemployed: @@ -2334,7 +2344,7 @@ unemployed: if (UNIV_UNLIKELY(lsn_limit != 0)) { n_flushed= buf_flush_list(srv_max_io_capacity, lsn_limit); - /* wake up buf_flush_wait_flushed() */ + /* wake up buf_flush_wait() */ pthread_cond_broadcast(&buf_pool.done_flush_list); goto try_checkpoint; } @@ -2440,6 +2450,7 @@ ATTRIBUTE_COLD void buf_flush_page_cleaner_init() os_thread_create(buf_flush_page_cleaner); } +#if defined(HAVE_SYSTEMD) && !defined(EMBEDDED_LIBRARY) /** @return the number of dirty pages in the buffer pool */ static ulint buf_flush_list_length() { @@ -2448,6 +2459,7 @@ static ulint buf_flush_list_length() mysql_mutex_unlock(&buf_pool.flush_list_mutex); return len; } +#endif /** Flush the buffer pool on shutdown. */ ATTRIBUTE_COLD void buf_flush_buffer_pool() @@ -2458,13 +2470,15 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool() service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, "Waiting to flush the buffer pool"); - while (buf_pool.n_flush_list() || buf_flush_list_length()) - { - buf_flush_list(srv_max_io_capacity); - timespec abstime; + mysql_mutex_lock(&buf_pool.flush_list_mutex); + while (buf_pool.get_oldest_modification(0)) + { + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + buf_flush_list(srv_max_io_capacity); if (buf_pool.n_flush_list()) { + timespec abstime; service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, "Waiting to flush " ULINTPF " pages", buf_flush_list_length()); @@ -2475,24 +2489,48 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool() &abstime); mysql_mutex_unlock(&buf_pool.mutex); } + mysql_mutex_lock(&buf_pool.flush_list_mutex); } + mysql_mutex_unlock(&buf_pool.flush_list_mutex); ut_ad(!buf_pool.any_io_pending()); } +/** Synchronously flush dirty blocks during recv_sys_t::apply(). +NOTE: The calling thread is not allowed to hold any buffer page latches! */ +void buf_flush_sync_batch(lsn_t lsn) +{ + thd_wait_begin(nullptr, THD_WAIT_DISKIO); + tpool::tpool_wait_begin(); + mysql_mutex_lock(&buf_pool.flush_list_mutex); + buf_flush_wait(lsn); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + tpool::tpool_wait_end(); + thd_wait_end(nullptr); +} + /** Synchronously flush dirty blocks. NOTE: The calling thread is not allowed to hold any buffer page latches! */ void buf_flush_sync() { ut_ad(!sync_check_iterate(dict_sync_check())); + if (recv_recovery_is_on()) + recv_sys.apply(true); + + thd_wait_begin(nullptr, THD_WAIT_DISKIO); + tpool::tpool_wait_begin(); + mysql_mutex_lock(&buf_pool.flush_list_mutex); for (;;) { - const ulint n_flushed= buf_flush_list(srv_max_io_capacity); - buf_flush_wait_batch_end_acquiring_mutex(false); - if (!n_flushed && !buf_flush_list_length()) - return; + const lsn_t lsn= log_sys.get_lsn(); + buf_flush_wait(lsn); + if (lsn == log_sys.get_lsn()) + break; } + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + tpool::tpool_wait_end(); + thd_wait_end(nullptr); } #ifdef UNIV_DEBUG diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 8d45cf2be38..e1be95ebcd0 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -85,13 +85,6 @@ buf_flush_init_for_writing( void* page_zip_, bool use_full_checksum); -/** Write out dirty blocks from buf_pool.flush_list. -@param max_n wished maximum mumber of blocks flushed -@param lsn buf_pool.get_oldest_modification(LSN_MAX) target -@return the number of processed pages -@retval 0 if a buf_pool.flush_list batch is already running */ -ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, lsn_t lsn= LSN_MAX); - /** Try to flush dirty pages that belong to a given tablespace. @param space tablespace @param n_flushed number of pages written @@ -144,6 +137,10 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool(); void buf_flush_validate(); #endif /* UNIV_DEBUG */ +/** Synchronously flush dirty blocks during recv_sys_t::apply(). +NOTE: The calling thread is not allowed to hold any buffer page latches! */ +void buf_flush_sync_batch(lsn_t lsn); + /** Synchronously flush dirty blocks. NOTE: The calling thread is not allowed to hold any buffer page latches! */ void buf_flush_sync(); diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 8f632305f7e..ba252433315 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -1111,8 +1111,7 @@ void os_aio_free(); @retval DB_IO_ERROR on I/O error */ dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n); -/** Wait until there are no pending asynchronous writes. -Only used on FLUSH TABLES...FOR EXPORT. */ +/** Wait until there are no pending asynchronous writes. */ void os_aio_wait_until_no_pending_writes(); diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index a5bebc34c39..fe2c33e219f 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -511,7 +511,7 @@ do { \ #ifdef HAVE_PSI_STAGE_INTERFACE /** Performance schema stage event for monitoring ALTER TABLE progress -everything after flush log_make_checkpoint(). */ +in ha_innobase::commit_inplace_alter_table(). */ extern PSI_stage_info srv_stage_alter_table_end; /** Performance schema stage event for monitoring ALTER TABLE progress diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 68bbf06ca49..9474cd31793 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2752,7 +2752,7 @@ next_page: /* Instead of flushing, last_batch could sort the buf_pool.flush_list in ascending order of buf_page_t::oldest_modification. */ - buf_flush_sync(); + buf_flush_sync_batch(recovered_lsn); if (!last_batch) { diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 9e1eeff202d..32c31b191ed 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -3821,8 +3821,7 @@ static void os_aio_wait_until_no_pending_writes_low() tpool::tpool_wait_end(); } -/** Wait until there are no pending asynchronous writes. -Only used on FLUSH TABLES...FOR EXPORT. */ +/** Wait until there are no pending asynchronous writes. */ void os_aio_wait_until_no_pending_writes() { os_aio_wait_until_no_pending_writes_low(); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 45cc8c278b5..3df29ac1830 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -2211,8 +2211,6 @@ row_import_cleanup( DBUG_EXECUTE_IF("ib_import_before_checkpoint_crash", DBUG_SUICIDE();); - log_make_checkpoint(); - return(err); } diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 73e67c12d58..c05562daca3 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -557,7 +557,7 @@ char srv_buffer_pool_load_at_startup = TRUE; #ifdef HAVE_PSI_STAGE_INTERFACE /** Performance schema stage event for monitoring ALTER TABLE progress -everything after flush log_make_checkpoint(). */ +in ha_innobase::commit_inplace_alter_table(). */ PSI_stage_info srv_stage_alter_table_end = {0, "alter table (end)", PSI_FLAG_STAGE_PROGRESS}; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index cf936893e1b..afb7834c9b9 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -329,6 +329,13 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn, log_sys.log.write_header_durable(lsn); + ut_ad(srv_startup_is_before_trx_rollback_phase); + if (create_new_db) { + srv_startup_is_before_trx_rollback_phase = false; + } + + /* Enable checkpoints in buf_flush_page_cleaner(). */ + recv_sys.recovery_on = false; mysql_mutex_unlock(&log_sys.mutex); log_make_checkpoint(); @@ -895,91 +902,74 @@ buffer pools. Flush the redo log buffer to the redo log file. @return lsn upto which data pages have been flushed. */ static lsn_t srv_prepare_to_delete_redo_log_file(bool old_exists) { - DBUG_ENTER("srv_prepare_to_delete_redo_log_file"); + DBUG_ENTER("srv_prepare_to_delete_redo_log_file"); - lsn_t flushed_lsn; - ulint count = 0; + /* Disable checkpoints in the page cleaner. */ + ut_ad(!recv_sys.recovery_on); + recv_sys.recovery_on= true; - if (log_sys.log.subformat != 2) { - srv_log_file_size = 0; - } + /* Clean the buffer pool. */ + buf_flush_sync(); - for (;;) { - /* Clean the buffer pool. */ - buf_flush_sync(); + if (log_sys.log.subformat != 2) + srv_log_file_size= 0; - DBUG_EXECUTE_IF("innodb_log_abort_1", DBUG_RETURN(0);); - DBUG_PRINT("ib_log", ("After innodb_log_abort_1")); + DBUG_EXECUTE_IF("innodb_log_abort_1", DBUG_RETURN(0);); + DBUG_PRINT("ib_log", ("After innodb_log_abort_1")); - mysql_mutex_lock(&log_sys.mutex); + mysql_mutex_lock(&log_sys.mutex); + const bool latest_format= (log_sys.log.format & ~log_t::FORMAT_ENCRYPTED) == + log_t::FORMAT_10_5; + lsn_t flushed_lsn= log_sys.get_lsn(); - fil_names_clear(log_sys.get_lsn(), false); + if (latest_format) + { + fil_names_clear(flushed_lsn, false); + flushed_lsn= log_sys.get_lsn(); + } - flushed_lsn = log_sys.get_lsn(); + { + const char *msg; + if (!latest_format || srv_log_file_size == 0) + { + msg= "Upgrading redo log: "; +same_size: + ib::info() << msg << srv_log_file_size_requested << " bytes; LSN=" + << flushed_lsn; + } + else if (old_exists && srv_log_file_size == srv_log_file_size_requested) + { + msg= srv_encrypt_log + ? "Encrypting redo log: " : "Removing redo log encryption: "; + goto same_size; + } + else + { + if (srv_encrypt_log == (my_bool)log_sys.is_encrypted()) + msg= srv_encrypt_log ? "Resizing encrypted" : "Resizing"; + else + msg= srv_encrypt_log + ? "Encrypting and resizing" + : "Removing encryption and resizing"; - { - ib::info info; - if (srv_log_file_size == 0 - || (log_sys.log.format & ~log_t::FORMAT_ENCRYPTED) - != log_t::FORMAT_10_5) { - info << "Upgrading redo log: "; - } else if (!old_exists - || srv_log_file_size - != srv_log_file_size_requested) { - if (srv_encrypt_log - == (my_bool)log_sys.is_encrypted()) { - info << (srv_encrypt_log - ? "Resizing encrypted" - : "Resizing"); - } else if (srv_encrypt_log) { - info << "Encrypting and resizing"; - } else { - info << "Removing encryption" - " and resizing"; - } + ib::info() << msg << " redo log from " << srv_log_file_size << " to " + << srv_log_file_size_requested + << " bytes; LSN=" << flushed_lsn; + } + } - info << " redo log from " << srv_log_file_size - << " to "; - } else if (srv_encrypt_log) { - info << "Encrypting redo log: "; - } else { - info << "Removing redo log encryption: "; - } + mysql_mutex_unlock(&log_sys.mutex); - info << srv_log_file_size_requested - << " bytes; LSN=" << flushed_lsn; - } + if (flushed_lsn != log_sys.get_flushed_lsn()) + { + log_write_up_to(flushed_lsn, false); + log_sys.log.flush(); + } - mysql_mutex_unlock(&log_sys.mutex); + ut_ad(flushed_lsn == log_sys.get_lsn()); + ut_ad(!buf_pool.any_io_pending()); - if (flushed_lsn != log_sys.get_flushed_lsn()) { - log_write_up_to(flushed_lsn, false); - log_sys.log.flush(); - } - - ut_ad(flushed_lsn == log_sys.get_lsn()); - - /* Check if the buffer pools are clean. If not - retry till it is clean. */ - if (ulint pending_io = buf_pool.io_pending()) { - count++; - /* Print a message every 60 seconds if we - are waiting to clean the buffer pools */ - if (srv_print_verbose_log && count > 600) { - ib::info() << "Waiting for " - << pending_io << " buffer " - << "page I/Os to complete"; - count = 0; - } - - os_thread_sleep(100000); - continue; - } - - break; - } - - DBUG_RETURN(flushed_lsn); + DBUG_RETURN(flushed_lsn); } /** Tries to locate LOG_FILE_NAME and check it's size, etc @@ -1259,7 +1249,7 @@ dberr_t srv_start(bool create_new_db) ut_ad(buf_page_cleaner_is_active); } - srv_startup_is_before_trx_rollback_phase = !create_new_db; + srv_startup_is_before_trx_rollback_phase = true; /* Check if undo tablespaces and redo log files exist before creating a new system tablespace */ @@ -1308,7 +1298,6 @@ dberr_t srv_start(bool create_new_db) if (create_new_db) { flushed_lsn = log_sys.get_lsn(); log_sys.set_flushed_lsn(flushed_lsn); - buf_flush_sync(); err = create_log_file(true, flushed_lsn, logfile0); @@ -1371,6 +1360,9 @@ dberr_t srv_start(bool create_new_db) if (!log_set_capacity(srv_log_file_size_requested)) { return(srv_init_abort(DB_ERROR)); } + + /* Enable checkpoints in the page cleaner. */ + recv_sys.recovery_on = false; } file_checked: @@ -2024,11 +2016,8 @@ void innodb_shutdown() break; case SRV_OPERATION_RESTORE: case SRV_OPERATION_RESTORE_EXPORT: - srv_shutdown_state = SRV_SHUTDOWN_CLEANUP; - if (!buf_page_cleaner_is_active) { - break; - } mysql_mutex_lock(&buf_pool.flush_list_mutex); + srv_shutdown_state = SRV_SHUTDOWN_CLEANUP; while (buf_page_cleaner_is_active) { pthread_cond_signal(&buf_pool.do_flush_list); my_cond_wait(&buf_pool.done_flush_list,