Skip to content

Commit ebbd5ef

Browse files
mkaruzaJan Lindström
authored andcommitted
MDEV-27862 Galera should replicate nextval()-related changes in sequences with INCREMENT <> 0, at least NOCACHE ones with engine=InnoDB
Sequence storage engine is not transactionl so cache will be written in stmt_cache that is not replicated in cluster. To fix this replicate what is available in both trans_cache and stmt_cache. Sequences will only work when NOCACHE keyword is used when sequnce is created. If WSREP is enabled and we don't have this keyword report error indicting that sequence will not work correctly in cluster. When binlog is enabled statement cache will be cleared in transaction before COMMIT so cache generated from sequence will not be replicated. We need to keep cache until replication. Tests are re-recorded because of replication changes that were introducted with this PR. Reviewed-by: Jan Lindström <jan.lindstrom@mariadb.com>
1 parent c8fabbe commit ebbd5ef

13 files changed

+197
-13
lines changed

mysql-test/suite/galera/r/MDEV-18832.result

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ INSERT INTO t1 VALUES (NEXT VALUE FOR Seq1_1);
1212
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
1313
DROP SEQUENCE Seq1_1;
1414
DROP TABLE t1;
15+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
16+
connection node_2;
17+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
connection node_2;
2+
connection node_1;
3+
CREATE SEQUENCE seq_nocache ENGINE=InnoDB;
4+
DROP SEQUENCE seq_nocache;
5+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
6+
connection node_2;
7+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
8+
connection node_1;
9+
CREATE SEQUENCE seq NOCACHE ENGINE=InnoDB;
10+
SELECT NEXTVAL(seq) = 1;
11+
NEXTVAL(seq) = 1
12+
1
13+
connection node_2;
14+
SELECT NEXTVAL(seq) = 2;
15+
NEXTVAL(seq) = 2
16+
1
17+
connection node_1;
18+
SELECT NEXTVAL(seq) = 3;
19+
NEXTVAL(seq) = 3
20+
1
21+
SELECT SETVAL(seq, 100);
22+
SETVAL(seq, 100)
23+
100
24+
connection node_2;
25+
SELECT NEXTVAL(seq) = 101;
26+
NEXTVAL(seq) = 101
27+
1
28+
connection node_1;
29+
SELECT NEXTVAL(seq) = 102;
30+
NEXTVAL(seq) = 102
31+
1
32+
DROP SEQUENCE seq;
33+
CREATE TABLE t1(f1 INT);
34+
CREATE SEQUENCE seq_transaction NOCACHE ENGINE=InnoDB;
35+
START TRANSACTION;
36+
INSERT INTO t1 VALUES (0);
37+
SELECT NEXTVAL(seq_transaction);
38+
NEXTVAL(seq_transaction)
39+
1
40+
INSERT INTO t1 VALUES (NEXTVAL(seq_transaction));
41+
COMMIT;
42+
connection node_2;
43+
SELECT COUNT(*) = 2 FROM t1;
44+
COUNT(*) = 2
45+
1
46+
SELECT NEXTVAL(seq_transaction) = 3;
47+
NEXTVAL(seq_transaction) = 3
48+
1
49+
connection node_1;
50+
SELECT NEXTVAL(seq_transaction) = 4;
51+
NEXTVAL(seq_transaction) = 4
52+
1
53+
DROP SEQUENCE seq_transaction;
54+
DROP TABLE t1;

