Unverified Commit f228ec1e authored by Oran Agra's avatar Oran Agra Committed by GitHub
Browse files

flushSlavesOutputBuffers should not write to replicas scheduled to drop (#12242)

This will increase the size of an already large COB (one already passed
the threshold for disconnection)

This could also mean that we'll attempt to write that data to the socket
and the replica will manage to read it, which will result in an
undesired partial sync (undesired for the test)
parent 0bfb6d55
...@@ -3947,6 +3947,7 @@ void flushSlavesOutputBuffers(void) { ...@@ -3947,6 +3947,7 @@ void flushSlavesOutputBuffers(void) {
* 3. Obviously if the slave is not ONLINE. * 3. Obviously if the slave is not ONLINE.
*/ */
if (slave->replstate == SLAVE_STATE_ONLINE && if (slave->replstate == SLAVE_STATE_ONLINE &&
!(slave->flags & CLIENT_CLOSE_ASAP) &&
can_receive_writes && can_receive_writes &&
!slave->repl_start_cmd_stream_on_ack && !slave->repl_start_cmd_stream_on_ack &&
clientHasPendingReplies(slave)) clientHasPendingReplies(slave))
......
...@@ -248,6 +248,7 @@ test {Replica client-output-buffer size is limited to backlog_limit/16 when no r ...@@ -248,6 +248,7 @@ test {Replica client-output-buffer size is limited to backlog_limit/16 when no r
set master [srv 0 client] set master [srv 0 client]
set master_host [srv 0 host] set master_host [srv 0 host]
set master_port [srv 0 port] set master_port [srv 0 port]
$master config set maxmemory-policy allkeys-lru
$master config set repl-backlog-size 16384 $master config set repl-backlog-size 16384
$master config set client-output-buffer-limit "replica 32768 32768 60" $master config set client-output-buffer-limit "replica 32768 32768 60"
...@@ -262,13 +263,21 @@ test {Replica client-output-buffer size is limited to backlog_limit/16 when no r ...@@ -262,13 +263,21 @@ test {Replica client-output-buffer size is limited to backlog_limit/16 when no r
fail "Can't turn the instance into a replica" 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] set _v [prepare_value $keysize]
$master set key $_v $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 wait_for_ofs_sync $master $replica
# Write another key to force the test to wait for another event loop iteration # Write another key to force the test to wait for another event loop iteration so that we
# to give the serverCron a chance to disconnect replicas with COB size exceeding the limits # give the serverCron a chance to disconnect replicas with COB size exceeding the limits
$master set key1 "1" $master config set maxmemory 0
$master set key1 1
wait_for_ofs_sync $master $replica wait_for_ofs_sync $master $replica
assert {[status $master connected_slaves] == 1} assert {[status $master connected_slaves] == 1}
...@@ -279,6 +288,8 @@ test {Replica client-output-buffer size is limited to backlog_limit/16 when no r ...@@ -279,6 +288,8 @@ test {Replica client-output-buffer size is limited to backlog_limit/16 when no r
fail "replica client-output-buffer usage is higher than expected." 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} assert {[status $master sync_partial_ok] == 0}
# Before this fix (#11905), the test would trigger an assertion in 'o->used >= c->ref_block_pos' # Before this fix (#11905), the test would trigger an assertion in 'o->used >= c->ref_block_pos'
......
...@@ -1106,3 +1106,12 @@ proc lmap args { ...@@ -1106,3 +1106,12 @@ proc lmap args {
} }
set temp set temp
} }
proc format_command {args} {
set cmd "*[llength $args]\r\n"
foreach a $args {
append cmd "$[string length $a]\r\n$a\r\n"
}
set _ $cmd
}
start_server {tags {"quit"}} { start_server {tags {"quit"}} {
proc format_command {args} {
set cmd "*[llength $args]\r\n"
foreach a $args {
append cmd "$[string length $a]\r\n$a\r\n"
}
set _ $cmd
}
test "QUIT returns OK" { test "QUIT returns OK" {
reconnect reconnect
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment