From ac3fd5acac6b3717ce206e3e9ebf78204af06861 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 3 Feb 2018 22:01:30 +1100 Subject: [PATCH 01/22] debian: VCS is on github --- debian/dist/Debian/control | 4 ++-- debian/dist/Ubuntu/control | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/dist/Debian/control b/debian/dist/Debian/control index e83ac1ffa5d..8c1173b8540 100644 --- a/debian/dist/Debian/control +++ b/debian/dist/Debian/control @@ -12,8 +12,8 @@ Build-Depends: procps | hurd, debhelper, libncurses5-dev (>= 5.0-6), ${CMAKE_DEP}libaio-dev, libjemalloc-dev (>= 3.0.0) Standards-Version: 3.8.3 Homepage: http://mariadb.org/ -Vcs-Browser: http://bazaar.launchpad.net/~maria-captains/maria/5.5/files -Vcs-Bzr: bzr://lp:maria +Vcs-Git: https://github.com/MariaDB/server.git +Vcs-Browser: https://github.com/MariaDB/server/ Package: libmariadbclient18 Section: libs diff --git a/debian/dist/Ubuntu/control b/debian/dist/Ubuntu/control index 94424f38db8..037c7bc1454 100644 --- a/debian/dist/Ubuntu/control +++ b/debian/dist/Ubuntu/control @@ -12,8 +12,8 @@ Build-Depends: procps | hurd, debhelper, libncurses5-dev (>= 5.0-6), ${CMAKE_DEP}libaio-dev, libjemalloc-dev (>= 3.0.0) Standards-Version: 3.8.2 Homepage: http://mariadb.org/ -Vcs-Browser: http://bazaar.launchpad.net/~maria-captains/maria/5.5/files -Vcs-Bzr: bzr://lp:maria +Vcs-Git: https://github.com/MariaDB/server.git +Vcs-Browser: https://github.com/MariaDB/server/ Package: libmariadbclient18 Section: libs From 0f0776b2adf10f559bc5c2bbea95a4c5832a47f8 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Thu, 8 Mar 2018 10:55:52 +0100 Subject: [PATCH 02/22] MDEV-13549 Fix and re-enable test galera.MW-286 This test failed to work properly because the fixes it came with were not merged from upstream. The test would fail with a spurious ER_LOCK_DEADLOCK error for a conflict that happened earlier in the test execution, while wsrep is disabled. The original fix was to set THD::wsrep_conflict_state only if wsrep is enabled (see wsrep_thd_set_conflict_state() in sql/wsrep_mysqld.cc) --- mysql-test/suite/galera/disabled.def | 1 - mysql-test/suite/galera/t/MW-286.test | 1 - sql/wsrep_mysqld.cc | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d82d5dd2023..d61da97355d 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -48,7 +48,6 @@ galera_toi_ddl_nonconflicting : MDEV-13549 Galera test failures galera_parallel_simple : MDEV-13549 Galera test failures galera_admin : MDEV-13549 Galera test failures galera_var_max_ws_rows : MDEV-13549 Galera test failures 10.1 -MW-286 : MDEV-13549 Galera test failures 10.1 galera_as_master: MDEV-13549 Galera test failures 10.1 galera_pc_ignore_sb : MDEV-13549 Galera test failures 10.1 galera_lock_table : MDEV-13549 Galera test failures 10.1 diff --git a/mysql-test/suite/galera/t/MW-286.test b/mysql-test/suite/galera/t/MW-286.test index 08deb317fbe..1b2e322f078 100644 --- a/mysql-test/suite/galera/t/MW-286.test +++ b/mysql-test/suite/galera/t/MW-286.test @@ -25,7 +25,6 @@ SET wsrep_on = FALSE; --error ER_QUERY_INTERRUPTED ALTER TABLE t1 ADD PRIMARY KEY (f1); -SET SESSION wsrep_sync_wait = 0; SET wsrep_on = TRUE; SET GLOBAL wsrep_desync = FALSE; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 285bb520b87..9d4037082bc 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2336,7 +2336,7 @@ extern "C" void wsrep_thd_set_query_state( void wsrep_thd_set_conflict_state(THD *thd, enum wsrep_conflict_state state) { - thd->wsrep_conflict_state= state; + if (WSREP(thd)) thd->wsrep_conflict_state= state; } From a3ba3aab5ad62b03d58ab64b0e10679ae9f583c8 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Thu, 8 Mar 2018 11:11:03 +0100 Subject: [PATCH 03/22] MDEV-13549 Wrong usage of mutex 'LOCK_wsrep_thd' and 'LOCK_thd_kill' test galera.MW-286 Test MW-286 occasionally failed with error the following message: ``` safe_mutex: Found wrong usage of mutex 'LOCK_wsrep_thd' and 'LOCK_thd_kill' Mutex currently locked (in reverse order): LOCK_thd_kill mariadb-server/sql/sql_class.h line 3535 LOCK_wsrep_thd mariadb-server/sql/wsrep_thd.cc line 88 ``` The fix consists in calling thd->reset_killed() in wsrep_mysql_parse() after LOCK_wsrep_thd is unlocked. Which avoids the taking locks LOCK_wsrep_thd and LOCK_thd_kill in reverse order. --- sql/sql_parse.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4dd8d9e124e..97d743d9a42 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7193,7 +7193,6 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, thd->wsrep_conflict_state == CERT_FAILURE) { thd->reset_for_next_command(); - thd->reset_killed(); if (is_autocommit && thd->lex->sql_command != SQLCOM_SELECT && (thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit)) @@ -7221,17 +7220,18 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, thd->thread_id, is_autocommit, thd->wsrep_retry_counter, thd->variables.wsrep_retry_autocommit, thd->query()); my_error(ER_LOCK_DEADLOCK, MYF(0), "wsrep aborted transaction"); - thd->reset_killed(); thd->wsrep_conflict_state= NO_CONFLICT; if (thd->wsrep_conflict_state != REPLAYING) thd->wsrep_retry_counter= 0; // reset } + mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + thd->reset_killed(); } else { set_if_smaller(thd->wsrep_retry_counter, 0); // reset; eventually ok + mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } /* If retry is requested clean up explain structure */ From 926edd48e1e67bf9a315b3602638a76c4c445ef6 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Tue, 6 Mar 2018 19:59:57 +0530 Subject: [PATCH 04/22] MDEV-15235: Assertion `length > 0' failed in create_ref_for_key The issue is that we are creating a materialised table with key of length 0 which is incorrect, we should disable materialisation for such a case. --- mysql-test/r/subselect_mat.result | 15 +++++++++++++++ mysql-test/t/subselect_mat.test | 13 +++++++++++++ sql/opt_subselect.cc | 4 +++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index d4dc519227b..00448ac4f91 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2642,3 +2642,18 @@ a b sq 4 4 1 4 2 1 drop table t1, t2; +# +# MDEV-15235: Assertion `length > 0' failed in create_ref_for_key +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f CHAR(1)); +INSERT INTO t2 VALUES ('a'),('b'); +explain +SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 +SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); +f +DROP TABLE t1, t2; diff --git a/mysql-test/t/subselect_mat.test b/mysql-test/t/subselect_mat.test index 09c6b3e1747..5211f35b48b 100644 --- a/mysql-test/t/subselect_mat.test +++ b/mysql-test/t/subselect_mat.test @@ -254,3 +254,16 @@ SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq FROM t1; drop table t1, t2; + +--echo # +--echo # MDEV-15235: Assertion `length > 0' failed in create_ref_for_key +--echo # + +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f CHAR(1)); +INSERT INTO t2 VALUES ('a'),('b'); +explain +SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); +SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); +DROP TABLE t1, t2; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 028bf44bf79..24f35a0c14c 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -873,8 +873,10 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs) Make sure that create_tmp_table will not fail due to too long keys. See MDEV-7122. This check is performed inside create_tmp_table also and we must do it so that we know the table has keys created. + Make sure that the length of the key for the temp_table is atleast + greater than 0. */ - if (total_key_length > tmp_table_max_key_length() || + if (!total_key_length || total_key_length > tmp_table_max_key_length() || elements > tmp_table_max_key_parts()) DBUG_RETURN(FALSE); From 05261f97c8c85e8c2cf5102e70c17dcaed4bfde2 Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Tue, 14 Jun 2016 08:14:37 -0700 Subject: [PATCH 05/22] Galera MTR Tests: Modify mysqltest so that if a --let = `SELECT ...` query is interrupted, the test does not fail but the error is communicated to caller --- client/mysqltest.cc | 9 +-------- mysql-test/include/wait_condition.inc | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 844a2d7bbf8..2897555da3f 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -2678,7 +2678,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end) init_dynamic_string(&ds_query, 0, (end - query) + 32, 256); do_eval(&ds_query, query, end, FALSE); - if (mysql_real_query(mysql, ds_query.str, ds_query.length)) + if (mysql_real_query(mysql, ds_query.str, ds_query.length) || !(res= mysql_store_result(mysql))) { handle_error(curr_command, mysql_errno(mysql), mysql_error(mysql), mysql_sqlstate(mysql), &ds_res); @@ -2688,13 +2688,6 @@ void var_query_set(VAR *var, const char *query, const char** query_end) DBUG_VOID_RETURN; } - if (!(res= mysql_store_result(mysql))) - { - report_or_die("Query '%s' didn't return a result set", ds_query.str); - dynstr_free(&ds_query); - eval_expr(var, "", 0); - DBUG_VOID_RETURN; - } dynstr_free(&ds_query); if ((row= mysql_fetch_row(res)) && row[0]) diff --git a/mysql-test/include/wait_condition.inc b/mysql-test/include/wait_condition.inc index 5fbde6950c8..d40b0e4d448 100644 --- a/mysql-test/include/wait_condition.inc +++ b/mysql-test/include/wait_condition.inc @@ -39,7 +39,7 @@ let $wait_timeout= 0; let $wait_condition_reps= 0; while ($wait_counter) { - --error 0,ER_NO_SUCH_TABLE,ER_LOCK_WAIT_TIMEOUT,ER_UNKNOWN_COM_ERROR + --error 0,ER_NO_SUCH_TABLE,ER_LOCK_WAIT_TIMEOUT,ER_UNKNOWN_COM_ERROR,ER_LOCK_DEADLOCK let $success= `$wait_condition`; inc $wait_condition_reps; if ($success) From f1de725fda1a7a6298ca8f33ca6909f815e61987 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Mon, 12 Mar 2018 13:41:47 +0100 Subject: [PATCH 06/22] MDEV-14144 Re-enable MTR test galera.galera_as_slave --- mysql-test/suite/galera/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d82d5dd2023..d77e91446fc 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -53,7 +53,6 @@ galera_as_master: MDEV-13549 Galera test failures 10.1 galera_pc_ignore_sb : MDEV-13549 Galera test failures 10.1 galera_lock_table : MDEV-13549 Galera test failures 10.1 MW-284 : MDEV-13549 Galera test failures 10.1 -galera_as_slave : MDEV-13549 Galera test failures 10.1 MW-328C : MDEV-13549 Galera test failures 10.1 MW-328A : MDEV-13549 Galera test failures 10.1 MW-328B : MDEV-13549 Galera test failures 10.1 From 48c11d407b409a1291c84782518c69ee9138ce72 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 13 Mar 2018 12:42:41 +0400 Subject: [PATCH 07/22] MDEV-13202 Assertion `ltime->neg == 0' failed in date_to_datetime --- mysql-test/r/func_time.result | 24 ++++++++++++++++++++++++ mysql-test/t/func_time.test | 16 ++++++++++++++++ sql/sql_time.cc | 2 ++ 3 files changed, 42 insertions(+) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index ab0576c69a7..7316724a16f 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -2878,5 +2878,29 @@ NULL Warnings: Warning 1441 Datetime function: datetime field overflow # +# MDEV-13202 Assertion `ltime->neg == 0' failed in date_to_datetime +# +CREATE TABLE t1 (i INT, d DATE); +INSERT INTO t1 VALUES (1, '1970-01-01'); +SELECT MAX(NULLIF(i,1)) FROM t1 ORDER BY DATE_SUB(d,INTERVAL 17300000 HOUR); +MAX(NULLIF(i,1)) +NULL +Warnings: +Warning 1441 Datetime function: datetime field overflow +DROP TABLE t1; +CREATE TABLE t1 (i INT, d DATE); +INSERT INTO t1 VALUES (1, '1970-01-01'); +SELECT CONCAT(DATE_SUB(d, INTERVAL 17300000 HOUR)) FROM t1; +CONCAT(DATE_SUB(d, INTERVAL 17300000 HOUR)) +NULL +Warnings: +Warning 1441 Datetime function: datetime field overflow +DROP TABLE t1; +SELECT CONCAT(DATE_SUB(TIMESTAMP'1970-01-01 00:00:00', INTERVAL 17300000 HOUR)); +CONCAT(DATE_SUB(TIMESTAMP'1970-01-01 00:00:00', INTERVAL 17300000 HOUR)) +NULL +Warnings: +Warning 1441 Datetime function: datetime field overflow +# # End of 10.0 tests # diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 1f1f3a29574..1baded9fef7 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1758,6 +1758,22 @@ SELECT ADDDATE(DATE'0000-01-01', INTERVAL '3652423:0:0:315569433559' DAY_SECOND) SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:87658175:0:315569433559' DAY_SECOND); SELECT ADDDATE(DATE'0000-01-01', INTERVAL '0:0:5259490559:315569433599' DAY_SECOND); +--echo # +--echo # MDEV-13202 Assertion `ltime->neg == 0' failed in date_to_datetime +--echo # + +CREATE TABLE t1 (i INT, d DATE); +INSERT INTO t1 VALUES (1, '1970-01-01'); +SELECT MAX(NULLIF(i,1)) FROM t1 ORDER BY DATE_SUB(d,INTERVAL 17300000 HOUR); +DROP TABLE t1; + +CREATE TABLE t1 (i INT, d DATE); +INSERT INTO t1 VALUES (1, '1970-01-01'); +SELECT CONCAT(DATE_SUB(d, INTERVAL 17300000 HOUR)) FROM t1; +DROP TABLE t1; + +SELECT CONCAT(DATE_SUB(TIMESTAMP'1970-01-01 00:00:00', INTERVAL 17300000 HOUR)); + --echo # --echo # End of 10.0 tests diff --git a/sql/sql_time.cc b/sql/sql_time.cc index 1bd68e89ecb..a618f751e65 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -960,6 +960,8 @@ bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, ltime->day= 0; return 0; } + else if (ltime->neg) + goto invalid_date; if (int_type != INTERVAL_DAY) ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date From 9ee39d2b9b915a837fae966a95a565f3a0cc018b Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Fri, 9 Mar 2018 10:20:19 +0100 Subject: [PATCH 08/22] MDEV-13549 Fix for test galera.galera_var_max_ws_rows This patch re-enables test galera.galera_var_max_ws_rows. The test did not work because there were two distinct places where the server was incrementing member THD::wsrep_affected_rows before enforcing wsrep_max_ws_rows. Essentially, the test would fail because every inserted row was counted twice. The patch removes the extra code. --- mysql-test/suite/galera/disabled.def | 1 - sql/handler.cc | 33 ---------------------------- 2 files changed, 34 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d82d5dd2023..5abd32e5f0a 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -47,7 +47,6 @@ lp1376747 : MDEV-13549 Galera test failures galera_toi_ddl_nonconflicting : MDEV-13549 Galera test failures galera_parallel_simple : MDEV-13549 Galera test failures galera_admin : MDEV-13549 Galera test failures -galera_var_max_ws_rows : MDEV-13549 Galera test failures 10.1 MW-286 : MDEV-13549 Galera test failures 10.1 galera_as_master: MDEV-13549 Galera test failures 10.1 galera_pc_ignore_sb : MDEV-13549 Galera test failures 10.1 diff --git a/sql/handler.cc b/sql/handler.cc index b2a00e48d65..a570638fc1a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5769,8 +5769,6 @@ static int write_locked_table_maps(THD *thd) typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*); -static int check_wsrep_max_ws_rows(); - static int binlog_log_row(TABLE* table, const uchar *before_record, const uchar *after_record, @@ -5824,13 +5822,6 @@ static int binlog_log_row(TABLE* table, bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE || table->file->has_transactions(); error= (*log_func)(thd, table, has_trans, before_record, after_record); - - /* - Now that the record has been logged, increment wsrep_affected_rows and - also check whether its within the allowable limits (wsrep_max_ws_rows). - */ - if (error == 0) - error= check_wsrep_max_ws_rows(); } } return error ? HA_ERR_RBR_LOGGING_FAILED : 0; @@ -5941,30 +5932,6 @@ int handler::ha_reset() } -static int check_wsrep_max_ws_rows() -{ -#ifdef WITH_WSREP - if (wsrep_max_ws_rows) - { - THD *thd= current_thd; - - if (!WSREP(thd)) - return 0; - - thd->wsrep_affected_rows++; - if (thd->wsrep_exec_mode != REPL_RECV && - thd->wsrep_affected_rows > wsrep_max_ws_rows) - { - trans_rollback_stmt(thd) || trans_rollback(thd); - my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0)); - return ER_ERROR_DURING_COMMIT; - } - } -#endif /* WITH_WSREP */ - return 0; -} - - int handler::ha_write_row(uchar *buf) { int error; From 9953588ac48bf762dfcef97ca5b92fa3e7e8cb62 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Tue, 13 Mar 2018 14:27:44 +0100 Subject: [PATCH 09/22] MDEV-13549 Fix and re-enable MTR test galera.MW-366 Test galera.MW-366 is not deterministic and depends on timing assumptions. The test occasionally fails after checking the number of 'system user' processes in processlist after changing the value of variable global wsrep_slave_threads, like this: ``` SET GLOBAL wsrep_slave_threads = x; --sleep 0.5 SELECT COUNT(*) = x FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; ``` The problem is that the number of slave threads is internally adjusted 'asynchronously', and it may take some time to spawn/kill new threads, especially in a heavily loaded system. This patch removes the '--sleep 0.5' statements from the test and replaces those with appropriate wait conditions, like this: ``` SET GLOBAL wsrep_slave_threads = x; let $wait_condition = SLECT COUNT(*) = x FROM ...; --source include/wait_condition.inc ``` --- mysql-test/suite/galera/disabled.def | 1 - mysql-test/suite/galera/r/MW-336.result | 9 --------- mysql-test/suite/galera/t/MW-336.test | 19 +++++++++++-------- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d82d5dd2023..ca7d88e4264 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -9,7 +9,6 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -MW-336 : MDEV-13549 Galera test failures galera_gra_log : MDEV-13549 Galera test failures galera_flush_local : MDEV-13549 Galera test failures galera_flush : MDEV-13549 Galera test failures diff --git a/mysql-test/suite/galera/r/MW-336.result b/mysql-test/suite/galera/r/MW-336.result index 9bdb61c1a9c..34874198c6f 100644 --- a/mysql-test/suite/galera/r/MW-336.result +++ b/mysql-test/suite/galera/r/MW-336.result @@ -3,13 +3,7 @@ SET GLOBAL wsrep_slave_threads = 10; SET GLOBAL wsrep_slave_threads = 1; INSERT INTO t1 VALUES (1); SET GLOBAL wsrep_slave_threads = 10; -SELECT COUNT(*) = 11 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; -COUNT(*) = 11 -1 SET GLOBAL wsrep_slave_threads = 20; -SELECT COUNT(*) = 21 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; -COUNT(*) = 21 -1 SET GLOBAL wsrep_slave_threads = 1; INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (2); @@ -35,8 +29,5 @@ INSERT INTO t1 VALUES (17); INSERT INTO t1 VALUES (18); INSERT INTO t1 VALUES (19); INSERT INTO t1 VALUES (20); -SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; -COUNT(*) = 2 -1 SET GLOBAL wsrep_slave_threads = 1; DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MW-336.test b/mysql-test/suite/galera/t/MW-336.test index 79d8951a822..9572489ebe9 100644 --- a/mysql-test/suite/galera/t/MW-336.test +++ b/mysql-test/suite/galera/t/MW-336.test @@ -10,20 +10,20 @@ CREATE TABLE t1 (f1 INTEGER) Engine=InnoDB; --connection node_1 SET GLOBAL wsrep_slave_threads = 10; SET GLOBAL wsrep_slave_threads = 1; +--let $wait_condition = SELECT COUNT(*) = 11 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--source include/wait_condition.inc --connection node_2 INSERT INTO t1 VALUES (1); --connection node_1 ---sleep 0.5 SET GLOBAL wsrep_slave_threads = 10; ---sleep 0.5 -SELECT COUNT(*) = 11 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--let $wait_condition = SELECT COUNT(*) = 11 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--source include/wait_condition.inc SET GLOBAL wsrep_slave_threads = 20; ---sleep 0.5 -SELECT COUNT(*) = 21 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; - +--let $wait_condition = SELECT COUNT(*) = 21 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--source include/wait_condition.inc SET GLOBAL wsrep_slave_threads = 1; @@ -40,6 +40,9 @@ INSERT INTO t1 VALUES (9); --connection node_1 +--let $wait_condition = SELECT COUNT(*) = 12 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--source include/wait_condition.inc + SET GLOBAL wsrep_slave_threads = 10; SET GLOBAL wsrep_slave_threads = 0; @@ -57,8 +60,8 @@ INSERT INTO t1 VALUES (19); INSERT INTO t1 VALUES (20); --connection node_1 ---sleep 0.5 -SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--source include/wait_condition.inc SET GLOBAL wsrep_slave_threads = 1; DROP TABLE t1; From fe66f766bb74c29c88e4ff0f84fb2b1198083d19 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 20 Sep 2017 18:38:08 +0300 Subject: [PATCH 10/22] Fix and enable galera.galera_bf_abort_for_update The test was not deterministic as it would not wait for the second INSERT to be applied (and thus the victim transaction rolled back). --- .../r/galera_bf_abort_for_update.result | 23 ++++++--- .../galera/t/galera_bf_abort_for_update.test | 51 ++++++++++++++----- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_bf_abort_for_update.result b/mysql-test/suite/galera/r/galera_bf_abort_for_update.result index 3978a3df193..2367924466c 100644 --- a/mysql-test/suite/galera/r/galera_bf_abort_for_update.result +++ b/mysql-test/suite/galera/r/galera_bf_abort_for_update.result @@ -1,10 +1,21 @@ -CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; -SET AUTOCOMMIT=OFF; -START TRANSACTION; -INSERT INTO t1 VALUES (1); -INSERT INTO t1 VALUES (1); +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 10); +BEGIN; SELECT * FROM t1 FOR UPDATE; +f1 f2 +1 10 +UPDATE t1 SET f1 = 2; +COMMIT; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction -wsrep_local_aborts_increment +wsrep_local_bf_aborts_diff +1 +BEGIN; +SELECT * FROM t1 FOR UPDATE; +f1 f2 +2 10 +UPDATE t1 SET f2 = 20; +COMMIT; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +wsrep_local_bf_aborts_diff 1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_bf_abort_for_update.test b/mysql-test/suite/galera/t/galera_bf_abort_for_update.test index 24c29778e5d..13e48f8f3ce 100644 --- a/mysql-test/suite/galera/t/galera_bf_abort_for_update.test +++ b/mysql-test/suite/galera/t/galera_bf_abort_for_update.test @@ -5,25 +5,52 @@ # Test a local transaction being aborted by a slave one while it is running a SELECT FOR UPDATE # -CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INT) ENGINE=InnoDB; ---connection node_2 ---let $wsrep_local_bf_aborts_before = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` -SET AUTOCOMMIT=OFF; -START TRANSACTION; -INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (1, 10); + +# Test updating the PK --connection node_1 -INSERT INTO t1 VALUES (1); - ---connection node_2 ---error ER_LOCK_DEADLOCK +--let $wsrep_local_bf_aborts_before = `SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'wsrep_local_bf_aborts'` +BEGIN; SELECT * FROM t1 FOR UPDATE; ---let $wsrep_local_bf_aborts_after = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` +--connection node_2 +UPDATE t1 SET f1 = 2; + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--let $wait_condition = SELECT COUNT(*) FROM t1 WHERE f1 = 2 +--source include/wait_condition.inc + +--connection node_1 +--error ER_LOCK_DEADLOCK +COMMIT; --disable_query_log ---eval SELECT $wsrep_local_bf_aborts_after - $wsrep_local_bf_aborts_before = 1 AS wsrep_local_aborts_increment; +--eval SELECT variable_value - $wsrep_local_bf_aborts_before AS wsrep_local_bf_aborts_diff FROM information_schema.global_status WHERE variable_name = 'wsrep_local_bf_aborts' +--enable_query_log + +# Test updating non-indexed column + +--connection node_1 +--let $wsrep_local_bf_aborts_before = `SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'wsrep_local_bf_aborts'` +BEGIN; +SELECT * FROM t1 FOR UPDATE; + +--connection node_2 +UPDATE t1 SET f2 = 20; + +--connection node_1a +--let $wait_condition = SELECT COUNT(*) FROM t1 WHERE f2 = 20 +--source include/wait_condition.inc + +--connection node_1 +--error ER_LOCK_DEADLOCK +COMMIT; + +--disable_query_log +--eval SELECT variable_value - $wsrep_local_bf_aborts_before AS wsrep_local_bf_aborts_diff FROM information_schema.global_status WHERE variable_name = 'wsrep_local_bf_aborts' --enable_query_log DROP TABLE t1; From 9a21fd34af0506c5b45133c87c23862b84b36717 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Wed, 14 Mar 2018 10:27:31 +0100 Subject: [PATCH 11/22] MDEV-13549 Re-enable test galera.galera_bf_abort_for_update Test passes reliably after applying missing commit from upstream. --- mysql-test/suite/galera/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d82d5dd2023..3e70924aa3c 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -34,7 +34,6 @@ galera_ist_mysqldump : MDEV-13549 Galera test failures mysql-wsrep#31 : MDEV-13549 Galera test failures galera_migrate : MariaDB 10.0 does not support START SLAVE USER galera_concurrent_ctas : MDEV-13549 Galera test failures -galera_bf_abort_for_update : MDEV-13549 Galera test failures galera_wsrep_desync_wsrep_on : MDEV-13549 Galera test failures galera_ssl_upgrade : MDEV-13549 Galera test failures mysql-wsrep#33 : MDEV-13549 Galera test failures From 38579cefa9f3a3f662e42dbe7808f82e94878686 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 14 Mar 2018 14:46:23 +0400 Subject: [PATCH 12/22] MDEV-14452 Precision in INTERVAL xxx DAY_MICROSECOND parsed wrong? --- mysql-test/r/func_date_add.result | 51 +++++++++++++++++++++++++++++++ mysql-test/t/func_date_add.test | 37 ++++++++++++++++++++++ sql/item_timefunc.cc | 14 ++++++--- 3 files changed, 98 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/func_date_add.result b/mysql-test/r/func_date_add.result index e8fbba786a4..0258267b5ec 100644 --- a/mysql-test/r/func_date_add.result +++ b/mysql-test/r/func_date_add.result @@ -102,3 +102,54 @@ select * from t1 where case a when adddate( '2012-12-12', 7 ) then true end; a drop table t1; End of 5.5 tests +# +# Start of 10.1 tests +# +# +# MDEV-14452 Precision in INTERVAL xxx DAY_MICROSECOND parsed wrong? +# +SELECT +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5' DAY_MICROSECOND) c1, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50' DAY_MICROSECOND) c2, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500' DAY_MICROSECOND) c3, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000' DAY_MICROSECOND) c4, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000' DAY_MICROSECOND) c5, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000' DAY_MICROSECOND) c6, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000' DAY_MICROSECOND) c7, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000' DAY_MICROSECOND) c8, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000' DAY_MICROSECOND) c9, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000' DAY_MICROSECOND) c10, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000' DAY_MICROSECOND) c11, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000' DAY_MICROSECOND) c12, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000' DAY_MICROSECOND) c13, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000' DAY_MICROSECOND) c14, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000000' DAY_MICROSECOND) c15, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000000' DAY_MICROSECOND) c16, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000000' DAY_MICROSECOND) c17, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000000000' DAY_MICROSECOND) c18, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000000000' DAY_MICROSECOND) c19, +DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000000000' DAY_MICROSECOND) c20 +; +c1 1000-01-01 00:00:01.500000 +c2 1000-01-01 00:00:01.500000 +c3 1000-01-01 00:00:01.500000 +c4 1000-01-01 00:00:01.500000 +c5 1000-01-01 00:00:01.500000 +c6 1000-01-01 00:00:01.500000 +c7 1000-01-01 00:00:01.500000 +c8 1000-01-01 00:00:01.500000 +c9 1000-01-01 00:00:01.500000 +c10 1000-01-01 00:00:01.500000 +c11 1000-01-01 00:00:01.500000 +c12 1000-01-01 00:00:01.500000 +c13 1000-01-01 00:00:01.500000 +c14 1000-01-01 00:00:01.500000 +c15 1000-01-01 00:00:01.500000 +c16 1000-01-01 00:00:01.500000 +c17 1000-01-01 00:00:01.500000 +c18 1000-01-01 00:00:01.500000 +c19 1000-01-01 00:00:01.500000 +c20 NULL +# +# End of 10.1 tests +# diff --git a/mysql-test/t/func_date_add.test b/mysql-test/t/func_date_add.test index 5f27978347c..e7e2b96f0eb 100644 --- a/mysql-test/t/func_date_add.test +++ b/mysql-test/t/func_date_add.test @@ -100,3 +100,40 @@ drop table t1; --echo End of 5.5 tests +--echo # +--echo # Start of 10.1 tests +--echo # + +--echo # +--echo # MDEV-14452 Precision in INTERVAL xxx DAY_MICROSECOND parsed wrong? +--echo # + +--vertical_results +SELECT + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5' DAY_MICROSECOND) c1, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50' DAY_MICROSECOND) c2, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500' DAY_MICROSECOND) c3, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000' DAY_MICROSECOND) c4, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000' DAY_MICROSECOND) c5, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000' DAY_MICROSECOND) c6, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000' DAY_MICROSECOND) c7, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000' DAY_MICROSECOND) c8, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000' DAY_MICROSECOND) c9, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000' DAY_MICROSECOND) c10, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000' DAY_MICROSECOND) c11, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000' DAY_MICROSECOND) c12, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000' DAY_MICROSECOND) c13, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000' DAY_MICROSECOND) c14, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000000' DAY_MICROSECOND) c15, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000000' DAY_MICROSECOND) c16, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000000' DAY_MICROSECOND) c17, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000000000' DAY_MICROSECOND) c18, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000000000' DAY_MICROSECOND) c19, + DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000000000' DAY_MICROSECOND) c20 +; +--horizontal_results + + +--echo # +--echo # End of 10.1 tests +--echo # diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 4a94c3a5f89..d7506026c62 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -702,7 +702,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, { const char *end=str+length; uint i; - long msec_length= 0; + long field_length= 0; while (str != end && !my_isdigit(cs,*str)) str++; @@ -713,7 +713,8 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, const char *start= str; for (value= 0; str != end && my_isdigit(cs, *str); str++) value= value*10 + *str - '0'; - msec_length= 6 - (str - start); + if ((field_length= str - start) >= 20) + return true; values[i]= value; while (str != end && !my_isdigit(cs,*str)) str++; @@ -728,8 +729,13 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, } } - if (transform_msec && msec_length > 0) - values[count - 1] *= (long) log_10_int[msec_length]; + if (transform_msec && field_length > 0) + { + if (field_length < 6) + values[count - 1] *= (long) log_10_int[6 - field_length]; + else if (field_length > 6) + values[count - 1] /= (long) log_10_int[field_length - 6]; + } return (str != end); } From 782fb1e016e0342074ca9938e412a14d20d6f793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Wed, 14 Mar 2018 18:47:02 +1100 Subject: [PATCH 13/22] fix ucontext configure check musl ships the header for other purposes, but makecontext is not implemented. fix the check to detect if makecontext is implemented before enabling code using it. --- configure.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.cmake b/configure.cmake index a1cddbb37fa..df180e72963 100644 --- a/configure.cmake +++ b/configure.cmake @@ -1111,6 +1111,9 @@ CHECK_INCLUDE_FILE(ucontext.h HAVE_UCONTEXT_H) IF(NOT HAVE_UCONTEXT_H) CHECK_INCLUDE_FILE(sys/ucontext.h HAVE_UCONTEXT_H) ENDIF() +IF(HAVE_UCONTEXT_H) + CHECK_FUNCTION_EXISTS(makecontext HAVE_UCONTEXT_H) +ENDIF() CHECK_STRUCT_HAS_MEMBER("struct timespec" tv_sec "time.h" STRUCT_TIMESPEC_HAS_TV_SEC) CHECK_STRUCT_HAS_MEMBER("struct timespec" tv_nsec "time.h" STRUCT_TIMESPEC_HAS_TV_NSEC) From efb9dec2b9f7dc60b2b45bf9d368c665c9132795 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 15 Mar 2018 10:23:42 +0400 Subject: [PATCH 14/22] A 32bit cleanup for MDEV-14452 Precision in INTERVAL xxx DAY_MICROSECOND parsed wrong? "mtr func_date_add" failed on 32-bit platforms. Removing a wrong case to "long". Both values[] and log_10_int[] are arrays of "ulonglong", no cast is needed. --- sql/item_timefunc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index d7506026c62..44105bd4a12 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -732,9 +732,9 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, if (transform_msec && field_length > 0) { if (field_length < 6) - values[count - 1] *= (long) log_10_int[6 - field_length]; + values[count - 1] *= log_10_int[6 - field_length]; else if (field_length > 6) - values[count - 1] /= (long) log_10_int[field_length - 6]; + values[count - 1] /= log_10_int[field_length - 6]; } return (str != end); From 0368e75a55abfc5fd7188d8a8e26d539d4cf274d Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Thu, 15 Mar 2018 11:36:36 +0100 Subject: [PATCH 15/22] MDEV-13549 Re-enable tests MW-328A, MW-328B, MW-328C and MW-329 These tests were also subject to error "Wrong usage of mutex 'LOCK_wsrep_thd' and 'LOCK_thd_kill'". --- mysql-test/suite/galera/disabled.def | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d61da97355d..e70ab112df9 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -13,7 +13,6 @@ MW-336 : MDEV-13549 Galera test failures galera_gra_log : MDEV-13549 Galera test failures galera_flush_local : MDEV-13549 Galera test failures galera_flush : MDEV-13549 Galera test failures -MW-329 : MDEV-13549 Galera test failures galera_account_management : MariaDB 10.0 does not support ALTER USER galera_binlog_row_image : MariaDB 10.0 does not support binlog_row_image galera_binlog_rows_query_log_events: MariaDB does not support binlog_rows_query_log_events @@ -53,10 +52,6 @@ galera_pc_ignore_sb : MDEV-13549 Galera test failures 10.1 galera_lock_table : MDEV-13549 Galera test failures 10.1 MW-284 : MDEV-13549 Galera test failures 10.1 galera_as_slave : MDEV-13549 Galera test failures 10.1 -MW-328C : MDEV-13549 Galera test failures 10.1 -MW-328A : MDEV-13549 Galera test failures 10.1 -MW-328B : MDEV-13549 Galera test failures 10.1 -MW-328 : MDEV-13549 Galera test failures 10.1 galera_suspend_slave : MDEV-13549 Galera test failures 10.1 galera_gtid : MDEV-13549 Galera test failures 10.1 galera_gtid_slave : MDEV-13549 Galera test failures 10.1 From ba6cf25396641aca657e0af794ef980e71d0bfa9 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Thu, 15 Mar 2018 16:03:25 +0100 Subject: [PATCH 16/22] MDEV-13549 Fix and re-enable test galera.galera_var_slave_threads Two changes were made to the test: 1) Suppress warning "Refusing exit for the last slave thread." This warning was already suppressed, but on the wrong node. 2) The test occasionally fails because it expects that the number of applier threads changes immediately after changing the value of ```variable wsrep_slave_threads```. Which is not true. This patch turns snippets like this: ``` SET GLOBAL wsrep_slave_threads = x; SELECT COUNT(*) = x FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; ``` Into proper wait_conditions: ``` SET GLOBAL wsrep_slave_threads = x; let $wait_condition = SELECT COUNT(*) = x FROM ...; --source include/wait_condition.inc ``` --- mysql-test/suite/galera/disabled.def | 1 - .../galera/r/galera_var_slave_threads.result | 14 +++++----- .../galera/t/galera_var_slave_threads.test | 28 ++++++++++++++----- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d82d5dd2023..27ae4af1ae8 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -20,7 +20,6 @@ galera_binlog_rows_query_log_events: MariaDB does not support binlog_rows_query_ GAL-419 : MDEV-13549 Galera test failures galera_toi_ddl_fk_insert : MDEV-13549 Galera test failures galera_var_notify_cmd : MDEV-13549 Galera test failures -galera_var_slave_threads : MDEV-13549 Galera test failures mysql-wsrep#90 : MDEV-13549 Galera test failures galera_as_master_gtid : Requires MySQL GTID galera_as_master_gtid_change_master : Requires MySQL GTID diff --git a/mysql-test/suite/galera/r/galera_var_slave_threads.result b/mysql-test/suite/galera/r/galera_var_slave_threads.result index 2340d25d160..89026bce907 100644 --- a/mysql-test/suite/galera/r/galera_var_slave_threads.result +++ b/mysql-test/suite/galera/r/galera_var_slave_threads.result @@ -1,6 +1,6 @@ -CALL mtr.add_suppression("WSREP: Refusing exit for the last slave thread."); CREATE TABLE t1 (f1 INT PRIMARY KEY) Engine=InnoDB; CREATE TABLE t2 (f1 INT AUTO_INCREMENT PRIMARY KEY) Engine=InnoDB; +CALL mtr.add_suppression("WSREP: Refusing exit for the last slave thread."); SET GLOBAL wsrep_slave_threads = 0; Warnings: Warning 1292 Truncated incorrect wsrep_slave_threads value: '0' @@ -22,9 +22,6 @@ INSERT INTO t1 VALUES (1); SELECT COUNT(*) = 1 FROM t1; COUNT(*) = 1 1 -SELECT COUNT(*) = @@wsrep_slave_threads + 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; -COUNT(*) = @@wsrep_slave_threads + 1 -1 SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%'; COUNT(*) = 1 1 @@ -96,9 +93,6 @@ INSERT INTO t2 VALUES (DEFAULT); SELECT COUNT(*) = 64 FROM t2; COUNT(*) = 64 1 -SELECT COUNT(*) = @@wsrep_slave_threads + 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; -COUNT(*) = @@wsrep_slave_threads + 1 -1 SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%'; COUNT(*) = 1 1 @@ -111,5 +105,11 @@ DROP TABLE t2; CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY) ENGINE=INNODB; SET GLOBAL wsrep_slave_threads = 4; SET GLOBAL wsrep_slave_threads = 1; +INSERT INTO t1 VALUES (DEFAULT); +INSERT INTO t1 VALUES (DEFAULT); +INSERT INTO t1 VALUES (DEFAULT); DROP TABLE t1; +SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%'; +COUNT(*) = 1 +1 # End of tests diff --git a/mysql-test/suite/galera/t/galera_var_slave_threads.test b/mysql-test/suite/galera/t/galera_var_slave_threads.test index 5e56800c5d6..5c775e67450 100644 --- a/mysql-test/suite/galera/t/galera_var_slave_threads.test +++ b/mysql-test/suite/galera/t/galera_var_slave_threads.test @@ -6,7 +6,6 @@ --source include/galera_cluster.inc --source include/have_innodb.inc -CALL mtr.add_suppression("WSREP: Refusing exit for the last slave thread."); --let $wsrep_slave_threads_orig = `SELECT @@wsrep_slave_threads` --connection node_1 @@ -14,7 +13,7 @@ CREATE TABLE t1 (f1 INT PRIMARY KEY) Engine=InnoDB; CREATE TABLE t2 (f1 INT AUTO_INCREMENT PRIMARY KEY) Engine=InnoDB; --connection node_2 - +CALL mtr.add_suppression("WSREP: Refusing exit for the last slave thread."); # Setting wsrep_slave_threads to zero triggers a warning SET GLOBAL wsrep_slave_threads = 0; SHOW WARNINGS; @@ -30,15 +29,14 @@ SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system use # SET GLOBAL wsrep_slave_threads = 64; ---sleep 0.5 --connection node_1 INSERT INTO t1 VALUES (1); --connection node_2 SELECT COUNT(*) = 1 FROM t1; - -SELECT COUNT(*) = @@wsrep_slave_threads + 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--let $wait_condition = SELECT COUNT(*) = @@wsrep_slave_threads + 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--source include/wait_condition.inc SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%'; # @@ -59,8 +57,8 @@ while ($count) --connection node_2 SELECT COUNT(*) = 64 FROM t2; - -SELECT COUNT(*) = @@wsrep_slave_threads + 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--let $wait_condition = SELECT COUNT(*) = @@wsrep_slave_threads + 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; +--source include/wait_condition.inc SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%'; @@ -78,7 +76,23 @@ CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY) ENGINE=INNODB; --connection node_2 SET GLOBAL wsrep_slave_threads = 4; +--let $wait_condition = SELECT COUNT(*) = @@wsrep_slave_threads + 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' +--source include/wait_condition.inc + SET GLOBAL wsrep_slave_threads = 1; + +--connection node_1 +INSERT INTO t1 VALUES (DEFAULT); +INSERT INTO t1 VALUES (DEFAULT); +INSERT INTO t1 VALUES (DEFAULT); DROP TABLE t1; +--connection node_2 +# +# make sure that we are left with exactly one applier thread before we leaving the test +# +--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' +--source include/wait_condition.inc +SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%'; + --echo # End of tests From a54abf01753a69c2186d60c155212149be59a7a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 13 Mar 2018 14:00:45 +0200 Subject: [PATCH 17/22] innobase_kill_query(): Use lock_trx_handle_wait() The caller of THD::awake() should never hold any InnoDB mutexes, so we can always acquire lock_sys->mutex and trx->mutex. --- storage/innobase/handler/ha_innodb.cc | 70 ++++------------------- storage/xtradb/handler/ha_innodb.cc | 82 +++++---------------------- 2 files changed, 24 insertions(+), 128 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4f76c568f17..521ac005437 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1199,7 +1199,9 @@ innobase_close_connection( THD* thd); /*!< in: MySQL thread handle for which to close the connection */ -static void innobase_kill_query(handlerton *hton, THD* thd, enum thd_kill_levels level); +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels); static void innobase_commit_ordered(handlerton *hton, THD* thd, bool all); /*****************************************************************//** @@ -4891,21 +4893,11 @@ innobase_close_thd( UNIV_INTERN void lock_cancel_waiting_and_release(lock_t* lock); -/*****************************************************************//** -Cancel any pending lock request associated with the current THD. */ -static -void -innobase_kill_query( -/*======================*/ - handlerton* hton, /*!< in: innobase handlerton */ - THD* thd, /*!< in: MySQL thread being killed */ - enum thd_kill_levels level) /*!< in: kill level */ +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) { - trx_t* trx; - DBUG_ENTER("innobase_kill_query"); - DBUG_ASSERT(hton == innodb_hton_ptr); - #ifdef WITH_WSREP wsrep_thd_LOCK(thd); if (wsrep_thd_get_conflict_state(thd) != NO_CONFLICT) { @@ -4920,51 +4912,11 @@ innobase_kill_query( } wsrep_thd_UNLOCK(thd); #endif /* WITH_WSREP */ - trx = thd_to_trx(thd); - if (trx && trx->lock.wait_lock) { - /* In wsrep BF we have already took lock_sys and trx - mutex either on wsrep_abort_transaction() or - before wsrep_kill_victim(). In replication we - could own lock_sys mutex taken in - lock_deadlock_check_and_resolve(). */ - - WSREP_DEBUG("Killing victim trx %p BF %d trx BF %d trx_id " TRX_ID_FMT " ABORT %d thd %p" - " current_thd %p BF %d wait_lock_modes: %s\n", - trx, wsrep_thd_is_BF(trx->mysql_thd, FALSE), - wsrep_thd_is_BF(thd, FALSE), - trx->id, trx->abort_type, - trx->mysql_thd, - current_thd, - wsrep_thd_is_BF(current_thd, FALSE), - lock_get_info(trx->lock.wait_lock).c_str()); - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) - && trx->abort_type == TRX_SERVER_ABORT) { - ut_ad(!lock_mutex_own()); - lock_mutex_enter(); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { - trx_mutex_enter(trx); - } - - ut_ad(lock_mutex_own()); - ut_ad(trx_mutex_own(trx)); - - /* Cancel a pending lock request. */ - if (trx->lock.wait_lock) { - lock_cancel_waiting_and_release(trx->lock.wait_lock); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { - trx_mutex_exit(trx); - } - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - trx->abort_type == TRX_SERVER_ABORT) { - lock_mutex_exit(); - } + if (trx_t* trx = thd_to_trx(thd)) { + ut_ad(trx->mysql_thd == thd); + /* Cancel a pending lock request if there are any */ + lock_trx_handle_wait(trx); } DBUG_VOID_RETURN; @@ -18759,7 +18711,7 @@ wsrep_innobase_kill_one_trx( thd_get_thread_id(thd))); WSREP_DEBUG("kill query for: %ld", thd_get_thread_id(thd)); - /* Note that innobase_kill_connection will take lock_mutex + /* Note that innobase_kill_query will take lock_mutex and trx_mutex */ wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 9749bcecfe9..d0a98eda0de 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1423,19 +1423,12 @@ innobase_close_connection( THD* thd); /*!< in: MySQL thread handle for which to close the connection */ +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels); static void innobase_commit_ordered(handlerton *hton, THD* thd, bool all); static void innobase_checkpoint_request(handlerton *hton, void *cookie); -/*****************************************************************//** -Cancel any pending lock request associated with the current THD. */ -static -void -innobase_kill_connection( -/*======================*/ - handlerton* hton, /*!< in: innobase handlerton */ - THD* thd, /*!< in: handle to the MySQL thread being killed */ - thd_kill_levels); - /*****************************************************************//** Commits a transaction in an InnoDB database or marks an SQL statement ended. @@ -3886,7 +3879,7 @@ innobase_init( innobase_hton->release_temporary_latches = innobase_release_temporary_latches; - innobase_hton->kill_query = innobase_kill_connection; + innobase_hton->kill_query = innobase_kill_query; if (srv_file_per_table) innobase_hton->tablefile_extensions = ha_innobase_exts; @@ -5496,20 +5489,11 @@ ha_innobase::get_row_type() const return(ROW_TYPE_NOT_USED); } -/*****************************************************************//** -Cancel any pending lock request associated with the current THD. */ -static -void -innobase_kill_connection( -/*======================*/ - handlerton* hton, /*!< in: innobase handlerton */ - THD* thd, /*!< in: handle to the MySQL thread being killed */ - thd_kill_levels) +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) { - trx_t* trx; - - DBUG_ENTER("innobase_kill_connection"); - DBUG_ASSERT(hton == innodb_hton_ptr); + DBUG_ENTER("innobase_kill_query"); #ifdef WITH_WSREP wsrep_thd_LOCK(thd); @@ -5525,50 +5509,10 @@ innobase_kill_connection( } wsrep_thd_UNLOCK(thd); #endif /* WITH_WSREP */ - trx = thd_to_trx(thd); - - if (trx && trx->lock.wait_lock) { - /* In wsrep BF we have already took lock_sys and trx - mutex either on wsrep_abort_transaction() or - before wsrep_kill_victim(). In replication we - could own lock_sys mutex taken in - lock_deadlock_check_and_resolve().*/ - - WSREP_DEBUG("Killing victim trx %p BF %d trx BF %d trx_id " TRX_ID_FMT " ABORT %d thd %p" - " current_thd %p BF %d wait_lock_modes: %s\n", - trx, wsrep_thd_is_BF(trx->mysql_thd, FALSE), - wsrep_thd_is_BF(thd, FALSE), - trx->id, trx->abort_type, - trx->mysql_thd, - current_thd, - wsrep_thd_is_BF(current_thd, FALSE), - lock_get_info(trx->lock.wait_lock).c_str()); - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) - && trx->abort_type == TRX_SERVER_ABORT) { - ut_ad(!lock_mutex_own()); - lock_mutex_enter(); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { - trx_mutex_enter(trx); - } - - ut_ad(lock_mutex_own()); - ut_ad(trx_mutex_own(trx)); - - if (trx->lock.wait_lock) { - lock_cancel_waiting_and_release(trx->lock.wait_lock); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { - trx_mutex_exit(trx); - } - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - trx->abort_type == TRX_SERVER_ABORT) { - lock_mutex_exit(); - } + if (trx_t* trx = thd_to_trx(thd)) { + ut_ad(trx->mysql_thd == thd); + /* Cancel a pending lock request if there are any */ + lock_trx_handle_wait(trx); } DBUG_VOID_RETURN; @@ -19802,7 +19746,7 @@ wsrep_innobase_kill_one_trx( thd_get_thread_id(thd))); WSREP_DEBUG("kill query for: %ld", thd_get_thread_id(thd)); - /* Note that innobase_kill_connection will take lock_mutex + /* Note that innobase_kill_query will take lock_mutex and trx_mutex */ wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal); From 723f87e9d318aedad30dfb9dde104312d6612662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 14 Mar 2018 09:39:47 +0200 Subject: [PATCH 18/22] lock_table_create(), lock_rec_create(): Clean up the WSREP code By definition, c_lock->trx->lock.wait_lock==c_lock cannot hold. That is, the owner transaction of a lock cannot be waiting for that particular lock. It must have been waiting for some other lock. Remove the dead code related to that. Also, test c_lock for NULLness only once. --- storage/innobase/lock/lock0lock.cc | 43 +++++++----------------------- storage/xtradb/lock/lock0lock.cc | 43 +++++++----------------------- 2 files changed, 20 insertions(+), 66 deletions(-) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index eb3d260e78a..68b19a6d2b5 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -898,7 +898,7 @@ UNIV_INLINE void lock_reset_lock_and_trx_wait( /*=========================*/ - lock_t* lock) /*!< in/out: record lock */ + lock_t* lock) /*!< in/out: record lock */ { ut_ad(lock_get_wait(lock)); ut_ad(lock_mutex_own()); @@ -2216,13 +2216,6 @@ lock_rec_create( trx_mutex_enter(trx); } - /* trx might not wait for c_lock, but some other lock - does not matter if wait_lock was released above - */ - if (c_lock->trx->lock.wait_lock == c_lock) { - lock_reset_lock_and_trx_wait(lock); - } - trx_mutex_exit(c_lock->trx); if (wsrep_debug) { @@ -4970,19 +4963,18 @@ lock_table_create( UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock); #ifdef WITH_WSREP - if (wsrep_thd_is_wsrep(trx->mysql_thd)) { - if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + if (c_lock) { + if (wsrep_thd_is_wsrep(trx->mysql_thd) + && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { UT_LIST_INSERT_AFTER( un_member.tab_lock.locks, table->locks, c_lock, lock); } else { UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock); } - if (c_lock) { - trx_mutex_enter(c_lock->trx); - } + trx_mutex_enter(c_lock->trx); - if (c_lock && c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { + if (c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { c_lock->trx->lock.was_chosen_as_deadlock_victim = TRUE; @@ -4991,36 +4983,21 @@ lock_table_create( wsrep_print_wait_locks(c_lock->trx->lock.wait_lock); } - /* have to release trx mutex for the duration of - victim lock release. This will eventually call - lock_grant, which wants to grant trx mutex again - */ - /* caller has trx_mutex, have to release for lock cancel */ + /* The lock release will call lock_grant(), + which would acquire trx->mutex again. */ trx_mutex_exit(trx); lock_cancel_waiting_and_release(c_lock->trx->lock.wait_lock); trx_mutex_enter(trx); - /* trx might not wait for c_lock, but some other lock - does not matter if wait_lock was released above - */ - if (c_lock->trx->lock.wait_lock == c_lock) { - lock_reset_lock_and_trx_wait(lock); - } - if (wsrep_debug) { fprintf(stderr, "WSREP: c_lock canceled " TRX_ID_FMT "\n", c_lock->trx->id); } } - if (c_lock) { - trx_mutex_exit(c_lock->trx); - } - } else { + trx_mutex_exit(c_lock->trx); + } else #endif /* WITH_WSREP */ UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock); -#ifdef WITH_WSREP - } -#endif /* WITH_WSREP */ if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) { diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index b50452c1d5d..e2b9a1671ca 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -910,7 +910,7 @@ UNIV_INLINE void lock_reset_lock_and_trx_wait( /*=========================*/ - lock_t* lock) /*!< in/out: record lock */ + lock_t* lock) /*!< in/out: record lock */ { ut_ad(lock_get_wait(lock)); ut_ad(lock_mutex_own()); @@ -2358,13 +2358,6 @@ lock_rec_create( trx_mutex_enter(trx); } - /* trx might not wait for c_lock, but some other lock - does not matter if wait_lock was released above - */ - if (c_lock->trx->lock.wait_lock == c_lock) { - lock_reset_lock_and_trx_wait(lock); - } - trx_mutex_exit(c_lock->trx); if (wsrep_debug) { @@ -5010,19 +5003,18 @@ lock_table_create( UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock); #ifdef WITH_WSREP - if (wsrep_thd_is_wsrep(trx->mysql_thd)) { - if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + if (c_lock) { + if (wsrep_thd_is_wsrep(trx->mysql_thd) + && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { UT_LIST_INSERT_AFTER( un_member.tab_lock.locks, table->locks, c_lock, lock); } else { UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock); } - if (c_lock) { - trx_mutex_enter(c_lock->trx); - } + trx_mutex_enter(c_lock->trx); - if (c_lock && c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { + if (c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { c_lock->trx->lock.was_chosen_as_deadlock_victim = TRUE; @@ -5031,36 +5023,21 @@ lock_table_create( wsrep_print_wait_locks(c_lock->trx->lock.wait_lock); } - /* have to release trx mutex for the duration of - victim lock release. This will eventually call - lock_grant, which wants to grant trx mutex again - */ - /* caller has trx_mutex, have to release for lock cancel */ + /* The lock release will call lock_grant(), + which would acquire trx->mutex again. */ trx_mutex_exit(trx); lock_cancel_waiting_and_release(c_lock->trx->lock.wait_lock); trx_mutex_enter(trx); - /* trx might not wait for c_lock, but some other lock - does not matter if wait_lock was released above - */ - if (c_lock->trx->lock.wait_lock == c_lock) { - lock_reset_lock_and_trx_wait(lock); - } - if (wsrep_debug) { fprintf(stderr, "WSREP: c_lock canceled " TRX_ID_FMT "\n", c_lock->trx->id); } } - if (c_lock) { - trx_mutex_exit(c_lock->trx); - } - } else { + trx_mutex_exit(c_lock->trx); + } else #endif /* WITH_WSREP */ UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock); -#ifdef WITH_WSREP - } -#endif /* WITH_WSREP */ if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) { From dbb3960ad8d92f3cc17527440b059bf80bf83120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 15 Mar 2018 19:48:29 +0200 Subject: [PATCH 19/22] Follow-up to MDEV-11236/MDEV-14846 debug assertion ha_innobase::unlock_row(): Use a relaxed version of the trx_state_eq() debug assertion, because rr_unlock_row() may be invoked after an error has been already reported and the transaction has been rolled back. --- storage/innobase/handler/ha_innodb.cc | 2 +- storage/xtradb/handler/ha_innodb.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 521ac005437..9c3b04b2a67 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9040,7 +9040,7 @@ ha_innobase::unlock_row(void) But there are some calls to this function from the SQL layer when the transaction is in state TRX_STATE_NOT_STARTED. The check on prebuilt->select_lock_type above gets around this issue. */ - ut_ad(trx_state_eq(prebuilt->trx, TRX_STATE_ACTIVE)); + ut_ad(trx_state_eq(prebuilt->trx, TRX_STATE_ACTIVE, true)); switch (prebuilt->row_read_type) { case ROW_READ_WITH_LOCKS: diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index d0a98eda0de..347b235b049 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -9616,7 +9616,7 @@ ha_innobase::unlock_row(void) But there are some calls to this function from the SQL layer when the transaction is in state TRX_STATE_NOT_STARTED. The check on prebuilt->select_lock_type above gets around this issue. */ - ut_ad(trx_state_eq(prebuilt->trx, TRX_STATE_ACTIVE)); + ut_ad(trx_state_eq(prebuilt->trx, TRX_STATE_ACTIVE, true)); switch (prebuilt->row_read_type) { case ROW_READ_WITH_LOCKS: From ca40330d1da6c1b30a33249eab546a5275a1a103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 16 Mar 2018 08:23:56 +0200 Subject: [PATCH 20/22] Fix a deadlock in thd_report_wait_for() Unlike commit a54abf01753a69c2186d60c155212149be59a7a6 claimed, the caller of THD::awake() may actually hold the InnoDB lock_sys->mutex. That commit introduced a deadlock of threads in the replication slave when running the test rpl.rpl_parallel_optimistic_nobinlog. lock_trx_handle_wait(): Expect the callers to acquire and release lock_sys->mutex and trx->mutex. innobase_kill_query(): Restore the logic for conditionally acquiring and releasing the mutexes. THD::awake() can be called from inside InnoDB while holding one or both mutexes, via thd_report_wait_for() and via wsrep_innobase_kill_one_trx(). --- storage/innobase/handler/ha_innodb.cc | 23 +++++++++++++++++++++++ storage/innobase/lock/lock0lock.cc | 23 ++++++++--------------- storage/innobase/row/row0sel.cc | 4 ++++ storage/xtradb/handler/ha_innodb.cc | 23 +++++++++++++++++++++++ storage/xtradb/lock/lock0lock.cc | 23 ++++++++--------------- storage/xtradb/row/row0sel.cc | 4 ++++ 6 files changed, 70 insertions(+), 30 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9c3b04b2a67..31ea969fa21 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4915,8 +4915,31 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) if (trx_t* trx = thd_to_trx(thd)) { ut_ad(trx->mysql_thd == thd); + + switch (trx->abort_type) { + case TRX_WSREP_ABORT: + break; + case TRX_SERVER_ABORT: + if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + lock_mutex_enter(); + } + /* fall through */ + case TRX_REPLICATION_ABORT: + trx_mutex_enter(trx); + } /* Cancel a pending lock request if there are any */ lock_trx_handle_wait(trx); + switch (trx->abort_type) { + case TRX_WSREP_ABORT: + break; + case TRX_SERVER_ABORT: + if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + lock_mutex_exit(); + } + /* fall through */ + case TRX_REPLICATION_ABORT: + trx_mutex_exit(trx); + } } DBUG_VOID_RETURN; diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 68b19a6d2b5..12c0051d09f 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -7977,26 +7977,19 @@ lock_trx_handle_wait( /*=================*/ trx_t* trx) /*!< in/out: trx lock state */ { - dberr_t err; - - lock_mutex_enter(); - - trx_mutex_enter(trx); + ut_ad(lock_mutex_own()); + ut_ad(trx_mutex_own(trx)); if (trx->lock.was_chosen_as_deadlock_victim) { - err = DB_DEADLOCK; - } else if (trx->lock.wait_lock != NULL) { - lock_cancel_waiting_and_release(trx->lock.wait_lock); - err = DB_LOCK_WAIT; - } else { + return DB_DEADLOCK; + } + if (!trx->lock.wait_lock) { /* The lock was probably granted before we got here. */ - err = DB_SUCCESS; + return DB_SUCCESS; } - lock_mutex_exit(); - trx_mutex_exit(trx); - - return(err); + lock_cancel_waiting_and_release(trx->lock.wait_lock); + return DB_LOCK_WAIT; } /*********************************************************************//** diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 6cca3e21c79..3cf7bc6ee80 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4615,7 +4615,11 @@ no_gap_lock: a deadlock and the transaction had to wait then release the lock it is waiting on. */ + lock_mutex_enter(); + trx_mutex_enter(trx); err = lock_trx_handle_wait(trx); + lock_mutex_exit(); + trx_mutex_exit(trx); switch (err) { case DB_SUCCESS: diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 347b235b049..7d550c45356 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -5511,8 +5511,31 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) #endif /* WITH_WSREP */ if (trx_t* trx = thd_to_trx(thd)) { ut_ad(trx->mysql_thd == thd); + + switch (trx->abort_type) { + case TRX_WSREP_ABORT: + break; + case TRX_SERVER_ABORT: + if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + lock_mutex_enter(); + } + /* fall through */ + case TRX_REPLICATION_ABORT: + trx_mutex_enter(trx); + } /* Cancel a pending lock request if there are any */ lock_trx_handle_wait(trx); + switch (trx->abort_type) { + case TRX_WSREP_ABORT: + break; + case TRX_SERVER_ABORT: + if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + lock_mutex_exit(); + } + /* fall through */ + case TRX_REPLICATION_ABORT: + trx_mutex_exit(trx); + } } DBUG_VOID_RETURN; diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index e2b9a1671ca..b8446013bc7 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -8087,26 +8087,19 @@ lock_trx_handle_wait( /*=================*/ trx_t* trx) /*!< in/out: trx lock state */ { - dberr_t err; - - lock_mutex_enter(); - - trx_mutex_enter(trx); + ut_ad(lock_mutex_own()); + ut_ad(trx_mutex_own(trx)); if (trx->lock.was_chosen_as_deadlock_victim) { - err = DB_DEADLOCK; - } else if (trx->lock.wait_lock != NULL) { - lock_cancel_waiting_and_release(trx->lock.wait_lock); - err = DB_LOCK_WAIT; - } else { + return DB_DEADLOCK; + } + if (!trx->lock.wait_lock) { /* The lock was probably granted before we got here. */ - err = DB_SUCCESS; + return DB_SUCCESS; } - lock_mutex_exit(); - trx_mutex_exit(trx); - - return(err); + lock_cancel_waiting_and_release(trx->lock.wait_lock); + return DB_LOCK_WAIT; } /*********************************************************************//** diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc index 03ae6822fb7..b81ea60a413 100644 --- a/storage/xtradb/row/row0sel.cc +++ b/storage/xtradb/row/row0sel.cc @@ -4627,7 +4627,11 @@ no_gap_lock: a deadlock and the transaction had to wait then release the lock it is waiting on. */ + lock_mutex_enter(); + trx_mutex_enter(trx); err = lock_trx_handle_wait(trx); + lock_mutex_exit(); + trx_mutex_exit(trx); switch (err) { case DB_SUCCESS: From 7033af9e81a69d75199faa028f8959667f755551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 16 Mar 2018 08:34:12 +0200 Subject: [PATCH 21/22] Conditionally define TRX_WSREP_ABORT --- storage/innobase/handler/ha_innodb.cc | 4 ++++ storage/innobase/include/trx0trx.h | 12 +++++++----- storage/xtradb/handler/ha_innodb.cc | 4 ++++ storage/xtradb/include/trx0trx.h | 12 +++++++----- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 31ea969fa21..7c412344920 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4917,8 +4917,10 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) ut_ad(trx->mysql_thd == thd); switch (trx->abort_type) { +#ifdef WITH_WSREP case TRX_WSREP_ABORT: break; +#endif case TRX_SERVER_ABORT: if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { lock_mutex_enter(); @@ -4930,8 +4932,10 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) /* Cancel a pending lock request if there are any */ lock_trx_handle_wait(trx); switch (trx->abort_type) { +#ifdef WITH_WSREP case TRX_WSREP_ABORT: break; +#endif case TRX_SERVER_ABORT: if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { lock_mutex_exit(); diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 68941363620..fe16b8272b8 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation. +Copyright (c) 2015, 2018, 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 @@ -695,11 +695,13 @@ lock_rec_convert_impl_to_expl()) will access transactions associated to other connections. The locks of transactions are protected by lock_sys->mutex and sometimes by trx->mutex. */ -typedef enum { +enum trx_abort_t { TRX_SERVER_ABORT = 0, - TRX_WSREP_ABORT = 1, - TRX_REPLICATION_ABORT = 2 -} trx_abort_t; +#ifdef WITH_WSREP + TRX_WSREP_ABORT, +#endif + TRX_REPLICATION_ABORT +}; struct trx_t{ ulint magic_n; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 7d550c45356..2b7dc01238c 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -5513,8 +5513,10 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) ut_ad(trx->mysql_thd == thd); switch (trx->abort_type) { +#ifdef WITH_WSREP case TRX_WSREP_ABORT: break; +#endif case TRX_SERVER_ABORT: if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { lock_mutex_enter(); @@ -5526,8 +5528,10 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) /* Cancel a pending lock request if there are any */ lock_trx_handle_wait(trx); switch (trx->abort_type) { +#ifdef WITH_WSREP case TRX_WSREP_ABORT: break; +#endif case TRX_SERVER_ABORT: if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { lock_mutex_exit(); diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h index 5db19b3959a..77afde4c35c 100644 --- a/storage/xtradb/include/trx0trx.h +++ b/storage/xtradb/include/trx0trx.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation +Copyright (c) 2015, 2018, 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 @@ -744,11 +744,13 @@ lock_rec_convert_impl_to_expl()) will access transactions associated to other connections. The locks of transactions are protected by lock_sys->mutex and sometimes by trx->mutex. */ -typedef enum { +enum trx_abort_t { TRX_SERVER_ABORT = 0, - TRX_WSREP_ABORT = 1, - TRX_REPLICATION_ABORT = 2 -} trx_abort_t; +#ifdef WITH_WSREP + TRX_WSREP_ABORT, +#endif + TRX_REPLICATION_ABORT +}; struct trx_t{ ulint magic_n; From 0a534348c75cf435d2017959855de2efa798fd0b Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 15 Mar 2018 15:34:45 +0400 Subject: [PATCH 22/22] MDEV-14265 - RPMLint warning: shared-lib-calls-exit Eliminated last exit() call from libmysqld. --- client/mysql.cc | 6 +----- client/mysql_upgrade.c | 6 ++---- client/mysqladmin.cc | 7 ++----- client/mysqlbinlog.cc | 4 +--- client/mysqlcheck.c | 5 +---- client/mysqldump.c | 3 +-- client/mysqlimport.c | 3 +-- client/mysqlshow.c | 3 +-- client/mysqlslap.c | 6 +----- client/mysqltest.cc | 4 +--- extra/mariabackup/xbcloud.cc | 4 +--- extra/mariabackup/xtrabackup.cc | 12 ++++-------- extra/my_print_defaults.c | 6 ++++-- include/my_default.h | 7 +++++++ mysys/my_default.c | 4 ++-- sql/mysqld.cc | 3 +-- sql/tztime.cc | 4 +--- storage/archive/archive_reader.c | 3 +-- storage/maria/maria_chk.c | 2 +- storage/maria/maria_dump_log.c | 2 +- storage/maria/maria_pack.c | 2 +- storage/maria/maria_read_log.c | 2 +- .../unittest/ma_test_loghandler_multigroup-t.c | 2 +- storage/myisam/myisamchk.c | 4 +--- storage/myisam/myisampack.c | 4 +--- tests/mysql_client_fw.c | 3 +-- tests/mysql_client_test.c | 13 ++----------- tests/thread_test.c | 4 ++-- 28 files changed, 45 insertions(+), 83 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 7973c3c7fc3..0b8be00c542 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1175,11 +1175,7 @@ int main(int argc,char *argv[]) close(stdout_fileno_copy); /* Clean up dup(). */ } - if (load_defaults("my",load_default_groups,&argc,&argv)) - { - my_end(0); - exit(1); - } + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; if ((status.exit_status= get_options(argc, (char **) argv))) mysql_end(-1); diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index cbdd398c1e1..5eb495774ce 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1133,6 +1133,8 @@ int main(int argc, char **argv) char self_name[FN_REFLEN + 1]; MY_INIT(argv[0]); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); + defaults_argv= argv; /* Must be freed by 'free_defaults' */ #if __WIN__ if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0) @@ -1145,10 +1147,6 @@ int main(int argc, char **argv) init_dynamic_string(&conn_args, "", 512, 256)) die("Out of memory"); - if (load_defaults("my", load_default_groups, &argc, &argv)) - die(NULL); - defaults_argv= argv; /* Must be freed by 'free_defaults' */ - if (handle_options(&argc, &argv, my_long_options, get_one_option)) die(NULL); if (debug_info_flag) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 897c2eb41c3..d4d40b0a0f2 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -319,8 +319,7 @@ int main(int argc,char *argv[]) MY_INIT(argv[0]); mysql_init(&mysql); sf_leaking_memory=1; /* don't report memory leaks on early exits */ - if ((error= load_defaults("my",load_default_groups,&argc,&argv))) - goto err1; + load_defaults_or_exit("my", load_default_groups, &argc, &argv); save_argv = argv; /* Save for free_defaults */ if ((error=handle_options(&argc, &argv, my_long_options, get_one_option))) @@ -500,10 +499,8 @@ err2: my_free(shared_memory_base_name); #endif free_defaults(save_argv); -err1: my_end(my_end_arg); - exit(error); - return 0; + return error; } diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index b871a70ef01..9753125dd67 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -2666,9 +2666,7 @@ int main(int argc, char** argv) tzset(); // set tzname init_alloc_root(&s_mem_root, 16384, 0, MYF(0)); - if (load_defaults("my", load_groups, &argc, &argv)) - exit(1); - + load_defaults_or_exit("my", load_groups, &argc, &argv); defaults_argv= argv; if (!(binlog_filter= new Rpl_filter)) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 47cb38751eb..a4410eba8aa 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1165,9 +1165,7 @@ int main(int argc, char **argv) /* ** Check out the args */ - if (load_defaults("my", load_default_groups, &argc, &argv)) - goto end2; - + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv= argv; if (get_options(&argc, &argv)) goto end1; @@ -1243,7 +1241,6 @@ int main(int argc, char **argv) my_free(shared_memory_base_name); mysql_library_end(); free_defaults(defaults_argv); - end2: my_end(my_end_arg); return ret; } /* main */ diff --git a/client/mysqldump.c b/client/mysqldump.c index 5c0ec2a5510..d2348284e31 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -976,8 +976,7 @@ static int get_options(int *argc, char ***argv) opt_net_buffer_length= *mysql_params->p_net_buffer_length; md_result_file= stdout; - if (load_defaults("my",load_default_groups,argc,argv)) - return 1; + load_defaults_or_exit("my", load_default_groups, argc, argv); defaults_argv= *argv; if (my_hash_init(&ignore_table, charset_info, 16, 0, 0, diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 9c84d4a62a6..a9c24e20b0a 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -641,8 +641,7 @@ int main(int argc, char **argv) MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ - if (load_defaults("my",load_default_groups,&argc,&argv)) - return 1; + load_defaults_or_exit("my", load_default_groups, &argc, &argv); /* argv is changed in the program */ argv_to_free= argv; if (get_options(&argc, &argv)) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index f851c15106e..95ee8d697f3 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -71,8 +71,7 @@ int main(int argc, char **argv) static char **defaults_argv; MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ - if (load_defaults("my",load_default_groups,&argc,&argv)) - exit(1); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; get_options(&argc,&argv); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 6a0b214305c..0b88a969bc5 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -325,11 +325,7 @@ int main(int argc, char **argv) MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ - if (load_defaults("my",load_default_groups,&argc,&argv)) - { - my_end(0); - exit(1); - } + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; if (get_options(&argc,&argv)) { diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 2897555da3f..895c837f68b 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7299,9 +7299,7 @@ get_one_option(int optid, const struct my_option *opt, char *argument) int parse_args(int argc, char **argv) { - if (load_defaults("my",load_default_groups,&argc,&argv)) - exit(1); - + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; if ((handle_options(&argc, &argv, my_long_options, get_one_option))) diff --git a/extra/mariabackup/xbcloud.cc b/extra/mariabackup/xbcloud.cc index 56661b03dd0..878b4c81023 100644 --- a/extra/mariabackup/xbcloud.cc +++ b/extra/mariabackup/xbcloud.cc @@ -443,9 +443,7 @@ int parse_args(int argc, char **argv) exit(EXIT_FAILURE); } - if (load_defaults("my", load_default_groups, &argc, &argv)) { - exit(EXIT_FAILURE); - } + load_defaults_or_exit("my", load_default_groups, &argc, &argv); if (handle_options(&argc, &argv, my_long_options, get_one_option)) { exit(EXIT_FAILURE); diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 2228e542dc7..44214b0c207 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -6350,10 +6350,8 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) *argv_client = argv; *argv_server = argv; - if (load_defaults(conf_file, xb_server_default_groups, - &argc_server, argv_server)) { - exit(EXIT_FAILURE); - } + load_defaults_or_exit(conf_file, xb_server_default_groups, + &argc_server, argv_server); int n; for (n = 0; (*argv_server)[n]; n++) {}; @@ -6403,10 +6401,8 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) xb_server_options, xb_get_one_option))) exit(ho_error); - if (load_defaults(conf_file, xb_client_default_groups, - &argc_client, argv_client)) { - exit(EXIT_FAILURE); - } + load_defaults_or_exit(conf_file, xb_client_default_groups, + &argc_client, argv_client); for (n = 0; (*argv_client)[n]; n++) {}; argc_client = n; diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c index 78940e02ca4..07c95a79ddc 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -206,6 +206,9 @@ int main(int argc, char **argv) if ((error= load_defaults(config_file, (const char **) load_default_groups, &count, &arguments))) { + my_end(0); + if (error == 4) + return 0; if (verbose && opt_defaults_file_used) { if (error == 1) @@ -216,8 +219,7 @@ int main(int argc, char **argv) fprintf(stderr, "WARNING: Defaults file '%s' is not a regular file!\n", config_file); } - error= 2; - exit(error); + return 2; } for (argument= arguments+1 ; *argument ; argument++) diff --git a/include/my_default.h b/include/my_default.h index 0ed94b09492..bd3a21f03a8 100644 --- a/include/my_default.h +++ b/include/my_default.h @@ -45,6 +45,13 @@ extern void free_defaults(char **argv); extern void my_print_default_files(const char *conf_file); extern void print_defaults(const char *conf_file, const char **groups); + +/** Simplify load_defaults() common use */ +#define load_defaults_or_exit(A, B, C, D) switch (load_defaults(A, B, C, D)) { \ + case 0: break; \ + case 4: my_end(0); exit(0); \ + default: my_end(0); exit(1); } + C_MODE_END #endif /* MY_DEFAULT_INCLUDED */ diff --git a/mysys/my_default.c b/mysys/my_default.c index 2358aed8f3b..9209c6869fc 100644 --- a/mysys/my_default.c +++ b/mysys/my_default.c @@ -631,7 +631,7 @@ int my_load_defaults(const char *conf_file, const char **groups, if (!my_getopt_is_args_separator((*argv)[i])) /* skip arguments separator */ printf("%s ", (*argv)[i]); puts(""); - exit(0); + DBUG_RETURN(4); } if (default_directories) @@ -641,7 +641,7 @@ int my_load_defaults(const char *conf_file, const char **groups, err: fprintf(stderr,"Fatal error in defaults handling. Program aborted\n"); - return 2; + DBUG_RETURN(2); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3cb8e41f94e..4f57d6d1910 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5511,8 +5511,7 @@ int mysqld_main(int argc, char **argv) orig_argc= argc; orig_argv= argv; my_getopt_use_args_separator= TRUE; - if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv)) - return 1; + load_defaults_or_exit(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv); my_getopt_use_args_separator= FALSE; defaults_argc= argc; defaults_argv= argv; diff --git a/sql/tztime.cc b/sql/tztime.cc index bed5f416f13..7df2ad7d0e8 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2689,9 +2689,7 @@ main(int argc, char **argv) char **default_argv; MY_INIT(argv[0]); - if (load_defaults("my",load_default_groups,&argc,&argv)) - exit(1); - + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; if ((handle_options(&argc, &argv, my_long_options, get_one_option))) diff --git a/storage/archive/archive_reader.c b/storage/archive/archive_reader.c index 1b15fa16ce4..e87bc70ade4 100644 --- a/storage/archive/archive_reader.c +++ b/storage/archive/archive_reader.c @@ -408,8 +408,7 @@ static void print_version(void) static void get_options(int *argc, char ***argv) { - if (load_defaults("my", load_default_groups, argc, argv)) - exit(1); + load_defaults_or_exit("my", load_default_groups, argc, argv); default_argv= *argv; handle_options(argc, argv, my_long_options, get_one_option); diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index aa01f4cd895..b47f1b8c824 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -895,7 +895,7 @@ static void get_options(register int *argc,register char ***argv) { int ho_error; - load_defaults("my", load_default_groups, argc, argv); + load_defaults_or_exit("my", load_default_groups, argc, argv); default_argv= *argv; check_param.testflag= T_UPDATE_STATE; if (isatty(fileno(stdout))) diff --git a/storage/maria/maria_dump_log.c b/storage/maria/maria_dump_log.c index 42c694bf1bf..3570dede80e 100644 --- a/storage/maria/maria_dump_log.c +++ b/storage/maria/maria_dump_log.c @@ -133,7 +133,7 @@ int main(int argc, char **argv) uchar buffer[TRANSLOG_PAGE_SIZE]; MY_INIT(argv[0]); - load_defaults("my", load_default_groups, &argc, &argv); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc, &argv); diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c index 814c50e1db8..28b4ff4cfc7 100644 --- a/storage/maria/maria_pack.c +++ b/storage/maria/maria_pack.c @@ -208,7 +208,7 @@ int main(int argc, char **argv) char **default_argv; MY_INIT(argv[0]); - load_defaults("my",load_default_groups,&argc,&argv); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc,&argv); maria_init(); diff --git a/storage/maria/maria_read_log.c b/storage/maria/maria_read_log.c index a0724b2199b..d0cf7521e9b 100644 --- a/storage/maria/maria_read_log.c +++ b/storage/maria/maria_read_log.c @@ -47,7 +47,7 @@ int main(int argc, char **argv) maria_data_root= (char *)"."; sf_leaking_memory=1; /* don't report memory leaks on early exits */ - load_defaults("my", load_default_groups, &argc, &argv); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc, &argv); diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c index 1ea31d228e1..dc7e0c79f87 100644 --- a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c @@ -256,7 +256,7 @@ int main(int argc __attribute__((unused)), char *argv[]) #endif long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2); - load_defaults("my", load_default_groups, &argc, &argv); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc, &argv); diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index edbe235e190..dfff5720847 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -753,9 +753,7 @@ static void get_options(register int *argc,register char ***argv) { int ho_error; - if (load_defaults("my", load_default_groups, argc, argv)) - exit(1); - + load_defaults_or_exit("my", load_default_groups, argc, argv); default_argv= *argv; if (isatty(fileno(stdout))) check_param.testflag|=T_WRITE_LOOP; diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index 966edc877cd..bb9f59f86f7 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -209,9 +209,7 @@ int main(int argc, char **argv) char **default_argv; MY_INIT(argv[0]); - if (load_defaults("my",load_default_groups,&argc,&argv)) - exit(1); - + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc,&argv); diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c index b7211989f1f..71fb3894b3c 100644 --- a/tests/mysql_client_fw.c +++ b/tests/mysql_client_fw.c @@ -1409,8 +1409,7 @@ int main(int argc, char **argv) for (i= 0; i < argc; i++) original_argv[i]= strdup(argv[i]); - if (load_defaults("my", client_test_load_default_groups, &argc, &argv)) - exit(1); + load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv); get_options(&argc, &argv); /* Set main opt_count. */ diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index c367e7ca35d..b63bcbaa037 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -7095,11 +7095,7 @@ static void test_embedded_start_stop() MY_INIT(argv[0]); /* Load the client defaults from the .cnf file[s]. */ - if (load_defaults("my", client_test_load_default_groups, &argc, &argv)) - { - myerror("load_defaults failed"); - exit(1); - } + load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv); /* Parse the options (including the ones given from defaults files). */ get_options(&argc, &argv); @@ -7147,12 +7143,7 @@ static void test_embedded_start_stop() MY_INIT(argv[0]); - if (load_defaults("my", client_test_load_default_groups, &argc, &argv)) - { - myerror("load_defaults failed \n "); - exit(1); - } - + load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv); get_options(&argc, &argv); /* Must start the main embedded server again after the test. */ diff --git a/tests/thread_test.c b/tests/thread_test.c index bf0fb8ea2c0..38e453e9cb8 100644 --- a/tests/thread_test.c +++ b/tests/thread_test.c @@ -168,8 +168,8 @@ static void get_options(int argc, char **argv) { int ho_error; - if ((ho_error= load_defaults("my",load_default_groups,&argc,&argv)) || - (ho_error= handle_options(&argc, &argv, my_long_options, get_one_option))) + load_defaults_or_exit("my", load_default_groups, &argc, &argv); + if ((ho_error= handle_options(&argc, &argv, my_long_options, get_one_option))) exit(ho_error); free_defaults(argv);