From ac086f70606e954833649d22ef5d39cb396f16c3 Mon Sep 17 00:00:00 2001 From: Venkatesh Prasad Venugopal Date: Mon, 6 Jul 2020 10:55:39 +0530 Subject: [PATCH] MTR test for creating gaps in the GTID executed table. --- .../rpl_gtid/t/rpl_gtid_create_gtid_gaps.cnf | 20 ++++ .../rpl_gtid/t/rpl_gtid_create_gtid_gaps.test | 106 ++++++++++++++++++ storage/innobase/clone/clone0repl.cc | 8 ++ 3 files changed, 134 insertions(+) create mode 100644 mysql-test/suite/rpl_gtid/t/rpl_gtid_create_gtid_gaps.cnf create mode 100644 mysql-test/suite/rpl_gtid/t/rpl_gtid_create_gtid_gaps.test diff --git a/mysql-test/suite/rpl_gtid/t/rpl_gtid_create_gtid_gaps.cnf b/mysql-test/suite/rpl_gtid/t/rpl_gtid_create_gtid_gaps.cnf new file mode 100644 index 00000000000..6d6666813eb --- /dev/null +++ b/mysql-test/suite/rpl_gtid/t/rpl_gtid_create_gtid_gaps.cnf @@ -0,0 +1,20 @@ +!include ../my.cnf + +[mysqld.1] +max_connections=5120 +gtid_mode = ON +enforce_gtid_consistency = ON +binlog_cache_size = 512M +binlog_format = ROW + +[mysqld.2] +slave_net_timeout = 60 +slave_parallel_type = LOGICAL_CLOCK +slave_parallel_workers = 32 +slave_pending_jobs_size_max = 1G +gtid_mode = ON +enforce_gtid_consistency = ON +binlog_format = ROW + +# disable binlog +skip-log-bin diff --git a/mysql-test/suite/rpl_gtid/t/rpl_gtid_create_gtid_gaps.test b/mysql-test/suite/rpl_gtid/t/rpl_gtid_create_gtid_gaps.test new file mode 100644 index 00000000000..e69f53182cc --- /dev/null +++ b/mysql-test/suite/rpl_gtid/t/rpl_gtid_create_gtid_gaps.test @@ -0,0 +1,106 @@ +# +# This test is designed to simulate a scenario where the GTID persister thread +# never updates the GTIDs to the mysql.gtid_executed table and causes the table +# size to grow bigger. +# +# Implementation: +# 1. Start two servers and setup replication. +# 2. Enable Replication Filter on a table on slave. +# 3. Create 2 InnoDB tables on master. Since one of them is filtered on slave, +# updates on that table generates empty transactions. +# 4. Sync the slave. +# 5. Add a debug point on slave to halt the GTID persister before it compresses +# the gtid_executed table. +# 6. Run mysqlslap on master to generate both transactional and +# non-transactional load on slave. +# 7. Using debug_sync utility, halt the GTID persister thread for 60 seconds. +# This is done to simulate the time taken by the persister thread for reading +# and compressing the mysql.gtid_executed table. +# 8. Sleep for 60 seconds. Connect a client and observe the growth in the GTID +# executed table. +# +# You can do by just running +# $ while true; do ../bin/mysql -uroot -h127.0.0.1 -P13001 -e 'select format(count(0),0) from mysql.gtid_executed;'; sleep 2; done +# +# 9. Signal the persister thread to proceed. This initially causes the count to +# decrease. But, thats only temporary and the count shall continue to +# increase there after. + +--source include/have_debug.inc +--source include/have_debug_sync.inc + +# 1. Start two servers and setup replication. +--let $use_gtids=0 +--source include/master-slave.inc + +# 2. Enable Replication Filter on a table on slave. +--source include/rpl_connection_slave.inc +--source include/stop_slave.inc +CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE=('db2.%'); +--source include/start_slave.inc + +# 3. Create 2 InnoDB tables on master. Since one of them is filtered on slave, +# updates on that table generates empty transactions. +--source include/rpl_connection_master.inc +CREATE DATABASE db1; +CREATE DATABASE db2; + +CREATE TABLE db1.t1(i int)engine=innodb; +CREATE TABLE db2.t1(i int)engine=innodb; + +# 4. Sync the slave. +--source include/sync_slave_sql_with_master.inc + +# 5. Add a debug point on slave to halt the GTID persister before it compresses the gtid_executed table. +--let $debug_point= halt_gtid_persister +--source include/add_debug_point.inc + +# 6. Run mysqlslap on master to generate both transactional and non-transactional load on slave. +--source include/rpl_connection_master.inc +--echo # Executing mysqlslap on master + +# db1.t1 is an Innodb transaction on slave and adds the GTID to the persister thread. +--exec_in_background $MYSQL_SLAP --create-schema=test --delimiter=";" --number-of-queries=10000000 --query="insert into db1.t1 values(rand() * 1000)" --concurrency=100 --silent 2>&1 +# db2.t1 causes empty transactions on slave and adds the GTID directly to the table. +--exec_in_background $MYSQL_SLAP --create-schema=test --delimiter=";" --number-of-queries=10000000 --query="insert into db2.t1 values(rand() * 1000)" --concurrency=100 --silent 2>&1 + +# Halt the GTID persister thread for 15 seconds. This is done to simulate the time taken by the persister thread for reading and compressing the mysql.gtid_executed table. +--source include/rpl_connection_slave.inc +SET DEBUG_SYNC='now WAIT_FOR before_compress'; +--echo +--echo # +--echo # Sleeping for 15 seconds. Now connect a client and observe the growth in the GTID executed table. +--echo # +--echo +--let $i=15 +while ($i) { + --echo $i + --sleep 1 + --dec $i +} +--echo # +--echo # Signal the persister thread to proceed. This initially causes the count to decrease. But, thats only temporary and the count shall continue to increase here after. +--echo # +SET DEBUG_SYNC='now SIGNAL go_ahead'; +--let $debug_point= halt_gtid_persister +--source include/remove_debug_point.inc + +# Wait for mysqlslap to finish +--source include/rpl_connection_master.inc +--let $wait_timeout= 100 +--let $wait_condition= SELECT count(*) = 10000000 FROM db2.t1 +--source include/wait_condition.inc + +--let $slave_timeout=1000 +--source include/sync_slave_sql_with_master.inc + +--echo # +--echo # After sync +SELECT @@GLOBAL.gtid_executed; +SELECT * FROM mysql.gtid_executed; + +--source include/rpl_connection_master.inc +DROP DATABASE db1; +DROP DATABASE db2; + +--source include/rpl_end.inc diff --git a/storage/innobase/clone/clone0repl.cc b/storage/innobase/clone/clone0repl.cc index ad4e314e8a8..0104b27b6cc 100644 --- a/storage/innobase/clone/clone0repl.cc +++ b/storage/innobase/clone/clone0repl.cc @@ -31,6 +31,7 @@ this program; if not, write to the Free Software Foundation, Inc., #include "clone0repl.h" #include "clone0api.h" #include "clone0clone.h" +#include "debug_sync.h" #include "sql/field.h" #include "sql/mysqld.h" #include "sql/rpl_gtid_persist.h" @@ -471,6 +472,13 @@ void Clone_persist_gtid::flush_gtids(THD *thd) { m_compression_gtid_counter = 0; /* Write non-innodb GTIDs before compression. */ write_other_gtids(); + DBUG_EXECUTE_IF("halt_gtid_persister", + { + const char action[]="now SIGNAL before_compress WAIT_FOR go_ahead"; + DBUG_ASSERT(!debug_sync_set_action(thd, + STRING_WITH_LEN(action))); + };); + err = gtid_table_persistor->compress(thd); } if (err != 0) { -- 2.25.1