mysql-test/suite/galera/r/galera_sequences.result

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ Table Create Table
4444
Seq1_1 CREATE SEQUENCE `Seq1_1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB
4545
select NEXT VALUE FOR Seq1_1;
4646
NEXT VALUE FOR Seq1_1
47-
1
47+
3001
4848
connection node_1;
4949
DROP SEQUENCE Seq1_1;
50+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
51+
connection node_2;
52+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");

mysql-test/suite/galera/t/MDEV-18832.test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,11 @@ CREATE SEQUENCE Seq1_1 START WITH 1 INCREMENT BY 1;
1313
INSERT INTO t1 VALUES (NEXT VALUE FOR Seq1_1);
1414
DROP SEQUENCE Seq1_1;
1515
DROP TABLE t1;
16+
17+
# Supress warning for SEQUENCES that are declared without `NOCACHE` introduced with MDEV-27862
18+
19+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
20+
21+
--connection node_2
22+
23+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
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: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
--source include/galera_cluster.inc
2+
--source include/have_innodb.inc
3+
4+
# Report WARNING when SEQUENCE is created without `NOCACHE`
5+
6+
CREATE SEQUENCE seq_nocache ENGINE=InnoDB;
7+
DROP SEQUENCE seq_nocache;
8+
9+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
10+
11+
--connection node_2
12+
13+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
14+
15+
# NEXTVAL
16+
17+
--connection node_1
18+
19+
CREATE SEQUENCE seq NOCACHE ENGINE=InnoDB;
20+
21+
SELECT NEXTVAL(seq) = 1;
22+
23+
--connection node_2
24+
25+
SELECT NEXTVAL(seq) = 2;
26+
27+
--connection node_1
28+
29+
SELECT NEXTVAL(seq) = 3;
30+
31+
32+
# SETVAL
33+
34+
SELECT SETVAL(seq, 100);
35+
36+
--connection node_2
37+
38+
SELECT NEXTVAL(seq) = 101;
39+
40+
--connection node_1
41+
42+
SELECT NEXTVAL(seq) = 102;
43+
44+
DROP SEQUENCE seq;
45+
46+
# TRANSACTIONS
47+
48+
CREATE TABLE t1(f1 INT);
49+
CREATE SEQUENCE seq_transaction NOCACHE ENGINE=InnoDB;
50+
51+
START TRANSACTION;
52+
INSERT INTO t1 VALUES (0);
53+
SELECT NEXTVAL(seq_transaction);
54+
INSERT INTO t1 VALUES (NEXTVAL(seq_transaction));
55+
COMMIT;
56+
57+
--connection node_2
58+
59+
SELECT COUNT(*) = 2 FROM t1;
60+
SELECT NEXTVAL(seq_transaction) = 3;
61+
62+
--connection node_1
63+
SELECT NEXTVAL(seq_transaction) = 4;
64+
65+
DROP SEQUENCE seq_transaction;
66+
DROP TABLE t1;
67+

mysql-test/suite/galera/t/galera_sequences.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,9 @@ select NEXT VALUE FOR Seq1_1;
4444

4545
--connection node_1
4646
DROP SEQUENCE Seq1_1;
47+
48+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");
49+
50+
--connection node_2
51+
52+
CALL mtr.add_suppression("SEQUENCES declared without `NOCACHE` will not behave correctly in galera cluster.");

sql/ha_sequence.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,9 @@ static int sequence_initialize(void *p)
434434
HTON_HIDDEN |
435435
HTON_TEMPORARY_NOT_SUPPORTED |
436436
HTON_ALTER_NOT_SUPPORTED |
437+
#ifdef WITH_WSREP
438+
HTON_WSREP_REPLICATION |
439+
#endif
437440
HTON_NO_PARTITION);
438441
DBUG_RETURN(0);
439442
}

sql/log.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,7 +2013,13 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
20132013

20142014
thd->backup_stage(&org_stage);
20152015
THD_STAGE_INFO(thd, stage_binlog_write);
2016+
#ifdef WITH_WSREP
2017+
// DON'T clear stmt cache in case we are in transaction
2018+
if (!cache_mngr->stmt_cache.empty() &&
2019+
(!wsrep_on(thd) || ending_trans(thd, all)))
2020+
#else
20162021
if (!cache_mngr->stmt_cache.empty())
2022+
#endif
20172023
{
20182024
error= binlog_commit_flush_stmt_cache(thd, all, cache_mngr);
20192025
}
@@ -10777,13 +10783,13 @@ maria_declare_plugin_end;
1077710783
#ifdef WITH_WSREP
1077810784
#include "wsrep_mysqld.h"
1077910785

10780-
IO_CACHE *wsrep_get_trans_cache(THD * thd)
10786+
IO_CACHE *wsrep_get_cache(THD * thd, bool is_transactional)
1078110787
{
1078210788
DBUG_ASSERT(binlog_hton->slot != HA_SLOT_UNDEF);
1078310789
binlog_cache_mngr *cache_mngr = (binlog_cache_mngr*)
1078410790
thd_get_ha_data(thd, binlog_hton);
1078510791
if (cache_mngr)
10786-
return cache_mngr->get_binlog_cache_log(true);
10792+
return cache_mngr->get_binlog_cache_log(is_transactional);
1078710793

1078810794
WSREP_DEBUG("binlog cache not initialized, conn: %llu",
1078910795
thd->thread_id);

sql/log.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,7 @@ static inline TC_LOG *get_tc_log_implementation()
12391239
}
12401240

12411241
#ifdef WITH_WSREP
1242-
IO_CACHE* wsrep_get_trans_cache(THD *);
1242+
IO_CACHE* wsrep_get_cache(THD *, bool);
12431243
void wsrep_thd_binlog_trx_reset(THD * thd);
12441244
void wsrep_thd_binlog_stmt_rollback(THD * thd);
12451245
#endif /* WITH_WSREP */

0 commit comments

Comments
 (0)