diff --git a/deps/xredis-gtid b/deps/xredis-gtid index 710a447f582..d1a083708ff 160000 --- a/deps/xredis-gtid +++ b/deps/xredis-gtid @@ -1 +1 @@ -Subproject commit 710a447f5823b85b6237dce947d50e205199f0fc +Subproject commit d1a083708ffc7105f9b93e2bca01cb82f87447e6 diff --git a/tests/gtid b/tests/gtid new file mode 120000 index 00000000000..68f4addb0e0 --- /dev/null +++ b/tests/gtid @@ -0,0 +1 @@ +../deps/xredis-gtid/xredis/tests/gtid \ No newline at end of file diff --git a/tests/gtid/aof.tcl b/tests/gtid/aof.tcl deleted file mode 100644 index d2c6bb0769e..00000000000 --- a/tests/gtid/aof.tcl +++ /dev/null @@ -1,166 +0,0 @@ -if {!$::swap} { -source tests/support/aofmanifest.tcl -set defaults {appendonly {yes} appendfilename {appendonly.aof} appenddirname {appendonlydir} auto-aof-rewrite-percentage {0}} -set server_path [tmpdir server.multi.aof] -set aof_dirname "appendonlydir" -set aof_basename "appendonly.aof" -set aof_dirpath "$server_path/$aof_dirname" -set aof_base1_file "$server_path/$aof_dirname/${aof_basename}.1$::base_aof_sufix$::aof_format_suffix" -set aof_base2_file "$server_path/$aof_dirname/${aof_basename}.2$::base_aof_sufix$::aof_format_suffix" -set aof_incr1_file "$server_path/$aof_dirname/${aof_basename}.1$::incr_aof_sufix$::aof_format_suffix" -set aof_incr2_file "$server_path/$aof_dirname/${aof_basename}.2$::incr_aof_sufix$::aof_format_suffix" -set aof_incr3_file "$server_path/$aof_dirname/${aof_basename}.3$::incr_aof_sufix$::aof_format_suffix" -set aof_manifest_file "$server_path/$aof_dirname/${aof_basename}$::manifest_suffix" -set aof_old_name_old_path "$server_path/$aof_basename" -set aof_old_name_new_path "$aof_dirpath/$aof_basename" -set aof_old_name_old_path2 "$server_path/${aof_basename}2" -set aof_manifest_file2 "$server_path/$aof_dirname/${aof_basename}2$::manifest_suffix" - - -test "aof" { - proc read_command_arg {fd} { - set len [::redis::redis_read_line $fd] - set len [string range $len 1 end] - set buf [gets $fd] - while {[string length $buf] != $len} { - set buf1 [gets $fd] - set buf "$buf$buf1" - } - return $buf - } - proc read_command {fd} { - set count [::redis::redis_read_line $fd] - if {$count == 0} { - return {} - } - set count [string range $count 1 end] - set res {} - for {set j 0} {$j < $count} {incr j} { - set arg [read_command_arg $fd] - if {$j == 0} {set arg [string tolower $arg]} - lappend res $arg - } - return $res - } - proc try_read_aof {file line_count} { - set try_num 3 - set res {} - while {$try_num > 0} { - set fd [open $file] - puts $file - set res {} - set command [read_command $fd] - while {$command != {}} { - lappend res $command - set command [read_command $fd] - } - close $fd - if {[llength $res] == $line_count} { - break - } - set try_num [expr {$try_num - 1}] - after 1000 - } - assert_equal [llength $res] $line_count - return $res - } - proc assert_aof {s patterns} { - assert_equal [llength $s] [llength $patterns] - for {set j 0} {$j < [llength $patterns]} {incr j} { - assert_match [lindex $patterns $j] [lindex $s $j] - } - } - test "save aof and reload aof" { - - start_server_aof [list dir $server_path aof-load-truncated yes gtid-enabled yes] { - test "write expire command save to aof" { - set client [redis [srv host] [srv port] 0 $::tls] - $client set k1 v ex 1000 - $client set k2 v px 2000 - $client set k3 v - $client expire k3 1000 - $client set k4 v - $client pexpire k4 2000 - $client set k v - # $client bgrewriteaof - # waitForBgrewriteaof $client - set config [srv config] - set dir [dict get $config dir] - set res [try_read_aof $dir/appendonlydir/appendonly.aof.1.incr.aof 8] - assert_aof $res { - {select *} - {gtid * 0 SET k1 v PXAT *} - {gtid * 0 SET k2 v PXAT *} - {gtid * 0 set k3 v} - {gtid * 0 PEXPIREAT k3 *} - {gtid * 0 set k4 v} - {gtid * 0 PEXPIREAT k4 *} - {gtid * 0 set k v} - } - } - } - - start_server_aof [list dir $server_path aof-load-truncated yes] { - test "restart redis load aof" { - set config [srv config] - set dir [dict get $config dir] - set res [try_read_aof $dir/appendonlydir/appendonly.aof.1.incr.aof 8] - assert_aof $res { - {select *} - {gtid * 0 SET k1 v PXAT *} - {gtid * 0 SET k2 v PXAT *} - {gtid * 0 set k3 v} - {gtid * 0 PEXPIREAT k3 *} - {gtid * 0 set k4 v} - {gtid * 0 PEXPIREAT k4 *} - {gtid * 0 set k v} - } - after 500 - set client [redis [ srv host] [srv port] 0 $::tls] - assert_equal [$client get k] v - } - } - create_aof $aof_dirpath $aof_incr1_file { - append_to_aof [formatCommand gtid A:1 0 set k1 y] - append_to_aof [formatCommand set k2 y] - append_to_aof [formatCommand gtid A:2 0 PEXPIREAT k2 100000] - } - - - start_server_aof [list dir $server_path aof-load-truncated yes gtid-enabled yes] { - test "Unfinished MULTI: Server should start if load-truncated is yes" { - assert_equal 1 [is_alive [srv pid]] - set client [redis [srv host] [srv port] 0 $::tls] - assert_equal [$client get k1] y - assert_equal [$client get k2] {} - } - } - - start_server [list overrides [list dir $server_path appendonly yes appendfilename appendonly.aof2 gtid-enabled yes]] { - test {Redis should not try to convert DEL into EXPIREAT for EXPIRE -1} { - r setex k1 10 y - r set k2 y - r expire k2 1000 - r set k3 y ex 1000 - r set k4 y - r gtid A:1 9 expire k4 200000000000 - r set k5 y - set config [srv 0 config] - set dir [dict get $config dir] - set res [try_read_aof $dir/appendonlydir/appendonly.aof2.1.incr.aof 8] - assert_aof $res { - {select *} - {gtid * 9 SET k1 y PXAT *} - {gtid * 9 set k2 y} - {gtid * 9 PEXPIREAT k2 *} - {gtid * 9 SET k3 y PXAT *} - {gtid * 9 set k4 y} - {gtid A:1 9 PEXPIREAT k4 *} - {gtid * 9 set k5 y} - } - } - } - } - -} -} \ No newline at end of file diff --git a/tests/gtid/gaplog.tcl b/tests/gtid/gaplog.tcl deleted file mode 120000 index 21d9e5954b3..00000000000 --- a/tests/gtid/gaplog.tcl +++ /dev/null @@ -1 +0,0 @@ -../../deps/xredis-gtid/xredis/tests/gtid/gaplog.tcl \ No newline at end of file diff --git a/tests/gtid/gaplog/gaplog.tcl b/tests/gtid/gaplog/gaplog.tcl deleted file mode 120000 index c3d7dd2105e..00000000000 --- a/tests/gtid/gaplog/gaplog.tcl +++ /dev/null @@ -1 +0,0 @@ -../../../deps/xredis-gtid/xredis/tests/gtid/gaplog.tcl \ No newline at end of file diff --git a/tests/gtid/gaplog/gaplog_commands.tcl b/tests/gtid/gaplog/gaplog_commands.tcl deleted file mode 120000 index 86f11cc7c99..00000000000 --- a/tests/gtid/gaplog/gaplog_commands.tcl +++ /dev/null @@ -1 +0,0 @@ -../../../deps/xredis-gtid/xredis/tests/gtid/gaplog_commands.tcl \ No newline at end of file diff --git a/tests/gtid/gaplog/gaplog_write_commands.tcl b/tests/gtid/gaplog/gaplog_write_commands.tcl deleted file mode 120000 index ed8002f59a2..00000000000 --- a/tests/gtid/gaplog/gaplog_write_commands.tcl +++ /dev/null @@ -1 +0,0 @@ -../../../deps/xredis-gtid/xredis/tests/gtid/gaplog_write_commands.tcl \ No newline at end of file diff --git a/tests/gtid/gaplog_commands.tcl b/tests/gtid/gaplog_commands.tcl deleted file mode 120000 index 7a96975b7e2..00000000000 --- a/tests/gtid/gaplog_commands.tcl +++ /dev/null @@ -1 +0,0 @@ -../../deps/xredis-gtid/xredis/tests/gtid/gaplog_commands.tcl \ No newline at end of file diff --git a/tests/gtid/gaplog_write_commands.tcl b/tests/gtid/gaplog_write_commands.tcl deleted file mode 120000 index 36b9c4e2001..00000000000 --- a/tests/gtid/gaplog_write_commands.tcl +++ /dev/null @@ -1 +0,0 @@ -../../deps/xredis-gtid/xredis/tests/gtid/gaplog_write_commands.tcl \ No newline at end of file diff --git a/tests/gtid/gtid.tcl b/tests/gtid/gtid.tcl deleted file mode 100644 index fdea50415f4..00000000000 --- a/tests/gtid/gtid.tcl +++ /dev/null @@ -1,612 +0,0 @@ -start_server {tags {"gtid"} overrides {gtid-enabled yes}} { - set master_repl [attach_to_replication_stream] - set orig_db 0 - - start_server {overrides {gtid-enabled yes}} { - set master [srv -1 client] - set master_host [srv -1 host] - set master_port [srv -1 port] - set slave [srv 0 client] - $slave config set repl-rdb-channel no - # Init replication link and and repl stream - $slave replicaof $master_host $master_port - wait_for_sync $slave - - set slave_repl [attach_to_replication_stream] - - $master SET key val0 - wait_for_gtid_sync $master $slave - assert_equal [$master GET key] val0 - assert_equal [$slave GET key] val0 - - set myuuid [status $master gtid_uuid] - set mygno [status $master gtid_executed_gno_count] - - assert_replication_stream $master_repl [list {select *} "gtid $myuuid:$mygno * SET key val0"] - assert_replication_stream $slave_repl [list {select *} "gtid $myuuid:$mygno * SET key val0"] - - test "propagte repl: GTID-ENABLED(yes) TX(yes) CMD(write,may-replicate)" { - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - $master MULTI - $master GET key - $master SET key val1 - $master PUBLISH hello world - $master SET key val2 - $master EXEC - - wait_for_gtid_sync $master $slave - - incr mygno - set mygtidset "$myuuid:1-$mygno" - - assert_equal [$master GET key] val2 - assert_equal [$slave GET key] val2 - - assert_replication_stream $master_repl [list multi {set key val1} {publish hello world} {set key val2} "gtid $myuuid:$mygno * EXEC"] - assert_replication_stream $slave_repl [list multi {set key val1} {publish hello world} {set key val2} "gtid $myuuid:$mygno * EXEC"] - - assert_match "*$mygtidset*" [status $master gtid_executed] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 0] [expr $orig_master_reploff+1] - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 0] [expr $orig_slave_reploff+1] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 1] "$myuuid:$mygno" - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 1] "$myuuid:$mygno" - } - - test "propagte repl: GTID-ENABLED(yes) TX(yes) CMD(gtid) => not allowed" { - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - set orig_val [$master GET key] - - $master MULTI - $master PUBLISH hello world - catch {$master GTID A:1 1 set key valx} err - assert_match "*gtidCommand not allowed in multi*" $err - catch {$master EXEC} err - assert_match "*EXECABORT Transaction discarded because of previous errors*" $err - - assert_replication_stream $master_repl {{}} - assert_replication_stream $slave_repl {{}} - - assert_equal [$master GET key] $orig_val - assert_equal [$slave GET key] $orig_val - } - - test "propagte repl: GTID-ENABLED(yes) auto-wrapped alsoPropagate TX maps to one GTID" { - set sadd_argv [list SADD spop_gtid] - for {set i 1} {$i <= 3000} {incr i} { - lappend sadd_argv $i - } - $master {*}$sadd_argv - wait_for_gtid_sync $master $slave - - incr mygno - assert_equal [$master SCARD spop_gtid] 3000 - assert_equal [$slave SCARD spop_gtid] 3000 - assert_replication_stream $master_repl [list "gtid $myuuid:$mygno * SADD spop_gtid *"] - assert_replication_stream $slave_repl [list "gtid $myuuid:$mygno * SADD spop_gtid *"] - - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - $master SPOP spop_gtid 2500 - wait_for_gtid_sync $master $slave - - incr mygno - set mygtidset "$myuuid:1-$mygno" - - assert_equal [$master SCARD spop_gtid] 500 - assert_equal [$slave SCARD spop_gtid] 500 - - assert_replication_stream $master_repl [list multi {srem spop_gtid *} {srem spop_gtid *} {srem spop_gtid *} "gtid $myuuid:$mygno * EXEC"] - assert_replication_stream $slave_repl [list multi {srem spop_gtid *} {srem spop_gtid *} {srem spop_gtid *} "gtid $myuuid:$mygno * EXEC"] - - assert_match "*$mygtidset*" [status $master gtid_executed] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 0] [expr $orig_master_reploff+1] - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 0] [expr $orig_slave_reploff+1] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 1] "$myuuid:$mygno" - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 1] "$myuuid:$mygno" - } - - test "propagte repl: GTID-ENABLED(yes) TX(no) CMD(write)" { - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - $master SET key val3 - - wait_for_gtid_sync $master $slave - - incr mygno - set mygtidset "$myuuid:1-$mygno" - - assert_equal [$master GET key] val3 - assert_equal [$slave GET key] val3 - - assert_replication_stream $master_repl [list "gtid $myuuid:$mygno * SET key val3"] - assert_replication_stream $slave_repl [list "gtid $myuuid:$mygno * SET key val3"] - - assert_match "*$mygtidset*" [status $master gtid_executed] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 0] [expr $orig_master_reploff+1] - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 0] [expr $orig_slave_reploff+1] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 1] "$myuuid:$mygno" - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 1] "$myuuid:$mygno" - } - - test "propagte repl: GTID-ENABLED(yes) TX(no) CMD(may-replicate)" { - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - $master PUBLISH hello world - - wait_for_gtid_sync $master $slave - - # mygno not incrmented - set mygtidset "$myuuid:1-$mygno" - - assert_replication_stream $master_repl {{publish hello world}} - assert_replication_stream $slave_repl {{publish hello world}} - - assert_match "*$mygtidset*" [status $master gtid_executed] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 0] -1 - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 0] -1 - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 1] {} - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 1] {} - } - - test "propagte repl: GTID-ENABLED(yes) TX(no) CMD(gtid)" { - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - $master GTID A:1 1 SET key val4; # master changed to db-1 - - wait_for_gtid_sync $master $slave - - $master select 1 - $slave select 1 - assert_equal [$master GET key] val4 - assert_equal [$slave GET key] val4 - - assert_replication_stream $master_repl [list {select 1} "gtid A:1 * SET key val4"] - assert_replication_stream $slave_repl [list {select 1} "gtid A:1 * SET key val4"] - - assert_match "*A:1*" [status $master gtid_executed] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 0] [expr $orig_master_reploff+1] - # length of *2\r\n$6\r\nselect\r\n$1\r\n0\r\n is 23 - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 0] [expr $orig_slave_reploff+1+23] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 1] "A:1" - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 1] "A:1" - - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - $master select $orig_db - $slave select $orig_db - - $master GTID A:2 0 SET key val5 - - wait_for_gtid_sync $master $slave - - assert_equal [$master GET key] val5 - assert_equal [$slave GET key] val5 - - assert_replication_stream $master_repl [list "select $orig_db" "gtid A:2 * SET key val5"] - assert_replication_stream $slave_repl [list "select $orig_db" "gtid A:2 * SET key val5"] - - assert_match "*A:1-2*" [status $master gtid_executed] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 0] [expr $orig_master_reploff+1] - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 0] [expr $orig_slave_reploff+1+23] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 1] "A:2" - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 1] "A:2" - - } - - test "propagte repl: expire" { - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - $master SET key val6 PX 100 - # Wait for active expire to fire and write DEL to the replication - # stream. Using wait_for_condition instead of a hard after-delay - # avoids flakiness in SWAP mode where cold-key expiry may not - # complete within a fixed 200 ms window. - wait_for_condition 100 100 { - [$master EXISTS key] == 0 - } else { - fail "key val6 did not expire on master" - } - - wait_for_gtid_sync $master $slave - - assert_equal [$master EXISTS key] 0 - assert_equal [$slave EXISTS key] 0 - - assert_replication_stream $master_repl [list "gtid $myuuid:[expr $mygno+1] * SET key val6 PXAT *" "gtid $myuuid:[expr $mygno+2] * DEL key"] - assert_replication_stream $slave_repl [list "gtid $myuuid:[expr $mygno+1] * SET key val6 PXAT *" "gtid $myuuid:[expr $mygno+2] * DEL key"] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 1] "$myuuid:[expr $mygno+1]-[expr $mygno+2]" - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 1] "$myuuid:[expr $mygno+1]-[expr $mygno+2]" - - incr mygno 2 - set mygtidset "$myuuid:1-$mygno" - assert_match "*$mygtidset*" [status $master gtid_executed] - } - } -} - -start_server {tags {"gtid"} overrides {gtid-enabled no}} { - set master_repl [attach_to_replication_stream] - if {$::swap} { - set orig_db 0 - } else { - set orig_db 9 - } - - start_server {overrides {gtid-enabled no}} { - set master [srv -1 client] - set master_host [srv -1 host] - set master_port [srv -1 port] - set slave [srv 0 client] - - # Init replication link and and repl stream - $slave replicaof $master_host $master_port - wait_for_sync $slave - - set slave_repl [attach_to_replication_stream] - - $master SET key val0 - wait_for_ofs_sync $master $slave - assert_equal [$master GET key] val0 - assert_equal [$slave GET key] val0 - - set myuuid [status $master gtid_uuid] - set mygno [status $master gtid_executed_gno_count] - - assert_replication_stream $master_repl [list {select *} "set key val0"] - assert_replication_stream $slave_repl [list {select *} "set key val0"] - - test "propagte repl: GTID-ENABLED(no) TX(no) CMD(gtid)" { - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - $master GTID A:1 $orig_db SET key val1 - - wait_for_ofs_sync $master $slave - - assert_equal [$master GET key] val1 - assert_equal [$slave GET key] val1 - - assert_replication_stream $master_repl [list "gtid A:1 * SET key val1"] - assert_replication_stream $slave_repl [list "gtid A:1 * SET key val1"] - - assert_match "*A:1*" [status $master gtid_executed] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 0] [expr $orig_master_reploff+1] - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 0] [expr $orig_slave_reploff+1] - - assert_equal [lindex [$master GTIDX SEQ LOCATE $orig_master_gtidset] 1] "A:1" - assert_equal [lindex [$slave GTIDX SEQ LOCATE $orig_slave_gtidset ] 1] "A:1" - } - - test "propagte repl: GTID-ENABLED(no) TX(yes) CMD(gtid) => not allowed" { - set orig_master_reploff [status $master master_repl_offset] - set orig_slave_reploff [status $slave master_repl_offset] - set orig_master_gtidset [status $master gtid_set] - set orig_slave_gtidset [status $slave gtid_set] - - set orig_val [$master GET key] - - $master MULTI - $master PUBLISH hello world - catch { $master GTID A:1 1 set key valx } err - assert_match "*gtidCommand not allowed in multi*" $err - catch { $master EXEC} err - assert_match "*EXECABORT Transaction discarded because of previous errors*" $err - - assert_replication_stream $master_repl {{}} - assert_replication_stream $slave_repl {{}} - - assert_equal [$master GET key] $orig_val - assert_equal [$slave GET key] $orig_val - } - - } -} - -start_server {tags {"gtid"} overrides {gtid-enabled yes}} { - - test "gtid command with gtid.set-lost ignored" { - r GTIDX ADD LOST A 1 10 - catch {r GTID A:5 0 set hello world} reply - assert_match "*gtid command already executed*" $reply - } - -} - -start_server {tags {"gtid"} overrides} { - test "gtid uses jemalloc allocator" { - assert_equal [s gtid_allocator] [s mem_allocator] - } -} - -start_server {tags {"master"} overrides} { - test "change gtid-enabled efficient" { - set repl [attach_to_replication_stream] - r set k v1 - assert_replication_stream $repl { - {select *} - {set k v1} - } - assert_equal [r get k] v1 - - r config set gtid-enabled yes - - set repl [attach_to_replication_stream] - r set k v2 - - assert_replication_stream $repl { - {select *} - {gtid * * set k v2} - } - assert_equal [r get k] v2 - - r config set gtid-enabled no - set repl [attach_to_replication_stream] - r set k v3 - assert_replication_stream $repl { - {select *} - {set k v3} - } - assert_equal [r get k] v3 - } -} - -#closed gtid-enabled, can exec gtid command -start_server {tags {"gtid"} overrides} { - test "exec gtid command" { - r gtid A:1 $::target_db set k v - assert_equal [r get k] v - assert_equal [dict get [get_gtid r] "A"] "1" - } -} - -# stand-alone redis exec gtid related commands -start_server {tags {"gtid"} overrides {gtid-enabled yes}} { - test {COMMANDS} { - test {GTID SET} { - r gtid A:1 $::target_db set x foobar - r get x - } {foobar} - - test {GTID REPATE SET} { - catch {r gtid A:1 $::target_db set x foobar} error - assert_match $error "gtid command already executed, `A:1`, `$::target_db`, `set`," - } - test {SET} { - r set y foobar - r get y - } {foobar} - - test {MULTI} { - r multi - r set z foobar - r gtid A:3 $::target_db exec - r set z f - r get z - } {f} - test {MULTI} { - set z_value [r get z] - r del x - assert_equal [r get x] {} - r multi - r set z foobar1 - catch {r gtid A:3 $::target_db exec} error - assert_equal $error "gtid command already executed, `A:3`, `$::target_db`, `exec`," - assert_equal [r get z] $z_value - r set x f1 - r get x - } {f1} - test "ERR WRONG NUMBER" { - catch {r gtid A } error - assert_match "ERR wrong number of arguments for 'gtid' command" $error - } - - } - - test {INFO GTID} { - set dicts [dict get [get_gtid r] [status r run_id]] - set value [lindex $dicts 0] - assert_equal [string match {1-*} $value] 1 - } -} - -# verify gtid command db -start_server {tags {"gtid"} overrides {gtid-enabled yes}} { - test "multi-exec select db" { - set repl [attach_to_replication_stream] - r set k v - r select 0 - r set k v - - if {$::swap} { - assert_replication_stream $repl { - {select *} - {gtid * * set k v} - {gtid * 0 set k v} - } - } else { - assert_replication_stream $repl { - {select *} - {gtid * * set k v} - {select *} - {gtid * 0 set k v} - } - } - r select $::target_db - } - - test "multi-exec select db" { - set repl [attach_to_replication_stream] - r multi - r set k v - r select 0 - r set k v - r exec - r set k v1 - - if {$::swap} { - assert_replication_stream $repl { - {multi} - {select *} - {set k v} - {set k v} - {gtid * * EXEC} - {gtid * 0 set k v1} - } - } else { - assert_replication_stream $repl { - {multi} - {select *} - {set k v} - {select 0} - {set k v} - {gtid * * EXEC} - {gtid * 0 set k v1} - } - } - } -} - -start_server {tags {"repl"} overrides} { - set master [srv 0 client] - $master config set repl-diskless-sync-delay 1 - set master_host [srv 0 host] - set master_port [srv 0 port] - $master config set gtid-enabled yes - set repl [attach_to_replication_stream] - start_server {tags {"slave"}} { - set slave [srv 0 client] - $slave slaveof $master_host $master_port - wait_for_sync $slave - $master multi - $master select 1 - $master select 2 - $master set k v - $master select 3 - $master set k v1 - $master exec - - if {$::swap} { - assert_replication_stream $repl { - {multi} - {select 2} - {set k v} - {select 3} - {set k v1} - {gtid * 0 EXEC} - } - } else { - assert_replication_stream $repl { - {multi} - {select 2} - {set k v} - {select 3} - {set k v1} - {gtid * 9 EXEC} - } - } - - after 1000 - - assert_equal [$slave get k] {} - $slave select 2 - assert_equal [$slave get k] v - $slave select 3 - assert_equal [$slave get k] v1 - - } -} - -start_server {tags {"repl"} overrides} { - set master [srv 0 client] - $master config set repl-diskless-sync-delay 1 - set master_host [srv 0 host] - set master_port [srv 0 port] - $master config set gtid-enabled yes - start_server {tags {"slave"}} { - set slave [srv 0 client] - $slave slaveof $master_host $master_port - wait_for_sync $slave - - test {GTID cross-DB transaction preserves body DB when stream already selected body DB} { - # Seed DB0 first so the replication stream may otherwise omit SELECT 0 - # before the transaction body. - $master select 0 - $master set gtid-cross-db-seed seed - wait_for_gtid_sync $master $slave - set repl [attach_to_replication_stream] - - $master select 9 - $master multi - $master select 0 - $master set gtid-cross-db-key:1 value-in-db0 - $master set gtid-cross-db-key:2 value-in-db0 - $master exec - - assert_replication_stream $repl { - {multi} - {select 0} - {set gtid-cross-db-key:1 value-in-db0} - {set gtid-cross-db-key:2 value-in-db0} - {gtid * 9 EXEC} - } - - wait_for_gtid_sync $master $slave - - $master select 0 - $slave select 0 - assert_equal value-in-db0 [$master get gtid-cross-db-key:1] - assert_equal value-in-db0 [$slave get gtid-cross-db-key:1] - assert_equal value-in-db0 [$master get gtid-cross-db-key:2] - assert_equal value-in-db0 [$slave get gtid-cross-db-key:2] - - $master select 9 - $slave select 9 - assert_equal {} [$master get gtid-cross-db-key:1] - assert_equal {} [$slave get gtid-cross-db-key:1] - assert_equal {} [$master get gtid-cross-db-key:2] - assert_equal {} [$slave get gtid-cross-db-key:2] - } - } -} diff --git a/tests/gtid/gtid_seq.tcl b/tests/gtid/gtid_seq.tcl deleted file mode 100644 index 4c24ca5a4f4..00000000000 --- a/tests/gtid/gtid_seq.tcl +++ /dev/null @@ -1,90 +0,0 @@ -start_server {tags {"gtid-seq"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - set master [srv -1 client] - set master_host [srv -1 host] - set master_port [srv -1 port] - set slave [srv 0 client] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - - test "build gtid seq index" { - # simple write command - $master SET key val0 - wait_for_ofs_sync $master $slave - assert_match {*:1} [$master GTIDX seq gtid.set] - assert_match {*:1} [$slave GTIDX seq gtid.set] - - # simple read command - wait_for_ofs_sync $master $slave - assert_equal [$master GET key] "val0" - assert_match {*:1} [$master GTIDX seq gtid.set] - assert_match {*:1} [$slave GTIDX seq gtid.set] - - # publish - $master PUBLISH foo bar - wait_for_ofs_sync $master $slave - assert_match {*:1} [$master GTIDX seq gtid.set] - assert_match {*:1} [$slave GTIDX seq gtid.set] - - # multi - $master MULTI - $master SET key val1 - $master SET key val2 - $master EXEC - wait_for_ofs_sync $master $slave - assert_match {*:1-2} [$master GTIDX seq gtid.set] - assert_match {*:1-2} [$slave GTIDX seq gtid.set] - - # lua - $master EVAL "redis.call('SET','key','val3'); redis.call('SET','key','val4')" 0 - wait_for_ofs_sync $master $slave - assert_match {*:1-3} [$master GTIDX seq gtid.set] - assert_match {*:1-3} [$slave GTIDX seq gtid.set] - - # # multi + lua - $master MULTI - $master SET key val5 - $master EVAL "redis.call('SET','key','val6'); redis.call('SET','key','val7')" 0 - $master SET key val8 - $master EXEC - wait_for_ofs_sync $master $slave - assert_match {*:1-4} [$master GTIDX seq gtid.set] - assert_match {*:1-4} [$slave GTIDX seq gtid.set] - - - # expire - $master MULTI - $master SET tmpkey val1 - $master pexpire tmpkey 100 - $master EXEC - after 200 - assert_equal [$master GET tmpkey] {} - assert_equal [$slave GET tmpkey] {} - wait_for_ofs_sync $master $slave - assert_match {*:1-6} [$master GTIDX seq gtid.set] - assert_match {*:1-6} [$slave GTIDX seq gtid.set] - - # gtid - $master GTID A:1 0 SET key val9 - wait_for_ofs_sync $master $slave - assert_match {*:1-6,A:1} [$master GTIDX seq gtid.set] - assert_match {*:1-6,A:1} [$slave GTIDX seq gtid.set] - - # multi + gtid: rejected - $master MULTI - catch {$master GTID A:2 0 SET key val10} e - catch {$master GTID A:3 0 SET key val11} e - catch {$master EXEC} e - wait_for_ofs_sync $master $slave - assert_match {*:1-6,A:1} [$master GTIDX seq gtid.set] - assert_match {*:1-6,A:1} [$slave GTIDX seq gtid.set] - - # lua + gtid: rejected - catch {$master EVAL "redis.call('GTID','A:4','SET','key','val12'); redis.call('GTID','A:5','SET','key','val13')" 0} e - wait_for_ofs_sync $master $slave - assert_match {*:1-6,A:1} [$master GTIDX seq gtid.set] - assert_match {*:1-6,A:1} [$slave GTIDX seq gtid.set] - } -} -} diff --git a/tests/gtid/master_restart.tcl b/tests/gtid/master_restart.tcl deleted file mode 100644 index 6ae838cd375..00000000000 --- a/tests/gtid/master_restart.tcl +++ /dev/null @@ -1,199 +0,0 @@ -proc restart_server_gtided {level wait_ready rotate_logs gtid_enabled {reconnect 1} {shutdown sigterm}} { - set srv [lindex $::servers end+$level] - if {$shutdown ne {sigterm}} { - catch {[dict get $srv "client"] shutdown $shutdown} - } - # Kill server doesn't mind if the server is already dead - kill_server $srv - # Remove the default client from the server - dict unset srv "client" - - set pid [dict get $srv "pid"] - set stdout [dict get $srv "stdout"] - set stderr [dict get $srv "stderr"] - if {$rotate_logs} { - set ts [clock format [clock seconds] -format %y%m%d%H%M%S] - file rename $stdout $stdout.$ts.$pid - file rename $stderr $stderr.$ts.$pid - } - set prev_ready_count [count_message_lines $stdout "Ready to accept"] - - # if we're inside a test, write the test name to the server log file - if {[info exists ::cur_test]} { - set fd [open $stdout "a+"] - puts $fd "### Restarting server for test $::cur_test" - close $fd - } - - set config_file [dict get $srv "config_file"] - set fileId [open $config_file "a"] - puts $fileId [format "\ngtid-enabled %s" $gtid_enabled] - flush $fileId - close $fileId - - set pid [spawn_server $config_file $stdout $stderr {}] - - # check that the server actually started - wait_server_started $config_file $stdout $pid - - # update the pid in the servers list - dict set srv "pid" $pid - # re-set $srv in the servers list - lset ::servers end+$level $srv - - if {$wait_ready} { - while 1 { - # check that the server actually started and is ready for connections - if {[count_message_lines $stdout "Ready to accept"] > $prev_ready_count} { - break - } - after 10 - } - } - if {$reconnect} { - reconnect $level - # In swap mode, restarting loads a heavier RDB (includes RocksDB - # snapshot data), so wait until loading completes before returning. - if {$::swap} { - wait_done_loading [srv $level client] - } - } -} - - -# master psync, slave psync -proc restart_test {master_gtid_enabled slave_gtid_enabled restat_master_gtid_enabled is_full_sync} { - test [format "restart master (%s => %s) slave (%s)" $master_gtid_enabled $restat_master_gtid_enabled $slave_gtid_enabled ]] { - start_server [list overrides [list "gtid-enabled" $slave_gtid_enabled]] { - start_server [list overrides [list "gtid-enabled" $master_gtid_enabled]] { - set master_id 0 - set master [srv 0 client] - set master_host [srv 0 host] - set master_port [srv 0 port] - - - #@step1 master sync data to slave - set slave [srv -1 client] - set slave_host [srv -1 host] - set slave_port [srv -1 port] - $slave slaveof $master_host $master_port - - wait_for_condition 50 100 { - [status $slave master_link_status] eq {up} - } else { - fail "Replication not started." - } - - # @step2 send command + bgsave - $master debug set-active-expire 0 - for {set j 0} {$j < 16} {incr j} { - # $master select [expr $j%16] - $master select 0 - $master set $j somevalue px 20 - } - - - after 20 - # Wait until master has received ACK from replica. If the master thinks - # that any replica is lagging when it shuts down, master would send - # GETACK to the replicas, affecting the replication offset. - set offset [status $master master_repl_offset] - wait_for_condition 500 100 { - [string match "*slave0:*,offset=$offset,*" [$master info replication]] && - $offset == [status $slave master_repl_offset] - } else { - fail "Replicas and master offsets were unable to match *exactly*." - } - - set offset [status $master master_repl_offset] - #@step3 save rdb - $master bgsave - wait_for_condition 1000 10 { - [s rdb_bgsave_in_progress] eq 0 - } else { - fail "bgsave did not stop in time" - } - - - # @step4 master restart load rdb - catch { - # Unlike the test above, here we use SIGTERM, which behaves - # differently compared to SHUTDOWN NOW if there are lagging - # replicas. This is just to increase coverage and let each test use - # a different shutdown approach. In this case there are no lagging - # replicas though. - restart_server_gtided 0 true false $restat_master_gtid_enabled - set master [srv 0 client] - } - - # In swap mode, restart loads a heavier RDB (RocksDB state). - # wait_done_loading inside restart_server_gtided has only a 5s - # timeout and is wrapped in catch, so add an explicit longer wait - # here to guarantee the master is fully loaded before proceeding. - if {$::swap} { - set master [srv 0 client] - wait_done_loading $master - } - - #@step4 check slave sync is continue - if $is_full_sync { - wait_for_condition 1000 10 { - [status $master sync_full] eq 1 - } else { - puts [status $master sync_full] - fail "full sync fail" - } - } else { - # assert {[status $master sync_partial_ok] eq 0} - wait_for_condition 1000 10 { - [status $master sync_partial_ok] eq 1 - } else { - puts [status $master sync_partial_ok] - fail "partial sync fail" - } - } - - # In swap mode, both full-sync (slave receives an RDB) and partial-sync - # (slave may trigger a transient LOADING phase) can cause the slave to - # enter LOADING state. Wait until loading is complete before checking - # dbsize, since wait_for_condition propagates LOADING errors immediately - # rather than retrying. - if {$::swap} { - wait_done_loading $slave - } - - wait_for_condition 1000 30 { - [dbsize_loadsafe $master master_dbsize] && - [dbsize_loadsafe $slave slave_dbsize] && - $master_dbsize eq $slave_dbsize && - $slave_dbsize eq 0 - } else { - puts [dbsize_loadsafe $master master_dbsize] - puts $master_dbsize - puts [dbsize_loadsafe $slave slave_dbsize] - puts $slave_dbsize - fail "slave dbszie != 0" - } - - } - } - } - -} - - -# unchange gtid mode -test "unchange gtid mode" { - restart_test "no" "no" "no" 0 - restart_test "yes" "no" "yes" 0 - restart_test "yes" "yes" "yes" 0 - restart_test "no" "yes" "no" 0 -} - - -test "change gtid mode" { - restart_test "no" "no" "yes" 0 - restart_test "yes" "yes" "no" 1 - restart_test "yes" "no" "no" 1 - restart_test "no" "yes" "yes" 0 -} diff --git a/tests/gtid/psync2-master-restart.tcl b/tests/gtid/psync2-master-restart.tcl deleted file mode 100644 index 7f60baf0946..00000000000 --- a/tests/gtid/psync2-master-restart.tcl +++ /dev/null @@ -1,342 +0,0 @@ -proc restart_server_gtided {level wait_ready rotate_logs gtid_enabled {reconnect 1} {shutdown sigterm}} { - set srv [lindex $::servers end+$level] - if {$shutdown ne {sigterm}} { - catch {[dict get $srv "client"] shutdown $shutdown} - } - # Kill server doesn't mind if the server is already dead - kill_server $srv - # Remove the default client from the server - dict unset srv "client" - - set pid [dict get $srv "pid"] - set stdout [dict get $srv "stdout"] - set stderr [dict get $srv "stderr"] - if {$rotate_logs} { - set ts [clock format [clock seconds] -format %y%m%d%H%M%S] - file rename $stdout $stdout.$ts.$pid - file rename $stderr $stderr.$ts.$pid - } - set prev_ready_count [count_message_lines $stdout "Ready to accept"] - - # if we're inside a test, write the test name to the server log file - if {[info exists ::cur_test]} { - set fd [open $stdout "a+"] - puts $fd "### Restarting server for test $::cur_test" - close $fd - } - - set config_file [dict get $srv "config_file"] - set fileId [open $config_file "a"] - puts $fileId [format "\ngtid-enabled %s" $gtid_enabled] - flush $fileId - close $fileId - - set pid [spawn_server $config_file $stdout $stderr {}] - - # check that the server actually started - wait_server_started $config_file $stdout $pid - - # update the pid in the servers list - dict set srv "pid" $pid - # re-set $srv in the servers list - lset ::servers end+$level $srv - - if {$wait_ready} { - while 1 { - # check that the server actually started and is ready for connections - if {[count_message_lines $stdout "Ready to accept"] > $prev_ready_count} { - break - } - after 10 - } - } - if {$reconnect} { - reconnect $level - # In swap mode, restarting loads a heavier RDB (includes RocksDB - # snapshot data), so wait until loading completes before returning. - if {$::swap} { - wait_done_loading [srv $level client] - } - } -} -start_server {tags {"psync2 external:skip"} overrides {gtid-enabled yes}} { -start_server {overrides {gtid-enabled yes}} { -start_server {overrides {gtid-enabled yes}} { - set master_id 0 - set master [srv 0 client] - set master_host [srv 0 host] - set master_port [srv 0 port] - - set replica [srv -1 client] - set replica_host [srv -1 host] - set replica_port [srv -1 port] - - set sub_replica [srv -2 client] - - # Make sure the server saves an RDB on shutdown - $master config set save "3600 1" - - # Because we will test partial resync later, we don't want a timeout to cause - # the master-replica disconnect, then the extra reconnections will break the - # sync_partial_ok stat test - $master config set repl-timeout 3600 - $replica config set repl-timeout 3600 - $sub_replica config set repl-timeout 3600 - - # Avoid PINGs - $master config set repl-ping-replica-period 3600 - $master config rewrite - - # Build replication chain - $replica replicaof $master_host $master_port - $sub_replica replicaof $replica_host $replica_port - - wait_for_condition 50 100 { - [status $replica master_link_status] eq {up} && - [status $sub_replica master_link_status] eq {up} - } else { - fail "Replication not started." - } - - test "PSYNC2: (gtid mode) Full resync after Master restart using RDB aux fields when offset is 0" { - assert {[status $master master_repl_offset] == 0} - - set replid [status $master master_replid] - $replica config resetstat - - catch { - # restart_server 0 true false true now - restart_server_gtided 0 true false "yes" true now - set master [srv 0 client] - } - wait_for_condition 50 1000 { - [status $replica master_link_status] eq {up} && - [status $sub_replica master_link_status] eq {up} - } else { - fail "Replicas didn't sync after master restart" - } - - # Make sure master restore replication info correctly - # assert {[status $master master_replid] != $replid} - # assert {[status $master master_repl_offset] == 0} - # assert {[status $master master_replid2] eq $replid} - # assert {[status $master second_repl_offset] == 1} - - # Make sure master set replication backlog correctly - assert {[status $master repl_backlog_active] == 1} - assert {[status $master repl_backlog_first_byte_offset] == 1} - assert {[status $master repl_backlog_histlen] == 0} - - # Partial resync after Master restart - wait_for_condition 1000 10 { - [status $master sync_full] eq 1 - } else { - fail "master sync fail" - } - - # replica only sync_full 1 - assert_equal [status $replica sync_full] 1 - } - - # Generate some data - createComplexDataset $master 1000 - - test "PSYNC2: Partial resync after Master restart using RDB aux fields with data" { - wait_for_condition 500 100 { - [status $master master_repl_offset] == [status $replica master_repl_offset] && - [status $master master_repl_offset] == [status $sub_replica master_repl_offset] - } else { - fail "Replicas and master offsets were unable to match *exactly*." - } - - set replid [status $master master_replid] - set offset [status $master master_repl_offset] - $replica config resetstat - - catch { - # SHUTDOWN NOW ensures master doesn't send GETACK to replicas before - # shutting down which would affect the replication offset. - # restart_server 0 true false true now - restart_server_gtided 0 true false "yes" true now - set master [srv 0 client] - } - wait_for_condition 50 1000 { - [status $replica master_link_status] eq {up} && - [status $sub_replica master_link_status] eq {up} - } else { - fail "Replicas didn't sync after master restart" - } - - # Make sure master restore replication info correctly - assert {[status $master master_replid] != $replid} - assert {[status $master master_repl_offset] == $offset} - assert {[status $master master_replid2] eq $replid} - assert {[status $master second_repl_offset] == [expr $offset+1]} - - # Make sure master set replication backlog correctly - assert {[status $master repl_backlog_active] == 1} - assert {[status $master repl_backlog_first_byte_offset] == [expr $offset+1]} - assert {[status $master repl_backlog_histlen] == 0} - - # Partial resync after Master restart - assert {[status $master sync_partial_ok] == 1} - assert {[status $replica sync_partial_ok] == 1} - } - - test "PSYNC2: Partial resync after Master restart using RDB aux fields with expire" { - $master debug set-active-expire 0 - for {set j 0} {$j < 1024} {incr j} { - $master select [expr $j%16] - $master set $j somevalue px 10 - } - - after 20 - - # Wait until master has received ACK from replica. If the master thinks - # that any replica is lagging when it shuts down, master would send - # GETACK to the replicas, affecting the replication offset. - set offset [status $master master_repl_offset] - wait_for_condition 500 100 { - [string match "*slave0:*,offset=$offset,*" [$master info replication]] && - $offset == [status $replica master_repl_offset] && - $offset == [status $sub_replica master_repl_offset] - } else { - show_cluster_status - fail "Replicas and master offsets were unable to match *exactly*." - } - - set offset [status $master master_repl_offset] - $replica config resetstat - - catch { - # Unlike the test above, here we use SIGTERM, which behaves - # differently compared to SHUTDOWN NOW if there are lagging - # replicas. This is just to increase coverage and let each test use - # a different shutdown approach. In this case there are no lagging - # replicas though. - # restart_server 0 true false - restart_server_gtided 0 true false "yes" - set master [srv 0 client] - } - wait_for_condition 50 1000 { - [status $replica master_link_status] eq {up} && - [status $sub_replica master_link_status] eq {up} - } else { - fail "Replicas didn't sync after master restart" - } - - set expired_offset [status $master repl_backlog_histlen] - # Stale keys expired and master_repl_offset grows correctly - - if {!$::swap} { - assert {[status $master rdb_last_load_keys_expired] == 1024} - # In SWAP mode, cold keys are lazily expired after RDB load, so - # additional DELs may propagate after expired_offset is snapshotted, - # making the exact offset arithmetic unreliable. - assert {[status $master master_repl_offset] == [expr $offset+$expired_offset]} - } - - # Partial resync after Master restart - assert {[status $master sync_partial_ok] == 1} - assert {[status $replica sync_partial_ok] == 1} - - if {$::swap} { - wait_for_condition 500 100 { - [status $master master_repl_offset] == [status $replica master_repl_offset] && - [status $master master_repl_offset] == [status $sub_replica master_repl_offset] && - [$master debug digest] eq [$replica debug digest] && - [$master debug digest] eq [$sub_replica debug digest] - } else { - show_cluster_status - puts "master digest: [$master debug digest]" - puts "replica digest: [$replica debug digest]" - puts "sub_replica digest: [$sub_replica debug digest]" - fail "Replication chain did not converge after expire restart." - } - } - - set digest [$master debug digest] - assert {$digest eq [$replica debug digest]} - assert {$digest eq [$sub_replica debug digest]} - } - - test "PSYNC2: Full resync after Master restart when too many key expired" { - $master config set repl-backlog-size 16384 - $master config rewrite - - $master debug set-active-expire 0 - # Make sure replication backlog is full and will be trimmed. - for {set j 0} {$j < 2048} {incr j} { - $master select [expr $j%16] - $master set $j somevalue px 10 - } - - if {!$::swap} { - ##### hash-field-expiration - # Hashes of type OBJ_ENCODING_LISTPACK_EX won't be discarded during - # RDB load, even if they are expired. - $master hset myhash1 f1 v1 f2 v2 f3 v3 - $master hpexpire myhash1 10 FIELDS 3 f1 f2 f3 - # Hashes of type RDB_TYPE_HASH_METADATA will be discarded during RDB load. - $master config set hash-max-listpack-entries 0 - $master hset myhash2 f1 v1 f2 v2 - - $master hpexpire myhash2 10 FIELDS 2 f1 f2 - $master config set hash-max-listpack-entries 1 - } else { - $master mset k1 v1 k2 v2 k3 v3 k4 v4 k5 v5 k6 v6 - $master pexpire k1 10 - $master pexpire k2 10 - $master pexpire k3 10 - $master pexpire k4 10 - $master pexpire k5 10 - $master pexpire k6 10 - } - after 20 - - wait_for_condition 500 100 { - [status $master master_repl_offset] == [status $replica master_repl_offset] && - [status $master master_repl_offset] == [status $sub_replica master_repl_offset] - } else { - fail "Replicas and master offsets were unable to match *exactly*." - } - - $replica config resetstat - - catch { - # Unlike the test above, here we use SIGTERM. This is just to - # increase coverage and let each test use a different shutdown - # approach. - # restart_server 0 true false - restart_server_gtided 0 true false "yes" - set master [srv 0 client] - } - - # set master_repl [attach_to_replication_stream_on_connection 0] - wait_for_condition 50 1000 { - [status $replica master_link_status] eq {up} && - [status $sub_replica master_link_status] eq {up} - } else { - fail "Replicas didn't sync after master restart" - } - - # Replication backlog is full. - # In SWAP mode, cold keys expire lazily (not during RDB load), so expiry DELs - # are not written to the backlog on restart and it does not overflow. - if {!$::swap} { - assert {[status $master repl_backlog_first_byte_offset] > [status $master second_repl_offset]} - } - - assert {[status $master sync_partial_ok] == 1} - assert {[status $master sync_full] == 0} - if {!$::swap} { - assert {[status $master rdb_last_load_keys_expired] == 2048} - } - assert {[status $replica sync_partial_ok] == 1} - - # set digest [$master debug digest] - # assert {$digest eq [$replica debug digest]} - # assert {$digest eq [$sub_replica debug digest]} - - } -}}} diff --git a/tests/gtid/replication-psync.tcl b/tests/gtid/replication-psync.tcl deleted file mode 100644 index fc9c5888eb5..00000000000 --- a/tests/gtid/replication-psync.tcl +++ /dev/null @@ -1,231 +0,0 @@ -# Creates a master-slave pair and breaks the link continuously to force -# partial resyncs attempts, all this while flooding the master with -# write queries. -# -# You can specify backlog size, ttl, delay before reconnection, test duration -# in seconds, and an additional condition to verify at the end. -# -# If reconnect is > 0, the test actually try to break the connection and -# reconnect with the master, otherwise just the initial synchronization is -# checked for consistency. -proc assert_partial_resync_rejected {sync_full_before sync_partial_err_before sync_partial_ok_before} { - set sync_partial_err [s -1 sync_partial_err] - if {$sync_partial_err > $sync_partial_err_before} { - return - } - set sync_full [s -1 sync_full] - if {$sync_full > $sync_full_before} { - return - } - set sync_partial_ok [s -1 sync_partial_ok] - fail "Expected rejected partial resync (sync_partial_ok=$sync_partial_ok->$sync_partial_ok_before sync_partial_err=$sync_partial_err->$sync_partial_err_before sync_full=$sync_full->$sync_full_before)" -} - -proc test_psync {descr duration backlog_size backlog_ttl delay cond mdl sdl reconnect} { - start_server {tags {"repl"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes gtid-xsync-max-gap 0}} { - - set master [srv -1 client] - set master_host [srv -1 host] - set master_port [srv -1 port] - set slave [srv 0 client] - - $master config set repl-backlog-size $backlog_size - $master config set repl-backlog-ttl $backlog_ttl - $master config set repl-diskless-sync $mdl - $master config set repl-diskless-sync-delay 1 - $slave config set repl-diskless-load $sdl - - # In SWAP mode with ASAN the diskless (socket) RDB fork has large - # shadow-memory overhead, making the RORDB streaming significantly - # slower. Unlike disk-based RDB, the master does NOT send keepalive - # newlines to slaves waiting on a socket-based bgsave. - # - # When repl-diskless-load is "disabled", the slave writes the received - # RDB to a temp file and then loads it via rdbLoad — a blocking - # operation that prevents the slave from sending ACKs. If rdbLoad - # takes longer than repl-timeout, the master drops the slave while - # it is still loading, causing a repeated full-resync livelock. - # - # Use a generous timeout (600 s) to cover both the RORDB stream time - # and the subsequent rdbLoad under ASAN instrumentation overhead. - if {$::swap && $::asan} { - $master config set repl-timeout 600 - $slave config set repl-timeout 600 - } - - if {$::swap} { - set use_sustained_write_load [expr {$::asan && ($backlog_size == 100 || $backlog_ttl == 1)}] - if {$use_sustained_write_load} { - # Keep write load active for the entire reconnect window - # without inflating the dataset. Rewriting a few fixed keys - # is enough to advance GTID / backlog and keeps diskless - # full-syncs fast under ASAN. - set write_cmds_before [status $master total_commands_processed] - set load_handle0 [start_write_load_on_db $master_host $master_port 30 0 psync-load-0] - set load_handle1 [start_write_load_on_db $master_host $master_port 30 1 psync-load-1] - set load_handle2 [start_write_load_on_db $master_host $master_port 30 2 psync-load-2] - } else { - set bg_limit [expr {$::asan ? 5000 : 100000}] - set load_handle0 [start_bg_complex_data $master_host $master_port 0 $bg_limit] - set load_handle1 [start_bg_complex_data $master_host $master_port 1 $bg_limit] - } - } else { - set load_handle0 [start_bg_complex_data $master_host $master_port 9 100000] - set load_handle1 [start_bg_complex_data $master_host $master_port 11 100000] - set load_handle2 [start_bg_complex_data $master_host $master_port 12 100000] - } - - test {Slave should be able to synchronize with the master} { - $slave slaveof $master_host $master_port - wait_for_condition 500 100 { - [lindex [r role] 0] eq {slave} && - [lindex [r role] 3] eq {connected} - } else { - fail "Replication not started." - } - } - - # Check that the background clients are actually writing. - test {Detect write load to master} { - if {$::swap && $use_sustained_write_load} { - wait_for_condition 50 1000 { - [status $master total_commands_processed] > ($write_cmds_before + 100) - } else { - fail "Can't detect write load from background clients." - } - } else { - wait_for_condition 50 1000 { - [$master dbsize] > 100 - } else { - fail "Can't detect write load from background clients." - } - } - } - - test "Test replication partial resync: $descr (diskless: $mdl, $sdl, reconnect: $reconnect)" { - set sync_full_before [s -1 sync_full] - set sync_partial_ok_before [s -1 sync_partial_ok] - set sync_partial_err_before [s -1 sync_partial_err] - # Now while the clients are writing data, break the maste-slave - # link multiple times. - if ($reconnect) { - for {set j 0} {$j < $duration*10} {incr j} { - after 100 - - if {($j % 20) == 0} { - catch { - if {$delay} { - $slave multi - $slave client kill $master_host:$master_port - $slave debug sleep $delay - $slave exec - } else { - $slave client kill $master_host:$master_port - } - } - } - } - } - - if {$::swap} { - stop_bg_complex_data $load_handle0 - stop_bg_complex_data $load_handle1 - if {$use_sustained_write_load} { - stop_bg_complex_data $load_handle2 - } - } else { - stop_bg_complex_data $load_handle0 - stop_bg_complex_data $load_handle1 - stop_bg_complex_data $load_handle2 - } - - # Wait for the slave to reach the "online" - # state from the POV of the master. - # With bg_limit reduced under ASAN the DB is small (~1k keys), - # so each full resync completes in <30 s. 600 s (6000 × 100 ms) - # gives 20× headroom while avoiding the 1000 s waste on genuine - # failures that inflated the total run time to 2000+ seconds. - set retry [expr {($::swap && $::asan) ? 6000 : 5000}] - while {$retry} { - set info [$master info] - if {[string match {*slave0:*state=online*} $info]} { - break - } else { - incr retry -1 - after 100 - } - } - if {$retry == 0} { - error "assertion:Slave not correctly synchronized" - } - - # Wait that slave acknowledge it is online so - # we are sure that DBSIZE and DEBUG DIGEST will not - # fail because of timing issues. (-LOADING error) - wait_for_condition 5000 100 { - [lindex [$slave role] 3] eq {connected} - } else { - fail "Slave still not connected after some time" - } - - if {$::swap} { - wait_for_condition 1000 50 { - [gtid_cmp [get_gtid $slave] [get_gtid $master]] == 0 - } else { - puts "master: [$master info gtid]" - puts "slave: [$slave info gtid]" - fail "master slave gtid wait sync err" - } - } else { - set retry 10 - while {$retry && ([$master debug digest] ne [$slave debug digest])}\ - { - after 1000 - incr retry -1 - } - assert {[$master dbsize] > 0} - if {[$master debug digest] ne [$slave debug digest]} { - set csv1 [csvdump r] - set csv2 [csvdump {r -1}] - set fd [open /tmp/repldump1.txt w] - puts -nonewline $fd $csv1 - close $fd - set fd [open /tmp/repldump2.txt w] - puts -nonewline $fd $csv2 - close $fd - puts "Master - Replica inconsistency" - puts "Run diff -u against /tmp/repldump*.txt for more info" - } - assert_equal [r debug digest] [r -1 debug digest] - assert_equal [gtid_cmp [get_gtid $slave] [get_gtid $master]] 0 - } - - eval $cond - } - } - } -} - -foreach mdl {no yes} { - foreach sdl {disabled swapdb} { - test_psync {no reconnection, just sync} 6 1000000 3600 0 { - } $mdl $sdl 0 - - test_psync {ok psync} 6 100000000 3600 0 { - assert {[s -1 sync_partial_ok] > 0} - } $mdl $sdl 1 - - test_psync {no backlog} 6 100 3600 0.5 { - assert_partial_resync_rejected $sync_full_before $sync_partial_err_before $sync_partial_ok_before - } $mdl $sdl 1 - - test_psync {ok after delay} 3 100000000 3600 3 { - assert {[s -1 sync_partial_ok] > 0} - } $mdl $sdl 1 - - test_psync {backlog expired} 3 100000000 1 3 { - assert_partial_resync_rejected $sync_full_before $sync_partial_err_before $sync_partial_ok_before - } $mdl $sdl 1 - } -} diff --git a/tests/gtid/sync.tcl b/tests/gtid/sync.tcl deleted file mode 100644 index d43a405bdbe..00000000000 --- a/tests/gtid/sync.tcl +++ /dev/null @@ -1,214 +0,0 @@ -# [functional testing] -# master slave sync -start_server {tags {"gtid replication"} overrides {gtid-enabled yes}} { -start_server {overrides {gtid-enabled yes}} { - # Config - set debug_msg 0 ; # Enable additional debug messages - - set no_exit 0 ; # Do not exit at end of the test - - set duration 20 ; # Total test seconds - for {set j 0} {$j < 2} {incr j} { - set R($j) [srv [expr 0-$j] client] - set R_host($j) [srv [expr 0-$j] host] - set R_port($j) [srv [expr 0-$j] port] - set R_unixsocket($j) [srv [expr 0-$j] unixsocket] - if {$debug_msg} {puts "Log file: [srv [expr 0-$j] stdout]"} - } - test "REPLICATION" { - test {GTID SET} { - $R(0) set k v - $R(1) slaveof $R_host(0) $R_port(0) - wait_for_condition 50 1000 { - [status $R(1) master_link_status] == "up" && - [dbsize_loadsafe $R(1) replica_dbsize] && - $replica_dbsize == 1 - } else { - fail "Replicas not replicating from master" - } - # exclude the select command - $R(0) set k v1 - set maxtries 3 - set result 0 - set backlog_size 58 - while {[incr maxtries -1] >= 0} { - set before [status $R(0) master_repl_offset] - $R(0) gtid A:1 $::target_db set x foobar - set after [status $R(0) master_repl_offset] - if {[expr $after-$before] == $backlog_size} { - set result 1 - break - } - } - assert_equal $result 1 - } - test "SYNC GTID COMMAND" { - set repl [attach_to_replication_stream] - $R(0) gtid A:2 $::target_db set k v - assert_replication_stream $repl { - {select *} - {gtid A:2 * set k v} - } - } - test "SYNC SET=>GTID SET COMMAND " { - set repl [attach_to_replication_stream] - $R(0) set k v1 - assert_replication_stream $repl { - {select *} - {gtid * * set k v1} - } - assert_equal [$R(0) get k] v1 - } - test "GTID MULTI " { - wait_for_gtid_sync $R(0) $R(1) - set repl [attach_to_replication_stream] - $R(0) multi - $R(0) set k v2 - $R(0) exec - $R(0) set k v3 - assert_replication_stream $repl { - {select *} - {gtid * * set k v2} - {gtid * * set k v3} - } - wait_for_gtid_sync $R(0) $R(1) - $R(1) get k - } {v3} - test "GTID MULTI ERROR" { - wait_for_gtid_sync $R(0) $R(1) - set repl [attach_to_replication_stream] - $R(0) multi - $R(0) set k v4 k - $R(0) set k v5 - catch {$R(0) exec } error - $R(0) set k v6 - assert_replication_stream $repl { - {select *} - {gtid * * set k v5} - {gtid * * set k v6} - } - wait_for_gtid_sync $R(0) $R(1) - $R(1) get k - } {v6} - - test "EXPIRE" { - wait_for_gtid_sync $R(0) $R(1) - set repl [attach_to_replication_stream] - $R(0) setex k 1 v7 - after 1000 - assert_replication_stream $repl { - {select *} - {gtid * * SET k v7 PXAT *} - {gtid * * DEL k} - } - wait_for_gtid_sync $R(0) $R(1) - $R(1) get k - } {} - - test "GTID with list arg rewrite" { - wait_for_gtid_sync $R(0) $R(1) - $R(0) MSET key1 val1 key2 val2 - $R(0) HMSET myhash f1 v1 f2 v2 - $R(0) RPUSH mylist a b c 1 2 3 - - if {$::swap} { - # list disabled untill 1.0.1 - catch { wait_keyspace_cold $R(0) } - } - - set repl [attach_to_replication_stream] - $R(0) multi - $R(0) mget key1 key2 - $R(0) ltrim mylist 1 -2 - $R(0) hdel myhash f1 f2 f3 - $R(0) exec - - wait_for_ofs_sync $R(0) $R(1) - - assert_replication_stream $repl { - {multi} - {select *} - {ltrim mylist 1 -2} - {hdel myhash f1 f2 f3} - {gtid * * EXEC} - } - - assert_equal [$R(1) mget key1 key2] {val1 val2} - assert_equal [$R(1) lrange mylist 0 -1] {b c 1 2} - assert_equal [$R(1) hmget myhash f1 f2 f3] {{} {} {}} - } - } -} -} - -# full sync test set -start_server {tags {"gtid replication"} overrides {gtid-enabled yes}} { -start_server {overrides {gtid-enabled yes}} { - # Config - set debug_msg 0 ; # Enable additional debug messages - - set no_exit 0 ; # Do not exit at end of the test - - set duration 20 ; # Total test seconds - for {set j 0} {$j < 2} {incr j} { - set R($j) [srv [expr 0-$j] client] - set R_host($j) [srv [expr 0-$j] host] - set R_port($j) [srv [expr 0-$j] port] - set R_unixsocket($j) [srv [expr 0-$j] unixsocket] - if {$debug_msg} {puts "Log file: [srv [expr 0-$j] stdout]"} - } - test "REPLICATION" { - test {FULL SYNC SET} { - $R(0) set k v - $R(1) slaveof $R_host(0) $R_port(0) - wait_for_condition 50 1000 { - [status $R(1) master_link_status] == "up" && - [dbsize_loadsafe $R(1) replica_dbsize] && - $replica_dbsize == 1 - } else { - fail "Replicas not replicating from master" - } - wait_for_gtid_sync $R(0) $R(1) - assert_equal [gtid_cmp [get_gtid $R(1)] [get_gtid $R(0)]] 0 - $R(0) set k1 v1 - wait_for_gtid_sync $R(0) $R(1) - assert_equal [$R(1) get k1] v1 - assert_equal [gtid_cmp [get_gtid $R(1)] [get_gtid $R(0)]] 0 - } - } -} -} - - -# partial sync test set -start_server {tags {"gtid replication"} overrides {gtid-enabled yes}} { -start_server {overrides {gtid-enabled yes}} { - # Config - set debug_msg 0 ; # Enable additional debug messages - - set no_exit 0 ; # Do not exit at end of the test - - set duration 20 ; # Total test seconds - for {set j 0} {$j < 2} {incr j} { - set R($j) [srv [expr 0-$j] client] - set R_host($j) [srv [expr 0-$j] host] - set R_port($j) [srv [expr 0-$j] port] - set R_unixsocket($j) [srv [expr 0-$j] unixsocket] - if {$debug_msg} {puts "Log file: [srv [expr 0-$j] stdout]"} - } - test "REPLICATION" { - test {PARTIAL SYNC SET} { - $R(1) slaveof $R_host(0) $R_port(0) - wait_for_condition 50 1000 { - [status $R(1) master_link_status] == "up" - } else { - fail "Replicas not replicating from master" - } - $R(0) set k v - wait_for_gtid_sync $R(0) $R(1) - assert_equal [$R(1) get k] v - assert_equal [gtid_cmp [get_gtid $R(1)] [get_gtid $R(0)]] 0 - } - } -} -} diff --git a/tests/gtid/xsync.tcl b/tests/gtid/xsync.tcl deleted file mode 100644 index 0d0bd67c4ab..00000000000 --- a/tests/gtid/xsync.tcl +++ /dev/null @@ -1,1728 +0,0 @@ -proc get_info_property {r section line property} { - set str [$r info $section] - if {[regexp ".*${line}:\[^\r\n\]*${property}=(\[^,\r\n\]*).*" $str match submatch]} { - set _ $submatch - } -} - -start_server {tags {"xsync"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - set M [srv -1 client] - set M_host [srv -1 host] - set M_port [srv -1 port] - set S [srv 0 client] - set S_host [srv 0 host] - set S_port [srv 0 port] - - # master: | (X) set hello world | (P) | (X) | - # slave: | (X) set hello world | (P) | - test "prev_repl_mode.from equals repl_mode.from" { - assert_equal [status $M gtid_repl_mode] xsync - assert_equal [status $S gtid_repl_mode] xsync - - # trigger master to create repl backlog, so that M S master_repl_offset will differ - $S replicaof $M_host $M_port - wait_for_sync $S - - $M set hello world - - wait_for_sync $S - wait_for_gtid_sync $M $S - - assert_equal [$S get hello] world - - $M config set gtid-enabled no - after 100 - wait_for_sync $S - - $M config set gtid-enabled yes - - $M set hello world_1 - wait_for_sync $S - wait_for_gtid_sync $M $S - - assert_equal [$S get hello] world_1 - } -} -} - -start_server {tags {"xsync"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - set M [srv -2 client] - set M_host [srv -2 host] - set M_port [srv -2 port] - set S [srv -1 client] - set S_host [srv -1 host] - set S_port [srv -1 port] - set SS [srv 0 client] - set SS_host [srv 0 host] - set SS_port [srv 0 port] - - test "master.uuid propagate to subslaves, master_repl_offset align" { - # trigger master to create repl backlog, so that M S master_repl_offset will differ - $S replicaof $M_host $M_port - wait_for_sync $S - if {$::swap} { - wait_done_loading $S - } - $S replicaof no one - - for {set i 0} {$i < 100} {incr i} { - $M set key-$i val-$i - } - - $S replicaof $M_host $M_port - - wait_for_sync $S - wait_for_gtid_sync $M $S - - for {set i 0} {$i < 100} {incr i} { - $M set key-$i val-$i - } - - $SS replicaof $S_host $S_port - - wait_for_sync $SS - wait_for_gtid_sync $M $SS - - assert { [status $M gtid_master_repl_offset] == [status $S gtid_master_repl_offset] } - assert { [status $S gtid_master_repl_offset] == [status $SS gtid_master_repl_offset] } - - assert { [status $S slave_repl_offset] == [status $SS slave_repl_offset] } - - assert_equal [status $M gtid_master_uuid] [status $S gtid_master_uuid] - assert_equal [status $M gtid_master_uuid] [status $SS gtid_master_uuid] - - assert { [status $M gtid_uuid] != [status $S gtid_uuid] } - assert { [status $M gtid_uuid] != [status $SS gtid_uuid] } - } -} -} -} - -start_server {tags {"xsync"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - set M [srv -2 client] - set M_host [srv -2 host] - set M_port [srv -2 port] - set S [srv -1 client] - set S_host [srv -1 host] - set S_port [srv -1 port] - set SS [srv 0 client] - set SS_host [srv 0 host] - set SS_port [srv 0 port] - - test "fallback to fullresync on wrong type" { - $M hmset hello f1 v1 f2 v1 - - $SS replicaof $S_host $S_port - $S replicaof $M_host $M_port - - wait_for_sync $S - wait_for_sync $SS - wait_for_gtid_sync $M $S - wait_for_gtid_sync $M $SS - - assert_equal [$M hmget hello f1 f2] {v1 v1} - assert_equal [$S hmget hello f1 f2] {v1 v1} - assert_equal [$SS hmget hello f1 f2] {v1 v1} - - $S replicaof no one - - $S set hello world - - wait_for_sync $SS - wait_for_gtid_sync $S $SS - - # generate M S data inconsistent - assert_equal [$S get hello] world - assert_equal [$SS get hello] world - assert_equal [$M hmget hello f1 f2] {v1 v1} - - $S replicaof $M_host $M_port - - wait_for_sync $S - wait_for_sync $SS - - wait_for_gtid_sync $M $S - wait_for_gtid_sync $M $SS - - # partial resync accepted, M S data inconsistent remains - assert_equal [$S get hello] world - assert_equal [$SS get hello] world - assert_equal [$M hmget hello f1 f2] {v1 v1} - - set orig_sync_full_MS [status $M sync_full] - set orig_sync_full_SSS [status $S sync_full] - - # we try multiple round to ensure M,S,SS consistent because - # fullresync are triggered in servercron, which means SS might - # force fullresync before S, and then psync with S. resulting - # that SS still inconsistent with M. - for {set i 1} {$i < 5} { incr i} { - # hmset will fail on slave because wrongtype error - $M hmset hello f1 v2 f2 v2 - - # wait for force fullresync on both M->S and S->SS, then wait - # until the replication links are back online before asserting - # on the repaired key contents. - wait_for_condition 50 100 { - [status $M sync_full] > $orig_sync_full_MS && - [status $S sync_full] > $orig_sync_full_SSS - } else { - fail "full resync didn't happen in time" - } - - wait_for_sync $S - wait_for_sync $SS - - # after fullresync, S SS is consistent with M - assert_equal [$M hmget hello f1 f2] {v2 v2} - - # In swap mode servercron (which triggers forced full resync on - # WRONGTYPE) may be delayed. wait_for_sync only - # checks master_link_status=="up", which can still be true before - # the resync fires. Wait explicitly for S to have the correct type. - if {$::swap} { - wait_for_condition 500 100 { - [catch {$S hmget hello f1 f2} _sr] == 0 && $_sr eq {v2 v2} - } else { - fail "S not fixed by forced full resync in swap mode" - } - } - assert_equal [$S hmget hello f1 f2] {v2 v2} - - catch {$SS hmget hello f1 f2} result - - if { $result eq {v2 v2} } { - break - } else { - assert_match "*WRONGTYPE*" $result - } - } - - wait_for_condition 50 100 { - [catch {$SS hmget hello f1 f2} result] == 0 && - $result eq {v2 v2} - } else { - fail "SS didn't finish full resync in time" - } - } -} -} -} - -proc press_enter_to_continue {{message "Hit Enter to continue ==> "}} { - puts -nonewline $message - flush stdout - gets stdin -} - -proc dump_gtid_sync_state {label r} { - puts "$label port=[lindex [$r config get port] 1] role=[lindex [$r role] 0]" - puts "$label gtid_repl_mode=[status $r gtid_repl_mode]" - puts "$label master_repl_offset=[status $r master_repl_offset] slave_repl_offset=[status $r slave_repl_offset]" - puts "$label gtid_master_repl_offset=[status $r gtid_master_repl_offset]" - puts "$label sync_full=[status $r sync_full] sync_partial_ok=[status $r sync_partial_ok]" - puts "$label gtid_set=[status $r gtid_set]" - puts "$label info replication: [$r info replication]" - puts "$label info gtid: [$r info gtid]" -} - -proc wait_for_gtid_sync_ex {label r1 r2 {maxtries 500} {delay 100}} { - wait_for_condition $maxtries $delay { - [gtid_set_is_equal [status $r1 gtid_set] [status $r2 gtid_set]] - } else { - puts "GTID sync timeout: $label" - dump_gtid_sync_state "upstream" $r1 - dump_gtid_sync_state "downstream" $r2 - fail "$label: gtid didn't sync in time" - } -} - -proc assert_repl_stream_aligned {master slave} { - wait_for_ofs_sync $master $slave - assert_equal [status $master master_replid] [status $slave master_replid] - wait_for_condition 50 100 { - [status $master master_repl_offset] eq [status $slave slave_repl_offset] - } else { - fail "slave_repl_offset not aligned" - } - wait_for_condition 50 100 { - [repl_ack_off_aligned $master] - } else { - fail "repl_ack_off not aligned" - } -} - -start_server {tags {"xsync"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - set master [srv -1 client] - set master_host [srv -1 host] - set master_port [srv -1 port] - set slave [srv 0 client] - - test "master(X) slave(X) LOCATE( ): gtid not related => xfullresync" { - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $slave gtid_repl_mode] xsync - - $master set hello world - $slave set foo bar - - set orig_sync_full [status $master sync_full] - set orig_xsync_xfullresync [get_info_property $slave gtid gtid_sync_stat xsync_xfullresync] - - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_xfullresync] 0 - - assert {[status $master gtid_uuid] != [status $slave gtid_uuid]} - assert {[status $master gtid_executed] != [status $slave gtid_executed]} - - $slave replicaof $master_host $master_port - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - assert_equal [status $master gtid_executed] [status $slave gtid_executed] - - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_xfullresync] [expr $orig_xsync_xfullresync+1] - - - $slave replicaof no one - } - - # master: | (X) set hello world | (P) set hello world_1 | (X) set hello world_2 | - # slave: | (X) - test "master( ) slave(X) LOCATE(?): xfullresync" { - assert_equal [status $master gtid_executed] [status $slave gtid_executed] - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $slave gtid_repl_mode] xsync - - $master set hello world - assert {[status $master gtid_executed] != [status $slave gtid_executed]} - - $master config set gtid-enabled no - assert_equal [status $master gtid_repl_mode] psync - assert_equal [status $master gtid_prev_repl_mode] xsync - $master set hello world_1 - - $master config set gtid-enabled yes - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $master gtid_prev_repl_mode] psync - $master set hello world_2 - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_xsync_xfullresync [get_info_property $slave gtid gtid_sync_stat xsync_xfullresync] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - assert_equal [status $master gtid_executed] [status $slave gtid_executed] - - verify_log_message -1 "*Partial sync request from*rejected*gtid.set-master(*) and gtid.set-slave(*) not related*" $orig_log_lines - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_xfullresync] [expr $orig_xsync_xfullresync+1] - - $slave replicaof no one - } - - # master: | (X) set hello world | (P) set hello world_1 | (X) set hello world_2 | - # slave: | (X) set hello world - test "xsync from prev prev repl stage: xfullresync (gtid not related)" { - assert_equal [status $master gtid_executed] [status $slave gtid_executed] - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $slave gtid_repl_mode] xsync - - $slave replicaof $master_host $master_port - wait_for_sync $slave - - $master set hello world - wait_for_ofs_sync $master $slave - assert_equal [$slave get hello] world - assert_repl_stream_aligned $master $slave - - $slave replicaof 127.0.0.1 0 - after 100 - - $master config set gtid-enabled no - assert_equal [status $master gtid_repl_mode] psync - assert_equal [status $master gtid_prev_repl_mode] xsync - $master set hello world_1 - - $master config set gtid-enabled yes - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $master gtid_prev_repl_mode] psync - $master set hello world_2 - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_xsync_xfullresync [get_info_property $slave gtid gtid_sync_stat xsync_xfullresync] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [status $master gtid_executed] [status $slave gtid_executed] - - verify_log_message -1 "*Partial sync request from*rejected*gtid.set-master(*) and gtid.set-slave(*) not related*" $orig_log_lines - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_xfullresync] [expr $orig_xsync_xfullresync+1] - - $slave replicaof no one - } - - # master: | (P) set hello world_1 set hello world_2 | (X) set hello world_3 | (P) set hello world_4 | - # slave: | (P) set hello world_1 | - test "master( ) slave(P) LOCATE(?): fullresync" { - $master config set gtid-enabled no - $slave config set gtid-enabled no - - assert_equal [status $master gtid_repl_mode] psync - assert_equal [status $slave gtid_repl_mode] psync - - $slave replicaof $master_host $master_port - wait_for_ofs_sync $master $slave - - $master set hello world_1 - wait_for_ofs_sync $master $slave - assert_equal [$slave get hello] world_1 - - $slave replicaof 127.0.0.1 0 - - $master set hello world_2 - - $master config set gtid-enabled yes - $master set hello world_3 - - $master config set gtid-enabled no - $master set hello world_4 - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_psync_fullresync [get_info_property $slave gtid gtid_sync_stat psync_fullresync] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - assert_equal [$slave get hello] world_4 - - verify_log_message -1 "*Partial sync request from*rejected*psync offset(*) < prev_repl_mode.from(*)*" $orig_log_lines - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat psync_fullresync] [expr $orig_psync_fullresync+1] - - $slave replicaof no one - $master config set gtid-enabled yes - $slave config set gtid-enabled yes - } - - # master: |(X) - # slave : |(X) set foo bar; ...(9999)...; set foo bar | - test "master(X) slave(X) LOCATE(X): gap > maxgap => xfullresync" { - # make gtid.set related - $slave replicaof $master_host $master_port - $master set foo bar - wait_for_sync $slave - wait_for_ofs_sync $master $slave - $slave replicaof no one - - assert_equal [status $master gtid_executed] [status $slave gtid_executed] - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $slave gtid_repl_mode] xsync - - for {set i 0} {$i < 10001} {incr i} { - $slave set foo bar - } - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_xsync_xfullresync [get_info_property $slave gtid gtid_sync_stat xsync_xfullresync] - - assert {[status $master gtid_executed] != [status $slave gtid_executed]} - - $slave replicaof $master_host $master_port - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - assert_equal [status $master gtid_executed] [status $slave gtid_executed] - - verify_log_message -1 "*Partial sync request from * rejected*gap*>*maxgap*" $orig_log_lines - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_xfullresync] [expr $orig_xsync_xfullresync+1] - - $slave replicaof no one - } - - # master: |(X) set hello world | - # slave: |(X) set foo bar | - test "master(X) slave(X) LOCATE(X): gap <= maxgap => xcontinue" { - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $slave gtid_repl_mode] xsync - assert_equal [status $master gtid_executed] [status $slave gtid_executed] - - $master set hello world - $slave set foo bar - - assert {[status $master gtid_executed] != [status $slave gtid_executed]} - - set orig_log_lines [count_log_lines -1] - set orig_sync_partial_ok [status $master sync_partial_ok] - set orig_xsync_xcontinue [get_info_property $slave gtid gtid_sync_stat xsync_xcontinue] - set orig_master_lost [status $master gtid_lost] - set orig_slave_lost [status $slave gtid_lost] - - set slave_replid [status $slave master_replid] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - # replid and offset untouched - assert_equal [status $slave master_replid] $slave_replid - - assert {[status $master gtid_executed] != [status $slave gtid_executed]} - verify_log_message -1 "*Partial sync request from*accepted*gap=1 <= maxgap=*" $orig_log_lines - assert_equal [status $master sync_partial_ok] [expr $orig_sync_partial_ok+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_xcontinue] [expr $orig_xsync_xcontinue+1] - assert {[status $master gtid_lost] != $orig_master_lost} - assert_equal [status $slave gtid_lost] $orig_slave_lost - - $slave replicaof no one - } - - # master: | (P) set hello world_1 set hello world_2 | (X) set hello world_3 | - # slave: | (P) set hello world_1 | - test "master(X) slave(P) LOCATE(P): continue + xcontinue" { - $master config set gtid-enabled no - $slave config set gtid-enabled no - - assert_equal [status $master gtid_repl_mode] psync - assert_equal [status $slave gtid_repl_mode] psync - - $slave replicaof $master_host $master_port - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - - $master set hello world_1 - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - assert_equal [$slave get hello] world_1 - - $slave replicaof 127.0.0.1 0 - - $master set hello world_2 - - assert_equal [$slave get hello] world_1 - - $master config set gtid-enabled yes - - $master set hello world_3 - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_sync_partial_ok [status $master sync_partial_ok] - set orig_psync_continue [get_info_property $slave gtid gtid_sync_stat psync_continue] - set orig_psync_xcontinue [get_info_property $slave gtid gtid_sync_stat psync_xcontinue] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_gtid_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [$slave get hello] world_3 - - verify_log_message -1 "*Partial sync request from * accepted: prior psync => xsync*" $orig_log_lines - verify_log_message -1 "*Disconnect slave * to notify repl mode switched*" $orig_log_lines - verify_log_message -1 "*Partial sync request from * accepted: psync => xsync*" $orig_log_lines - - assert_equal [status $master sync_full] [expr $orig_sync_full] - assert_equal [status $master sync_partial_ok] [expr $orig_sync_partial_ok+2] - assert_equal [get_info_property $slave gtid gtid_sync_stat psync_continue] [expr $orig_psync_continue+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat psync_xcontinue] [expr $orig_psync_xcontinue+1] - - $slave replicaof no one - $slave config set gtid-enabled yes - } - - # master: | (psync) set hello world_1 | (X) set hello world_2 set hello world_3 | - # slave: | (psync) set hello world_1 set hello world_2 | - test "master(X) slave(P) LOCATE(X): xfullresync" { - $master config set gtid-enabled no - $slave config set gtid-enabled no - - assert_equal [status $master gtid_repl_mode] psync - assert_equal [status $slave gtid_repl_mode] psync - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - - $master set hello world_1 - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - assert_equal [$slave get hello] world_1 - - $slave replicaof no one - $slave set hello world_2 - - $master config set gtid-enabled yes - $master set hello world_2 - $master set hello world_3 - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_psync_xfullresync [get_info_property $slave gtid gtid_sync_stat psync_xfullresync] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_gtid_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [$slave get hello] world_3 - - verify_log_message -1 "*Partial sync request from * rejected: request mode(psync) != located mode(xsync)*" $orig_log_lines - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat psync_xfullresync] [expr $orig_psync_xfullresync+1] - - $slave replicaof no one - $slave config set gtid-enabled yes - } - - # master: | (X) set hello world_1 set hello world_2 | (P) set hello world_3 | - # slave: | (X) set hello world_1 | - test "master(P) slave(X) locate(X): gap=0 => xcontinue + continue" { - $master config set gtid-enabled yes - $slave config set gtid-enabled yes - - $slave replicaof $master_host $master_port - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - $master set hello world_1 - wait_for_gtid_sync $master $slave - assert_equal [$slave get hello] world_1 - - $slave replicaof 127.0.0.1 0 - - $master set hello world_2 - - $master config set gtid-enabled no - $master set hello world_3 - - set master_replid [status $master master_replid] - assert {[status $slave master_replid] != $master_replid} - - set orig_log_lines [count_log_lines -1] - set orig_sync_partial_ok [status $master sync_partial_ok] - set orig_xsync_xcontinue [get_info_property $slave gtid gtid_sync_stat xsync_xcontinue] - set orig_xsync_continue [get_info_property $slave gtid gtid_sync_stat xsync_continue] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_gtid_sync $master $slave - assert_repl_stream_aligned $master $slave - - #replid and offset aligned - assert_equal [status $slave master_replid] $master_replid - - assert_equal [$slave get hello] world_3 - - verify_log_message -1 "*Partial sync request from * accepted: gap=0 <= maxgap=*" $orig_log_lines - verify_log_message -1 "*Disconnect slave * to notify repl mode switched*" $orig_log_lines - verify_log_message -1 "*Partial sync request from * accepted: xsync => psync, offset=*, limit=0, *" $orig_log_lines - - assert_equal [status $master sync_partial_ok] [expr $orig_sync_partial_ok+2] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_xcontinue] [expr $orig_xsync_xcontinue+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_continue] [expr $orig_xsync_continue+1] - - $slave replicaof no one - } - - # master: | (X) set hello world_1 set hello world_3 | (P) set hello world_4 | - # slave: | (X) set hello world_1 set hello world_2 | - test "master(P) slave(X) locate(X): gap <= maxgap => xcontinue + continue" { - $master config set gtid-enabled yes - $slave config set gtid-enabled yes - - $slave replicaof $master_host $master_port - wait_for_sync $slave - - $master set hello world_1 - wait_for_gtid_sync $master $slave - assert_equal [$slave get hello] world_1 - assert_repl_stream_aligned $master $slave - - $slave replicaof no one - $slave set hello world_2 - - $master set hello world_3 - - $master config set gtid-enabled no - $master set hello world_4 - - set master_replid [status $master master_replid] - assert {[status $slave master_replid] != $master_replid} - - set orig_log_lines [count_log_lines -1] - set orig_sync_partial_ok [status $master sync_partial_ok] - set orig_xsync_xcontinue [get_info_property $slave gtid gtid_sync_stat xsync_xcontinue] - set orig_xsync_continue [get_info_property $slave gtid gtid_sync_stat xsync_continue] - set orig_master_gtid_lost [status $master gtid_lost] - set orig_slave_gtid_lost [status $slave gtid_lost] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_gtid_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [status $slave master_replid] $master_replid - assert_equal [status $master master_replid] $master_replid - - assert_equal [$slave get hello] world_4 - - verify_log_message -1 "*Partial sync request from * accepted: gap=1 <= maxgap=*" $orig_log_lines - verify_log_message -1 "*Disconnect slave * to notify repl mode switched*" $orig_log_lines - verify_log_message -1 "*Partial sync request from * accepted: xsync => psync, offset=*, limit=0, *" $orig_log_lines - - assert_equal [status $master sync_partial_ok] [expr $orig_sync_partial_ok+2] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_xcontinue] [expr $orig_xsync_xcontinue+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_continue] [expr $orig_xsync_continue+1] - assert {[status $master gtid_lost] != $orig_master_gtid_lost} - assert_equal [status $slave gtid_lost] $orig_slave_gtid_lost - - $slave replicaof no one - $master set gtid-enabled yes - } - - # master: | (X) set hello world_0 set foo bar_0 | (P) set hello world_2a | - # slave : | (X) set hello world_0 ...(10000)... set hello world_10001 set hello world_2b | - test "master(P) slave(X) locate(X): gap > maxgap => fullresync" { - $master config set gtid-enabled yes - $slave config set gtid-enabled yes - - $slave replicaof $master_host $master_port - wait_for_sync $slave - - $master set hello world_0 - wait_for_gtid_sync $master $slave - assert_equal [$slave get hello] world_0 - assert_repl_stream_aligned $master $slave - - $slave replicaof no one - assert_equal [status $slave gtid_repl_mode] xsync - - $master set foo bar_0 - - $master config set gtid-enabled no - assert_equal [status $master gtid_repl_mode] psync - - $master set hello world_2a - - for {set i 1} {$i < 10002} {incr i} { - $slave set hello world_$i - } - $slave set hello world_2b - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_xsync_fullresync [get_info_property $slave gtid gtid_sync_stat xsync_fullresync] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_gtid_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [$slave get foo] bar_0 - assert_equal [$slave get hello] world_2a - - verify_log_message -1 "*Partial sync request from * rejected: gap=* > maxgap=*" $orig_log_lines - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_fullresync] [expr $orig_xsync_fullresync+1] - - $master config set gtid-enabled yes - $slave replicaof no one - - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $slave gtid_repl_mode] xsync - } - - # master: | (X) set hello world_0 | (P) set hello world_2a | - # slave : | (X) set hello world_0 ...(10000)... set hello world_10001 set hello world_2b | - test "master(P) slave(X) locate(P): gap > maxgap => fullresync" { - $master config set gtid-enabled yes - $slave config set gtid-enabled yes - - $slave replicaof $master_host $master_port - wait_for_sync $slave - - $master set hello world_0 - wait_for_gtid_sync $master $slave - assert_repl_stream_aligned $master $slave - assert_equal [$slave get hello] world_0 - - $slave replicaof no one - assert_equal [status $slave gtid_repl_mode] xsync - - $master config set gtid-enabled no - assert_equal [status $master gtid_repl_mode] psync - - $master set hello world_2a - - for {set i 1} {$i < 10002} {incr i} { - $slave set hello world_$i - } - $slave set hello world_2b - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_xsync_fullresync [get_info_property $slave gtid gtid_sync_stat xsync_fullresync] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_gtid_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [$slave get foo] bar_0 - assert_equal [$slave get hello] world_2a - - verify_log_message -1 "*continue point adjust to psync from*" $orig_log_lines - verify_log_message -1 "*Partial sync request from * rejected: gap=* > maxgap=*" $orig_log_lines - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat xsync_fullresync] [expr $orig_xsync_fullresync+1] - - $master config set gtid-enabled yes - $slave replicaof no one - - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $slave gtid_repl_mode] xsync - } - - # Psync are used to align replication offset - # master: | (P) set hello world | (X) set hello world_0 set hello world_1a | (P) set hello world_2 | - # slave : | (P) set hello world | (X) set hello world_0 | (P) set hello world_1b | - test "master(P) slave(P) locate(X): gap > maxgap => fullresync" { - $master config set gtid-enabled no - - $slave replicaof $master_host $master_port - - $master set hello world - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [$slave get hello] world - - $master config set gtid-enabled yes - after 100 - wait_for_sync $slave - - assert_equal [status $slave gtid_repl_mode] xsync - - $master set hello world_0 - wait_for_gtid_sync $master $slave - assert_repl_stream_aligned $master $slave - assert_equal [$slave get hello] world_0 - - $slave replicaof no one - $slave config set gtid-enabled no - $slave set hello world_1b - - $master set hello world_1a - $master config set gtid-enabled no - $master set hello world_2 - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_psync_fullresync [get_info_property $slave gtid gtid_sync_stat psync_fullresync] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_gtid_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [$slave get hello] world_2 - - verify_log_message -1 "*Partial sync request from * rejected: request mode(psync) != located mode(xsync)*" $orig_log_lines - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat psync_fullresync] [expr $orig_psync_fullresync+1] - - $master config set gtid-enabled yes - $slave config set gtid-enabled yes - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - $slave replicaof no one - - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $slave gtid_repl_mode] xsync - } - - # master: | (P) set hello world set hello world_1 | - # slave : | (P) set hello world | - test "master(P) slave(P) locate(P): handled by redis, offset valid => psync" { - $master config set gtid-enabled no - - $slave replicaof $master_host $master_port - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - assert_equal [status $master gtid_repl_mode] psync - assert_equal [status $slave gtid_repl_mode] psync - - $master set hello world - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - assert_equal [$slave get hello] world - - $slave replicaof 127.0.0.1 0 - - $master set hello world_1 - assert_equal [$slave get hello] world - - set orig_log_lines [count_log_lines -1] - set orig_sync_partial_ok [status $master sync_partial_ok] - set orig_psync_continue [get_info_property $slave gtid gtid_sync_stat psync_continue] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [$slave get hello] world_1 - - verify_log_message -1 "*Partial sync request from * handle by vanilla redis*" $orig_log_lines - assert_equal [status $master sync_partial_ok] [expr $orig_sync_partial_ok+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat psync_continue] [expr $orig_psync_continue+1] - - $master config set gtid-enabled yes - $slave config set gtid-enabled yes - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - $slave replicaof no one - } - - # master: | (P) set hello world set hello world_1 | - # slave : | (P) set hello world; | - test "master(P) slave(P) locate(P): handled by redis, replid changed => fullresync" { - $master config set gtid-enabled no - $slave config set gtid-enabled no - - $slave replicaof $master_host $master_port - wait_for_sync $slave - - assert_equal [status $master gtid_repl_mode] psync - assert_equal [status $slave gtid_repl_mode] psync - - $master set hello world - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - assert_equal [$slave get hello] world - - $slave replicaof no one - - $master set hello world_1 - assert_equal [$slave get hello] world - - set orig_log_lines [count_log_lines -1] - set orig_sync_full [status $master sync_full] - set orig_psync_fullresync [get_info_property $slave gtid gtid_sync_stat psync_fullresync] - - $slave replicaof $master_host $master_port - wait_for_sync $slave - wait_for_ofs_sync $master $slave - assert_repl_stream_aligned $master $slave - - assert_equal [$slave get hello] world_1 - - verify_log_message -1 "*Partial sync request from * handle by vanilla redis*" $orig_log_lines - assert_equal [status $master sync_full] [expr $orig_sync_full+1] - assert_equal [get_info_property $slave gtid gtid_sync_stat psync_fullresync] [expr $orig_psync_fullresync+1] - - $master config set gtid-enabled yes - $slave config set gtid-enabled yes - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - $slave replicaof no one - } -} -} - -start_server {tags {"xsync"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - set master [srv -1 client] - set master_host [srv -1 host] - set master_port [srv -1 port] - set slave [srv 0 client] - - test "master xsync => psync: replid and offset reset" { - assert_equal [status $master gtid_repl_mode] xsync - - set origin_replid [status $master master_replid] - - $master config set gtid-enabled no - assert_equal [status $master gtid_repl_mode] psync - - assert {[status $master master_replid] != $origin_replid} - assert {[status $master master_replid] != $origin_replid} - assert_equal [status $master master_replid2] "0000000000000000000000000000000000000000" - } - - test "master psync => xsync: replid and offset switch and saved to prev_repl_mode" { - assert_equal [status $master gtid_repl_mode] psync - - set origin_replid [status $master master_replid] - - $master config set gtid-enabled yes - - assert_equal [status $master gtid_repl_mode] xsync - assert {[status $master master_replid] != $origin_replid} - assert_equal [status $master master_replid2] 0000000000000000000000000000000000000000 - } - - test "master xsync => psync (defered untill slave promoted to master): replid and offset reset" { - $master config set gtid-enabled no - $slave config set gtid-enabled no - - $slave replicaof $master_host $master_port - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - set orig_replid [status $master master_replid] - - # master would shift replid - # slave would psync ok and upate replid - $master replicaof 127.0.0.1 0 - # 8.x dont disconnectSlaves - # after 200 - # assert_equal [status $slave master_link_status] "down" - - $master replicaof no one - $master set hello world - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - set master_replid [status $master master_replid] - set master_replid2 [status $master master_replid2] - assert {$master_replid != $orig_replid} - - assert_equal [status $master master_replid] [status $slave master_replid] - assert_equal [status $master master_replid2] [status $slave master_replid2] - assert {[status $slave master_replid2] != "0000000000000000000000000000000000000000"} - - $master config set gtid-enabled yes - after 100 - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - assert_equal [status $master gtid_repl_mode] xsync - assert_equal [status $slave gtid_repl_mode] xsync - - assert {[status $master master_replid] != $master_replid} - assert_equal [status $master master_replid2] "0000000000000000000000000000000000000000" - - assert_match "*$master_replid*$master_replid2*" [status $master gtid_prev_repl_detail] - - # psync mode defered untill slave promoted to master - $slave replicaof no one - - assert_equal [status $slave gtid_repl_mode] psync - assert {$master_replid != [status $slave master_replid]} - assert_equal [status $slave master_replid2] "0000000000000000000000000000000000000000" - - $slave config set gtid-enabled yes - } - - test "master psync => xsync (defered untill slave promoted to master): replid and offset switch and saved to prev_repl_mode " { - $master config set gtid-enabled no - - $slave replicaof $master_host $master_port - wait_for_sync $slave - assert_repl_stream_aligned $master $slave - - assert_equal [status $master gtid_repl_mode] psync - assert_equal [status $master gtid_repl_mode] psync - - set orig_replid [status $slave master_replid] - set orig_replid2 [status $slave master_replid2] - - $master set hello world - wait_for_ofs_sync $master $slave - - $slave replicaof no one - after 100 - assert_equal [status $slave gtid_repl_mode] xsync - - assert {$orig_replid != [status $slave master_replid]} - assert_match "*$orig_replid*$orig_replid2*" [status $slave gtid_prev_repl_detail] - - $master config set gtid-enabled yes - } - - # following case already tested in previous cases: - # "slave xsync: replid and offset untouched" - # "slave xsync => psync: replid and offset aligned" - # "slave psync => xsync: replid and offset untouched" -} -} - -start_server {tags {"xsync"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - set master [srv -1 client] - set master_host [srv -1 host] - set master_port [srv -1 port] - set slave [srv 0 client] - - # master: (P)... | (X) set hello world_1 | (P) set hello world_3 | - # slave: (P)... | (X) set hello world_1 set hello world_2 ... set hello world_2 | - test "xcontinue + continue: align offset would invalidate replication backlog" { - $master config set gtid-enabled no - $slave config set gtid-enabled yes - - $slave replicaof $master_host $master_port - wait_for_sync $slave - - $master set hello world_0 - wait_for_ofs_sync $master $slave - assert_equal [$slave get hello] world_0 - - - $master config set gtid-enabled yes - after 100 - wait_for_sync $slave - assert_equal [status $slave gtid_repl_mode] xsync - - $master set hello world_1 - wait_for_gtid_sync $master $slave - assert_equal [$slave get hello] world_1 - - $slave replicaof no one - assert_equal [status $slave gtid_repl_mode] xsync - - for {set i 0} {$i < 10} {incr i} { - $slave set hello world_2 - } - - $master config set gtid-enabled no - $master set hello world_3 - - set master_replid [status $master master_replid] - assert {[status $slave master_replid] != $master_replid} - - set orig_log_lines [count_log_lines -1] - set orig_sync_partial_ok [status $master sync_partial_ok] - set orig_xsync_xcontinue [get_info_property $slave gtid gtid_sync_stat xsync_xcontinue] - set orig_xsync_continue [get_info_property $slave gtid gtid_sync_stat xsync_continue] - - $slave replicaof $master_host $master_port - - # gtid.set, replid and offset aligned - wait_for_sync $slave - wait_for_gtid_sync $master $slave - assert_equal [status $slave master_replid] $master_replid - - assert_equal [$slave get hello] world_3 - $slave replicaof no one - - # if backlog not invalidated, append to gtid_seq would assert fail - $slave set hello crash - - $master set gtid-enabled yes - } -} -} - -proc wait_for_repl_mode_sync {r1 r2} { - wait_for_condition 500 100 { - [status $r1 gtid_repl_mode] eq [status $r2 gtid_repl_mode] - } else { - fail "repl mode didn't sync in time" - } -} - -start_server {tags {"xsync"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - - set M [srv -3 client] - set M_host [srv -3 host] - set M_port [srv -3 port] - set S [srv -2 client] - set S_host [srv -2 host] - set S_port [srv -2 port] - set SS1 [srv -1 client] - set SS1_host [srv -1 host] - set SS1_port [srv -1 port] - set SS2 [srv 0 client] - set SS2_host [srv 0 host] - set SS2_port [srv 0 port] - - test "gtid.set-lost updated: init" { - # create some gtid gap - $M set hello master - $S set hello slave - $SS1 set hello sub-slave-1 - $SS2 set hello sub-slave-2 - - assert {[status $M gtid_set] != [status $S gtid_set]} - assert {[status $M gtid_set] != [status $SS1 gtid_set]} - assert {[status $M gtid_set] != [status $SS2 gtid_set]} - - - $S replicaof $M_host $M_port - wait_for_sync $S - - $SS1 replicaof $S_host $S_port - $SS2 replicaof $S_host $S_port - - wait_for_sync $SS1 - wait_for_sync $SS2 - - wait_for_gtid_sync $M $S - wait_for_gtid_sync $M $SS1 - wait_for_gtid_sync $M $SS2 - - assert_equal [$M get hello] master - assert_equal [$S get hello] master - assert_equal [$SS1 get hello] master - assert_equal [$SS2 get hello] master - - $M set hello master-again - - wait_for_gtid_sync $M $S - wait_for_gtid_sync $M $SS1 - wait_for_gtid_sync $M $SS2 - - assert_equal [$M get hello] master-again - assert_equal [$S get hello] master-again - assert_equal [$SS1 get hello] master-again - assert_equal [$SS2 get hello] master-again - } - - test "gtid.set-lost updated by downstream: disconnect upstream and downstreams (except triggering one)" { - $SS1 replicaof no one - $SS1 set hello sub-slave-1-again - - assert {[status $M gtid_set] != [status $SS1 gtid_set]} - - set orig_sync_partial_ok_M [status $M sync_partial_ok] - set orig_sync_partial_ok_S [status $S sync_partial_ok] - set orig_xsync_xcontinue_S [get_info_property $S gtid gtid_sync_stat xsync_xcontinue] - set orig_xsync_xcontinue_SS1 [get_info_property $SS1 gtid gtid_sync_stat xsync_xcontinue] - set orig_xsync_xcontinue_SS2 [get_info_property $SS2 gtid gtid_sync_stat xsync_xcontinue] - - $SS1 replicaof $S_host $S_port - - wait_for_gtid_sync $SS1 $M - wait_for_gtid_sync $SS1 $S - wait_for_gtid_sync $SS1 $SS2 - - assert_equal [status $M sync_partial_ok] [expr $orig_sync_partial_ok_M+1] - assert_equal [status $S sync_partial_ok] [expr $orig_sync_partial_ok_S+2] - assert_equal [get_info_property $S gtid gtid_sync_stat xsync_xcontinue] [expr $orig_xsync_xcontinue_S+1] - assert_equal [get_info_property $SS1 gtid gtid_sync_stat xsync_xcontinue] [expr $orig_xsync_xcontinue_SS1+1] - assert_equal [get_info_property $SS2 gtid gtid_sync_stat xsync_xcontinue] [expr $orig_xsync_xcontinue_SS2+1] - } - - test "gtid.set-lost updated by upstream: disconnect upstream and downstreams(except triggering one)" { - $S replicaof no one - $S set hello sub-slave-again - - $M gtidx add lost A 1 10 - - wait_for_gtid_sync $S $SS1 - wait_for_gtid_sync $S $SS2 - - assert_equal [$SS1 get hello] sub-slave-again - assert_equal [$SS2 get hello] sub-slave-again - - assert {[status $M gtid_set] != [status $S gtid_set]} - - set orig_sync_partial_ok_M [status $M sync_partial_ok] - set orig_sync_partial_ok_S [status $S sync_partial_ok] - set orig_xsync_xcontinue_S [get_info_property $S gtid gtid_sync_stat xsync_xcontinue] - set orig_xsync_xcontinue_SS1 [get_info_property $SS1 gtid gtid_sync_stat xsync_xcontinue] - set orig_xsync_xcontinue_SS2 [get_info_property $SS2 gtid gtid_sync_stat xsync_xcontinue] - - $S replicaof $M_host $M_port - - wait_for_gtid_sync $SS1 $M - wait_for_gtid_sync $SS1 $S - wait_for_gtid_sync $SS1 $SS2 - - assert_equal [status $M sync_partial_ok] [expr $orig_sync_partial_ok_M+1] - assert_equal [status $S sync_partial_ok] [expr $orig_sync_partial_ok_S+2] - assert_equal [get_info_property $S gtid gtid_sync_stat xsync_xcontinue] [expr $orig_xsync_xcontinue_S+1] - assert_equal [get_info_property $SS1 gtid gtid_sync_stat xsync_xcontinue] [expr $orig_xsync_xcontinue_SS1+1] - assert_equal [get_info_property $SS2 gtid gtid_sync_stat xsync_xcontinue] [expr $orig_xsync_xcontinue_SS2+1] - } - - test "repl mode change propagates to all replicas" { - assert_equal [status $M gtid_repl_mode] xsync - assert_equal [status $S gtid_repl_mode] xsync - - set orig_sync_full_M [status $M sync_full] - set orig_sync_partial_ok_M [status $M sync_partial_ok] - set orig_sync_partial_ok_S [status $S sync_partial_ok] - - for {set i 0} {$i < 10} {incr i} { - puts "chaos repl mode change: round - $i" - - if {[expr {$i % 2}] == 0} { - set gtid_enabled "yes" - set gtid_repl_mode "xsync" - } else { - set gtid_enabled "no" - set gtid_repl_mode "psync" - } - - set load_hanler [start_write_load $M_host $M_port 5] - after 500 - $M config set gtid-enabled $gtid_enabled - stop_write_load $load_hanler - wait_load_handlers_disconnected -3 - - wait_for_sync $S - wait_for_sync $SS1 - wait_for_sync $SS2 - - # Mode propagation and stream realignment happen before the stronger - # GTID-set equality check. Waiting in that order preserves the - # original "switch under load" semantics while avoiding a premature - # GTID equality check during reconnect / realignment. - wait_for_repl_mode_sync $M $S - wait_for_repl_mode_sync $M $SS1 - wait_for_repl_mode_sync $M $SS2 - assert_equal [status $M gtid_repl_mode] $gtid_repl_mode - assert_equal [status $S gtid_repl_mode] $gtid_repl_mode - assert_equal [status $SS1 gtid_repl_mode] $gtid_repl_mode - assert_equal [status $SS2 gtid_repl_mode] $gtid_repl_mode - assert_repl_stream_aligned $M $S - assert_repl_stream_aligned $M $SS1 - assert_repl_stream_aligned $M $SS2 - # In SWAP mode, GTID state propagation can lag behind the replication - # offset because RocksDB background I/O flushes are asynchronous. - # Wait along the actual topology first so timeout reports identify - # the exact hop that did not converge. - set gtid_retry [expr {$::swap ? 1000 : 500}] - wait_for_gtid_sync_ex "M->S" $M $S $gtid_retry 100 - wait_for_gtid_sync_ex "S->SS1" $S $SS1 $gtid_retry 100 - wait_for_gtid_sync_ex "S->SS2" $S $SS2 $gtid_retry 100 - - assert {[gtid_set_is_equal [status $M gtid_set] [status $S gtid_set]]} - assert {[gtid_set_is_equal [status $M gtid_set] [status $SS1 gtid_set]]} - assert {[gtid_set_is_equal [status $M gtid_set] [status $SS2 gtid_set]]} - - assert_equal [status $M sync_full] $orig_sync_full_M - # assert_equal [status $M sync_partial_ok] [expr $orig_sync_partial_ok_M+$i] - # S may transiently trigger an extra full resync for its downstreams - # during repl-mode switches under load in swap mode. The core intent - # here is that repl mode propagates and GTID state converges. - # assert_equal [status $S sync_partial_ok] [expr $orig_sync_partial_ok_S+2*$i] - - # TODO 判断 数据一致 - } - } -} -} -} -} - -proc region_info_create {redis1 redis2 keeper} { - set region_info [dict create] - - set redis1_host [lindex [$redis1 config get bind] 1] - if {$redis1_host == ""} { - set redis1_host "127.0.0.1" - } - dict set region_info "redis1" "client" $redis1 - dict set region_info "redis1" "host" $redis1_host - dict set region_info "redis1" "port" [lindex [$redis1 config get port] 1] - - set redis2_host [lindex [$redis2 config get bind] 1] - if {$redis2_host == ""} { - set redis2_host "127.0.0.1" - } - dict set region_info "redis2" "client" $redis2 - dict set region_info "redis2" "host" $redis2_host - dict set region_info "redis2" "port" [lindex [$redis2 config get port] 1] - - set keeper_host [lindex [$keeper config get bind] 1] - if {$keeper_host == ""} { - set keeper_host "127.0.0.1" - } - dict set region_info "keeper" "client" $keeper - dict set region_info "keeper" "host" $keeper_host - dict set region_info "keeper" "port" [lindex [$keeper config get port] 1] - - return $region_info -} - -# setup master/slave/keeper replicaion link within region. -# role can be master/dr. -proc region_setup_topo {region_info_var_name role master_name} { - upvar $region_info_var_name region_info - - if {$role == "master"} { - if {$master_name == "redis1"} { - set slave_redis "redis2" - } elseif {$master_name == "redis2"} { - set slave_redis "redis1" - } else { - error "unexpected master name" - } - - set M [dict get $region_info $master_name client] - set M_host [dict get $region_info $master_name host] - set M_port [dict get $region_info $master_name port] - set S [dict get $region_info $slave_redis client] - set K [dict get $region_info keeper client] - - $M replicaof no one - $S replicaof $M_host $M_port - $K replicaof $M_host $M_port - - dict set region_info master_name $master_name - } elseif {$role == "dr"} { - set K [dict get $region_info keeper client] - set K_host [dict get $region_info keeper host] - set K_port [dict get $region_info keeper port] - set S1 [dict get $region_info redis1 client] - set S2 [dict get $region_info redis2 client] - - $K replicaof no one - $S1 replicaof $K_host $K_port - $S2 replicaof $K_host $K_port - - dict set region_info master_name $master_name - } else { - error "unexpcted region role" - } -} - -# setup replication link across region. -proc region_setup_dr {master_ri dr_ri} { - set dr_keeper [dict get $dr_ri keeper client] - set M_host [dict get $master_ri keeper host] - set M_port [dict get $master_ri keeper port] - $dr_keeper replicaof $M_host $M_port -} - -proc region_start_write_load {region_info_var_name {sleep 0}} { - upvar $region_info_var_name region_info - if {[dict exists $region_info master_name]} { - if {[dict get $region_info master_name] != "unset"} { - if {[dict exists $region_info loader]} { - stop_write_load [dict get $region_info loader] - } - set mi_info [dict get $region_info [dict get $region_info master_name]] - set loader [start_write_load [dict get $mi_info host] [dict get $mi_info port] 3600 "" 0 $sleep] - dict set region_info loader $loader - } - } -} - -proc region_stop_write_load {region_info} { - if {[dict exists $region_info loader]} { - stop_write_load [dict get $region_info loader] - } -} - -proc region_assert_repl_stream_aligned {ainfo binfo} { - if {[dict get $ainfo master_name] == "redis1"} { - assert_repl_stream_aligned [dict get $ainfo redis1 client] [dict get $ainfo redis2 client] - } else { - assert_repl_stream_aligned [dict get $ainfo redis2 client] [dict get $ainfo redis1 client] - } - - if {[dict get $binfo master_name] == "redis1"} { - assert_repl_stream_aligned [dict get $binfo redis1 client] [dict get $binfo redis2 client] - } else { - assert_repl_stream_aligned [dict get $binfo redis2 client] [dict get $binfo redis1 client] - } - - assert_repl_stream_aligned [dict get $ainfo redis1 client] [dict get $ainfo keeper client] - assert_repl_stream_aligned [dict get $binfo redis1 client] [dict get $binfo keeper client] - - assert_repl_stream_aligned [dict get $ainfo keeper client] [dict get $binfo keeper client] -} - -proc region_wait_for_gtid_sync {region_info} { - wait_for_gtid_sync [dict get $region_info redis1 client] [dict get $region_info redis2 client] - wait_for_gtid_sync [dict get $region_info redis1 client] [dict get $region_info keeper client] -} - -proc region_wait_for_sync {region_info} { - if {[dict get $region_info master_name] != "redis1"} { - wait_for_sync [dict get $region_info redis1 client] - } - if {[dict get $region_info master_name] != "redis2"} { - wait_for_sync [dict get $region_info redis2 client] - } - wait_for_sync [dict get $region_info keeper client] -} - -proc my_write_log_lines {count msg} { - for {set i 0} {$i < $count} {incr i} { - set svr_idx [expr 0 - $i] - write_log_line $svr_idx $msg - } -} - -start_server {tags {"xsync"} overrides {gtid-enabled yes gtid-xsync-max-gap 100000}} { - start_server {overrides {gtid-enabled yes gtid-xsync-max-gap 100000}} { - start_server {overrides {gtid-enabled yes gtid-xsync-max-gap 100000}} { - start_server {overrides {gtid-enabled yes gtid-xsync-max-gap 100000}} { - start_server {overrides {gtid-enabled yes gtid-xsync-max-gap 100000}} { - start_server {overrides {gtid-enabled yes gtid-xsync-max-gap 100000}} { - - set A_info [region_info_create [srv -5 client] [srv -4 client] [srv -3 client]] - set B_info [region_info_create [srv -2 client] [srv -1 client] [srv 0 client]] - - test "xsync chaos: init" { - region_setup_topo A_info master redis1 - region_setup_topo B_info dr "unset" - region_setup_dr $A_info $B_info - - region_wait_for_sync $A_info - region_wait_for_sync $B_info - region_wait_for_gtid_sync $A_info - region_wait_for_gtid_sync $B_info - wait_for_gtid_sync [dict get $A_info keeper client] [dict get $B_info keeper client] - } - - test "xsync chaos: failover" { - set orig_sync_full_redis1 [status [dict get $A_info redis1 client] sync_full] - set orig_sync_full_redis2 [status [dict get $A_info redis2 client] sync_full] - - for {set i 0} {$i < 10} {incr i} { - puts "xsync chaos: failover - round $i" - my_write_log_lines 6 "xsync chaos: failover - round $i: start" - - if {[expr {$i % 2}] == 0} { - set A_master "redis1" - } else { - set A_master "redis2" - } - - region_start_write_load A_info - - after 500 - - # mock active failover - region_setup_topo A_info master $A_master - after 100 - region_stop_write_load $A_info - - region_wait_for_sync $A_info - region_wait_for_sync $B_info - wait_for_gtid_sync [dict get $A_info keeper client] [dict get $B_info keeper client] - region_wait_for_gtid_sync $A_info - region_wait_for_gtid_sync $B_info - region_assert_repl_stream_aligned $A_info $B_info - - assert_equal [status [dict get $A_info redis1 client] sync_full] $orig_sync_full_redis1 - assert_equal [status [dict get $A_info redis2 client] sync_full] $orig_sync_full_redis2 - - my_write_log_lines 6 "xsync chaos: failover - round $i: end" - } - } - - test "xsync chaos: active dr" { - for {set i 0} {$i < 10} {incr i} { - puts "xsync chaos: active dr - round $i" - my_write_log_lines 6 "xsync chaos: active dr - round $i: start" - - if {[expr {$i % 4}] < 2} { - set master_name "redis1" - } else { - set master_name "redis2" - } - - if {[expr {$i % 2}] == 0} { - set A_role "master" - set A_master $master_name - set B_role "dr" - set B_master "unset" - upvar 0 A_info master_ri - upvar 0 B_info dr_ri - } else { - set A_role "dr" - set A_master "unset" - set B_role "master" - set B_master $master_name - upvar 0 B_info master_ri - upvar 0 A_info dr_ri - } - - set orig_sync_full_A_redis1 [status [dict get $A_info redis1 client] sync_full] - set orig_sync_full_A_redis2 [status [dict get $A_info redis2 client] sync_full] - set orig_sync_full_B_redis1 [status [dict get $B_info redis1 client] sync_full] - set orig_sync_full_B_redis2 [status [dict get $B_info redis2 client] sync_full] - - region_stop_write_load $A_info - region_stop_write_load $B_info - - region_setup_topo A_info $A_role $A_master - region_setup_topo B_info $B_role $B_master - region_setup_dr $master_ri $dr_ri - - region_wait_for_sync $A_info - region_wait_for_sync $B_info - - region_start_write_load master_ri - after 500 - region_stop_write_load $master_ri - - region_wait_for_gtid_sync $A_info - region_wait_for_gtid_sync $B_info - wait_for_gtid_sync [dict get $A_info keeper client] [dict get $B_info keeper client] - - region_assert_repl_stream_aligned $A_info $B_info - - assert_equal [status [dict get $A_info redis1 client] sync_full] $orig_sync_full_A_redis1 - assert_equal [status [dict get $A_info redis2 client] sync_full] $orig_sync_full_A_redis2 - assert_equal [status [dict get $B_info redis1 client] sync_full] $orig_sync_full_B_redis1 - assert_equal [status [dict get $B_info redis2 client] sync_full] $orig_sync_full_B_redis2 - - my_write_log_lines 6 "xsync chaos: active dr - round $i: end" - } - } - - test "xsync chaos: passive dr" { - if {$::swap} { - foreach r [list \ - [dict get $A_info redis1 client] \ - [dict get $A_info redis2 client] \ - [dict get $A_info keeper client] \ - [dict get $B_info redis1 client] \ - [dict get $B_info redis2 client] \ - [dict get $B_info keeper client]] { - $r config set repl-backlog-size 50mb - } - set passive_dr_load_sleep 1 - } else { - set passive_dr_load_sleep 0 - } - - for {set i 0} {$i < 10} {incr i} { - puts "xsync chaos: passive dr - round $i" - my_write_log_lines 6 "xsync chaos: passive dr - round $i: start" - - if {[expr {$i % 4}] < 2} { - set master_name "redis1" - } else { - set master_name "redis2" - } - - if {[expr {$i % 2}] == 0} { - set A_role "master" - set A_master $master_name - set B_role "dr" - set B_master "unset" - upvar 0 A_info master_ri - upvar 0 B_info dr_ri - } else { - set A_role "dr" - set A_master "unset" - set B_role "master" - set B_master $master_name - upvar 0 B_info master_ri - upvar 0 A_info dr_ri - } - - set orig_sync_full_A_redis1 [status [dict get $A_info redis1 client] sync_full] - set orig_sync_full_A_redis2 [status [dict get $A_info redis2 client] sync_full] - set orig_sync_full_B_redis1 [status [dict get $B_info redis1 client] sync_full] - set orig_sync_full_B_redis2 [status [dict get $B_info redis2 client] sync_full] - - # before topo change - region_start_write_load master_ri $passive_dr_load_sleep - region_start_write_load dr_ri $passive_dr_load_sleep - after 500 ; # wait write loader ready - - # topo change - region_setup_topo A_info $A_role $A_master - after 100 ; # single client ops < 100000/0.1, parital sync accepted - region_setup_topo B_info $B_role $B_master - after 100 ; # single client ops < 100000/0.1, parital sync accepted - region_setup_dr $master_ri $dr_ri - - region_wait_for_sync $A_info - region_wait_for_sync $B_info - - # after topo change - after 500 - region_stop_write_load $A_info - region_stop_write_load $B_info - - region_wait_for_gtid_sync $A_info - region_wait_for_gtid_sync $B_info - wait_for_gtid_sync [dict get $A_info keeper client] [dict get $B_info keeper client] - - region_assert_repl_stream_aligned $A_info $B_info - - assert_equal [status [dict get $A_info redis1 client] sync_full] $orig_sync_full_A_redis1 - assert_equal [status [dict get $A_info redis2 client] sync_full] $orig_sync_full_A_redis2 - assert_equal [status [dict get $B_info redis1 client] sync_full] $orig_sync_full_B_redis1 - assert_equal [status [dict get $B_info redis2 client] sync_full] $orig_sync_full_B_redis2 - - my_write_log_lines 6 "xsync chaos: passive dr - round $i: end" - } - } - -} -} -} -} -} -} - - - - -start_server {tags {"xsync"} overrides {gtid-enabled yes}} { - start_server {overrides {gtid-enabled yes}} { - set M [srv -1 client] - set M_host [srv -1 host] - set M_port [srv -1 port] - set S [srv 0 client] - set S_host [srv 0 host] - set S_port [srv 0 port] - - # trigger master to create repl backlog, so that M S master_repl_offset will differ - $S replicaof $M_host $M_port - wait_for_sync $S - - wait_for_gtid_sync $M $S - - $M config set repl-backlog-size 16484 - for {set i 0} {$i < 100} {incr i} { - $M set key-$i val-$i - } - - - for {set j 0} {$j < 3} {incr j} { - $S slaveof "127.0.0.1" 1 - if {[expr {$j % 2 }] == 0} { - $M config set gtid-enabled no - } else { - $M config set gtid-enabled yes - } - - - for {set i 0} {$i < 1000} {incr i} { - $M set key-$i val-$i - } - - $S replicaof $M_host $M_port - wait_for_sync $S - - wait_for_gtid_sync $M $S - } - - } -} diff --git a/tests/test_helper.tcl b/tests/test_helper.tcl index 38e9c17bd54..afccc9e4811 100644 --- a/tests/test_helper.tcl +++ b/tests/test_helper.tcl @@ -53,6 +53,7 @@ proc load_tests {dir test_dirs} { set ::gtid_test_dirs { gtid + gtid/8_x } set ::gtid_tests [load_tests $dir $::gtid_test_dirs]