Skip to content

MDEV-36554 Assertion `is_wsrep() == wsrep_on(mysql_thd)' failed #508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: 11.4-retry-applying
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions include/mysql/service_wsrep.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ enum Wsrep_service_key_type
WSREP_SERVICE_KEY_UPDATE,
WSREP_SERVICE_KEY_EXCLUSIVE
};


/* the bits in the bitmask for disabling temporarily some asserts */
#define WSREP_ASSERT_INNODB_TRX 1


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

Expand Down Expand Up @@ -64,6 +69,7 @@ extern struct wsrep_service_st {
bool (*wsrep_thd_ignore_table_func)(MYSQL_THD thd);
long long (*wsrep_thd_trx_seqno_func)(const MYSQL_THD thd);
my_bool (*wsrep_thd_is_aborting_func)(const MYSQL_THD thd);
my_bool (*wsrep_thd_in_rollback_func)(const THD *thd);
void (*wsrep_set_data_home_dir_func)(const char *data_dir);
my_bool (*wsrep_thd_is_BF_func)(const MYSQL_THD thd, my_bool sync);
my_bool (*wsrep_thd_is_local_func)(const MYSQL_THD thd);
Expand Down Expand Up @@ -123,6 +129,7 @@ extern struct wsrep_service_st {
#define wsrep_set_data_home_dir(A) wsrep_service->wsrep_set_data_home_dir_func(A)
#define wsrep_thd_is_BF(T,S) wsrep_service->wsrep_thd_is_BF_func(T,S)
#define wsrep_thd_is_aborting(T) wsrep_service->wsrep_thd_is_aborting_func(T)
#define wsrep_thd_in_rollback_func(T) wsrep_service->wsrep_thd_in_rollback_func(T)
#define wsrep_thd_is_local(T) wsrep_service->wsrep_thd_is_local_func(T)
#define wsrep_thd_self_abort(T) wsrep_service->wsrep_thd_self_abort_func(T)
#define wsrep_thd_append_key(T,W,N,K) wsrep_service->wsrep_thd_append_key_func(T,W,N,K)
Expand Down Expand Up @@ -225,6 +232,8 @@ extern "C" my_bool wsrep_thd_order_before(const MYSQL_THD left, const MYSQL_THD
extern "C" my_bool wsrep_thd_skip_locking(const MYSQL_THD thd);
/* Return true if thd is aborting */
extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd);
/* Return true if thd is a WSREP applier rolling back a transaction locally */
extern "C" my_bool wsrep_thd_in_rollback(const MYSQL_THD thd);

struct wsrep_key;
struct wsrep_key_array;
Expand Down
25 changes: 25 additions & 0 deletions mysql-test/suite/galera/r/mdev-36554.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
connection node_2;
connection node_1;
CALL mtr.add_suppression("Event .* Update_rows.* apply failed");
CALL mtr.add_suppression("mariadbd: Can't find record in 't1'");
CALL mtr.add_suppression("Failed to apply write set.*");
CALL mtr.add_suppression("Inconsistency detected");
connection node_1;
CREATE TABLE t1 (f1 INTEGER);
INSERT INTO t1 VALUES (1);
connection node_2;
SET SESSION wsrep_on = OFF;
DELETE FROM t1;
SET SESSION wsrep_on = ON;
SET GLOBAL wsrep_applier_retry_count=1;
connection node_1;
UPDATE t1 SET f1 = f1 + 1;
connection node_2;
Shutting down server ...
SET wsrep_on=OFF;
Restarting server ...
connection node_1;
SET wsrep_sync_wait=0;
connection node_1;
SET GLOBAL wsrep_applier_retry_count = 0;
DROP TABLE t1;
45 changes: 45 additions & 0 deletions mysql-test/suite/galera/t/mdev-36554.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#
# Test for MDEV-36554
#

--source include/galera_cluster.inc

CALL mtr.add_suppression("Event .* Update_rows.* apply failed");
CALL mtr.add_suppression("mariadbd: Can't find record in 't1'");
CALL mtr.add_suppression("Failed to apply write set.*");
CALL mtr.add_suppression("Inconsistency detected");

--connection node_1
CREATE TABLE t1 (f1 INTEGER);
INSERT INTO t1 VALUES (1);

--connection node_2
SET SESSION wsrep_on = OFF;
DELETE FROM t1;
SET SESSION wsrep_on = ON;
SET GLOBAL wsrep_applier_retry_count=1;

--connection node_1
UPDATE t1 SET f1 = f1 + 1;

# restart node 2
--connection node_2
--echo Shutting down server ...
SET wsrep_on=OFF;
--source include/shutdown_mysqld.inc
--source include/wait_until_disconnected.inc
--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat
--echo Restarting server ...
--source include/start_mysqld.inc

# wait till node 2 is back in the cluster
--connection node_1
SET wsrep_sync_wait=0;
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_size'
--source include/wait_condition.inc

# cleanup
--connection node_1
SET GLOBAL wsrep_applier_retry_count = 0;
DROP TABLE t1;

16 changes: 16 additions & 0 deletions sql/service_wsrep.cc
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,22 @@ extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd)
return false;
}

/** Check if a wsrep applier is rolling back a transaction locally.

This function is used for notifying InnoDB routines that this thread
is rolling back a wsrep transaction locally.

@param thd thread handle

@return true if wsrep applier is rolling back a transaction locally
@return false otherwise

*/
extern "C" my_bool wsrep_thd_in_rollback(const THD *thd)
{
return thd->wsrep_applier_is_in_rollback();
}

static inline enum wsrep::key::type
map_key_type(enum Wsrep_service_key_type type)
{
Expand Down
1 change: 1 addition & 0 deletions sql/sql_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
,
wsrep_applier(is_wsrep_applier),
wsrep_applier_closing(false),
wsrep_applier_in_rollback(false),
wsrep_client_thread(false),
wsrep_retry_counter(0),
wsrep_PA_safe(true),
Expand Down
5 changes: 4 additions & 1 deletion sql/sql_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -5641,6 +5641,8 @@ class THD: public THD_count, /* this must be first */
#ifdef WITH_WSREP
bool wsrep_applier; /* dedicated slave applier thread */
bool wsrep_applier_closing; /* applier marked to close */
bool wsrep_applier_in_rollback; /* applier is rolling
back a transaction */
bool wsrep_client_thread; /* to identify client threads*/
query_id_t wsrep_last_query_id;
XID wsrep_xid;
Expand Down Expand Up @@ -5720,7 +5722,6 @@ class THD: public THD_count, /* this must be first */
return m_wsrep_client_state.transaction().id().get();
}


/*
Set next trx id
*/
Expand Down Expand Up @@ -5760,6 +5761,8 @@ class THD: public THD_count, /* this must be first */
Wsrep_applier_service* wsrep_applier_service;
/* wait_for_commit struct for binlog group commit */
wait_for_commit wsrep_wfc;
bool wsrep_applier_is_in_rollback() const
{ return wsrep_applier_in_rollback; }
#endif /* WITH_WSREP */

/* Handling of timeouts for commands */
Expand Down
1 change: 1 addition & 0 deletions sql/sql_plugin_services.inl
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ static struct wsrep_service_st wsrep_handler = {
wsrep_thd_ignore_table,
wsrep_thd_trx_seqno,
wsrep_thd_is_aborting,
wsrep_thd_in_rollback,
wsrep_set_data_home_dir,
wsrep_thd_is_BF,
wsrep_thd_is_local,
Expand Down
3 changes: 3 additions & 0 deletions sql/wsrep_applier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,14 @@ int wsrep_apply_events(THD* thd,

/* rollback to savepoint without telling Wsrep-lib */
thd->variables.wsrep_on = false;
thd->wsrep_applier_in_rollback= true;
if (FALSE != trans_rollback_to_savepoint(thd, savepoint)) {
thd->variables.wsrep_on = true;
thd->wsrep_applier_in_rollback= false;
break;
}
thd->variables.wsrep_on = true;
thd->wsrep_applier_in_rollback= false;

/* reset THD object for retry */
thd->clear_error();
Expand Down
3 changes: 3 additions & 0 deletions sql/wsrep_dummy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ long long wsrep_thd_trx_seqno(const THD *)
my_bool wsrep_thd_is_aborting(const THD *)
{ return 0; }

my_bool wsrep_thd_in_rollback(const THD *)
{ return 0; }

void wsrep_set_data_home_dir(const char *)
{ }

Expand Down
6 changes: 5 additions & 1 deletion storage/innobase/trx/trx0trx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1501,7 +1501,11 @@ TRANSACTIONAL_INLINE inline void trx_t::commit_in_memory(const mtr_t *mtr)
trx_finalize_for_fts(this, undo_no != 0);

#ifdef WITH_WSREP
ut_ad(is_wsrep() == wsrep_on(mysql_thd));
/* Assert that any transaction which is started as a wsrep
transaction, also commits or rolls back as a wsrep
transaction. Wsrep applier may turn wsrep off temporarily for
rollback when the applying of wsrep transactions is retried. */
ut_ad(is_wsrep() == wsrep_on(mysql_thd) || wsrep_thd_in_rollback(mysql_thd));

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