Commit c3707691 authored by Daniele Sciascia's avatar Daniele Sciascia Committed by Jan Lindström

MDEV-25718 Assertion `transaction.is_streaming()' failed

* Update wsrep-lib which contains the fix
* Add deterministic test case that reproduces the assertion
Reviewed-by: default avatarJan Lindström <jan.lindstrom@mariadb.com>
parent 865e5b64
connection node_2;
connection node_1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
connection node_1;
SET SESSION wsrep_trx_fragment_size = 1;
START TRANSACTION;
SET debug_sync = "ha_write_row_end SIGNAL write_row_end WAIT_FOR write_row_continue";
INSERT INTO t1 VALUES (1);;
connect node_ctrl, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_ctrl;
SET debug_sync = "now WAIT_FOR write_row_end";
SET GLOBAL debug_dbug = '+d,wsrep_streaming_rollback';
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_1a;
TRUNCATE TABLE t1;;
connection node_ctrl;
SET SESSION debug_sync = "now WAIT_FOR wsrep_streaming_rollback_reached";
SET SESSION wsrep_sync_wait = 0;
SET debug_sync = "now SIGNAL write_row_continue";
SET SESSION debug_sync = "now SIGNAL wsrep_streaming_rollback_continue";
connection node_1a;
connection node_1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
connection node_ctrl;
SET GLOBAL debug_dbug = "";
SET DEBUG_SYNC = 'RESET';
DROP TABLE t1;
# Set thread-handling as a workaround to avoid MDEV-26528.
# The file can be removed once fixed.
!include ../galera_2nodes.cnf
[mysqld.1]
thread-handling=pool-of-threads
#
# MDEV-25718 Assertion `transaction.is_streaming()' failed in
# void wsrep::transaction::adopt()
#
--source include/galera_cluster.inc
--source include/have_debug_sync.inc
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
#
# Start a SR transaction and block it after it has replicated
# a fragment. Notice the transaction is still in executing state.
#
--connection node_1
SET SESSION wsrep_trx_fragment_size = 1;
START TRANSACTION;
SET debug_sync = "ha_write_row_end SIGNAL write_row_end WAIT_FOR write_row_continue";
--send INSERT INTO t1 VALUES (1);
--connect node_ctrl, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connection node_ctrl
SET debug_sync = "now WAIT_FOR write_row_end";
SET GLOBAL debug_dbug = '+d,wsrep_streaming_rollback';
#
# Issue a conflicting DDL, that will block in streaming_rollback
# sync point.
#
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connection node_1a
--send TRUNCATE TABLE t1;
--connection node_ctrl
SET SESSION debug_sync = "now WAIT_FOR wsrep_streaming_rollback_reached";
#
# Let the INSERT continue. If bug is present will be able to go through
# before_rollback() / streaming_rollback() and clear its streaming context,
# which causes the assertion to trigger in BF aborter.
#
SET SESSION wsrep_sync_wait = 0;
SET debug_sync = "now SIGNAL write_row_continue";
# Let's give the INSERT some time, to make sure it does rollback
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO = "INSERT INTO t1 VALUES (1)" AND STATE = "Freeing items";
--source include/wait_condition.inc
# Resume the DDL in streaming_rollback
SET SESSION debug_sync = "now SIGNAL wsrep_streaming_rollback_continue";
--connection node_1a
--reap
--connection node_1
--error ER_LOCK_DEADLOCK
--reap
# Cleanup
--connection node_ctrl
SET GLOBAL debug_dbug = "";
SET DEBUG_SYNC = 'RESET';
DROP TABLE t1;
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "sql_class.h" /* system variables */ #include "sql_class.h" /* system variables */
#include "transaction.h" /* trans_xxx */ #include "transaction.h" /* trans_xxx */
#include "sql_base.h" /* close_thread_tables */ #include "sql_base.h" /* close_thread_tables */
#include "debug_sync.h"
static void init_service_thd(THD* thd, char* thread_stack) static void init_service_thd(THD* thd, char* thread_stack)
{ {
...@@ -388,6 +389,16 @@ int Wsrep_server_service::wait_committing_transactions(int timeout) ...@@ -388,6 +389,16 @@ int Wsrep_server_service::wait_committing_transactions(int timeout)
return wsrep_wait_committing_connections_close(timeout); return wsrep_wait_committing_connections_close(timeout);
} }
void Wsrep_server_service::debug_sync(const char*) void Wsrep_server_service::debug_sync(const char* sync_point)
{ {
DBUG_EXECUTE_IF(sync_point, {
std::stringstream dbug_action;
dbug_action << "now "
<< "SIGNAL " << sync_point << "_reached "
<< "WAIT_FOR " << sync_point << "_continue";
const std::string& action(dbug_action.str());
DBUG_ASSERT(!debug_sync_set_action(current_thd,
action.c_str(),
action.length()));
};);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment