summaryrefslogtreecommitdiffstats
path: root/storage/rocksdb/mysql-test/rocksdb_rpl/t
diff options
context:
space:
mode:
Diffstat (limited to 'storage/rocksdb/mysql-test/rocksdb_rpl/t')
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/consistent_snapshot_mixed_engines-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/consistent_snapshot_mixed_engines.test81
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def34
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test317
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/multiclient_2pc-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/multiclient_2pc.test77
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/optimize_myrocks_replace_into.test149
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rocksdb_slave_check_before_image_consistency-slave.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rocksdb_slave_check_before_image_consistency.test22
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test20
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_check_for_binlog_info.pl19
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_crash_safe_wal_corrupt.cnf13
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_crash_safe_wal_corrupt.test12
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_ddl_high_priority.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe-slave.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe.test11
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized-slave.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_optimized.test11
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.cnf18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc154
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.test12
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header-slave.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_rocksdb_sys_header.test40
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf13
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test69
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test64
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag-slave.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag.test7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag_mts-slave.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_no_unique_check_on_lag_mts.test3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover-slave.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test57
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized-slave.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_slave_gtid_info_optimized.test51
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot-slave.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot.test374
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_snapshot_without_gtid.test18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash-master.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash-slave.opt3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_stress_crash.test26
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format-master.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format-slave.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_skip_trx_api_binlog_format.test52
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_xa.inc84
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_xa.test7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_recovery.cnf15
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_recovery.test78
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf11
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test44
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
+
+