1
+ start_server {tags {" scan-consistency-on-failover external:skip" }} {
2
+
3
+ set fixed_seed " 00112233445566778899aabbccddeeff"
4
+ set shared_overrides [list appendonly no save " " db-hash-seed $fixed_seed ]
5
+
6
+ start_server [list overrides $shared_overrides ] {
7
+ set primary_host [srv 0 host]
8
+ set primary_port [srv 0 port]
9
+
10
+ start_server [list overrides $shared_overrides ] {
11
+ set replica_host [srv 0 host]
12
+ set replica_port [srv 0 port]
13
+
14
+ set primary [srv -1 client]
15
+ set replica [srv 0 client]
16
+
17
+ $primary flushall
18
+ $replica replicaof $primary_host $primary_port
19
+
20
+ wait_for_sync $replica 200 50
21
+
22
+ set n 1000
23
+ for {set i 0} {$i < $n } {incr i} {
24
+ $primary set " k:$i " x
25
+ }
26
+ for {set i 0} {$i < $n } {incr i} {
27
+ $primary sadd s " m:$i "
28
+ $primary hset h " f:$i " v
29
+ $primary zadd z $i " z:$i "
30
+ }
31
+
32
+ wait_for_condition 200 50 {
33
+ [$replica dbsize] == [$primary dbsize]
34
+ } else {
35
+ fail " replica did not catch up dbsize"
36
+ }
37
+
38
+ # ensuring both instances have finished rehashing.
39
+ wait_for_condition 200 50 {
40
+ ![string match {Hash table 1 stats} [$primary debug htstats 0]] &&
41
+ ![string match {Hash table 1 stats} [$replica debug htstats 0]]
42
+ } else {
43
+ fail " hash tables still rehashing"
44
+ }
45
+
46
+ # SCAN across failover
47
+ set cur 0
48
+ set steps 0
49
+ set seen {}
50
+
51
+ while {1} {
52
+ set res [$primary scan $cur count 100]
53
+ set cur [lindex $res 0]
54
+ set keys [lindex $res 1]
55
+ foreach k $keys {
56
+ if {[string match " k:*" $k ]} {
57
+ dict set seen $k 1
58
+ }
59
+ }
60
+ incr steps
61
+
62
+ # After a few pages, promote the replica
63
+ if {$steps == 5} {
64
+ $replica replicaof no one
65
+ wait_for_condition 100 50 {
66
+ ([string match {*master*} [$replica info replication]])
67
+ } else {
68
+ fail " replica did not promote to master"
69
+ }
70
+ break
71
+ }
72
+ }
73
+
74
+ # Perform a full SCAN sweep to ensure all keys are covered.
75
+ set failover_steps 0
76
+ while {1} {
77
+ set res [$replica scan $cur count 100]
78
+ set cur [lindex $res 0]
79
+ set keys [lindex $res 1]
80
+ foreach k $keys {
81
+ if {[string match " k:*" $k ]} {
82
+ dict set seen $k 1
83
+ }
84
+ }
85
+ incr failover_steps
86
+ if {$cur eq " 0" } break
87
+
88
+ # safety guardrail incase scan doesn't end
89
+ if {$failover_steps > 200} {
90
+ fail " SCAN did not complete after failover"
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
0 commit comments