Skip to content

Commit

Permalink
MDEV-31723: Crash on SET SESSION gtid_seq_no= DEFAULT
Browse files Browse the repository at this point in the history
A simple "SET SESSION gtid_seq_no= DEFAULT" did not work, it would straight
up crash the server! Also, explicitly setting gtid_seq_no to 0 gave an error
in --gtid-strict-mode=1.

Setting to DEFAULT or 0 should disable any prior setting of
gtid_seq_no, so that the next transaction is allocated the next GTID
in sequence, as normal.

Reviewed-by: Monty <monty@mariadb.org>
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
  • Loading branch information
knielsen committed Jul 30, 2023
1 parent 9854fb6 commit d632c85
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 7 deletions.
56 changes: 56 additions & 0 deletions mysql-test/suite/binlog_encryption/rpl_gtid_basic.result
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,62 @@ a
32
33
34
*** MDEV-31723: Crash on SET SESSION gtid_seq_no= DEFAULT
connection server_1;
SET SESSION gtid_seq_no= 2000;
SELECT @@SESSION.gtid_seq_no;
@@SESSION.gtid_seq_no
2000
INSERT INTO t1 VALUES (40);
SELECT @@SESSION.gtid_seq_no;
@@SESSION.gtid_seq_no
0
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2000
INSERT INTO t1 VALUES (41);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2001
SET SESSION gtid_seq_no= 2010;
INSERT INTO t1 VALUES (42);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2010
SET @old_strict= @@GLOBAL.gtid_strict_mode;
SET GLOBAL gtid_strict_mode= 1;
SET SESSION gtid_seq_no= 0;
INSERT INTO t1 VALUES (43);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2011
SET GLOBAL gtid_strict_mode= @old_strict;
INSERT INTO t1 VALUES (44);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2012
SET SESSION gtid_seq_no= 2020;
SET SESSION gtid_seq_no= 2030;
INSERT INTO t1 VALUES (45);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2030
SET SESSION gtid_seq_no= 2040;
SET SESSION gtid_seq_no= DEFAULT;
INSERT INTO t1 VALUES (46);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2031
INSERT INTO t1 VALUES (47);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2032
SET SESSION gtid_seq_no= 2050;
SET SESSION gtid_seq_no= 0;
INSERT INTO t1 VALUES (48);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2033
connection server_1;
DROP TABLE t1;
include/rpl_end.inc
Expand Down
56 changes: 56 additions & 0 deletions mysql-test/suite/rpl/r/rpl_gtid_basic.result
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,62 @@ a
32
33
34
*** MDEV-31723: Crash on SET SESSION gtid_seq_no= DEFAULT
connection server_1;
SET SESSION gtid_seq_no= 2000;
SELECT @@SESSION.gtid_seq_no;
@@SESSION.gtid_seq_no
2000
INSERT INTO t1 VALUES (40);
SELECT @@SESSION.gtid_seq_no;
@@SESSION.gtid_seq_no
0
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2000
INSERT INTO t1 VALUES (41);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2001
SET SESSION gtid_seq_no= 2010;
INSERT INTO t1 VALUES (42);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2010
SET @old_strict= @@GLOBAL.gtid_strict_mode;
SET GLOBAL gtid_strict_mode= 1;
SET SESSION gtid_seq_no= 0;
INSERT INTO t1 VALUES (43);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2011
SET GLOBAL gtid_strict_mode= @old_strict;
INSERT INTO t1 VALUES (44);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2012
SET SESSION gtid_seq_no= 2020;
SET SESSION gtid_seq_no= 2030;
INSERT INTO t1 VALUES (45);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2030
SET SESSION gtid_seq_no= 2040;
SET SESSION gtid_seq_no= DEFAULT;
INSERT INTO t1 VALUES (46);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2031
INSERT INTO t1 VALUES (47);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2032
SET SESSION gtid_seq_no= 2050;
SET SESSION gtid_seq_no= 0;
INSERT INTO t1 VALUES (48);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
dom0_pos
0-1-2033
connection server_1;
DROP TABLE t1;
include/rpl_end.inc
Expand Down
44 changes: 44 additions & 0 deletions mysql-test/suite/rpl/t/rpl_gtid_basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,50 @@ SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
SELECT * FROM t1 WHERE a >= 30 ORDER BY a;


