Skip to content

Commit 2d16452

Browse files
mkaruzaJan Lindström
authored andcommitted
MDEV-22021: Galera database could get inconsistent with rollback to savepoint
When binlog is disabled, WSREP will not behave correctly when SAVEPOINT ROLLBACK is executed since we don't register handlers for such case. Fixed by registering WSREP handlerton for SAVEPOINT related commands.
1 parent 5001487 commit 2d16452

File tree

10 files changed

+133
-40
lines changed

10 files changed

+133
-40
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
2+
START TRANSACTION;
3+
INSERT INTO t1 VALUES (1);
4+
SAVEPOINT sp1;
5+
INSERT INTO t1 VALUES (2);
6+
ROLLBACK TO SAVEPOINT sp1;
7+
COMMIT;
8+
SELECT COUNT(*) = 1 FROM t1;
9+
COUNT(*) = 1
10+
1
11+
connection node_2;
12+
SELECT COUNT(*) = 1 FROM t1;
13+
COUNT(*) = 1
14+
1
15+
connection node_1;
16+
DELETE FROM t1;
17+
START TRANSACTION;
18+
SAVEPOINT sp1;
19+
INSERT INTO t1 VALUES (1);
20+
SAVEPOINT sp2;
21+
INSERT INTO t1 VALUES (2);
22+
ROLLBACK TO SAVEPOINT sp2;
23+
ROLLBACK TO SAVEPOINT sp1;
24+
COMMIT;
25+
SELECT COUNT(*) = 0 FROM t1;
26+
COUNT(*) = 0
27+
1
28+
connection node_2;
29+
SELECT COUNT(*) = 0 FROM t1;
30+
COUNT(*) = 0
31+
1
32+
connection node_1;
33+
DELETE FROM t1;
34+
START TRANSACTION;
35+
SAVEPOINT sp1;
36+
INSERT INTO t1 VALUES (1);
37+
INSERT INTO t1 VALUES (2);
38+
INSERT INTO t1 VALUES (3);
39+
INSERT INTO t1 VALUES (4);
40+
SAVEPOINT sp2;
41+
INSERT INTO t1 VALUES (5);
42+
ROLLBACK TO SAVEPOINT sp2;
43+
INSERT INTO t1 VALUES (6);
44+
INSERT INTO t1 VALUES (7);
45+
ROLLBACK TO SAVEPOINT sp1;
46+
INSERT INTO t1 VALUES (8);
47+
COMMIT;
48+
SELECT COUNT(*) = 1 FROM t1;
49+
COUNT(*) = 1
50+
1
51+
connection node_2;
52+
SELECT COUNT(*) = 1 FROM t1;
53+
COUNT(*) = 1
54+
1
55+
DROP TABLE t1;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[binlogoff]
2+
3+
[binlogon]
4+
log-bin
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#
2+
# SAVEPOINT ROLLBACK can introduce incosistency in cluster.
3+
#
4+
5+
--source include/galera_cluster.inc
6+
7+
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
8+
9+
START TRANSACTION;
10+
INSERT INTO t1 VALUES (1);
11+
SAVEPOINT sp1;
12+
INSERT INTO t1 VALUES (2);
13+
ROLLBACK TO SAVEPOINT sp1;
14+
COMMIT;
15+
16+
SELECT COUNT(*) = 1 FROM t1;
17+
18+
--connection node_2
19+
SELECT COUNT(*) = 1 FROM t1;
20+
21+
--connection node_1
22+
DELETE FROM t1;
23+
24+
START TRANSACTION;
25+
SAVEPOINT sp1;
26+
INSERT INTO t1 VALUES (1);
27+
SAVEPOINT sp2;
28+
INSERT INTO t1 VALUES (2);
29+
ROLLBACK TO SAVEPOINT sp2;
30+
ROLLBACK TO SAVEPOINT sp1;
31+
COMMIT;
32+
33+
SELECT COUNT(*) = 0 FROM t1;
34+
--connection node_2
35+
SELECT COUNT(*) = 0 FROM t1;
36+
37+
--connection node_1
38+
DELETE FROM t1;
39+
40+
START TRANSACTION;
41+
SAVEPOINT sp1;
42+
INSERT INTO t1 VALUES (1);
43+
INSERT INTO t1 VALUES (2);
44+
INSERT INTO t1 VALUES (3);
45+
INSERT INTO t1 VALUES (4);
46+
SAVEPOINT sp2;
47+
INSERT INTO t1 VALUES (5);
48+
ROLLBACK TO SAVEPOINT sp2;
49+
INSERT INTO t1 VALUES (6);
50+
INSERT INTO t1 VALUES (7);
51+
ROLLBACK TO SAVEPOINT sp1;
52+
INSERT INTO t1 VALUES (8);
53+
COMMIT;
54+
55+
SELECT COUNT(*) = 1 FROM t1;
56+
57+
--connection node_2
58+
SELECT COUNT(*) = 1 FROM t1;
59+
60+
DROP TABLE t1;

