mariadb/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa.test
Monty 567c097359 MDEV-33582 Add more warnings to be able to better diagnose network issues
Warnings are added to net_server.cc when
global_system_variables.log_warnings >= 4.

When the above condition holds then:
- All communication errors from net_serv.cc is also written to the
  error log.
- In case of a of not being able to read or write a packet, a more
  detailed error is given.

Other things:
- Added detection of slaves that has hangup to Ack_receiver::run()
- vio_close() is now first marking the socket closed before closing it.
  The reason for this is to ensure that the connection that gets a read
  error can check if the reason was that the socket was closed.
- Add a new state to vio to be able to detect if vio is acive, shutdown or
  closed. This is used to detect if socket is closed by another thread.
- Testing of the new warnings is done in rpl_get_lock.test
- Suppress some of the new warnings in mtr to allow one to run some of
  the tests with -mysqld=--log-warnings=4. All test in the 'rpl' suite
  can now be run with this option.
 - Ensure that global.log_warnings are restored at test end in a way
   that allows one to use mtr --mysqld=--log-warnings=4.

Reviewed-by: <serg@mariadb.org>,<brandon.nesterenko@mariadb.com>
2024-03-05 20:19:49 +02:00

234 lines
6.4 KiB
Text

# The tests verify concurrent execution of replicated (MDEV-742)
# XA transactions in the parallel optimistic mode.
--source include/have_innodb.inc
--source include/have_perfschema.inc
--source include/master-slave.inc
# Tests' global declarations
--let $trx = _trx_
call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction");
call mtr.add_suppression("WSREP: handlerton rollback failed");
#call mtr.add_suppression("Can't find record in 't1'");
CREATE VIEW v_processlist as SELECT * FROM performance_schema.threads where type = 'FOREGROUND';
--connection master
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
--save_master_pos
# Prepare to restart slave into optimistic parallel mode
--connection slave
--sync_with_master
--source include/stop_slave.inc
SET @old_parallel_threads = @@GLOBAL.slave_parallel_threads;
SET @@global.slave_parallel_threads = 7;
SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode;
SET @@global.slave_parallel_mode ='optimistic';
# Run the first part of the test with high batch size and see that
# old rows remain in the table.
SET @old_gtid_cleanup_batch_size = @@GLOBAL.gtid_cleanup_batch_size;
SET @@global.gtid_cleanup_batch_size = 1000000;
CHANGE MASTER TO master_use_gtid=slave_pos;
# LOAD GENERATOR creates XA:s interleaved in binlog when they are from
# different connections. All the following block XA:s of the same connection
# update the same data which challenges slave optimistic scheduler's correctness.
# Slave must eventually apply such load, and correctly (checked).
--connection master
CREATE TABLE t0 (a int, b INT) ENGINE=InnoDB;
CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, 0);
# I. Logging some sequence of XA:s by one connection.
#
# The slave applier's task is to successfully execute a series of
# Prepare and Complete parts of a sequence of XA:s
--let $trx_num = 300
--let $i = $trx_num
--let $conn = master
--disable_query_log
while($i > 0)
{
# 'decision' to commit 0, or rollback 1
--let $decision = `SELECT $i % 2`
--eval XA START '$conn$trx$i'
--eval UPDATE t1 SET b = 1 - 2 * $decision WHERE a = 1
--eval XA END '$conn$trx$i'
--let $one_phase = `SELECT IF(floor(rand()*10)%2, "ONE PHASE", 0)`
if (!$one_phase)
{
--eval XA PREPARE '$conn$trx$i'
--let $one_phase =
}
--let $term = COMMIT
if ($decision)
{
--let $term = ROLLBACK
--let $one_phase =
}
--eval XA $term '$conn$trx$i' $one_phase
--dec $i
}
--enable_query_log
--source include/save_master_gtid.inc
--connection slave
--source include/start_slave.inc
--source include/sync_with_master_gtid.inc
--source include/stop_slave.inc
# II. Logging XS:s from multiple connections in random interweaving manner:
#
# in a loop ($i) per connection
# arrange an inner ($k) loop where
# start and prepare an XA;
# decide whether to terminate it and then continue to loop innerly
# OR disconnect to break the inner loop;
# the disconnected one's XA is taken care by 'master' connection
#
# Effectively binlog must collect a well mixed XA- prepared and terminated
# groups for slave to handle.
--connection master
# Total # of connections
--let $conn_num=53
--let $i = $conn_num
--disable_query_log
while($i > 0)
{
--connect (master_conn$i, 127.0.0.1,root,,test,$MASTER_MYPORT,)
--dec $i
}
--enable_query_log
--let $i = $conn_num
while($i > 0)
{
--let $conn_i = conn$i
# $i2 indexes the current connection's "own" row
--let $i2 = `SELECT $i + 2`
--disable_query_log
--connection master_conn$i
--enable_query_log
--disable_query_log
--let $i_conn_id = `SELECT connection_id()`
--let $decision = 0
# the row id of the last connection that committed its XA
--let $c_max = 1
--let $k = 0
while ($decision < 3)
{
--inc $k
--eval XA START '$conn_i$trx$k'
# UPDATE depends on previously *committed* transactions
--eval UPDATE t1 SET b = b + $k + 1 WHERE a = $c_max
if (`SELECT $k % 2 = 1`)
{
--eval REPLACE INTO t1 VALUES ($i2, $k)
}
if (`SELECT $k % 2 = 0`)
{
--eval DELETE FROM t1 WHERE a = $i2
}
CREATE TEMPORARY TABLE tmp LIKE t0;
--eval INSERT INTO tmp SET a=$i, b= $k
INSERT INTO t0 SELECT * FROM tmp;
DROP TEMPORARY TABLE tmp;
--eval XA END '$conn_i$trx$k'
--let $term = COMMIT
--let $decision = `SELECT (floor(rand()*10 % 10) + ($i+$k)) % 4`
if ($decision == 1)
{
--let $term = ROLLBACK
}
if ($decision < 2)
{
--eval XA PREPARE '$conn_i$trx$k'
--eval XA $term '$conn_i$trx$k'
# Iteration counter is taken care *now*
}
if ($decision == 2)
{
--eval XA COMMIT '$conn_i$trx$k' ONE PHASE
}
}
# $decision = 3
--eval XA PREPARE '$conn_i$trx$k'
# disconnect now
--disconnect master_conn$i
--connection master
--let $wait_condition= SELECT count(*) = 0 FROM v_processlist WHERE PROCESSLIST_ID = $i_conn_id
--source include/wait_condition.inc
--disable_query_log
--let $decision = `SELECT ($i+$k) % 2`
--let $term = COMMIT
if ($decision == 1)
{
--let $term = ROLLBACK
}
--eval XA $term '$conn_i$trx$k'
--let $c_max = $i2
--dec $i
}
--enable_query_log
--source include/save_master_gtid.inc
--connection slave
--source include/start_slave.inc
--source include/sync_with_master_gtid.inc
#
# Overall consistency check
#
--let $diff_tables= master:t0, slave:t0
--source include/diff_tables.inc
--let $diff_tables= master:t1, slave:t1
--source include/diff_tables.inc
#
# Clean up.
#
--connection slave
--source include/stop_slave.inc
SET GLOBAL slave_parallel_mode=@old_parallel_mode;
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
--source include/start_slave.inc
--connection master
DROP VIEW v_processlist;
DROP TABLE t0, t1;
--source include/save_master_gtid.inc
--connection slave
--source include/sync_with_master_gtid.inc
# Check that old rows are deleted from mysql.gtid_slave_pos.
# Deletion is asynchronous, so use wait_condition.inc.
# Also, there is a small amount of non-determinism in the deletion of old
# rows, so it is not guaranteed that there can never be more than
# @@gtid_cleanup_batch_size rows in the table; so allow a bit of slack
# here.
let $wait_condition=
SELECT COUNT(*) <= 5*@@GLOBAL.gtid_cleanup_batch_size
FROM mysql.gtid_slave_pos;
--source include/wait_condition.inc
eval $wait_condition;
SET GLOBAL gtid_cleanup_batch_size= @old_gtid_cleanup_batch_size;
--connection master
--source include/rpl_end.inc