summaryrefslogtreecommitdiff
path: root/examples/redis-unstable/tests/integration/replication-buffer.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'examples/redis-unstable/tests/integration/replication-buffer.tcl')
-rw-r--r--examples/redis-unstable/tests/integration/replication-buffer.tcl365
1 files changed, 0 insertions, 365 deletions
diff --git a/examples/redis-unstable/tests/integration/replication-buffer.tcl b/examples/redis-unstable/tests/integration/replication-buffer.tcl
deleted file mode 100644
index 11e604c..0000000
--- a/examples/redis-unstable/tests/integration/replication-buffer.tcl
+++ /dev/null
@@ -1,365 +0,0 @@
-#
-# Copyright (c) 2009-Present, Redis Ltd.
-# All rights reserved.
-#
-# Copyright (c) 2024-present, Valkey contributors.
-# All rights reserved.
-#
-# Licensed under your choice of (a) the Redis Source Available License 2.0
-# (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
-# GNU Affero General Public License v3 (AGPLv3).
-#
-# Portions of this file are available under BSD3 terms; see REDISCONTRIBUTIONS for more information.
-#
-
-# This test group aims to test that all replicas share one global replication buffer,
-# two replicas don't make replication buffer size double, and when there is no replica,
-# replica buffer will shrink.
-foreach rdbchannel {"yes" "no"} {
-start_server {tags {"repl external:skip"}} {
-start_server {} {
-start_server {} {
-start_server {} {
- set replica1 [srv -3 client]
- set replica2 [srv -2 client]
- set replica3 [srv -1 client]
-
- $replica1 config set repl-rdb-channel $rdbchannel
- $replica2 config set repl-rdb-channel $rdbchannel
- $replica3 config set repl-rdb-channel $rdbchannel
-
- set master [srv 0 client]
- set master_host [srv 0 host]
- set master_port [srv 0 port]
-
- $master config set save ""
- $master config set repl-backlog-size 16384
- $master config set repl-diskless-sync-delay 5
- $master config set repl-diskless-sync-max-replicas 1
- $master config set client-output-buffer-limit "replica 0 0 0"
- $master config set repl-rdb-channel $rdbchannel
-
- # Make sure replica3 is synchronized with master
- $replica3 replicaof $master_host $master_port
- wait_for_sync $replica3
-
- # Generating RDB will take some 100 seconds
- $master config set rdb-key-save-delay 1000000
- populate 100 "" 16
-
- # Make sure replica1 and replica2 are waiting bgsave
- $master config set repl-diskless-sync-max-replicas 2
- $replica1 replicaof $master_host $master_port
- $replica2 replicaof $master_host $master_port
- wait_for_condition 50 100 {
- ([s rdb_bgsave_in_progress] == 1) &&
- [lindex [$replica1 role] 3] eq {sync} &&
- [lindex [$replica2 role] 3] eq {sync}
- } else {
- fail "fail to sync with replicas"
- }
-
- test "All replicas share one global replication buffer rdbchannel=$rdbchannel" {
- set before_used [s used_memory]
- populate 1024 "" 1024 ; # Write extra 1M data
-
- # In case we are running with IO-threads we need to give a few cycles
- # for IO-threads to start sending the cmd stream. If we don't do that
- # the checks related to the repl_buf_mem will be incorrect as the buffer
- # will still be full with the above 1Mb data.
- set iothreads [s io_threads_active]
- if {$iothreads && $rdbchannel == "yes"} {
- after 1000
- }
-
- # New data uses 1M memory, but all replicas use only one
- # replication buffer, so all replicas output memory is not
- # more than double of replication buffer.
- set repl_buf_mem [s mem_total_replication_buffers]
- set extra_mem [expr {[s used_memory]-$before_used-1024*1024}]
- if {$rdbchannel == "yes"} {
- # master's replication buffers should not grow
- assert {$extra_mem < 1024*1024}
- assert {$repl_buf_mem < 1024*1024}
- } else {
- assert {$extra_mem < 2*$repl_buf_mem}
- }
-
- # Kill replica1, replication_buffer will not become smaller
- catch {$replica1 shutdown nosave}
- wait_for_condition 50 100 {
- [s connected_slaves] eq {2}
- } else {
- fail "replica doesn't disconnect with master"
- }
- assert_equal $repl_buf_mem [s mem_total_replication_buffers]
- }
-
- test "Replication buffer will become smaller when no replica uses rdbchannel=$rdbchannel" {
- # Make sure replica3 catch up with the master
- wait_for_ofs_sync $master $replica3
-
- set repl_buf_mem [s mem_total_replication_buffers]
- # Kill replica2, replication_buffer will become smaller
- catch {$replica2 shutdown nosave}
- wait_for_condition 50 100 {
- [s connected_slaves] eq {1}
- } else {
- fail "replica2 doesn't disconnect with master"
- }
- if {$rdbchannel == "yes"} {
- # master's replication buffers should not grow
- assert {1024*512 > [s mem_total_replication_buffers]}
- } else {
- assert {[expr $repl_buf_mem - 1024*1024] > [s mem_total_replication_buffers]}
- }
- }
-}
-}
-}
-}
-}
-
-# This test group aims to test replication backlog size can outgrow the backlog
-# limit config if there is a slow replica which keep massive replication buffers,
-# and replicas could use this replication buffer (beyond backlog config) for
-# partial re-synchronization. Of course, replication backlog memory also can
-# become smaller when master disconnects with slow replicas since output buffer
-# limit is reached.
-foreach rdbchannel {"yes" "no"} {
-start_server {tags {"repl external:skip debug_defrag:skip"}} {
-start_server {} {
-start_server {} {
- set replica1 [srv -2 client]
- set replica1_pid [s -2 process_id]
- set replica2 [srv -1 client]
- set replica2_pid [s -1 process_id]
-
- set master [srv 0 client]
- set master_host [srv 0 host]
- set master_port [srv 0 port]
-
- $master config set save ""
- $master config set repl-backlog-size 16384
- $master config set repl-rdb-channel $rdbchannel
- $master config set client-output-buffer-limit "replica 0 0 0"
-
- # Executing 'debug digest' on master which has many keys costs much time
- # (especially in valgrind), this causes that replica1 and replica2 disconnect
- # with master.
- $master config set repl-timeout 1000
- $replica1 config set repl-timeout 1000
- $replica1 config set repl-rdb-channel $rdbchannel
- $replica1 config set client-output-buffer-limit "replica 1024 0 0"
- $replica2 config set repl-timeout 1000
- $replica2 config set client-output-buffer-limit "replica 1024 0 0"
- $replica2 config set repl-rdb-channel $rdbchannel
-
- $replica1 replicaof $master_host $master_port
- wait_for_sync $replica1
-
- test "Replication backlog size can outgrow the backlog limit config rdbchannel=$rdbchannel" {
- # Generating RDB will take 1000 seconds
- $master config set rdb-key-save-delay 1000000
- populate 1000 master 10000
- $replica2 replicaof $master_host $master_port
- # Make sure replica2 is waiting bgsave
- wait_for_condition 5000 100 {
- ([s rdb_bgsave_in_progress] == 1) &&
- [lindex [$replica2 role] 3] eq {sync}
- } else {
- fail "fail to sync with replicas"
- }
- # Replication actual backlog grow more than backlog setting since
- # the slow replica2 kept replication buffer.
- populate 20000 master 10000
- assert {[s repl_backlog_histlen] > [expr 10000*10000]}
- }
-
- # Wait replica1 catch up with the master
- wait_for_condition 1000 100 {
- [s -2 master_repl_offset] eq [s master_repl_offset]
- } else {
- fail "Replica offset didn't catch up with the master after too long time"
- }
-
- test "Replica could use replication buffer (beyond backlog config) for partial resynchronization rdbchannel=$rdbchannel" {
- # replica1 disconnects with master
- $replica1 replicaof [srv -1 host] [srv -1 port]
- # Write a mass of data that exceeds repl-backlog-size
- populate 10000 master 10000
- # replica1 reconnects with master
- $replica1 replicaof $master_host $master_port
- wait_for_condition 1000 100 {
- [s -2 master_repl_offset] eq [s master_repl_offset]
- } else {
- fail "Replica offset didn't catch up with the master after too long time"
- }
-
- # replica2 still waits for bgsave ending
- assert {[s rdb_bgsave_in_progress] eq {1} && [lindex [$replica2 role] 3] eq {sync}}
- # master accepted replica1 partial resync
- assert_equal [s sync_partial_ok] {1}
- assert_equal [$master debug digest] [$replica1 debug digest]
- }
-
- test "Replication backlog memory will become smaller if disconnecting with replica rdbchannel=$rdbchannel" {
- assert {[s repl_backlog_histlen] > [expr 2*10000*10000]}
- assert_equal [s connected_slaves] {2}
-
- pause_process $replica2_pid
- r config set client-output-buffer-limit "replica 128k 0 0"
- # trigger output buffer limit check
- r set key [string repeat A [expr 64*1024]]
- # master will close replica2's connection since replica2's output
- # buffer limit is reached, so there only is replica1.
- # In case of rdbchannel=yes, main channel will be disconnected only.
- wait_for_condition 100 100 {
- [s connected_slaves] eq {1} ||
- ([s connected_slaves] eq {2} &&
- [string match {*slave*state=wait_bgsave*} [$master info]])
- } else {
- fail "master didn't disconnect with replica2"
- }
-
- # Since we trim replication backlog inrementally, replication backlog
- # memory may take time to be reclaimed.
- wait_for_condition 1000 100 {
- [s repl_backlog_histlen] < [expr 10000*10000]
- } else {
- fail "Replication backlog memory is not smaller"
- }
- resume_process $replica2_pid
- }
- # speed up termination
- $master config set shutdown-timeout 0
-}
-}
-}
-}
-
-foreach rdbchannel {"yes" "no"} {
-test "Partial resynchronization is successful even client-output-buffer-limit is less than repl-backlog-size rdbchannel=$rdbchannel" {
- start_server {tags {"repl external:skip"}} {
- start_server {} {
- r config set save ""
- r config set repl-backlog-size 100mb
- r config set client-output-buffer-limit "replica 512k 0 0"
- r config set repl-rdb-channel $rdbchannel
-
- set replica [srv -1 client]
- $replica config set repl-rdb-channel $rdbchannel
- $replica replicaof [srv 0 host] [srv 0 port]
- wait_for_sync $replica
-
- set big_str [string repeat A [expr 10*1024*1024]] ;# 10mb big string
- r multi
- r client kill type replica
- r set key $big_str
- r set key $big_str
- r debug sleep 2 ;# wait for replica reconnecting
- r exec
- # When replica reconnects with master, master accepts partial resync,
- # and don't close replica client even client output buffer limit is
- # reached.
- r set key $big_str ;# trigger output buffer limit check
- wait_for_ofs_sync r $replica
- # master accepted replica partial resync
- assert_equal [s sync_full] {1}
- assert_equal [s sync_partial_ok] {1}
-
- r multi
- r set key $big_str
- r set key $big_str
- r exec
- # replica's reply buffer size is more than client-output-buffer-limit but
- # doesn't exceed repl-backlog-size, we don't close replica client.
- wait_for_condition 1000 100 {
- [s -1 master_repl_offset] eq [s master_repl_offset]
- } else {
- fail "Replica offset didn't catch up with the master after too long time"
- }
- assert_equal [s sync_full] {1}
- assert_equal [s sync_partial_ok] {1}
- }
- }
-}
-
-# This test was added to make sure big keys added to the backlog do not trigger psync loop.
-test "Replica client-output-buffer size is limited to backlog_limit/16 when no replication data is pending rdbchannel=$rdbchannel" {
- proc client_field {r type f} {
- set client [$r client list type $type]
- if {![regexp $f=(\[a-zA-Z0-9-\]+) $client - res]} {
- error "field $f not found for in $client"
- }
- return $res
- }
-
- start_server {tags {"repl external:skip"}} {
- start_server {} {
- set replica [srv -1 client]
- set replica_host [srv -1 host]
- set replica_port [srv -1 port]
- set master [srv 0 client]
- set master_host [srv 0 host]
- set master_port [srv 0 port]
- $master config set maxmemory-policy allkeys-lru
-
- $master config set repl-backlog-size 16384
- $master config set client-output-buffer-limit "replica 32768 32768 60"
- $master config set repl-rdb-channel $rdbchannel
- $replica config set repl-rdb-channel $rdbchannel
- # Key has has to be larger than replica client-output-buffer limit.
- set keysize [expr 256*1024]
-
- $replica replicaof $master_host $master_port
- wait_for_condition 50 100 {
- [lindex [$replica role] 0] eq {slave} &&
- [string match {*master_link_status:up*} [$replica info replication]]
- } else {
- fail "Can't turn the instance into a replica"
- }
-
- # Write a big key that is gonna breach the obuf limit and cause the replica to disconnect,
- # then in the same event loop, add at least 16 more keys, and enable eviction, so that the
- # eviction code has a chance to call flushSlavesOutputBuffers, and then run PING to trigger the eviction code
- set _v [prepare_value $keysize]
- $master write "[format_command mset key $_v k1 1 k2 2 k3 3 k4 4 k5 5 k6 6 k7 7 k8 8 k9 9 ka a kb b kc c kd d ke e kf f kg g kh h]config set maxmemory 1\r\nping\r\n"
- $master flush
- $master read
- $master read
- $master read
- wait_for_ofs_sync $master $replica
-
- # Write another key to force the test to wait for another event loop iteration so that we
- # give the serverCron a chance to disconnect replicas with COB size exceeding the limits
- $master config set maxmemory 0
- $master set key1 1
- wait_for_ofs_sync $master $replica
-
- assert {[status $master connected_slaves] == 1}
-
- wait_for_condition 50 100 {
- [client_field $master replica tot-mem] < $keysize
- } else {
- fail "replica client-output-buffer usage is higher than expected."
- }
-
- # now we expect the replica to re-connect but fail partial sync (it doesn't have large
- # enough COB limit and must result in a full-sync)
- assert {[status $master sync_partial_ok] == 0}
-
- # Before this fix (#11905), the test would trigger an assertion in 'o->used >= c->ref_block_pos'
- test {The update of replBufBlock's repl_offset is ok - Regression test for #11666} {
- set rd [redis_deferring_client]
- set replid [status $master master_replid]
- set offset [status $master repl_backlog_first_byte_offset]
- $rd psync $replid $offset
- assert_equal {PONG} [$master ping] ;# Make sure the master doesn't crash.
- $rd close
- }
- }
- }
-}
-}
-