diff options
Diffstat (limited to 'storage/rocksdb/mysql-test/rocksdb_rpl/t')
56 files changed, 1996 insertions, 0 deletions
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/consistent_snapshot_mixed_engines-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/consistent_snapshot_mixed_engines-master.opt new file mode 100644 index 00000000..c747adc9 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/consistent_snapshot_mixed_engines-master.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_bin --log_slave_updates diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/consistent_snapshot_mixed_engines.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/consistent_snapshot_mixed_engines.test new file mode 100644 index 00000000..acea1903 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/consistent_snapshot_mixed_engines.test @@ -0,0 +1,81 @@ +--source include/have_log_bin.inc +--source include/have_rocksdb.inc +--source include/have_innodb.inc +--enable_connect_log +-- let $uuid = `select @@server_uuid;` + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +create table i1 (id int primary key , value int) engine=innodb; +create table r1 (id int primary key , value int) engine=rocksdb; + + +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; + +# Without setting engine, this takes both InnoDB and RocksDB snapshots +-- replace_result $uuid uuid +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +connection con2; +insert into i1 values (1,1); +insert into r1 values (1,1); + +connection con1; +select * from i1; +select * from r1; + +# This takes RocksDB snapshot only but both InnoDB participates in transaction. +-- replace_result $uuid uuid +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; + +connection con2; +insert into i1 values (2,2); +insert into r1 values (2,2); + +connection con1; +# takes InnoDB snapshot here so changes after that not visible +select * from i1; +select * from r1; + +connection con2; +insert into i1 values (3,2); +insert into r1 values (3,2); + +connection con1; +select * from i1; +select * from r1; + +# RocksDB also partipates in transaction +-- replace_result $uuid uuid +START TRANSACTION WITH CONSISTENT INNODB SNAPSHOT; + +connection con2; +insert into r1 values (4,4); + +connection con1; +# takes RocksDB snapshot here so changes after that are not visible +select * from r1; + +connection con2; +insert into r1 values (5,5); + +connection con1; +select * from r1; + +drop table i1; +drop table r1; + +connection default; +disconnect con1; +disconnect con2; +reset master; +--source include/wait_until_count_sessions.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def new file mode 100644 index 00000000..2147e3e0 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def @@ -0,0 +1,34 @@ +## +## Tests that require FB/MySQL specific features for which there are +## no plans to port them to MariaDB +## +rpl_no_unique_check_on_lag : unique_check_lag_threshold is not available in MariaDB +rpl_no_unique_check_on_lag_mts : unique_check_lag_threshold is not available in MariaDB +consistent_snapshot_mixed_engines : Tests START TRANSACTION WITH CONSISTENT $ENGINE_NAME SNAPSHOT +rpl_skip_trx_api_binlog_format : requires @@rpl_skip_tx_api +rpl_ddl_high_priority : DDL commands with HIGH_PRIORITY syntax are not in MariaDB +rpl_gtid_rocksdb_sys_header : MariaDB doesn't support printing "RocksDB: Last MySQL Gtid UUID" into server stderr on startup +singledelete_idempotent_recovery: MariaDB doesn't support --slave-use-idempotent-for-recovery +rpl_mts_dependency_unique_key_conflicts: MariaDB doesn't support --slave-use-idempotent-for-recovery +rpl_missing_columns_sk_update : Uses log_column_names=ON feature which is only present in FB/MySQL +optimize_myrocks_replace_into: requires @@enable_blind_replace support. +rpl_gtid_crash_safe_optimized: requires slave_gtid_info=optimized + +## +## Tests that do not fit MariaDB's test environment (Functional tests only, +## can't have stress tests) +## +rpl_rocksdb_stress_crash : Stress test + +## +## Tests that are disabled for other reasons +## + +multiclient_2pc : Didn't try with MariaDB, yet +rpl_crash_safe_wal_corrupt : Didn't try with MariaDB, yet +rpl_gtid_crash_safe : Didn't try with MariaDB, yet +rpl_gtid_crash_safe_wal_corrupt : Didn't try with MariaDB, yet +rpl_rocksdb_snapshot : Didn't try with MariaDB, yet +rpl_rocksdb_snapshot_without_gtid : Didn't try with MariaDB, yet +rpl_rocksdb_slave_gtid_info_optimized: requires slave-gtid-info=optimized which is an FB/MySQL-only feature +rocksdb_slave_check_before_image_consistency: requires slave_check_before_image_consistency feature diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test new file mode 100644 index 00000000..845f1558 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test @@ -0,0 +1,317 @@ +--source include/have_rocksdb.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc + +# Set GTID cleanup limit high enough that cleanup will not run and we +# can rely on consistent table output in .result. +--let $old_gtid_cleanup_batch_size=`SELECT @@GLOBAL.gtid_cleanup_batch_size` +SET GLOBAL gtid_cleanup_batch_size = 999999999; + +CHANGE MASTER TO master_use_gtid=slave_pos; +SET sql_log_bin=0; +CREATE TABLE mysql.gtid_slave_pos_innodb LIKE mysql.gtid_slave_pos; +ALTER TABLE mysql.gtid_slave_pos_innodb ENGINE=InnoDB; +CREATE TABLE mysql.gtid_slave_pos_rocksdb LIKE mysql.gtid_slave_pos; +ALTER TABLE mysql.gtid_slave_pos_rocksdb ENGINE=rocksdb; +CREATE TABLE mysql.gtid_slave_pos_myisam_redundant LIKE mysql.gtid_slave_pos; +CREATE TABLE mysql.gtid_slave_pos_innodb_redundant LIKE mysql.gtid_slave_pos; +ALTER TABLE mysql.gtid_slave_pos_innodb_redundant ENGINE=InnoDB; +call mtr.add_suppression("Ignoring redundant table.*since.*has the same storage engine"); +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY) ENGINE=rocksdb; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +INSERT INTO t3 VALUES (1); +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM mysql.gtid_slave_pos ORDER BY sub_id; +SELECT * FROM ( SELECT * FROM mysql.gtid_slave_pos_innodb + UNION ALL SELECT * FROM mysql.gtid_slave_pos_innodb_redundant) inner_select + ORDER BY sub_id; +SELECT * FROM mysql.gtid_slave_pos_rocksdb ORDER BY sub_id; + + +# Test status variable Transactions_multi_engine. +--connection server_2 +FLUSH NO_WRITE_TO_BINLOG STATUS; +SET sql_log_bin=0; +SHOW STATUS LIKE "Transactions_multi_engine"; +INSERT INTO t1 VALUES (100); +SHOW STATUS LIKE "Transactions_multi_engine"; +INSERT INTO t2 VALUES (101); +SHOW STATUS LIKE "Transactions_multi_engine"; +INSERT INTO t3 VALUES (101); +SHOW STATUS LIKE "Transactions_multi_engine"; +BEGIN; +INSERT INTO t3 VALUES (102); +INSERT INTO t2 VALUES (103); +COMMIT; +SHOW STATUS LIKE "Transactions_multi_engine"; +BEGIN; +INSERT INTO t2 VALUES (104); +INSERT INTO t3 VALUES (105); +COMMIT; +SHOW STATUS LIKE "Transactions_multi_engine"; +UPDATE t2, t3 SET t2.a=106, t3.a=107 WHERE t2.a=104 AND t3.a=105; +SHOW STATUS LIKE "Transactions_multi_engine"; +# Try again with binlog enabled. +SET sql_log_bin=1; +INSERT INTO t1 VALUES (200); +SHOW STATUS LIKE "Transactions_multi_engine"; +INSERT INTO t2 VALUES (201); +SHOW STATUS LIKE "Transactions_multi_engine"; +INSERT INTO t3 VALUES (201); +SHOW STATUS LIKE "Transactions_multi_engine"; +BEGIN; +INSERT INTO t3 VALUES (202); +INSERT INTO t2 VALUES (203); +COMMIT; +SHOW STATUS LIKE "Transactions_multi_engine"; +BEGIN; +INSERT INTO t2 VALUES (204); +INSERT INTO t3 VALUES (205); +COMMIT; +SHOW STATUS LIKE "Transactions_multi_engine"; +UPDATE t2, t3 SET t2.a=206, t3.a=207 WHERE t2.a=204 AND t3.a=205; +SHOW STATUS LIKE "Transactions_multi_engine"; + +DELETE FROM t1 WHERE a >= 100; +DELETE FROM t2 WHERE a >= 100; +DELETE FROM t3 WHERE a >= 100; + + +# Create a bunch more GTIDs in mysql.gtid_slave_pos* tables to test with. +--connection server_1 +--disable_query_log +let $i=10; +while ($i) { + eval INSERT INTO t1 VALUES (300+$i); + eval INSERT INTO t2 VALUES (300+$i); + eval INSERT INTO t3 VALUES (300+$i); + dec $i; +} +--enable_query_log +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +# Check that we have many rows in mysql.gtid_slave_pos now (since +# @@gtid_cleanup_batch_size was set to a huge value). No need to check +# for an exact number, since that will require changing .result if +# anything changes prior to this point, and we just need to know that +# we have still have some data in the tables to make the following +# test effective. +SELECT COUNT(*)>=10 FROM mysql.gtid_slave_pos; +SELECT COUNT(*)>=10 FROM ( SELECT * FROM mysql.gtid_slave_pos_innodb + UNION ALL SELECT * FROM mysql.gtid_slave_pos_innodb_redundant) inner_select; +SELECT COUNT(*)>=10 FROM mysql.gtid_slave_pos_rocksdb; + +# Check that old GTID rows will be deleted when batch delete size is +# set reasonably. Old row deletion is not 100% deterministic (by design), so +# we must wait for it to occur, but it should occur eventually. +SET GLOBAL gtid_cleanup_batch_size = 3; +let $i=40; +--disable_query_log +--let $keep_include_silent=1 +while ($i) { + let N=`SELECT 1+($i MOD 3)`; + --connection server_1 + eval UPDATE t$N SET a=a+1 WHERE a=(SELECT MAX(a) FROM t$N); + --source include/save_master_gtid.inc + --connection server_2 + --source include/sync_with_master_gtid.inc + let $j=50; + while ($j) { + let $is_done=`SELECT SUM(a)=1 FROM ( + SELECT COUNT(*) AS a FROM mysql.gtid_slave_pos + UNION ALL + SELECT COUNT(*) AS a FROM ( SELECT * FROM mysql.gtid_slave_pos_innodb + UNION ALL SELECT * FROM mysql.gtid_slave_pos_innodb_redundant) inner_select + UNION ALL + SELECT COUNT(*) AS a FROM mysql.gtid_slave_pos_rocksdb) outer_select`; + if ($is_done) { + let $j=0; + } + if (!$is_done) { + real_sleep 0.1; + dec $j; + } + } + dec $i; + if ($is_done) { + let $i=0; + } +} +--enable_query_log +--let $keep_include_silent=0 +if (!$is_done) { + --echo Timed out waiting for mysql.gtid_slave_pos* tables to be cleaned up +} + +--disable_query_log +DELETE FROM t1 WHERE a >= 100; +DELETE FROM t2 WHERE a >= 100; +DELETE FROM t3 WHERE a >= 100; +--enable_query_log + + +# Test status variables Rpl_transactions_multi_engine and Transactions_gtid_foreign_engine. +# Have mysql.gtid_slave_pos* for myisam and innodb but not rocksdb. +--connection server_2 +--source include/stop_slave.inc +SET sql_log_bin=0; +DROP TABLE mysql.gtid_slave_pos_rocksdb; +DROP TABLE mysql.gtid_slave_pos_myisam_redundant; +DROP TABLE mysql.gtid_slave_pos_innodb_redundant; +SET sql_log_bin=1; +FLUSH NO_WRITE_TO_BINLOG STATUS; +--source include/start_slave.inc +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +INSERT INTO t1 VALUES (100); +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +INSERT INTO t2 VALUES (101); +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +INSERT INTO t3 VALUES (101); +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +BEGIN; +INSERT INTO t3 VALUES (102); +INSERT INTO t2 VALUES (103); +COMMIT; +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +BEGIN; +INSERT INTO t2 VALUES (104); +INSERT INTO t3 VALUES (105); +COMMIT; +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +UPDATE t2, t3 SET t2.a=106, t3.a=107 WHERE t2.a=104 AND t3.a=105; +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +# Now the same thing, but without binlogging on the slave. +--connection server_2 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +# Restart without binary log. +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-log-bin +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc +SHOW VARIABLES LIKE 'log_bin'; +--source include/start_slave.inc +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +INSERT INTO t1 VALUES (200); +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +INSERT INTO t2 VALUES (201); +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +INSERT INTO t3 VALUES (201); +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +BEGIN; +INSERT INTO t3 VALUES (202); +INSERT INTO t2 VALUES (203); +COMMIT; +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +BEGIN; +INSERT INTO t2 VALUES (204); +INSERT INTO t3 VALUES (205); +COMMIT; +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + +--connection server_1 +UPDATE t2, t3 SET t2.a=206, t3.a=207 WHERE t2.a=204 AND t3.a=205; +--save_master_pos +--connection server_2 +--sync_with_master +SHOW STATUS LIKE "%transactions%engine"; + + +--connection server_2 +SET sql_log_bin=0; +DROP TABLE mysql.gtid_slave_pos_innodb; +SET sql_log_bin=1; +--disable_query_log +eval SET GLOBAL gtid_cleanup_batch_size = $old_gtid_cleanup_batch_size; +--enable_query_log + +--connection server_1 +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +--source include/rpl_end.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/multiclient_2pc-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/multiclient_2pc-master.opt new file mode 100644 index 00000000..c747adc9 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/multiclient_2pc-master.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_bin --log_slave_updates diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/multiclient_2pc.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/multiclient_2pc.test new file mode 100644 index 00000000..ff484171 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/multiclient_2pc.test @@ -0,0 +1,77 @@ +--source include/have_rocksdb.inc +--source include/have_binlog_format_row.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/big_test.inc +# The test involves a crash which does not seem to be handled well with +# mysql-test/lib/My/SafeProcess/my_safe_process under valgrind as it hangs +# forever. The test did not mean to verify the memory leaks so not much +# coverage should be missed by not running it under valgrind. +--source include/not_valgrind.inc + +--exec echo > $MYSQLTEST_VARDIR/log/mysqld.1.err + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +# Set it to the minimum so that we can make the binlog rotate with a few inserts +SET GLOBAL MAX_BINLOG_SIZE = 4096; +SET GLOBAL ROCKSDB_ENABLE_2PC = ON; +create table t1 (a int primary key, b int, c varchar(255)) engine=rocksdb; + +connect (con1, localhost, root,,); +connect (con2, localhost, root,,); + +# On connection one we insert a row and pause after prepare marker is written to +# WAL. Connection two then inserts many rows to rotate the binlog. After +# connection two completes, connection one continues only to crash before commit +# but after binlog write. On crash recovery we see that connection one's value +# has been recovered and commited +connection con1; +--echo 'con1' +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug="d,crash_commit_after_log"; +SET DEBUG_SYNC='rocksdb.prepared SIGNAL parked WAIT_FOR go'; +--error 0,2013 +--send insert into t1 values (1, 1, "iamtheogthealphaandomega"); + +connection con2; +--echo 'con2' +insert into t1 values (2, 1, "i_am_just_here_to_trigger_a_flush"); + +# Disable 2PC and syncing for faster inserting of dummy rows +# These rows only purpose is to rotate the binlog +SET GLOBAL ROCKSDB_FLUSH_LOG_AT_TRX_COMMIT = 0; +SET GLOBAL SYNC_BINLOG = 0; + +SET DEBUG_SYNC='now WAIT_FOR parked'; +--disable_query_log +--let $pk= 3 +# binlog size is 4096 bytes so with that many insertion it will definitely rotate +while ($pk < 4096) { + eval insert into t1 values ($pk, 1, "foobardatagoesheresothatmorelogsrollwhichiswhatwewant"); + --inc $pk +} +--enable_query_log + +# re-enable 2PC an syncing then write to trigger a flush +# before we trigger the crash to simulate full-durability +SET GLOBAL ROCKSDB_FLUSH_LOG_AT_TRX_COMMIT = 2; +SET GLOBAL SYNC_BINLOG = 1; + +insert into t1 values (1000000, 1, "i_am_just_here_to_trigger_a_flush"); + +--error 0,2013 +SET DEBUG_SYNC='now SIGNAL go'; +--source include/wait_until_disconnected.inc +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect + +--exec python suite/rocksdb/t/check_log_for_xa.py $MYSQLTEST_VARDIR/log/mysqld.1.err commit,prepare,rollback + +select * from t1 where a=1; +select count(*) from t1; + +drop table t1; diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/optimize_myrocks_replace_into.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/optimize_myrocks_replace_into.test new file mode 100644 index 00000000..82b231d4 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/optimize_myrocks_replace_into.test @@ -0,0 +1,149 @@ +--source include/have_rocksdb.inc +--source include/master-slave.inc +--source include/have_debug.inc + +connection master; +SET @prior_rocksdb_perf_context_level = @@rocksdb_perf_context_level; +SET GLOBAL rocksdb_perf_context_level=3; +SET GLOBAL enable_blind_replace=ON; + +# Create and insert some rows in a table +create table t1(c1 int,c2 int, primary key (c1)) engine=rocksdb; +insert into t1 values(1,1),(2,2),(3,3); +select * from t1; + +# Create table which has a trigger only in slave +create table t2(c1 int,c2 int, primary key (c1)) engine=rocksdb; +insert into t2 values(1,1),(2,2),(3,3); +select * from t2; + +# Create table which has a secondary key only in slave +create table t3(c1 int,c2 int, primary key (c1)) engine=rocksdb; +insert into t3 values(1,1),(2,2),(3,3); +select * from t3; + +sync_slave_with_master; + +# Enable blind replace in both slave and master +connection slave; +SET GLOBAL enable_blind_replace=ON; +create trigger trg before insert on t2 for each row set @a:=1; +alter table t3 add constraint slave_unique_key unique (c2); + +connection master; + +sync_slave_with_master; +--echo connect slave +select variable_value into @d from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; + +# Case 1 - 'replace into' on a table with no triggers or secondary keys. Blind replace optimization should kick in both in master and slave +--echo Case 1 +connection master; +--echo connect master +select variable_value into @d from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; + +replace into t1 values(1,11); +replace into t1 values(2,22); +replace into t1 values(3,33); +select case when variable_value-@d > 3 then 'false' else 'true' end as read_free from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; + +select * from t1; + +sync_slave_with_master; +--echo connect slave +select case when variable_value-@d > 3 then 'false' else 'true' end as read_free from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; +select * from t1; + +select variable_value into @d from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; + +# Case 2 - Multiple replaces in a single statement. blind replace optimization should kick in +connection master; +--echo Case 2 +--echo connect master +select variable_value into @d from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; +replace into t1 values(2,44),(3,55); +select case when variable_value-@d > 2 then 'false' else 'true' end as read_free from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; +select * from t1; + +sync_slave_with_master; +--echo connect slave +select case when variable_value-@d > 2 then 'false' else 'true' end as read_free from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; +select * from t1; + +select variable_value into @d from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; + +# Case 3 - A regular update. This is not a blind replace +--echo Case 3 +connection master; +--echo connect master +update t1 set c2=66 where c1=3; +select * from t1; + +sync_slave_with_master; +--echo connect slave +select * from t1; + +select variable_value into @d from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; + +# Case 4 - Slave has trigger on its table. No triggers on the table in master. +# Blind replace optimization should kick in on master. +# Slave should convert this statement into a regular update +--echo Case 4 +connection master; +--echo connect master +select variable_value into @d from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; +replace into t2 values(1,111); +replace into t2 values(2,222); +replace into t2 values(3,333); +select case when variable_value-@d > 3 then 'false' else 'true' end as read_free from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; +select * from t2; + +sync_slave_with_master; +--echo connect slave +select case when variable_value-@d > 3 then 'false' else 'true' end as read_free from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; +select * from t2; + +select variable_value into @d from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; + +# Case 5 - Slave has secondary keys on the table. No secondary keys on the table in master +# Blind replace optimization should kick in on master. +# Slave should convert this statement into a regular delete_insert +--echo Case 5 +connection master; +--echo connect master +select variable_value into @d from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; +replace into t3 values(1,1111); +replace into t3 values(2,2222); +replace into t3 values(3,3333); +select * from t3; + +select case when variable_value-@d > 3 then 'false' else 'true' end as read_free from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; + +sync_slave_with_master; +--echo connect slave +select case when variable_value-@d > 3 then 'false' else 'true' end as read_free from information_schema.global_status where variable_name='rocksdb_num_get_for_update_calls'; +select * from t3; +select * from t3 use index (slave_unique_key); + +# Case 6 - Just to verify all binlog events. +# blind replace will generate a write_rows event. +# Or else, it will be a update_rows event or a delete_rows_write_rows event +--echo Case 6 +connection master; +--source include/show_binlog_events.inc + +connection slave; +--source include/show_binlog_events.inc + +# Cleanup +connection master; +drop table t1; +drop table t2; +drop table t3; +SET GLOBAL rocksdb_perf_context_level = @prior_rocksdb_perf_context_level; +SET GLOBAL enable_blind_replace=DEFAULT; + +connection slave; +SET GLOBAL enable_blind_replace=DEFAULT; + +--source include/rpl_end.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rocksdb_slave_check_before_image_consistency-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rocksdb_slave_check_before_image_consistency-slave.opt new file mode 100644 index 00000000..78b517e9 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rocksdb_slave_check_before_image_consistency-slave.opt @@ -0,0 +1 @@ +--slave_check_before_image_consistency=ON diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rocksdb_slave_check_before_image_consistency.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rocksdb_slave_check_before_image_consistency.test new file mode 100644 index 00000000..d7db127a --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rocksdb_slave_check_before_image_consistency.test @@ -0,0 +1,22 @@ +source include/master-slave.inc; +source include/have_binlog_format_row.inc; + +call mtr.add_suppression("Error_code: 1032"); + +let $engine= rocksdb; + +source extra/rpl_tests/rpl_slave_check_before_image_consistency.inc; + +# check detection with HASH_SCAN enabled +connection slave; +source include/stop_slave.inc; +set @@global.slave_rows_search_algorithms = 'INDEX_SCAN,TABLE_SCAN,HASH_SCAN'; +source include/start_slave.inc; +source extra/rpl_tests/rpl_slave_check_before_image_consistency.inc; + +# cleanup +source include/stop_slave.inc; +set @@global.slave_rows_search_algorithms = DEFAULT; +source include/start_slave.inc; + +source include/rpl_end.inc; diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt new file mode 100644 index 00000000..ed50a8a3 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt @@ -0,0 +1,3 @@ +--innodb --max-binlog-size=4096 + + diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test new file mode 100644 index 00000000..7667f153 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test @@ -0,0 +1,20 @@ +--source include/have_rocksdb.inc +--source include/have_binlog_format_row.inc + +CREATE TABLE `t` ( + `a` text DEFAULT NULL +) ENGINE=ROCKSDB; + + +--let $size=`SELECT @@GLOBAL.max_binlog_size` +--let $loop_cnt= 100 +while ($loop_cnt) +{ + --eval INSERT INTO t SET a=repeat('a', $size) + --eval INSERT INTO t SET a=repeat('a', $size/2) + + --dec $loop_cnt +} + +# Cleanup +DROP TABLE t; diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_check_for_binlog_info.pl b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_check_for_binlog_info.pl new file mode 100644 index 00000000..a5e4d9d8 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_check_for_binlog_info.pl @@ -0,0 +1,19 @@ +my $pid_file = $ARGV[0]; +my $log_file = $ARGV[1]; + +open(my $fh, '<', $pid_file) || die "Cannot open pid file $pid_file"; +my $slave_pid = <$fh>; +close($fh); + +$slave_pid =~ s/\s//g; +open(my $log_fh, '<', $log_file) || die "Cannot open log file $log_file"; + +my $pid_found = 0; +while (my $line = <$log_fh>) { + next unless ($pid_found || $line =~ /^[\d-]* [\d:]* $slave_pid /); + $pid_found = 1 unless ($pid_found); + if ($line =~ /^RocksDB: Last binlog file position.*slave-bin\..*\n/) { + print "Binlog Info Found\n"; + } +} +close($log_fh); diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_crash_safe_wal_corrupt.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_crash_safe_wal_corrupt.cnf new file mode 100644 index 00000000..bbffb0ec --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_crash_safe_wal_corrupt.cnf @@ -0,0 +1,13 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log_slave_updates +rocksdb_enable_2pc=OFF +rocksdb_wal_recovery_mode=2 + +[mysqld.2] +relay_log_recovery=1 +relay_log_info_repository=TABLE +log_slave_updates +rocksdb_enable_2pc=OFF +rocksdb_wal_recovery_mode=2 diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_crash_safe_wal_corrupt.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_crash_safe_wal_corrupt.test new file mode 100644 index 00000000..0e40e542 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_crash_safe_wal_corrupt.test @@ -0,0 +1,12 @@ +--source suite/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc + +connection slave; +--let slave_pid_file= query_get_value(SELECT @@pid_file, @@pid_file, 1) + +# Verify the log file contains the Last binlog line, but only if the slave server's pid is found +--exec perl suite/rocksdb_rpl/t/rpl_check_for_binlog_info.pl $slave_pid_file $MYSQLTEST_VARDIR/log/mysqld.2.err + +--disable_query_log +connection slave; +call mtr.add_suppression("Recovery from master pos"); +--enable_query_log diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_ddl_high_priority.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_ddl_high_priority.test new file mode 100644 index 00000000..7cf4a4d3 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_ddl_high_priority.test @@ -0,0 +1,2 @@ +--source include/have_rocksdb.inc +--source include/rpl_ddl_high_priority.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe-master.opt new file mode 100644 index 00000000..397310d3 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe-master.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates --rocksdb_enable_2pc=OFF diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe-slave.opt new file mode 100644 index 00000000..3f959684 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe-slave.opt @@ -0,0 +1,2 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates --rocksdb_enable_2pc=OFF +--sync_binlog=1000 --relay_log_recovery=1 diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe.test new file mode 100644 index 00000000..5a3e665a --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe.test @@ -0,0 +1,11 @@ +-- source include/have_rocksdb.inc +-- source include/have_gtid.inc +-- source include/master-slave.inc +-- source include/have_debug.inc +-- source include/not_valgrind.inc + +if (`select count(*) = 1 from information_schema.global_variables where variable_name = 'slave_gtid_info' and variable_value = 'optimized';`) { + --skip Test does not support row_write_committed_slave_gtid_optimized policy due to subtle behavioral differences. rpl_gtid_crash_safe_optimized covers slave_gtid_info=optimized. +} + +-- source ../include/rpl_gtid_crash_safe.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized-master.opt new file mode 100644 index 00000000..397310d3 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized-master.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates --rocksdb_enable_2pc=OFF diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized-slave.opt new file mode 100644 index 00000000..e41dcc5e --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized-slave.opt @@ -0,0 +1,2 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates --rocksdb_enable_2pc=OFF +--sync_binlog=1000 --relay_log_recovery=1 --slave_gtid_info=optimized diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized.test new file mode 100644 index 00000000..c2624032 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized.test @@ -0,0 +1,11 @@ +-- source include/have_rocksdb.inc +-- source include/have_gtid.inc +-- source include/master-slave.inc +-- source include/have_debug.inc +-- source include/not_valgrind.inc + +if (`select count(*) = 0 from information_schema.global_variables where variable_name = 'slave_gtid_info' and variable_value = 'optimized';`) { + --skip Test requires row_write_committed_slave_gtid_optimized policy where slave_gtid_info=optimized +} + +-- source ../include/rpl_gtid_crash_safe.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.cnf new file mode 100644 index 00000000..457665f9 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.cnf @@ -0,0 +1,18 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log_slave_updates +gtid_mode=ON +enforce_gtid_consistency=ON +rocksdb_enable_2pc=OFF +rocksdb_wal_recovery_mode=2 + +[mysqld.2] +sync_relay_log_info=100 +relay_log_recovery=1 +relay_log_info_repository=FILE +log_slave_updates +gtid_mode=ON +enforce_gtid_consistency=ON +rocksdb_enable_2pc=OFF +rocksdb_wal_recovery_mode=2 diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc new file mode 100644 index 00000000..16ad535f --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc @@ -0,0 +1,154 @@ +source include/have_rocksdb.inc; +source include/master-slave.inc; +-- let $uuid = `select @@server_uuid;` + +--exec echo > $MYSQLTEST_VARDIR/log/mysqld.1.err + +connection master; +--disable_warnings +drop table if exists x; +--enable_warnings + +connection master; + +select @@binlog_format; + +create table x (id int primary key, value int, value2 int, index(value)) engine=rocksdb; +insert into x values (1,1,1); +insert into x values (2,1,1); +insert into x values (3,1,1); +insert into x values (4,1,1); +insert into x values (5,1,1); +-- replace_result $uuid uuid +select @@global.gtid_executed; + +sync_slave_with_master; +connection slave; +--let slave_data_dir= query_get_value(SELECT @@DATADIR, @@DATADIR, 1) +--let slave_pid_file= query_get_value(SELECT @@pid_file, @@pid_file, 1) +--disable_query_log +select "--- slave state before crash ---" as ""; +--enable_query_log +select * from x; +-- replace_result $uuid uuid +select @@global.gtid_executed; +-- replace_result $uuid uuid +select * from mysql.slave_gtid_info; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect + +--write_file $MYSQL_TMP_DIR/truncate_tail_wal.sh +#!/bin/bash + +F=`ls -t $slave_data_dir/\#rocksdb/*.log | head -n 1` +SIZE=`stat -c %s $F` +NEW_SIZE=`expr $SIZE - 30` +truncate -s $NEW_SIZE $F +rc=$? +if [[ $rc != 0 ]]; then + exit 1 +fi + +kill -9 `head -1 $slave_pid_file` + +exit 0 +EOF +--chmod 0755 $MYSQL_TMP_DIR/truncate_tail_wal.sh +--exec $MYSQL_TMP_DIR/truncate_tail_wal.sh + +--let $rpl_skip_start_slave= 1 +--source include/rpl_start_server.inc +--disable_query_log +select "--- slave state after crash recovery, slave stop, one transaction recovered---" as ""; +--enable_query_log +connection slave; +--exec python suite/rocksdb/t/check_log_for_xa.py $MYSQLTEST_VARDIR/log/mysqld.2.err commit,prepare,rollback +select * from x; +-- replace_result $uuid uuid +select @@global.gtid_executed; +-- replace_result $uuid uuid +select * from mysql.slave_gtid_info; + +--disable_query_log +select "--- slave state after restart, slave start ---" as ""; +--enable_query_log +--source include/start_slave.inc +connection master; +sync_slave_with_master; +connection slave; +select * from x; +-- replace_result $uuid uuid +select @@global.gtid_executed; +-- replace_result $uuid uuid +select * from mysql.slave_gtid_info; + +connection master; +insert into x values (6,1,1); + +sync_slave_with_master; +connection slave; +select * from x; +-- replace_result $uuid uuid +select @@global.gtid_executed; +-- replace_result $uuid uuid +select * from mysql.slave_gtid_info; + +connection master; +insert into x values (7,1,1); +insert into x values (8,1,1); +insert into x values (9,1,1); +insert into x values (10,1,1); +insert into x values (11,1,1); +insert into x values (12,1,1); +select * from x; +-- replace_result $uuid uuid +select @@global.gtid_executed; +sync_slave_with_master; + +connection slave; + +# Corrupting WAL. MyRocks does point in time recovery with wal_recovery_mode=2. +# It loses some data but can resync after restarting slave. + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect + +--write_file $MYSQL_TMP_DIR/corrupt_wal.sh +#!/bin/bash + +# expected to be around 950 bytes +F=`ls -t $slave_data_dir/\#rocksdb/*.log | head -n 1` +SIZE=`stat -c %s $F` +OFFSET=$(( $SIZE-500 )) +dd bs=1 if=/dev/zero of=$F count=100 seek=$OFFSET conv=notrunc + +kill -9 `head -1 $slave_pid_file` + +exit 0 +EOF +--chmod 0755 $MYSQL_TMP_DIR/corrupt_wal.sh +--exec $MYSQL_TMP_DIR/corrupt_wal.sh + +--let $rpl_skip_start_slave= 1 +--source include/rpl_start_server.inc +--disable_query_log +select "--- slave state after crash recovery, slave stop, WAL was corrupted, point in time recovery with wal_recovery_mode=2 ---" as ""; +--enable_query_log +select * from x; +--source include/start_slave.inc +connection master; +sync_slave_with_master; +connection slave; +select * from x; +-- replace_result $uuid uuid +select @@global.gtid_executed; +-- replace_result $uuid uuid +select * from mysql.slave_gtid_info; + +connection master; +drop table x; + + +--remove_file $MYSQL_TMP_DIR/truncate_tail_wal.sh +--remove_file $MYSQL_TMP_DIR/corrupt_wal.sh +--source include/rpl_end.inc + diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.test new file mode 100644 index 00000000..3b660b26 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.test @@ -0,0 +1,12 @@ +-- source suite/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc + +connection slave; +-- let _SLAVE_PID_FILE= query_get_value(SELECT @@pid_file, @@pid_file, 1) + +# Verify the log file contains the Last binlog line, but only if the slave server's pid is found +--exec perl suite/rocksdb_rpl/t/rpl_check_for_binlog_info.pl $slave_pid_file $MYSQLTEST_VARDIR/log/mysqld.2.err + +--disable_query_log +connection slave; +call mtr.add_suppression("Recovery from master pos"); +--enable_query_log diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header-master.opt new file mode 100644 index 00000000..d828b6c0 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header-master.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header-slave.opt new file mode 100644 index 00000000..d828b6c0 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header-slave.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header.test new file mode 100644 index 00000000..d1793c4a --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header.test @@ -0,0 +1,40 @@ +# based on rpl/rpl_gtid_innondb_sys_header.test +source include/have_rocksdb.inc; +source include/master-slave.inc; +source include/have_gtid.inc; +source include/have_debug.inc; +source include/not_valgrind.inc; + +--let $old_debug = `select @@global.debug;` + +connection master; +create table t1 (a int primary key) engine=rocksdb; +insert into t1 values(1); +--eval SET GLOBAL debug = '+d,crash_before_writing_xid' +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--error 2013 +insert into t1 values(2); + +--source include/wait_until_disconnected.inc +--let $rpl_server_number = 1 +--source include/rpl_reconnect.inc + +--eval SET GLOBAL debug = `$old_debug` + +connection slave; +disable_warnings; +source include/start_slave.inc; +enable_warnings; +connection master; +sync_slave_with_master; + +connection master; +--let $master_uuid= query_get_value(select @@server_uuid, @@server_uuid, 1) +--replace_result $master_uuid master_uuid +--exec grep 'RocksDB: Last MySQL Gtid $master_uuid' $MYSQLTEST_VARDIR/log/mysqld.1.err + +drop table t1; +source include/rpl_end.inc; +-- move_file $MYSQLTEST_VARDIR/log/mysqld.1.err $MYSQLTEST_VARDIR/log/mysqld.1.err.orig +-- write_file $MYSQLTEST_VARDIR/log/mysqld.1.err +EOF diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf new file mode 100644 index 00000000..92ed7198 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf @@ -0,0 +1,13 @@ +!include include/default_mysqld.cnf + +[mysqld.1] +binlog_row_image = COMPLETE +log_column_names= ON + +[mysqld.2] +binlog_row_image = COMPLETE +log_column_names= ON + +[ENV] +SERVER_MYPORT_1= @mysqld.1.port +SERVER_MYPORT_2= @mysqld.2.port diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test new file mode 100644 index 00000000..624f54ac --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test @@ -0,0 +1,69 @@ +source include/master-slave.inc; +source include/have_binlog_format_row.inc; + +# Create a table with SKs on master +connection master; +set @@sql_log_bin = 0; +CREATE TABLE `t1` ( + `a` int(10) unsigned NOT NULL DEFAULT '0', + `b` bigint(20) unsigned NOT NULL DEFAULT '0', + `c` bigint(20) unsigned NOT NULL DEFAULT '0', + `d` bigint(20) unsigned NOT NULL DEFAULT '0', + `e` varbinary(64) DEFAULT NULL, + `f` int(10) NOT NULL DEFAULT '0', + `g` int(10) NOT NULL DEFAULT '0', + `h` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`a`,`b`), + KEY `key1` (`a`, `e`(1)), + KEY `key2` (`a`,`h`) +) ENGINE=RocksDB; +set @@sql_log_bin = 1; + +# Create same table on slaves but with two extra columns in the middle (x, y) +connection slave; +set @@sql_log_bin = 0; +CREATE TABLE `t1` ( + `a` int(10) unsigned NOT NULL DEFAULT '0', + `b` bigint(20) unsigned NOT NULL DEFAULT '0', + `c` bigint(20) unsigned NOT NULL DEFAULT '0', + `d` bigint(20) unsigned NOT NULL DEFAULT '0', + `e` varbinary(64) DEFAULT NULL, + `f` int(10) NOT NULL DEFAULT '0', + `g` int(10) NOT NULL DEFAULT '0', + `x` TINYINT(3) UNSIGNED DEFAULT NULL, + `y` INT(10) DEFAULT NULL, + `h` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`a`,`b`), + KEY `key1` (`a`, `e`(1)), + KEY `key2` (`a`,`h`) +) ENGINE=RocksDB; +set @@sql_log_bin = 1; + +# Insert something in the table +connection master; +INSERT INTO t1 VALUES (1, 1, 1, 1, 'a', 1, 1, 1); +SELECT * FROM t1; +sync_slave_with_master; + +connection slave; +SELECT * FROM t1; + +# Update a column that belongs to an SK +connection master; +UPDATE t1 SET h = 10 WHERE h = 1; +SELECT * FROM t1; +sync_slave_with_master; + +# Check if all keys are updated on the slave +connection slave; +SELECT * FROM t1; +SELECT COUNT(*) FROM t1 FORCE INDEX (key1) WHERE h = 10 AND a = 1; +SELECT COUNT(*) FROM t1 FORCE INDEX (key2) WHERE h = 10 AND a = 1; +SELECT COUNT(*) FROM t1 FORCE INDEX (PRIMARY) WHERE h = 10 AND a = 1; + +# Cleanup +connection master; +DROP TABLE t1; +sync_slave_with_master; + +source include/rpl_end.inc; diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test new file mode 100644 index 00000000..5869b9a3 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test @@ -0,0 +1,64 @@ +# RocksDB clone of rpl_mts.rpl_mts_dependency_unique_key_conflicts +source include/have_rocksdb.inc; +source include/have_debug_sync.inc; +source include/master-slave.inc; + +connection slave; +source include/stop_slave.inc; +set @save.slave_parallel_workers= @@global.slave_parallel_workers; +set @save.slave_use_idempotent_for_recovery= @@global.slave_use_idempotent_for_recovery; +set @save.mts_dependency_replication= @@global.mts_dependency_replication; +set @save.mts_dependency_order_commits= @@global.mts_dependency_order_commits; +set @save.debug= @@global.debug; +set @@global.slave_parallel_workers= 2; +set @@global.slave_use_idempotent_for_recovery= YES; +set @@global.mts_dependency_replication= STMT; +set @@global.mts_dependency_order_commits= false; +set @@global.debug= '+d,dbug.dep_wait_before_update_execution'; +source include/start_slave.inc; + +connection master; +create table t1 (a int primary key, b int unique key) engine = rocksdb; +insert into t1 values(1, 1); +source include/sync_slave_sql_with_master.inc; +source include/stop_slave.inc; + +connection master; +update t1 set b = 2 where a = 1; # this will stall on slave due to dbug_sync +insert into t1 values(2, 1); # this should wait for the update to finish + +connection slave; +source include/start_slave.inc; +# wait till one of the workers reach the point just before execution of update +set debug_sync="now wait_for signal.reached"; + +# wait till the other worker is waiting after executing the table map for the +# insert +let $wait_condition= + select count(*)= 1 from information_schema.processlist + where state = 'Waiting for dependencies to be satisfied'; +source include/wait_condition.inc; + +select * from t1; +set debug_sync="now signal signal.done"; + +connection master; +source include/sync_slave_sql_with_master.inc; + +connection slave; +select * from t1; + +# Cleanup +connection master; +drop table t1; +source include/sync_slave_sql_with_master.inc; +connection slave; +source include/stop_slave.inc; +set @@global.slave_parallel_workers= @save.slave_parallel_workers; +set @@global.mts_dependency_replication= @save.mts_dependency_replication; +set @@global.slave_use_idempotent_for_recovery= @save.slave_use_idempotent_for_recovery; +set @@global.mts_dependency_order_commits= @save.mts_dependency_order_commits; +set @@global.debug= @save.debug; +source include/start_slave.inc; + +source include/rpl_end.inc; diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag-slave.opt new file mode 100644 index 00000000..1c8dc1e6 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag-slave.opt @@ -0,0 +1 @@ +--unique-check-lag-threshold=5 diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag.test new file mode 100644 index 00000000..cecacda4 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag.test @@ -0,0 +1,7 @@ +--echo # +--echo # Ensure skip_unique_check is set when lag exceeds lag_threshold +--echo # + +--source include/have_rocksdb.inc +--source ../include/rpl_no_unique_check_on_lag.inc + diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag_mts-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag_mts-slave.opt new file mode 100644 index 00000000..1c8dc1e6 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag_mts-slave.opt @@ -0,0 +1 @@ +--unique-check-lag-threshold=5 diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag_mts.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag_mts.test new file mode 100644 index 00000000..7e77ec87 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag_mts.test @@ -0,0 +1,3 @@ +--source include/have_rocksdb.inc +--source ../include/rpl_no_unique_check_on_lag.inc + diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover-master.opt new file mode 100644 index 00000000..f8f297c5 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover-master.opt @@ -0,0 +1 @@ +--log_bin --log_slave_updates --rocksdb_flush_log_at_trx_commit=1 diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover-slave.opt new file mode 100644 index 00000000..7a3f630f --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover-slave.opt @@ -0,0 +1 @@ +--log_bin --log_slave_updates diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test new file mode 100644 index 00000000..58b37209 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test @@ -0,0 +1,57 @@ +--source include/have_binlog_format_row.inc +--source include/have_rocksdb.inc +--source include/have_debug.inc +--source include/not_valgrind.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +create table t1 (a int primary key, msg varchar(255)) engine=rocksdb; + +SET GLOBAL ROCKSDB_ENABLE_2PC = ON; +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="d,crash_commit_after_prepare"; +--error 0,2013 +insert into t1 values (1, 'dogz'); +--enable_reconnect +--source include/wait_until_connected_again.inc +select * from t1; + +SET GLOBAL ROCKSDB_ENABLE_2PC = ON; +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="d,crash_commit_after_log"; +--error 0,2013 +insert into t1 values (2, 'catz'), (3, 'men'); +--enable_reconnect +--source include/wait_until_connected_again.inc +select * from t1; + +SET GLOBAL ROCKSDB_ENABLE_2PC = ON; +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="d,crash_commit_after"; +--error 0,2013 +insert into t1 values (4, 'cars'), (5, 'foo'); +--enable_reconnect +--source include/wait_until_connected_again.inc +select * from t1; + +SET GLOBAL ROCKSDB_ENABLE_2PC = OFF; +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="d,crash_commit_after_log"; +--error 0,2013 +insert into t1 values (6, 'shipz'), (7, 'tankz'); +--enable_reconnect +--source include/wait_until_connected_again.inc +select * from t1; + +SET GLOBAL ROCKSDB_ENABLE_2PC = OFF; +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="d,crash_commit_after"; +--error 0,2013 +insert into t1 values (8, 'space'), (9, 'time'); +--enable_reconnect +--source include/wait_until_connected_again.inc +select * from t1; + +drop table t1; diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized-master.opt new file mode 100644 index 00000000..c747adc9 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized-master.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_bin --log_slave_updates diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized-slave.opt new file mode 100644 index 00000000..6cde3c55 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized-slave.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_bin --log_slave_updates --slave-gtid-info=optimized diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized.test new file mode 100644 index 00000000..c8a0c8da --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized.test @@ -0,0 +1,51 @@ +--source include/have_rocksdb.inc +--source include/master-slave.inc +--source include/have_binlog_format_row.inc + +if (`select count(*) = 0 from information_schema.global_variables where variable_name = 'slave_gtid_info' and variable_value = 'optimized';`) { + --skip Test requires row_write_committed_slave_gtid_optimized policy where slave_gtid_info=optimized +} + +--echo Make changes in master +create table test1 (a int primary key, b int) engine=rocksdb; +insert into test1 values (1, 1); + +--echo Make sure slave is up-to-date and mysql.slave_gtid_info is good +sync_slave_with_master slave; +connection slave; +select * from test1; +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +select id, database_name, last_gtid from mysql.slave_gtid_info; + +--echo Make changes in master +connection master; +insert into test1 values (2, 2); + +--echo Make sure slave is up-to-date and mysql.slave_gtid_info is good +sync_slave_with_master slave; +connection slave; +select @@slave_gtid_info; +select * from test1; + +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +select * from mysql.slave_gtid_info; + +--echo Make changes in master +connection master; +insert into test1 values (3, 3); +insert into test1 values (4, 4); + +--echo Make sure slave is up-to-date and mysql.slave_gtid_info is good +sync_slave_with_master slave; +connection slave; +select * from test1; + +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +select id, database_name, last_gtid from mysql.slave_gtid_info; + +connection master; +DROP TABLE IF EXISTS test1; + +sync_slave_with_master slave; + +--source include/rpl_end.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot-master.opt new file mode 100644 index 00000000..c747adc9 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot-master.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_bin --log_slave_updates diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot-slave.opt new file mode 100644 index 00000000..c747adc9 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot-slave.opt @@ -0,0 +1 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_bin --log_slave_updates diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot.test new file mode 100644 index 00000000..200f1cb3 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot.test @@ -0,0 +1,374 @@ +--source include/have_rocksdb.inc +--source include/master-slave.inc +--source include/have_binlog_format_row.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +--echo # Establish connection con1 (user=root) +connect (con1,localhost,root,,); +--echo # Establish connection con2 (user=root) +connect (con2,localhost,root,,); +--echo # Establish connection con3 (user=root) +connect (con3,localhost,root,,); +--echo # Establish connection con4 (user=root) +connect (con4,localhost,root,,); + +--echo # reset replication to guarantee that master-bin.000001 is used +connection slave; +--source include/stop_slave.inc +RESET SLAVE; +RESET MASTER; + +connection master; +RESET MASTER; + +connection slave; +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host="127.0.0.1",master_port=$MASTER_MYPORT,master_user="root"; +--source include/start_slave.inc + +### Test 1: +### - While a consistent snapshot transaction is executed, +### no external inserts should be visible to the transaction. + +--echo # Switch to connection con1 +connection con1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=rocksdb; +INSERT INTO t1 VALUES(1); + +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +--error ER_ISOLATION_LEVEL_WITH_CONSISTENT_SNAPSHOT +START TRANSACTION WITH CONSISTENT SNAPSHOT; +--error ER_ISOLATION_LEVEL_WITH_CONSISTENT_SNAPSHOT +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; +ROLLBACK; +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + + +--disable_query_log +--disable_result_log +let $x=1000; +while ($x) { + START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; + dec $x; +} +--enable_query_log +--enable_result_log + +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; + +--echo # Switch to connection con2 +connection con2; +INSERT INTO t1 VALUES(2); +INSERT INTO t1 VALUES(3); + +--echo # Switch to connection con1 +connection con1; +SELECT * FROM t1; # should fetch one row +COMMIT; + +SELECT * FROM t1; # should fetch three rows + +DROP TABLE t1; + +### Test 2: +### - confirm result from snapshot select and replication replay matches original + +--echo # Switch to connection con1 +connection con1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=rocksdb; +INSERT INTO t1 VALUES(1); + +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; + +let $binlog_pos = query_get_value(START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT, Position, 1); + +--echo # Switch to connection con2 +connection con2; +INSERT INTO t1 VALUES(2); +INSERT INTO t1 VALUES(3); + +--echo # Switch to connection con1 +connection con1; +SELECT * FROM t1; + +--let $outfile = $MYSQLTEST_VARDIR/tmp/rpl_rocksdb_snapshot.out.file + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT * INTO OUTFILE '$outfile' FROM t1; +COMMIT; + +--echo # Switch to slave +sync_slave_with_master slave; + +CREATE TABLE t1_backup LIKE t1; +INSERT INTO t1_backup SELECT * FROM t1; +--source include/stop_slave.inc +RESET SLAVE; +RESET MASTER; +DELETE FROM t1; +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval LOAD DATA INFILE '$outfile' INTO TABLE t1; +SELECT * FROM t1; + +--replace_result $MASTER_MYPORT MASTER_PORT $binlog_pos binlog_pos +eval CHANGE MASTER TO master_host="127.0.0.1",master_port=$MASTER_MYPORT,master_user="root",master_log_file="master-bin.000001",master_log_pos=$binlog_pos; +--source include/start_slave.inc + +connection master; +sync_slave_with_master slave; + +SELECT * FROM t1; +SELECT * FROM t1_backup; +DROP TABLE t1_backup; + +connection master; +DROP TABLE t1; +--remove_file $outfile + +### Test 3: +### - confirm result from snapshot select and replication replay matches original +### - use non-deterministic concurrency + +--echo # Switch to connection con1 +connection con1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=rocksdb; +INSERT INTO t1 VALUES(1); + +--echo # async queries from con2 +connection con2; +send INSERT INTO t1 VALUES(2); + +--echo # async queries from con3 +connection con3; +send INSERT INTO t1 VALUES(21); + +--echo # Switch to connection con1 +connection con1; + +let $binlog_pos = query_get_value(START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT, Position, 1); + +--echo # Switch to connection con4 +connection con4; +INSERT INTO t1 VALUES(9); + +--echo # Switch to connection con1 +connection con1; + +--let $outfile = $MYSQLTEST_VARDIR/tmp/rpl_rocksdb_snapshot.out.file + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT * INTO OUTFILE '$outfile' FROM t1; +COMMIT; + +--echo # reap async statements +connection con2; +reap; + +connection con3; +reap; + +--echo # Switch to slave +sync_slave_with_master slave; + +CREATE TABLE t1_backup LIKE t1; +INSERT INTO t1_backup SELECT * FROM t1; +--source include/stop_slave.inc +RESET SLAVE; +RESET MASTER; +DELETE FROM t1; +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval LOAD DATA INFILE '$outfile' INTO TABLE t1; + +--replace_result $MASTER_MYPORT MASTER_PORT $binlog_pos binlog_pos +eval CHANGE MASTER TO master_host="127.0.0.1",master_port=$MASTER_MYPORT,master_user="root",master_log_file="master-bin.000001",master_log_pos=$binlog_pos; +--source include/start_slave.inc + +--echo # sync and then query slave +connection master; +sync_slave_with_master slave; + +let $sum1 = `SELECT SUM(a) from t1`; +let $sum2 = `SELECT SUM(a) from t1_backup`; +--disable_query_log +eval select $sum2 - $sum1 ShouldBeZero; +--enable_query_log + +DROP TABLE t1_backup; + +connection master; +DROP TABLE t1; +--remove_file $outfile + +### Test 4: +### - confirm result from snapshot select and replication relay using gtid protocol matches original + +--echo # Switch to connection con1 +connection con1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=rocksdb; +INSERT INTO t1 VALUES(1); + +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; +-- replace_regex /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/UUID/ +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; + +let $gtid_executed = query_get_value(START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT, Gtid_executed, 1); + +--echo # Switch to connection con2 +connection con2; +INSERT INTO t1 VALUES(2); +INSERT INTO t1 VALUES(3); + +--echo # Switch to connection con1 +connection con1; +SELECT * FROM t1; + +--let $outfile = $MYSQLTEST_VARDIR/tmp/rpl_rocksdb_snapshot.out.file + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT * INTO OUTFILE '$outfile' FROM t1; +COMMIT; + +--echo # Switch to slave +sync_slave_with_master slave; + +CREATE TABLE t1_backup LIKE t1; +INSERT INTO t1_backup SELECT * FROM t1; +--source include/stop_slave.inc +RESET SLAVE; +RESET MASTER; +--replace_result $gtid_executed gtid_executed_from_snapshot +eval SET @@global.gtid_purged='$gtid_executed'; +DELETE FROM t1; +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval LOAD DATA INFILE '$outfile' INTO TABLE t1; +SELECT * FROM t1; + +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host="127.0.0.1",master_port=$MASTER_MYPORT,master_user="root", master_auto_position=1; +--source include/start_slave.inc + +connection master; +sync_slave_with_master slave; + +SELECT * FROM t1; +SELECT * FROM t1_backup; +DROP TABLE t1_backup; + +connection master; +DROP TABLE t1; +--remove_file $outfile + +### Test 5: +### - confirm result from snapshot select and replication replay using gtid_protocol matches original +### - use non-deterministic concurrency + +--echo # Switch to connection con1 +connection con1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=rocksdb; +INSERT INTO t1 VALUES(1); + +--echo # async queries from con2 +connection con2; +send INSERT INTO t1 VALUES(2); + +--echo # async queries from con3 +connection con3; +send INSERT INTO t1 VALUES(21); + +--echo # Switch to connection con1 +connection con1; + +let $gtid_executed = query_get_value(START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT, Gtid_executed, 1); + +--echo # Switch to connection con4 +connection con4; +INSERT INTO t1 VALUES(9); + +--echo # Switch to connection con1 +connection con1; + +--let $outfile = $MYSQLTEST_VARDIR/tmp/rpl_rocksdb_snapshot.out.file + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval SELECT * INTO OUTFILE '$outfile' FROM t1; +COMMIT; + +--echo # reap async statements +connection con2; +reap; + +connection con3; +reap; + +--echo # Switch to slave +sync_slave_with_master slave; + +CREATE TABLE t1_backup LIKE t1; +INSERT INTO t1_backup SELECT * FROM t1; +--source include/stop_slave.inc +RESET SLAVE; +RESET MASTER; +--replace_result $gtid_executed gtid_executed_from_snapshot +eval SET @@global.gtid_purged='$gtid_executed'; +DELETE FROM t1; + +--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> +eval LOAD DATA INFILE '$outfile' INTO TABLE t1; + +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host="127.0.0.1",master_port=$MASTER_MYPORT,master_user="root", master_auto_position=1; +--source include/start_slave.inc + +--echo # sync and then query slave +connection master; +sync_slave_with_master slave; + +let $sum1 = `SELECT SUM(a) from t1`; +let $sum2 = `SELECT SUM(a) from t1_backup`; +--disable_query_log +eval select $sum2 - $sum1 ShouldBeZero; +--enable_query_log + +DROP TABLE t1_backup; + +connection master; +DROP TABLE t1; +--remove_file $outfile + +--echo # Switch to connection default + close connections con1 and con2 +connection con1; +disconnect con1; +--source include/wait_until_disconnected.inc +connection con2; +disconnect con2; +--source include/wait_until_disconnected.inc +connection con3; +disconnect con3; +--source include/wait_until_disconnected.inc +connection con4; +disconnect con4; +--source include/wait_until_disconnected.inc + +connection default; +sync_slave_with_master slave; +--source include/stop_slave.inc +CHANGE MASTER to master_auto_position=0; +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot_without_gtid.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot_without_gtid.test new file mode 100644 index 00000000..79d71f20 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot_without_gtid.test @@ -0,0 +1,18 @@ +--source include/have_rocksdb.inc +--source include/master-slave.inc +--source include/have_binlog_format_row.inc + +--connection master +create table t1(a int primary key); + +FLUSH LOGS; + +insert into t1 values(1); +insert into t1 values(2); + +FLUSH LOGS; + +START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; + +drop table t1; +-- source include/rpl_end.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash-master.opt new file mode 100644 index 00000000..5c5a73bf --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash-master.opt @@ -0,0 +1,2 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates +--binlog_rows_query_log_events=TRUE --rocksdb_unsafe_for_binlog=TRUE diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash-slave.opt new file mode 100644 index 00000000..b3d52445 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash-slave.opt @@ -0,0 +1,3 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates --max_binlog_size=50000 +--slave_parallel_workers=30 --relay_log_recovery=1 --rocksdb_unsafe_for_binlog=TRUE +--rocksdb_wal_recovery_mode=2 diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash.test new file mode 100644 index 00000000..17b86606 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash.test @@ -0,0 +1,26 @@ +-- source include/big_test.inc +-- source include/master-slave.inc +-- source include/not_valgrind.inc +-- source include/have_gtid.inc +-- source include/have_rocksdb.inc + +connection master; +call mtr.add_suppression(".*"); +sync_slave_with_master; +-- source include/stop_slave.inc +change master to master_auto_position=1; +-- source include/start_slave.inc + +-- let $iter=100 +-- let $databases=30 +-- let $num_crashes=100 +-- let $include_silent=1 +-- let $storage_engine='rocksdb' +-- source extra/rpl_tests/rpl_parallel_load_innodb.test +-- let $include_silent=0 + +-- source include/stop_slave.inc +change master to master_auto_position=0; +-- source include/start_slave.inc + +-- source include/rpl_end.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format-master.opt new file mode 100644 index 00000000..39bb3238 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format-master.opt @@ -0,0 +1,2 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates +--binlog_format=STATEMENT --default-storage-engine=rocksdb diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format-slave.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format-slave.opt new file mode 100644 index 00000000..826f1ee9 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format-slave.opt @@ -0,0 +1,2 @@ +--gtid_mode=ON --enforce_gtid_consistency --log_slave_updates +--sync_binlog=1000 --relay_log_recovery=1 --default-storage-engine=rocksdb diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format.test new file mode 100644 index 00000000..1ea9add8 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format.test @@ -0,0 +1,52 @@ +# Checks if the slave stops executing transactions when master's binlog format +# is STATEMENT but rpl_skip_tx_api is enabled +-- source include/have_rocksdb.inc +-- source include/master-slave.inc + +call mtr.add_suppression("Master's binlog format is not ROW but rpl_skip_tx_api is enabled on the slave"); + +connection slave; +let $old_rpl_skip_tx_api= `SELECT @@global.rpl_skip_tx_api`; +set global rpl_skip_tx_api=ON; + +connection master; +let $old_rocksdb_unsafe_for_binlog= `SELECT @@global.rocksdb_unsafe_for_binlog`; +set global rocksdb_unsafe_for_binlog=1; +create table t1(a int); +set session binlog_format=STATEMENT; +insert into t1 values(1); + +# Wait till we hit the binlog format mismatch error +connection slave; +let $slave_sql_errno= convert_error(ER_MTS_INCONSISTENT_DATA); # 1756 +let $show_slave_sql_error= 1; +source include/wait_for_slave_sql_error.inc; + +# Print table +connection slave; +echo "Table after error"; +select * from t1; + +connection slave; +# Turn off rpl_skip_tx_api and start the slave again +set global rpl_skip_tx_api=OFF; +source include/start_slave.inc; + +connection slave; +source include/sync_slave_sql_with_master.inc; + +connection slave; +# Print table again +echo "Table after error fixed"; +select * from t1; + +# Cleanup +connection master; +drop table t1; +eval set global rocksdb_unsafe_for_binlog=$old_rocksdb_unsafe_for_binlog; +sync_slave_with_master; + +connection slave; +eval set global rpl_skip_tx_api=$old_rpl_skip_tx_api; + +-- source include/rpl_end.inc diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_xa.inc b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_xa.inc new file mode 100644 index 00000000..253d9f16 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_xa.inc @@ -0,0 +1,84 @@ +# +# This "body" file checks general properties of XA transaction replication +# as of MDEV-7974, including XA of mixed engine branches. +# Parameters: +# --let rpl_xa_check= SELECT ... +# +connection master; +create table ti (a int, b int) engine=innodb; +create table t1 (a int, b int) engine=rocksdb; +insert into ti values(0, 0); +insert into t1 values(0, 0); +xa start 't'; +insert into ti values(1, 2); +insert into t1 values(1, 2); +xa end 't'; +xa prepare 't'; +xa commit 't'; + +sync_slave_with_master; +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +connection master; + +xa start 't'; +insert into ti values(3, 4); +insert into t1 values(3, 4); +xa end 't'; +xa prepare 't'; +xa rollback 't'; + +sync_slave_with_master; +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +connection master; +SET pseudo_slave_mode=1; +create table t2 (a int) engine=rocksdb; +xa start 't'; +insert into ti values (5, 6); +insert into t1 values (5, 6); +xa end 't'; +xa prepare 't'; +xa start 's'; +insert into ti values (7, 8); +insert into t2 values (0); +xa end 's'; +xa prepare 's'; +--source include/save_master_gtid.inc + +connection slave; +source include/sync_with_master_gtid.inc; +if ($rpl_xa_check) +{ + --eval $rpl_xa_check + if ($rpl_xa_verbose) + { + --eval SELECT $rpl_xa_check_lhs + --eval SELECT $rpl_xa_check_rhs + } +} +xa recover; + +connection master; +xa commit 't'; +xa commit 's'; +SET pseudo_slave_mode=0; + +# pure rocksdb xa +xa start 'r'; +insert into t1 values(7, 8); +xa end 'r'; +xa prepare 'r'; +xa commit 'r'; + + +sync_slave_with_master; +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; +let $diff_tables= master:t2, slave:t2; +source include/diff_tables.inc; + +connection master; +drop table ti, t1, t2; diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_xa.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_xa.test new file mode 100644 index 00000000..34384c74 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_xa.test @@ -0,0 +1,7 @@ +source include/have_rocksdb.inc; +source include/have_innodb.inc; +source include/master-slave.inc; +source include/have_binlog_format_row.inc; + +source rpl_xa.inc; +source include/rpl_end.inc; diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_recovery.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_recovery.cnf new file mode 100644 index 00000000..71e124ad --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_recovery.cnf @@ -0,0 +1,15 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log_slave_updates +gtid_mode=ON +enforce_gtid_consistency=ON + +[mysqld.2] +relay_log_recovery=1 +relay_log_info_repository=FILE +log_slave_updates +gtid_mode=ON +enforce_gtid_consistency=ON +slave_use_idempotent_for_recovery=Yes + diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_recovery.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_recovery.test new file mode 100644 index 00000000..6d953ead --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_recovery.test @@ -0,0 +1,78 @@ + +--source include/have_binlog_format_row.inc +--source include/have_rocksdb.inc +--source include/master-slave.inc +--source include/have_gtid.inc +--source include/not_valgrind.inc + +# This is a test case for issue#655 -- SingleDelete on Primary Key may +# cause extra rows than Secondary Keys + +call mtr.add_suppression("Recovery from master pos"); + +connection master; +--disable_warnings +drop table if exists r1; +--enable_warnings +create table r1 (id1 int, id2 int, primary key (id1, id2), index i (id2)) engine=rocksdb; +insert into r1 values (1, 1000); + +sync_slave_with_master; +connection slave; +set global rocksdb_force_flush_memtable_now=1; +--let slave_data_dir= query_get_value(SELECT @@DATADIR, @@DATADIR, 1) +--let slave_binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) +--let slave_pid_file= query_get_value(SELECT @@pid_file, @@pid_file, 1) +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect + +--write_file $MYSQL_TMP_DIR/truncate_tail_binlog.sh +#!/bin/bash + +F=$slave_data_dir/$slave_binlog_file +SIZE=`stat -c %s $F` +NEW_SIZE=`expr $SIZE - 100` +truncate -s $NEW_SIZE $F +rc=$? +if [[ $rc != 0 ]]; then + exit 1 +fi + +kill -9 `head -1 $slave_pid_file` + +exit 0 +EOF +--chmod 0755 $MYSQL_TMP_DIR/truncate_tail_binlog.sh +--exec $MYSQL_TMP_DIR/truncate_tail_binlog.sh + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect + +# Crash recovery (losing some binlogs) with slave_use_idempotent_for_recovery may +# replay same transactions with slave_exec_mode=idempotent implicitly enabled. +# On slave, the last insert is converted to update with the same key. +# It should be treated as SD and Put (same as singledelete_idempotent_table.test). + +--source include/rpl_start_server.inc +--source include/start_slave.inc + +# Due to the binlogs being truncated, the slave may still think it's processed up to +# the truncated binlog and select master_pos_wait() can return prematurely. Add +# a new transaction to the master to force master_pos_wait() to wait. +connection master; +insert into r1 values (2,2000); +sync_slave_with_master; + +connection slave; +delete r1 from r1 force index (i) where id2=1000; +select id1,id2 from r1 force index (primary) where id1=1 and id2=1000; +select id2 from r1 force index (i) where id1=1 and id2=1000; +set global rocksdb_compact_cf='default'; +select id1,id2 from r1 force index (primary) where id1=1 and id2=1000; +select id2 from r1 force index (i) where id1=1 and id2=1000; + +connection master; +drop table r1; + +--remove_file $MYSQL_TMP_DIR/truncate_tail_binlog.sh +--source include/rpl_end.inc + + diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf new file mode 100644 index 00000000..5f1f87d7 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf @@ -0,0 +1,11 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log_slave_updates + +[mysqld.2] +relay_log_recovery=1 +#relay_log_info_repository=FILE +log_slave_updates +#rbr_idempotent_tables='r1' +slave_exec_mode=IDEMPOTENT diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test new file mode 100644 index 00000000..00dce7c2 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test @@ -0,0 +1,44 @@ + +--source include/have_binlog_format_row.inc +--source include/have_rocksdb.inc +--source include/master-slave.inc +#--source include/have_gtid.inc +--source include/not_valgrind.inc + +# This is a test case for issue#655 -- SingleDelete on Primary Key may +# cause extra rows than Secondary Keys + +connection master; +--disable_warnings +drop table if exists r1; +--enable_warnings +create table r1 (id1 int, id2 int, primary key (id1, id2), index i (id2)) engine=rocksdb; +insert into r1 values (1, 1000); +set sql_log_bin=0; +delete from r1 where id1=1 and id2=1000; +set sql_log_bin=1; + +sync_slave_with_master; +connection slave; +set global rocksdb_force_flush_memtable_now=1; + +connection master; +# same key insert on slave. Since slave sets rbr_idempotent_tables, the insert +# is converted to update with the same key. MyRocks should call SD and Put for the key +insert into r1 values (1, 1000); +sync_slave_with_master; + +connection slave; +delete r1 from r1 force index (i) where id2=1000; +select id1,id2 from r1 force index (primary); +select id2 from r1 force index (i); +set global rocksdb_compact_cf='default'; +select id1,id2 from r1 force index (primary); +select id2 from r1 force index (i); + +connection master; +drop table r1; + +--source include/rpl_end.inc + + |