mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Move deletion of old GTID rows to slave background thread
This patch changes how old rows in mysql.gtid_slave_pos* tables are deleted. Instead of doing it as part of every replicated transaction in record_gtid(), it is done periodically (every @@gtid_cleanup_batch_size transaction) in the slave background thread. This removes the deletion step from the replication process in SQL or worker threads, which could speed up replication with many small transactions. It also decreases contention on the global mutex LOCK_slave_state. And it simplifies the logic, eg. when a replicated transaction fails after having deleted old rows. With this patch, the deletion of old GTID rows happens asynchroneously and slightly non-deterministic. Thus the number of old rows in mysql.gtid_slave_pos can temporarily exceed @@gtid_cleanup_batch_size. But all old rows will be deleted eventually after sufficiently many new GTIDs have been replicated.
This commit is contained in:
@@ -21,6 +21,10 @@ SET GLOBAL slave_parallel_threads=10;
|
||||
CHANGE MASTER TO master_use_gtid=slave_pos;
|
||||
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;
|
||||
|
||||
|
||||
--connection server_1
|
||||
@@ -108,7 +112,12 @@ SELECT * FROM t3 ORDER BY c;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
SELECT * FROM t3 ORDER BY c;
|
||||
#SHOW STATUS LIKE 'Slave_retried_transactions';
|
||||
# Check that we have a bunch of old rows left-over - they were not deleted
|
||||
# due to high @@gtid_cleanup_batch_size. Then set a low
|
||||
# @@gtid_cleanup_batch_size so we can test that rows start being deleted.
|
||||
SELECT IF(COUNT(*) >= 30, "OK", CONCAT("Error: too few old rows found: ", COUNT(*)))
|
||||
FROM mysql.gtid_slave_pos;
|
||||
SET GLOBAL gtid_cleanup_batch_size=1;
|
||||
|
||||
|
||||
--echo *** Test @@skip_parallel_replication. ***
|
||||
@@ -557,25 +566,18 @@ DROP TABLE t1, t2, t3;
|
||||
|
||||
--connection server_2
|
||||
--source include/sync_with_master_gtid.inc
|
||||
# Check for left-over rows in table mysql.gtid_slave_pos (MDEV-12147).
|
||||
#
|
||||
# There was a bug when a transaction got a conflict and was rolled back. It
|
||||
# might have also handled deletion of some old rows, and these deletions would
|
||||
# then also be rolled back. And since the deletes were never re-tried, old no
|
||||
# longer needed rows would accumulate in the table without limit.
|
||||
#
|
||||
# The earlier part of this test file have plenty of transactions being rolled
|
||||
# back. But the last DROP TABLE statement runs on its own and should never
|
||||
# conflict, thus at this point the mysql.gtid_slave_pos table should be clean.
|
||||
#
|
||||
# To support @@gtid_pos_auto_engines, when a row is inserted in the table, it
|
||||
# is associated with the engine of the table at insertion time, and it will
|
||||
# only be deleted during record_gtid from a table of the same engine. Since we
|
||||
# alter the table from MyISAM to InnoDB at the start of this test, we should
|
||||
# end up with 4 rows: two left-over from when the table was MyISAM, and two
|
||||
# left-over from the InnoDB part.
|
||||
--echo Check that no more than the expected last four GTIDs are in mysql.gtid_slave_pos
|
||||
select count(4) <= 4 from mysql.gtid_slave_pos order by domain_id, sub_id;
|
||||
# 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 server_1
|
||||
--source include/rpl_end.inc
|
||||
|
Reference in New Issue
Block a user