diff options
author | zhaozhao.zz <276441700@qq.com> | 2021-09-08 16:07:25 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-08 16:07:25 +0800 |
commit | 1b83353dc382959e218191f64d94edb9703552e3 (patch) | |
tree | 65c87fd59e43f7d24769d1e7e2f7bd1104246943 /tests | |
parent | 74d9a35621d66a816e1c30de9cd84c461297495a (diff) | |
download | redis-1b83353dc382959e218191f64d94edb9703552e3.tar.gz |
Fix wrong offset when replica pause (#9448)
When a replica paused, it would not apply any commands event the command comes from master, if we feed the non-applied command to replication stream, the replication offset would be wrong, and data would be lost after failover(since replica's `master_repl_offset` grows but command is not applied).
To fix it, here are the changes:
* Don't update replica's replication offset or propagate commands to sub-replicas when it's paused in `commandProcessed`.
* Show `slave_read_repl_offset` in info reply.
* Add an assert to make sure master client should never be blocked unless pause or module (some modules may use block way to do background (parallel) processing and forward original block module command to the replica, it's not a good way but it can work, so the assert excludes module now, but someday in future all modules should rewrite block command to propagate like what `BLPOP` does).
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/pause.tcl | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/tests/unit/pause.tcl b/tests/unit/pause.tcl index 35d8dff6b..a9a1f3554 100644 --- a/tests/unit/pause.tcl +++ b/tests/unit/pause.tcl @@ -163,6 +163,57 @@ start_server {tags {"pause network"}} { $rd close } + start_server {tags {needs:repl external:skip}} { + set master [srv -1 client] + set master_host [srv -1 host] + set master_port [srv -1 port] + + # Avoid PINGs + $master config set repl-ping-replica-period 3600 + r replicaof $master_host $master_port + + wait_for_condition 50 100 { + [s master_link_status] eq {up} + } else { + fail "Replication not started." + } + + test "Test when replica paused, offset would not grow" { + $master set foo bar + set old_master_offset [status $master master_repl_offset] + + wait_for_condition 50 100 { + [s slave_repl_offset] == [status $master master_repl_offset] + } else { + fail "Replication offset not matched." + } + + r client pause 100000 write + $master set foo2 bar2 + + # Make sure replica received data from master + wait_for_condition 50 100 { + [s slave_read_repl_offset] == [status $master master_repl_offset] + } else { + fail "Replication not work." + } + + # Replica would not apply the write command + assert {[s slave_repl_offset] == $old_master_offset} + r get foo2 + } {} + + test "Test replica offset would grow after unpause" { + r client unpause + wait_for_condition 50 100 { + [s slave_repl_offset] == [status $master master_repl_offset] + } else { + fail "Replication not continue." + } + r get foo2 + } {bar2} + } + # Make sure we unpause at the end r client unpause } |