1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
Files
mariadb/mysql-test/suite/galera/t/galera_sequences_recovery.test
sjaakola 57ebfb607a MDEV_38952 Improve galera_sequences family of tests
This commit fixes a sporadic failure with the test case 1,
where recorded result depends on node 1 applying node 2's replicated
sequence update before it resumes its already-open transaction:

- Node 2 SELECT NEXTVAL(s) writes reserved_until=21 and replicates it.
- On node 1 that lands in Rows_log_event::update_sequence()
  Since 21 > next_free_value (9), adjust_values(21) discards node 1's  still-cached value 9.

  Nothing enforced that ordering: node 1's INSERTs run inside BEGIN, and sync wait does not happen mid-transaction.

The fix is to use selarate session, node_1_ctrl, to wait until node 1 has applied the update, before node 1 resumes its transaction
2026-08-24 13:18:02 +03:00

237 lines
7.6 KiB
Plaintext

#
# Test sequences crash recovery.
#
--source include/galera_cluster.inc
--source include/have_sequence.inc
--source include/big_test.inc
--source include/no_protocol.inc
--disable_ps2_protocol
#
# Case 1: Crash a node during a transaction, bring the
# sequence in sync by receiving higher current value
#
--connection node_1
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY DEFAULT NEXTVAL(s), f2 INT) ENGINE=InnoDB;
--connection node_1
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
--connect node_1_ctrl, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connection node_1_ctrl
SET GLOBAL innodb_log_checkpoint_now=1;
--connection node_2
BEGIN;
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
--echo # Crash and restart the node, losing the transaction (1)
--source include/kill_galera.inc
--let $galera_wsrep_recover_server_id=2
--source include/galera_wsrep_recover.inc
--let $start_mysqld_params =
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
--source include/start_mysqld.inc
--connection node_1
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
--source include/wait_condition_with_debug.inc
--connection node_2
--echo # Wait for the next_not_cached_value = 11 FROM s (1)
--let $wait_condition = SELECT next_not_cached_value = 11 FROM s;
--let $wait_condition_on_error_output = SELECT next_not_cached_value FROM s
--source include/wait_condition_with_debug.inc
# Check and update the last written sequence value
SELECT NEXTVAL(s);
SELECT LASTVAL(s);
SET GLOBAL innodb_log_checkpoint_now=1;
# Node 1 has an open transaction and wsrep_sync_wait is not effective
# inside a transaction. Wait here until node 1 has applied the sequence
# update replicated by NEXTVAL above, otherwise node 1 may still consume
# its own cached value before the update arrives.
--connection node_1_ctrl
--echo # Wait for the next_not_cached_value = 21 FROM s (1_ctrl)
--let $wait_condition = SELECT next_not_cached_value = 21 FROM s
--let $wait_condition_on_error_output = SELECT next_not_cached_value FROM s
--source include/wait_condition_with_debug.inc
--connection node_1
# Update the sequence value further
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
COMMIT;
SET GLOBAL innodb_log_checkpoint_now=1;
SELECT LASTVAL(s);
SELECT COUNT(*) FROM t1;
SELECT * FROM t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 10 FROM t1
--source include/wait_condition.inc
--echo # Wait for the next_not_cached_value = 42 FROM s
--let $wait_condition = SELECT next_not_cached_value = 42 FROM s
--let $wait_condition_on_error_output = SELECT next_not_cached_value FROM s
--source include/wait_condition_with_debug.inc
# The next value should be in sync now, but the last
# value is still the same
SELECT LASTVAL(s);
SELECT NEXTVAL(s);
SELECT * FROM t1;
SET GLOBAL innodb_log_checkpoint_now=1;
--connection node_1
DROP TABLE t1;
DROP SEQUENCE s;
SET GLOBAL innodb_log_checkpoint_now=1;
#
# Case 2: Crash a node during a transaction, bring the
# sequence in sync by sending higher current value
#
--connection node_1
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY DEFAULT NEXTVAL(s), f2 INT) ENGINE=InnoDB;
--connection node_1
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
--connection node_1_ctrl
SET GLOBAL innodb_log_checkpoint_now=1;
--connection node_2
# Exhaust the cached values once, but no replication happens even
# though the sequnce table is updated
BEGIN;
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
INSERT INTO t1(f2) values (2);
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
SET GLOBAL innodb_log_checkpoint_now=1;
SET SESSION wsrep_sync_wait=0;
--echo # Wait for the next_not_cached_value = 31 FROM s (2a)
--let $wait_condition = SELECT next_not_cached_value = 31 FROM s
--let $wait_condition_on_error_output = SELECT next_not_cached_value FROM s
--source include/wait_condition_with_debug.inc
SELECT next_not_cached_value = 31 FROM s;
--connection node_2
--echo # Crash and restart the node, losing the transaction (2)
--source include/kill_galera.inc
--let $galera_wsrep_recover_server_id=2
--source include/galera_wsrep_recover.inc
--let $start_mysqld_params =
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
--source include/start_mysqld.inc
--connection node_1
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
--source include/wait_condition.inc
--connection node_2
--echo # Wait for the next_not_cached_value = 31 FROM s (2)
--let $wait_condition = SELECT next_not_cached_value = 31 FROM s
--let $wait_condition_on_error_output = SELECT next_not_cached_value FROM s
--source include/wait_condition_with_debug.inc
SELECT LASTVAL(s);
--connection node_1
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
SELECT COUNT(*) FROM t1;
COMMIT;
SELECT LASTVAL(s);
SELECT * FROM t1;
SET GLOBAL innodb_log_checkpoint_now=1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 15 FROM t1
--source include/wait_condition.inc
--echo # Wait for the next_not_cached_value = 31 FROM s
--let $wait_condition = SELECT next_not_cached_value = 31 FROM s
--let $wait_condition_on_error_output = SELECT next_not_cached_value FROM s
--source include/wait_condition_with_debug.inc
# Check and update the last written sequence value, it's still
# higher than the one from the other node
SELECT LASTVAL(s);
SELECT NEXTVAL(s);
SELECT * FROM t1;
SET GLOBAL innodb_log_checkpoint_now=1;
--connection node_1
--let $wait_condition = SELECT COUNT(*) = 15 FROM t1
--source include/wait_condition.inc
--let $wait_condition = SELECT LASTVAL(s) = 29
--let $wait_condition_on_error_output = SELECT LASTVAL(s)
--source include/wait_condition_with_debug.inc
--echo # Wait for the next_not_cached_value = 41 FROM s
--let $wait_condition = SELECT next_not_cached_value = 41 FROM s
--let $wait_condition_on_error_output = SELECT next_not_cached_value FROM s
--source include/wait_condition_with_debug.inc
# The next value should be in sync now, but the last
# value is still the same
SELECT LASTVAL(s);
SELECT NEXTVAL(s);
SET GLOBAL innodb_log_checkpoint_now=1;
--connection node_2
--let $wait_condition = SELECT LASTVAL(s) = 32
--let $wait_condition_on_error_output = SELECT LASTVAL(s)
--source include/wait_condition_with_debug.inc
--echo # Wait for the next_not_cached_value = 52 FROM s
--let $wait_condition = SELECT next_not_cached_value = 52 FROM s
--let $wait_condition_on_error_output = SELECT next_not_cached_value FROM s
--source include/wait_condition_with_debug.inc
SELECT LASTVAL(s);
SELECT * from t1;
--connection node_1
SELECT * FROM t1;
DROP TABLE t1;
DROP SEQUENCE s;