diff options
| author | Aleksey Midenkov <midenok@gmail.com> | 2022-12-10 14:25:55 +0300 |
|---|---|---|
| committer | Aleksey Midenkov <midenok@gmail.com> | 2023-01-17 12:34:44 +0300 |
| commit | 8022a6fff7bd0dca33ed23d13a2a02e8b1080434 (patch) | |
| tree | 1d2b3c883072c21bea9d2717366a8ec40f3ebafa | |
| parent | 6f17c5a6c4be698b5f86debfa1855176931dae6a (diff) | |
| download | mariadb-git-8022a6fff7bd0dca33ed23d13a2a02e8b1080434.tar.gz | |
MDEV-29824 Galera crashes when running CoR for a locked table
locked_tables_list.reopen_tables() does external_lock() which in
InnoDB opens new transaction. The previous commit in send_eof() sets
s_committed state in wsrep. The new transaction didn't change that
state yet and on commit s_committed state is unexpected.
The fix is similar to MDEV-22222 (2b8b7394a12): we update wsrep state
before starting new transaction. The better wsrep fix would track the
state properly when the new transaction is started.
| -rw-r--r-- | mysql-test/suite/galera/r/create.result | 9 | ||||
| -rw-r--r-- | mysql-test/suite/galera/t/create.test | 10 | ||||
| -rw-r--r-- | sql/sql_table.cc | 17 |
3 files changed, 36 insertions, 0 deletions
diff --git a/mysql-test/suite/galera/r/create.result b/mysql-test/suite/galera/r/create.result index cd0380b206d..b434052727f 100644 --- a/mysql-test/suite/galera/r/create.result +++ b/mysql-test/suite/galera/r/create.result @@ -91,6 +91,15 @@ c1 SELECT * FROM t2; c1 DROP TABLE t1, t2; +# +# MDEV-29824 Galera crashes when running CoR for a locked table +# +connection node_1; +SET autocommit=0; +CREATE TABLE t0 (x INT,y INT); +LOCK TABLES t0 WRITE; +CREATE OR REPLACE TABLE t0 SELECT 1; +DROP TABLE t0; disconnect node_2; disconnect node_1; # End of tests diff --git a/mysql-test/suite/galera/t/create.test b/mysql-test/suite/galera/t/create.test index 96a6640c21f..7ebee7e2e47 100644 --- a/mysql-test/suite/galera/t/create.test +++ b/mysql-test/suite/galera/t/create.test @@ -84,6 +84,16 @@ SELECT * FROM t2; # Cleanup DROP TABLE t1, t2; +--echo # +--echo # MDEV-29824 Galera crashes when running CoR for a locked table +--echo # +--connection node_1 +SET autocommit=0; +CREATE TABLE t0 (x INT,y INT); +LOCK TABLES t0 WRITE; +CREATE OR REPLACE TABLE t0 SELECT 1; +DROP TABLE t0; + --source include/galera_end.inc --echo # End of tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4905bb18801..cbe0707ec83 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -60,6 +60,9 @@ #include "debug.h" // debug_crash_here() #include <algorithm> #include "wsrep_mysqld.h" +#ifdef WITH_WSREP +#include "wsrep_trans_observer.h" /* wsrep transaction hooks */ +#endif #include "rpl_mi.h" #include "rpl_rli.h" #include "log.h" @@ -4627,6 +4630,20 @@ bool HA_CREATE_INFO::finalize_locked_tables(THD *thd, bool operation_failed) DBUG_ASSERT(pos_in_locked_tables); DBUG_ASSERT(thd->locked_tables_mode); DBUG_ASSERT(thd->variables.option_bits & OPTION_TABLE_LOCK); + +#ifdef WITH_WSREP + /* + finalize_locked_tables() is done after commit. Cleanup wsrep transaction + state (s_committed) before reopen_tables() starts new transaction. + */ + if (WSREP_NNULL(thd) && wsrep_thd_is_local(thd) && + wsrep_after_statement(thd)) + { + thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); + return true; + } +#endif + if (!operation_failed) { /* |
