Skip to content

Commit

Permalink
MDEV-32549 Cluster inconsistent after SAVEPOINT is rolled back
Browse files Browse the repository at this point in the history
Attempting to set a SAVEPOINT when one of the involved storage engines
does not support savepoints, raises an error, and results in statement
rollback. If Galera is enabled with binlog emulation, the above
scenario was not handled correctly, and resulted in cluster wide
inconsistency.

The problem was in wsrep_register_binlog_handler(), which is called
towards the beginning of SAVEPOINT execution. This function is
supposed to mark the beginning of statement position in trx cache
through `set_prev_position()`. However, it did so only on condition
that `get_prev_position()` returns `MY_OFF_T_UNDEF`.
This before statement position is typically reset to undefined at the
end of statement in `binlog_commit()` / `binlog_rollback()`.
However that's not the case with Galera and binlog emulation, for
which binlog commit / rollback hooks are not called due to the
optimization that avoids internal 2PC (MDEV-16509).

Signed-off-by: Julius Goryavsky <julius.goryavsky@mariadb.com>
  • Loading branch information
sciascid authored and sysprg committed Dec 22, 2023
1 parent c89f769 commit 362c095
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 6 deletions.
24 changes: 24 additions & 0 deletions mysql-test/suite/galera/r/MDEV-32549.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
connection node_2;
connection node_1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) engine=innodb;
CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) engine=aria;
START TRANSACTION;
INSERT INTO t1 VALUES (1);
SELECT * FROM t2;
f1
SAVEPOINT s1;
ERROR 42000: The storage engine for the table doesn't support SAVEPOINT
INSERT INTO t1 VALUES (2);
COMMIT;
connection node_1;
SELECT * FROM t1;
f1
1
2
connection node_2;
SELECT * FROM t1;
f1
1
2
connection node_1;
DROP TABLE t1,t2;
28 changes: 28 additions & 0 deletions mysql-test/suite/galera/t/MDEV-32549.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# MDEV-32549: Cluster is inconsitent after savepoint
# statement is rolled back
#
--source include/galera_cluster.inc

CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) engine=innodb;
CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) engine=aria;

START TRANSACTION;
INSERT INTO t1 VALUES (1);
SELECT * FROM t2;
--error ER_CHECK_NOT_IMPLEMENTED
SAVEPOINT s1;
INSERT INTO t1 VALUES (2);
COMMIT;

--connection node_1
SELECT * FROM t1;

# If bug is present: only the second INSERT
# is replicated, causing an inconsistent
# cluster.
--connection node_2
SELECT * FROM t1;

--connection node_1
DROP TABLE t1,t2;
9 changes: 3 additions & 6 deletions sql/log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11257,12 +11257,9 @@ void wsrep_register_binlog_handler(THD *thd, bool trx)
/*
Set an implicit savepoint in order to be able to truncate a trx-cache.
*/
if (cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF)
{
my_off_t pos= 0;
binlog_trans_log_savepos(thd, &pos);
cache_mngr->trx_cache.set_prev_position(pos);
}
my_off_t pos= 0;
binlog_trans_log_savepos(thd, &pos);
cache_mngr->trx_cache.set_prev_position(pos);

/*
Set callbacks in order to be able to call commmit or rollback.
Expand Down

0 comments on commit 362c095

Please sign in to comment.