mysql-test/suite/wsrep/r/trans.result

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
#
77
START TRANSACTION WITH CONSISTENT SNAPSHOT;
88
SAVEPOINT A;
9+
ERROR HY000: Got error 1 "Operation not permitted" from storage engine binlog
910
End of test.

mysql-test/suite/wsrep/t/trans.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
--echo #
1010

1111
START TRANSACTION WITH CONSISTENT SNAPSHOT;
12+
--error 1030
1213
SAVEPOINT A;
1314

1415
--echo End of test.

sql/log.cc

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,9 +2209,6 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
22092209
int error= 1;
22102210
DBUG_ENTER("binlog_savepoint_set");
22112211

2212-
if (wsrep_emulate_bin_log)
2213-
DBUG_RETURN(0);
2214-
22152212
char buf[1024];
22162213

22172214
String log_query(buf, sizeof(buf), &my_charset_bin);
@@ -2245,9 +2242,6 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
22452242
{
22462243
DBUG_ENTER("binlog_savepoint_rollback");
22472244

2248-
if (wsrep_emulate_bin_log)
2249-
DBUG_RETURN(0);
2250-
22512245
/*
22522246
Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
22532247
non-transactional table. Otherwise, truncate the binlog cache starting

sql/transaction.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,9 @@ bool trans_savepoint(THD *thd, LEX_STRING name)
614614
if (thd->transaction.xid_state.check_has_uncommitted_xa())
615615
DBUG_RETURN(TRUE);
616616

617+
if (WSREP_ON)
618+
wsrep_register_hton(thd, thd->in_multi_stmt_transaction_mode());
619+
617620
sv= find_savepoint(thd, name);
618621

619622
if (*sv) /* old savepoint of the same name exists */
@@ -690,6 +693,9 @@ bool trans_rollback_to_savepoint(THD *thd, LEX_STRING name)
690693
if (thd->transaction.xid_state.check_has_uncommitted_xa())
691694
DBUG_RETURN(TRUE);
692695

696+
if (WSREP_ON)
697+
wsrep_register_hton(thd, thd->in_multi_stmt_transaction_mode());
698+
693699
/**
694700
Checking whether it is safe to release metadata locks acquired after
695701
savepoint, if rollback to savepoint is successful.

sql/wsrep_binlog.cc

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -376,20 +376,6 @@ int wsrep_binlog_close_connection(THD* thd)
376376
DBUG_RETURN(0);
377377
}
378378

379-
int wsrep_binlog_savepoint_set(THD *thd, void *sv)
380-
{
381-
if (!wsrep_emulate_bin_log) return 0;
382-
int rcode = binlog_hton->savepoint_set(binlog_hton, thd, sv);
383-
return rcode;
384-
}
385-
386-
int wsrep_binlog_savepoint_rollback(THD *thd, void *sv)
387-
{
388-
if (!wsrep_emulate_bin_log) return 0;
389-
int rcode = binlog_hton->savepoint_rollback(binlog_hton, thd, sv);
390-
return rcode;
391-
}
392-
393379
#if 0
394380
void wsrep_dump_rbr_direct(THD* thd, IO_CACHE* cache)
395381
{

sql/wsrep_binlog.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,5 @@ void wsrep_dump_rbr_buf_with_header(THD *thd, const void *rbr_buf,
5454
size_t buf_len);
5555

5656
int wsrep_binlog_close_connection(THD* thd);
57-
int wsrep_binlog_savepoint_set(THD *thd, void *sv);
58-
int wsrep_binlog_savepoint_rollback(THD *thd, void *sv);
5957

6058
#endif /* WSREP_BINLOG_H */

sql/wsrep_hton.cc

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -219,32 +219,20 @@ static int wsrep_prepare(handlerton *hton, THD *thd, bool all)
219219
DBUG_RETURN(0);
220220
}
221221

222+
/*
223+
Empty callbacks to support SAVEPOINT callbacks.
224+
*/
225+
222226
static int wsrep_savepoint_set(handlerton *hton, THD *thd, void *sv)
223227
{
224228
DBUG_ENTER("wsrep_savepoint_set");
225-
226-
if (thd->wsrep_exec_mode == REPL_RECV)
227-
{
228-
DBUG_RETURN(0);
229-
}
230-
231-
if (!wsrep_emulate_bin_log) DBUG_RETURN(0);
232-
int rcode = wsrep_binlog_savepoint_set(thd, sv);
233-
DBUG_RETURN(rcode);
229+
DBUG_RETURN(0);
234230
}
235231

236232
static int wsrep_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
237233
{
238234
DBUG_ENTER("wsrep_savepoint_rollback");
239-
240-
if (thd->wsrep_exec_mode == REPL_RECV)
241-
{
242-
DBUG_RETURN(0);
243-
}
244-
245-
if (!wsrep_emulate_bin_log) DBUG_RETURN(0);
246-
int rcode = wsrep_binlog_savepoint_rollback(thd, sv);
247-
DBUG_RETURN(rcode);
235+
DBUG_RETURN(0);
248236
}
249237

250238
static int wsrep_rollback(handlerton *hton, THD *thd, bool all)

0 commit comments

Comments
 (0)