Test tcp deadlock fixes (#14946)
Some checks are pending
CI / test-ubuntu-latest (push) Waiting to run
CI / test-sanitizer-address (push) Waiting to run
CI / build-debian-old (push) Waiting to run
CI / build-macos-latest (push) Waiting to run
CI / build-32bit (push) Waiting to run
CI / build-libc-malloc (push) Waiting to run
CI / build-centos-jemalloc (push) Waiting to run
CI / build-old-chain-jemalloc (push) Waiting to run
Codecov / code-coverage (push) Waiting to run
External Server Tests / test-external-standalone (push) Waiting to run
External Server Tests / test-external-cluster (push) Waiting to run
External Server Tests / test-external-nodebug (push) Waiting to run
Spellcheck / Spellcheck (push) Waiting to run

This fix follows #14667 and #14886

Several tests pipelined large numbers of commands on deferring clients
without draining replies. That can fill buffers and stall progress.

Fix by draining replies every 500 pipelined requests to avoid TCP
stalls.

---------

Co-authored-by: oranagra <oran@redislabs.com>
This commit is contained in:
debing.sun 2026-03-30 19:50:47 +08:00 committed by GitHub
parent 5f5ddfd1a1
commit a6a27f56f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 44 additions and 11 deletions

View file

@ -54,9 +54,12 @@ test "Main db not affected when fail to diskless load" {
set rd [redis_deferring_client redis $master_id]
for {set j 0} {$j < $num} {incr j} {
$rd set $j $value
}
for {set j 0} {$j < $num} {incr j} {
$rd read
if {($j + 1) % 500 == 0} {
for {set i 0} {$i < 500} {incr i} {
$rd read
}
}
}
# Start the replica again

View file

@ -22,13 +22,18 @@ proc gen_write_load {host port seconds tls {key ""} {size 0} {sleep 0}} {
set start_time [clock seconds]
set r [redis $host $port 1 $tls]
$r client setname LOAD_HANDLER
catch {$r select 9} ;# select 9 will fail in cluster mode
$r read
catch {
$r select 9
$r read
} ;# select 9 will fail in cluster mode
# fixed size value
if {$size != 0} {
set value [string repeat "x" $size]
}
set count 0
while 1 {
if {$size == 0} {
set value [expr rand()]
@ -39,13 +44,27 @@ proc gen_write_load {host port seconds tls {key ""} {size 0} {sleep 0}} {
} else {
$r set $key $value
}
incr count
if {$count % 500 == 0} {
for {set i 0} {$i < 500} {incr i} {
$r read
}
}
if {[clock seconds]-$start_time > $seconds} {
exit 0
break
}
if {$sleep ne 0} {
after $sleep
}
}
# Read remaining replies
for {set i 0} {$i < $count} {incr i} {
$r read
}
exit 0
}
gen_write_load [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3] [lindex $argv 4] [lindex $argv 5] [lindex $argv 6]

View file

@ -24,9 +24,12 @@ proc test_memory_efficiency {range} {
incr written [string length $key]
incr written [string length $val]
incr written 2 ;# A separator is the minimum to store key-value data.
}
for {set j 0} {$j < 10000} {incr j} {
$rd read ; # Discard replies
if {($j + 1) % 500 == 0} {
for {set i 0} {$i < 500} {incr i} {
$rd read ; # Discard replies
}
}
}
set current_mem [s used_memory]
@ -352,7 +355,7 @@ run_solo {defrag} {
# create big keys with 10k items
# Use batching to avoid TCP deadlock
set rd [redis_deferring_client]
set batch_size 1000
set batch_size 100
for {set j 0} {$j < 10000} {incr j} {
$rd hset bighash $j [concat "asdfasdfasdf" $j]
$rd lpush biglist [concat "asdfasdfasdf" $j]
@ -937,7 +940,7 @@ run_solo {defrag} {
$rd lpush biglist2 $val
incr count
discard_replies_every $rd $count 10000 20000
discard_replies_every $rd $count 1000 2000
}
# create some fragmentation

View file

@ -1027,10 +1027,18 @@ foreach type {single multiple single_multiple} {
}
}
r deferred 1
set count 0
foreach m $members {
r srem $myset $m
incr count
if {$count == 500} {
for {set i 0} {$i < 500} {incr i} {
r read
}
set count 0
}
}
foreach m $members {
for {set i 0} {$i < $count} {incr i} {
r read
}
r deferred 0