Skip to content

Commit 7694880

Browse files
committed
MDEV-36554 Assertion `is_wsrep() == wsrep_on(mysql_thd)' failed
in void trx_t::commit_in_memory(const mtr_t*) This bug fix prevents debug assertion failure when Galera feature retry applying is enabled. This patch introduces also a general mechanism for temporarily disabling some debug assertions in InnoDB code.
1 parent e3d0315 commit 7694880

File tree

7 files changed

+110
-2
lines changed

7 files changed

+110
-2
lines changed

include/mysql/service_wsrep.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ enum Wsrep_service_key_type
88
WSREP_SERVICE_KEY_UPDATE,
99
WSREP_SERVICE_KEY_EXCLUSIVE
1010
};
11+
12+
13+
/* the bits in the bitmask for disabling temporarily some asserts */
14+
#define WSREP_ASSERT_INNODB_TRX 1
15+
1116

1217
#if (defined (MYSQL_DYNAMIC_PLUGIN) && defined(MYSQL_SERVICE_WSREP_DYNAMIC_INCLUDED)) || (!defined(MYSQL_DYNAMIC_PLUGIN) && defined(MYSQL_SERVICE_WSREP_STATIC_INCLUDED))
1318

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
connection node_2;
2+
connection node_1;
3+
CALL mtr.add_suppression("Event .* Update_rows.* apply failed");
4+
CALL mtr.add_suppression("mariadbd: Can't find record in 't1'");
5+
CALL mtr.add_suppression("Failed to apply write set.*");
6+
CALL mtr.add_suppression("Inconsistency detected");
7+
connection node_1;
8+
CREATE TABLE t1 (f1 INTEGER);
9+
INSERT INTO t1 VALUES (1);
10+
connection node_2;
11+
SET SESSION wsrep_on = OFF;
12+
DELETE FROM t1;
13+
SET SESSION wsrep_on = ON;
14+
SET GLOBAL wsrep_applier_retry_count=1;
15+
connection node_1;
16+
UPDATE t1 SET f1 = f1 + 1;
17+
connection node_2;
18+
Shutting down server ...
19+
SET wsrep_on=OFF;
20+
Restarting server ...
21+
connection node_1;
22+
SET wsrep_sync_wait=0;
23+
connection node_1;
24+
SET GLOBAL wsrep_applier_retry_count = 0;
25+
DROP TABLE t1;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#
2+
# Test for MDEV-36554
3+
#
4+
5+
--source include/galera_cluster.inc
6+
7+
CALL mtr.add_suppression("Event .* Update_rows.* apply failed");
8+
CALL mtr.add_suppression("mariadbd: Can't find record in 't1'");
9+
CALL mtr.add_suppression("Failed to apply write set.*");
10+
CALL mtr.add_suppression("Inconsistency detected");
11+
12+
--connection node_1
13+
CREATE TABLE t1 (f1 INTEGER);
14+
INSERT INTO t1 VALUES (1);
15+
16+
--connection node_2
17+
SET SESSION wsrep_on = OFF;
18+
DELETE FROM t1;
19+
SET SESSION wsrep_on = ON;
20+
SET GLOBAL wsrep_applier_retry_count=1;
21+
22+
--connection node_1
23+
UPDATE t1 SET f1 = f1 + 1;
24+
25+
# restart node 2
26+
--connection node_2
27+
--echo Shutting down server ...
28+
SET wsrep_on=OFF;
29+
--source include/shutdown_mysqld.inc
30+
--source include/wait_until_disconnected.inc
31+
--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat
32+
--echo Restarting server ...
33+
--source include/start_mysqld.inc
34+
35+
# wait till node 2 is back in the cluster
36+
--connection node_1
37+
SET wsrep_sync_wait=0;
38+
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_size'
39+
--source include/wait_condition.inc
40+
41+
# cleanup
42+
--connection node_1
43+
SET GLOBAL wsrep_applier_retry_count = 0;
44+
DROP TABLE t1;
45+

sql/sql_class.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
762762
wsrep_affected_rows(0),
763763
wsrep_has_ignored_error(false),
764764
wsrep_was_on(false),
765+
wsrep_assert_bitmask(0),
765766
wsrep_ignore_table(false),
766767
wsrep_aborter(0),
767768
wsrep_delayed_BF_abort(false),
@@ -8659,3 +8660,20 @@ LEX_CSTRING make_string(THD *thd, const char *start_ptr,
86598660
size_t length= end_ptr - start_ptr;
86608661
return {strmake_root(thd->mem_root, start_ptr, length), length};
86618662
}
8663+
8664+
8665+
#ifdef WITH_WSREP
8666+
void wsrep_set_assert(THD *thd, uint64 assert, bool is_disabled)
8667+
{
8668+
if (is_disabled) {
8669+
thd->wsrep_assert_bitmask |= assert;
8670+
} else {
8671+
thd->wsrep_assert_bitmask &= ~assert;
8672+
}
8673+
}
8674+
8675+
bool wsrep_get_assert(THD *thd, uint64 assert)
8676+
{
8677+
return (thd->wsrep_assert_bitmask & assert ? true: false);
8678+
}
8679+
#endif /* WITH_WSREP */

sql/sql_class.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5682,6 +5682,7 @@ class THD: public THD_count, /* this must be first */
56825682
bool wsrep_has_ignored_error;
56835683
/* true if wsrep_on was ON in last wsrep_on_update */
56845684
bool wsrep_was_on;
5685+
uint64 wsrep_assert_bitmask;
56855686

56865687
/*
56875688
When enabled, do not replicate/binlog updates from the current table that's
@@ -5720,7 +5721,6 @@ class THD: public THD_count, /* this must be first */
57205721
return m_wsrep_client_state.transaction().id().get();
57215722
}
57225723

5723-
57245724
/*
57255725
Set next trx id
57265726
*/
@@ -8522,5 +8522,11 @@ LEX_CSTRING make_string(THD *thd, const char *start_ptr,
85228522

85238523
#include "deprecation.h"
85248524

8525+
8526+
#ifdef WITH_WSREP
8527+
extern void wsrep_set_assert(THD* thd, uint64 assert, bool is_disabled);
8528+
extern bool wsrep_get_assert(THD* thd, uint64 assert);
8529+
#endif
8530+
85258531
#endif /* MYSQL_SERVER */
85268532
#endif /* SQL_CLASS_INCLUDED */

sql/wsrep_applier.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,14 @@ int wsrep_apply_events(THD* thd,
292292

293293
/* rollback to savepoint without telling Wsrep-lib */
294294
thd->variables.wsrep_on = false;
295+
wsrep_set_assert(thd, true, WSREP_ASSERT_INNODB_TRX);
295296
if (FALSE != trans_rollback_to_savepoint(thd, savepoint)) {
296297
thd->variables.wsrep_on = true;
298+
wsrep_set_assert(thd, false, WSREP_ASSERT_INNODB_TRX);
297299
break;
298300
}
299301
thd->variables.wsrep_on = true;
302+
wsrep_set_assert(thd, false, WSREP_ASSERT_INNODB_TRX);
300303

301304
/* reset THD object for retry */
302305
thd->clear_error();

storage/innobase/trx/trx0trx.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,10 @@ ATTRIBUTE_NOINLINE static void trx_commit_cleanup(trx_undo_t *&undo)
13821382
undo= nullptr;
13831383
}
13841384

1385+
1386+
extern bool wsrep_get_assert(THD *thd, uint64 assert);
1387+
1388+
13851389
TRANSACTIONAL_INLINE inline void trx_t::commit_in_memory(const mtr_t *mtr)
13861390
{
13871391
/* We already detached from rseg in write_serialisation_history() */
@@ -1501,7 +1505,9 @@ TRANSACTIONAL_INLINE inline void trx_t::commit_in_memory(const mtr_t *mtr)
15011505
trx_finalize_for_fts(this, undo_no != 0);
15021506

15031507
#ifdef WITH_WSREP
1504-
ut_ad(is_wsrep() == wsrep_on(mysql_thd));
1508+
if (!mysql_thd || !wsrep_get_assert(mysql_thd, WSREP_ASSERT_INNODB_TRX)) {
1509+
ut_ad(is_wsrep() == wsrep_on(mysql_thd));
1510+
}
15051511

15061512
/* Serialization history has been written and the transaction is
15071513
committed in memory, which makes this commit ordered. Release commit

0 commit comments

Comments
 (0)