--echo *** MDEV-31723: Crash on SET SESSION gtid_seq_no= DEFAULT
--connection server_1

# Setting gtid_seq_no forces the GTID logged, but only once.
SET SESSION gtid_seq_no= 2000;
SELECT @@SESSION.gtid_seq_no;
INSERT INTO t1 VALUES (40);
SELECT @@SESSION.gtid_seq_no;
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
INSERT INTO t1 VALUES (41);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;

# Setting to 0 has no effect.
SET SESSION gtid_seq_no= 2010;
INSERT INTO t1 VALUES (42);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
SET @old_strict= @@GLOBAL.gtid_strict_mode;
SET GLOBAL gtid_strict_mode= 1;
SET SESSION gtid_seq_no= 0;
INSERT INTO t1 VALUES (43);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
SET GLOBAL gtid_strict_mode= @old_strict;
INSERT INTO t1 VALUES (44);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;

# Setting gtid_seq_no multiple times.
SET SESSION gtid_seq_no= 2020;
SET SESSION gtid_seq_no= 2030;
INSERT INTO t1 VALUES (45);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;

# Setting to DEFAULT or 0 disables prior setting.
SET SESSION gtid_seq_no= 2040;
SET SESSION gtid_seq_no= DEFAULT;
INSERT INTO t1 VALUES (46);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
INSERT INTO t1 VALUES (47);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;
SET SESSION gtid_seq_no= 2050;
SET SESSION gtid_seq_no= 0;
INSERT INTO t1 VALUES (48);
SELECT REGEXP_REPLACE(@@gtid_binlog_pos, ".*\\b(0-1-[0-9]+)\\b.*", "\\1") AS dom0_pos;


# Clean up.
--connection server_1
DROP TABLE t1;
Expand Down
1 change: 1 addition & 0 deletions mysql-test/suite/sys_vars/r/gtid_seq_no_basic.result
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ SELECT @@session.gtid_seq_no;
20
SET GLOBAL gtid_seq_no= DEFAULT;
ERROR HY000: Variable 'gtid_seq_no' is a SESSION variable and can't be used with SET GLOBAL
SET SESSION gtid_seq_no= DEFAULT;
SET SESSION gtid_seq_no= -1;
Warnings:
Warning 1292 Truncated incorrect gtid_seq_no value: '-1'
Expand Down
2 changes: 2 additions & 0 deletions mysql-test/suite/sys_vars/t/gtid_seq_no_basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ SELECT @@session.gtid_seq_no;
--error ER_LOCAL_VARIABLE
SET GLOBAL gtid_seq_no= DEFAULT;

SET SESSION gtid_seq_no= DEFAULT;

SET SESSION gtid_seq_no= -1;
SELECT @@session.gtid_seq_no;
24 changes: 17 additions & 7 deletions sql/sys_vars.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,13 @@ static Sys_var_uint Sys_gtid_domain_id(
ON_CHECK(check_gtid_domain_id));


/*
Check that setting gtid_seq_no isn't done inside a transaction, and (in
gtid_strict_mode) doesn't create an out-of-order GTID sequence.

Setting gtid_seq_no to DEFAULT or 0 means we 'reset' it so that the value
doesn't affect the GTID of the next event group written to the binlog.
*/
static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var)
{
uint32 domain_id, server_id;
Expand All @@ -1710,13 +1717,16 @@ static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var)
ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO)))
return true;

domain_id= thd->variables.gtid_domain_id;
server_id= thd->variables.server_id;
seq_no= (uint64)var->value->val_uint();
DBUG_EXECUTE_IF("ignore_set_gtid_seq_no_check", return 0;);
if (opt_gtid_strict_mode && opt_bin_log &&
mysql_bin_log.check_strict_gtid_sequence(domain_id, server_id, seq_no))
return true;
DBUG_EXECUTE_IF("ignore_set_gtid_seq_no_check", return false;);
if (var->value && opt_gtid_strict_mode && opt_bin_log)
{
domain_id= thd->variables.gtid_domain_id;
server_id= thd->variables.server_id;
seq_no= (uint64)var->value->val_uint();
if (seq_no != 0 &&
mysql_bin_log.check_strict_gtid_sequence(domain_id, server_id, seq_no))
return true;
}

return false;
}
Expand Down

0 comments on commit d632c85

Please sign in to comment.