Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
77a7ec72
Commit
77a7ec72
authored
Jul 23, 2018
by
antirez
Browse files
Merge branch 'unstable' into 5.0 branch
parents
48dfd42d
4ff47a0b
Changes
84
Show whitespace changes
Inline
Side-by-side
src/t_zset.c
View file @
77a7ec72
...
@@ -507,7 +507,7 @@ static int zslParseRange(robj *min, robj *max, zrangespec *spec) {
...
@@ -507,7 +507,7 @@ static int zslParseRange(robj *min, robj *max, zrangespec *spec) {
* + means the max string possible
* + means the max string possible
*
*
* If the string is valid the *dest pointer is set to the redis object
* If the string is valid the *dest pointer is set to the redis object
* that will be used for the comparis
i
on, and ex will be set to 0 or 1
* that will be used for the comparison, and ex will be set to 0 or 1
* respectively if the item is exclusive or inclusive. C_OK will be
* respectively if the item is exclusive or inclusive. C_OK will be
* returned.
* returned.
*
*
...
...
src/util.c
View file @
77a7ec72
...
@@ -451,7 +451,7 @@ int string2ld(const char *s, size_t slen, long double *dp) {
...
@@ -451,7 +451,7 @@ int string2ld(const char *s, size_t slen, long double *dp) {
/* Convert a double to a string representation. Returns the number of bytes
/* Convert a double to a string representation. Returns the number of bytes
* required. The representation should always be parsable by strtod(3).
* required. The representation should always be parsable by strtod(3).
* This function does not support human-friendly formatting like ld2string
* This function does not support human-friendly formatting like ld2string
* does. It is inten
t
ed mainly to be used inside t_zset.c when writing scores
* does. It is inten
d
ed mainly to be used inside t_zset.c when writing scores
* into a ziplist representing a sorted set. */
* into a ziplist representing a sorted set. */
int
d2string
(
char
*
buf
,
size_t
len
,
double
value
)
{
int
d2string
(
char
*
buf
,
size_t
len
,
double
value
)
{
if
(
isnan
(
value
))
{
if
(
isnan
(
value
))
{
...
...
src/ziplist.c
View file @
77a7ec72
...
@@ -269,7 +269,7 @@
...
@@ -269,7 +269,7 @@
* Note that this is not how the data is actually encoded, is just what we
* Note that this is not how the data is actually encoded, is just what we
* get filled by a function in order to operate more easily. */
* get filled by a function in order to operate more easily. */
typedef
struct
zlentry
{
typedef
struct
zlentry
{
unsigned
int
prevrawlensize
;
/* Bytes used to encode the previos entry len*/
unsigned
int
prevrawlensize
;
/* Bytes used to encode the previo
u
s entry len*/
unsigned
int
prevrawlen
;
/* Previous entry len. */
unsigned
int
prevrawlen
;
/* Previous entry len. */
unsigned
int
lensize
;
/* Bytes used to encode this entry type/len.
unsigned
int
lensize
;
/* Bytes used to encode this entry type/len.
For example strings have a 1, 2 or 5 bytes
For example strings have a 1, 2 or 5 bytes
...
@@ -431,7 +431,7 @@ unsigned int zipStorePrevEntryLength(unsigned char *p, unsigned int len) {
...
@@ -431,7 +431,7 @@ unsigned int zipStorePrevEntryLength(unsigned char *p, unsigned int len) {
/* Return the length of the previous element, and the number of bytes that
/* Return the length of the previous element, and the number of bytes that
* are used in order to encode the previous element length.
* are used in order to encode the previous element length.
* 'ptr' must point to the prevlen prefix of an entry (that encodes the
* 'ptr' must point to the prevlen prefix of an entry (that encodes the
* length of the previos entry in order to navigate the elements backward).
* length of the previo
u
s entry in order to navigate the elements backward).
* The length of the previous entry is stored in 'prevlen', the number of
* The length of the previous entry is stored in 'prevlen', the number of
* bytes needed to encode the previous entry length are stored in
* bytes needed to encode the previous entry length are stored in
* 'prevlensize'. */
* 'prevlensize'. */
...
...
src/zmalloc.c
View file @
77a7ec72
...
@@ -165,7 +165,7 @@ void *zrealloc(void *ptr, size_t size) {
...
@@ -165,7 +165,7 @@ void *zrealloc(void *ptr, size_t size) {
*
((
size_t
*
)
newptr
)
=
size
;
*
((
size_t
*
)
newptr
)
=
size
;
update_zmalloc_stat_free
(
oldsize
);
update_zmalloc_stat_free
(
oldsize
);
update_zmalloc_stat_alloc
(
size
);
update_zmalloc_stat_alloc
(
size
+
PREFIX_SIZE
);
return
(
char
*
)
newptr
+
PREFIX_SIZE
;
return
(
char
*
)
newptr
+
PREFIX_SIZE
;
#endif
#endif
}
}
...
@@ -182,6 +182,9 @@ size_t zmalloc_size(void *ptr) {
...
@@ -182,6 +182,9 @@ size_t zmalloc_size(void *ptr) {
if
(
size
&
(
sizeof
(
long
)
-
1
))
size
+=
sizeof
(
long
)
-
(
size
&
(
sizeof
(
long
)
-
1
));
if
(
size
&
(
sizeof
(
long
)
-
1
))
size
+=
sizeof
(
long
)
-
(
size
&
(
sizeof
(
long
)
-
1
));
return
size
+
PREFIX_SIZE
;
return
size
+
PREFIX_SIZE
;
}
}
size_t
zmalloc_usable
(
void
*
ptr
)
{
return
zmalloc_usable
(
ptr
)
-
PREFIX_SIZE
;
}
#endif
#endif
void
zfree
(
void
*
ptr
)
{
void
zfree
(
void
*
ptr
)
{
...
@@ -380,7 +383,7 @@ size_t zmalloc_get_private_dirty(long pid) {
...
@@ -380,7 +383,7 @@ size_t zmalloc_get_private_dirty(long pid) {
}
}
/* Returns the size of physical memory (RAM) in bytes.
/* Returns the size of physical memory (RAM) in bytes.
* It looks ugly, but this is the cleanest way to achive cross platform results.
* It looks ugly, but this is the cleanest way to achi
e
ve cross platform results.
* Cleaned up from:
* Cleaned up from:
*
*
* http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system
* http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system
...
...
src/zmalloc.h
View file @
77a7ec72
...
@@ -63,6 +63,11 @@
...
@@ -63,6 +63,11 @@
#ifndef ZMALLOC_LIB
#ifndef ZMALLOC_LIB
#define ZMALLOC_LIB "libc"
#define ZMALLOC_LIB "libc"
#ifdef __GLIBC__
#include <malloc.h>
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) malloc_usable_size(p)
#endif
#endif
#endif
/* We can enable the Redis defrag capabilities only if we are using Jemalloc
/* We can enable the Redis defrag capabilities only if we are using Jemalloc
...
@@ -93,6 +98,9 @@ void *zmalloc_no_tcache(size_t size);
...
@@ -93,6 +98,9 @@ void *zmalloc_no_tcache(size_t size);
#ifndef HAVE_MALLOC_SIZE
#ifndef HAVE_MALLOC_SIZE
size_t
zmalloc_size
(
void
*
ptr
);
size_t
zmalloc_size
(
void
*
ptr
);
size_t
zmalloc_usable
(
void
*
ptr
);
#else
#define zmalloc_usable(p) zmalloc_size(p)
#endif
#endif
#endif
/* __ZMALLOC_H */
#endif
/* __ZMALLOC_H */
tests/cluster/tests/05-slave-selection.tcl
View file @
77a7ec72
...
@@ -92,3 +92,80 @@ test "Node #10 should eventually replicate node #5" {
...
@@ -92,3 +92,80 @@ test "Node #10 should eventually replicate node #5" {
fail
"#10 didn't became slave of #5"
fail
"#10 didn't became slave of #5"
}
}
}
}
source
"../tests/includes/init-tests.tcl"
# Create a cluster with 3 master and 15 slaves, so that we have 5
# slaves for eatch master.
test
"Create a 3 nodes cluster"
{
create_cluster 3 15
}
test
"Cluster is up"
{
assert_cluster_state ok
}
test
"The first master has actually 5 slaves"
{
assert
{[
llength
[
lindex
[
R 0 role
]
2
]]
== 5
}
}
test
{
Slaves of #0 are instance #3, #6, #9, #12 and #15 as expected
}
{
set port0
[
get_instance_attrib redis 0 port
]
assert
{[
lindex
[
R 3 role
]
2
]
== $port0
}
assert
{[
lindex
[
R 6 role
]
2
]
== $port0
}
assert
{[
lindex
[
R 9 role
]
2
]
== $port0
}
assert
{[
lindex
[
R 12 role
]
2
]
== $port0
}
assert
{[
lindex
[
R 15 role
]
2
]
== $port0
}
}
test
{
Instance #3, #6, #9, #12 and #15 synced with the master
}
{
wait_for_condition 1000 50
{
[
RI 3 master_link_status
]
eq
{
up
}
&&
[
RI 6 master_link_status
]
eq
{
up
}
&&
[
RI 9 master_link_status
]
eq
{
up
}
&&
[
RI 12 master_link_status
]
eq
{
up
}
&&
[
RI 15 master_link_status
]
eq
{
up
}
}
else
{
fail
"Instance #3 or #6 or #9 or #12 or #15 master link status is not up"
}
}
proc master_detected
{
instances
}
{
foreach instance
[
dict keys $instances
]
{
if
{[
RI $instance role
]
eq
{
master
}}
{
return true
}
}
return false
}
test
"New Master down consecutively"
{
set instances
[
dict create 0 1 3 1 6 1 9 1 12 1 15 1
]
set loops
[
expr
{[
dict size $instances
]
-1
}]
for
{
set i 0
}
{
$i
< $loops
}
{
incr i
}
{
set master_id -1
foreach instance
[
dict keys $instances
]
{
if
{[
RI $instance role
]
eq
{
master
}}
{
set master_id $instance
break
;
}
}
if
{
$master
_id eq -1
}
{
fail
"no master detected, #loop
$i
"
}
set instances
[
dict remove $instances $master_id
]
kill_instance redis $master_id
wait_for_condition 1000 50
{
[
master_detected $instances
]
}
else
{
failover
"No failover detected when master
$master
_id fails"
}
assert_cluster_state ok
}
}
tests/integration/rdb.tcl
View file @
77a7ec72
...
@@ -39,6 +39,25 @@ start_server [list overrides [list "dir" $server_path]] {
...
@@ -39,6 +39,25 @@ start_server [list overrides [list "dir" $server_path]] {
}
{
0000000000000000000000000000000000000000
}
}
{
0000000000000000000000000000000000000000
}
}
}
start_server
[
list overrides
[
list
"dir"
$server_path
]]
{
test
{
Test RDB stream encoding
}
{
for
{
set j 0
}
{
$j
< 1000
}
{
incr j
}
{
if
{
rand
()
< 0.9
}
{
r xadd stream * foo $j
}
else
{
r xadd stream * bar $j
}
}
r xgroup create stream mygroup 0
r xreadgroup GROUP mygroup Alice COUNT 1 STREAMS stream >
set digest
[
r debug digest
]
r debug reload
set newdigest
[
r debug digest
]
assert
{
$digest
eq $newdigest
}
r del stream
}
}
# Helper function to start a server and kill it, just to check the error
# Helper function to start a server and kill it, just to check the error
# logged.
# logged.
set defaults
{}
set defaults
{}
...
...
tests/integration/replication-psync.tcl
View file @
77a7ec72
...
@@ -11,7 +11,7 @@ proc stop_bg_complex_data {handle} {
...
@@ -11,7 +11,7 @@ proc stop_bg_complex_data {handle} {
# partial resyncs attempts, all this while flooding the master with
# partial resyncs attempts, all this while flooding the master with
# write queries.
# write queries.
#
#
# You can specif
i
y backlog size, ttl, delay before reconnection, test duration
# You can specify backlog size, ttl, delay before reconnection, test duration
# in seconds, and an additional condition to verify at the end.
# in seconds, and an additional condition to verify at the end.
#
#
# If reconnect is > 0, the test actually try to break the connection and
# If reconnect is > 0, the test actually try to break the connection and
...
...
tests/sentinel/tests/07-down-conditions.tcl
View file @
77a7ec72
...
@@ -66,3 +66,13 @@ test "SDOWN is triggered by misconfigured instance repling with errors" {
...
@@ -66,3 +66,13 @@ test "SDOWN is triggered by misconfigured instance repling with errors" {
R 0 bgsave
R 0 bgsave
ensure_master_up
ensure_master_up
}
}
# We use this test setup to also test command renaming, as a side
# effect of the master going down if we send PONG instead of PING
test
"SDOWN is triggered if we rename PING to PONG"
{
ensure_master_up
S 4 SENTINEL SET mymaster rename-command PING PONG
ensure_master_down
S 4 SENTINEL SET mymaster rename-command PING PING
ensure_master_up
}
tests/support/server.tcl
View file @
77a7ec72
...
@@ -276,6 +276,12 @@ proc start_server {options {code undefined}} {
...
@@ -276,6 +276,12 @@ proc start_server {options {code undefined}} {
error_and_quit $config_file $line
error_and_quit $config_file $line
}
}
if
{
$::wait
_server
}
{
set msg
"server started PID:
[
dict get $srv
"pid"
]
. press any key to continue..."
puts $msg
read stdin 1
}
while 1
{
while 1
{
# check that the server actually started and is ready for connections
# check that the server actually started and is ready for connections
if
{[
exec grep -i
"Ready to accept"
| wc -l < $stdout
]
> 0
}
{
if
{[
exec grep -i
"Ready to accept"
| wc -l < $stdout
]
> 0
}
{
...
...
tests/support/util.tcl
View file @
77a7ec72
...
@@ -375,3 +375,19 @@ proc start_write_load {host port seconds} {
...
@@ -375,3 +375,19 @@ proc start_write_load {host port seconds} {
proc stop_write_load
{
handle
}
{
proc stop_write_load
{
handle
}
{
catch
{
exec /bin/kill -9 $handle
}
catch
{
exec /bin/kill -9 $handle
}
}
}
proc K
{
x y
}
{
set x
}
# Shuffle a list. From Tcl wiki. Originally from Steve Cohen that improved
# other versions. Code should be under public domain.
proc lshuffle
{
list
}
{
set n
[
llength $list
]
while
{
$n
>0
}
{
set j
[
expr
{
int
(
rand
()
*$n
)}]
lappend slist
[
lindex $list $j
]
incr n -1
set temp
[
lindex $list $n
]
set list
[
lreplace
[
K $list
[
set list
{}]]
$j $j $temp
]
}
return $slist
}
tests/test_helper.tcl
View file @
77a7ec72
...
@@ -61,6 +61,7 @@ set ::all_tests {
...
@@ -61,6 +61,7 @@ set ::all_tests {
unit/hyperloglog
unit/hyperloglog
unit/lazyfree
unit/lazyfree
unit/wait
unit/wait
unit/pendingquerybuf
}
}
# Index to the next test to run in the ::all_tests list.
# Index to the next test to run in the ::all_tests list.
set ::next_test 0
set ::next_test 0
...
@@ -82,6 +83,8 @@ set ::force_failure 0
...
@@ -82,6 +83,8 @@ set ::force_failure 0
set ::timeout 600
;
# 10 minutes without progresses will quit the test.
set ::timeout 600
;
# 10 minutes without progresses will quit the test.
set ::last_progress
[
clock seconds
]
set ::last_progress
[
clock seconds
]
set ::active_servers
{}
;
# Pids of active Redis instances.
set ::active_servers
{}
;
# Pids of active Redis instances.
set ::dont_clean 0
set ::wait_server 0
# Set to 1 when we are running in client mode. The Redis test uses a
# Set to 1 when we are running in client mode. The Redis test uses a
# server-client model to run tests simultaneously. The server instance
# server-client model to run tests simultaneously. The server instance
...
@@ -175,6 +178,9 @@ proc s {args} {
...
@@ -175,6 +178,9 @@ proc s {args} {
}
}
proc cleanup
{}
{
proc cleanup
{}
{
if
{
$::dont
_clean
}
{
return
}
if
{
!$::quiet
}
{
puts -nonewline
"Cleanup: may take some time... "
}
if
{
!$::quiet
}
{
puts -nonewline
"Cleanup: may take some time... "
}
flush stdout
flush stdout
catch
{
exec rm -rf
{*}
[
glob tests/tmp/redis.conf.*
]}
catch
{
exec rm -rf
{*}
[
glob tests/tmp/redis.conf.*
]}
...
@@ -224,6 +230,7 @@ proc test_server_cron {} {
...
@@ -224,6 +230,7 @@ proc test_server_cron {} {
if
{
$elapsed
> $::timeout
}
{
if
{
$elapsed
> $::timeout
}
{
set err
"
\[
[
colorstr red TIMEOUT
]
\]
: clients state report follows."
set err
"
\[
[
colorstr red TIMEOUT
]
\]
: clients state report follows."
puts $err
puts $err
lappend ::failed_tests $err
show_clients_state
show_clients_state
kill_clients
kill_clients
force_kill_all_servers
force_kill_all_servers
...
@@ -410,6 +417,8 @@ proc print_help_screen {} {
...
@@ -410,6 +417,8 @@ proc print_help_screen {} {
"--clients <num> Number of test clients (default 16)."
"--clients <num> Number of test clients (default 16)."
"--timeout <sec> Test timeout in seconds (default 10 min)."
"--timeout <sec> Test timeout in seconds (default 10 min)."
"--force-failure Force the execution of a test that always fails."
"--force-failure Force the execution of a test that always fails."
"--dont-clean don't delete redis log files after the run"
"--wait-server wait after server is started (so that you can attach a debugger)"
"--help Print this help screen."
"--help Print this help screen."
}
"
\n
"
]
}
"
\n
"
]
}
}
...
@@ -463,6 +472,10 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
...
@@ -463,6 +472,10 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
}
elseif
{
$opt
eq
{
--clients
}}
{
}
elseif
{
$opt
eq
{
--clients
}}
{
set ::numclients $arg
set ::numclients $arg
incr j
incr j
}
elseif
{
$opt
eq
{
--dont-clean
}}
{
set ::dont_clean 1
}
elseif
{
$opt
eq
{
--wait-server
}}
{
set ::wait_server 1
}
elseif
{
$opt
eq
{
--timeout
}}
{
}
elseif
{
$opt
eq
{
--timeout
}}
{
set ::timeout $arg
set ::timeout $arg
incr j
incr j
...
...
tests/unit/dump.tcl
View file @
77a7ec72
...
@@ -26,6 +26,39 @@ start_server {tags {"dump"}} {
...
@@ -26,6 +26,39 @@ start_server {tags {"dump"}} {
r get foo
r get foo
}
{
bar
}
}
{
bar
}
test
{
RESTORE can set an absolute expire
}
{
r set foo bar
set encoded
[
r dump foo
]
r del foo
set now
[
clock milliseconds
]
r restore foo
[
expr $now+3000
]
$encoded absttl
set ttl
[
r pttl foo
]
assert
{
$ttl
>= 2998 && $ttl <= 3000
}
r get foo
}
{
bar
}
test
{
RESTORE can set LRU
}
{
r set foo bar
set encoded
[
r dump foo
]
r del foo
r config set maxmemory-policy allkeys-lru
r restore foo 0 $encoded idletime 1000
set idle
[
r object idletime foo
]
assert
{
$idle
>= 1000 && $idle <= 1002
}
r get foo
}
{
bar
}
test
{
RESTORE can set LFU
}
{
r set foo bar
set encoded
[
r dump foo
]
r del foo
r config set maxmemory-policy allkeys-lfu
r restore foo 0 $encoded freq 100
set freq
[
r object freq foo
]
assert
{
$freq
== 100
}
r get foo
}
{
bar
}
test
{
RESTORE returns an error of the key already exists
}
{
test
{
RESTORE returns an error of the key already exists
}
{
r set foo bar
r set foo bar
set e
{}
set e
{}
...
@@ -246,7 +279,7 @@ start_server {tags {"dump"}} {
...
@@ -246,7 +279,7 @@ start_server {tags {"dump"}} {
set e
set e
}
{
*empty string*
}
}
{
*empty string*
}
test
{
MIGRATE with mu
t
liple keys migrate just existing ones
}
{
test
{
MIGRATE with mul
t
iple keys migrate just existing ones
}
{
set first
[
srv 0 client
]
set first
[
srv 0 client
]
r set key1
"v1"
r set key1
"v1"
r set key2
"v2"
r set key2
"v2"
...
...
tests/unit/expire.tcl
View file @
77a7ec72
...
@@ -121,7 +121,7 @@ start_server {tags {"expire"}} {
...
@@ -121,7 +121,7 @@ start_server {tags {"expire"}} {
list $a $b
list $a $b
}
{
somevalue
{}}
}
{
somevalue
{}}
test
{
TTL returns ti
e
m to live in seconds
}
{
test
{
TTL returns tim
e
to live in seconds
}
{
r del x
r del x
r setex x 10 somevalue
r setex x 10 somevalue
set ttl
[
r ttl x
]
set ttl
[
r ttl x
]
...
...
tests/unit/maxmemory.tcl
View file @
77a7ec72
...
@@ -142,3 +142,95 @@ start_server {tags {"maxmemory"}} {
...
@@ -142,3 +142,95 @@ start_server {tags {"maxmemory"}} {
}
}
}
}
}
}
proc test_slave_buffers
{
cmd_count payload_len limit_memory pipeline
}
{
start_server
{
tags
{
"maxmemory"
}}
{
start_server
{}
{
set slave
[
srv 0 client
]
set slave_host
[
srv 0 host
]
set slave_port
[
srv 0 port
]
set master
[
srv -1 client
]
set master_host
[
srv -1 host
]
set master_port
[
srv -1 port
]
# add 100 keys of 100k
(
10MB total
)
for
{
set j 0
}
{
$j
< 100
}
{
incr j
}
{
$master setrange
"key:
$j
"
100000 asdf
}
$master config set maxmemory-policy allkeys-random
$master config set client-output-buffer-limit
"slave 100000000 100000000 60"
$master config set repl-backlog-size
[
expr
{
10*1024
}]
$slave slaveof $master_host $master_port
wait_for_condition 50 100
{
[
s 0 master_link_status
]
eq
{
up
}
}
else
{
fail
"Replication not started."
}
# measure used memory after the slave connected and set maxmemory
set orig_used
[
s -1 used_memory
]
set orig_client_buf
[
s -1 mem_clients_normal
]
set orig_mem_not_counted_for_evict
[
s -1 mem_not_counted_for_evict
]
set orig_used_no_repl
[
expr
{
$orig
_used - $orig_mem_not_counted_for_evict
}]
set limit
[
expr
{
$orig
_used - $orig_mem_not_counted_for_evict + 20*1024
}]
if
{
$limit
_memory==1
}
{
$master config set maxmemory $limit
}
# put the slave to sleep
set rd_slave
[
redis_deferring_client
]
$rd_slave debug sleep 60
# send some 10mb woth of commands that don't increase the memory usage
if
{
$pipeline
== 1
}
{
set rd_master
[
redis_deferring_client -1
]
for
{
set k 0
}
{
$k
< $cmd_count
}
{
incr k
}
{
$rd_master setrange key:0 0
[
string repeat A $payload_len
]
}
for
{
set k 0
}
{
$k
< $cmd_count
}
{
incr k
}
{
#$rd_master read
}
}
else
{
for
{
set k 0
}
{
$k
< $cmd_count
}
{
incr k
}
{
$master setrange key:0 0
[
string repeat A $payload_len
]
}
}
set new_used
[
s -1 used_memory
]
set slave_buf
[
s -1 mem_clients_slaves
]
set client_buf
[
s -1 mem_clients_normal
]
set mem_not_counted_for_evict
[
s -1 mem_not_counted_for_evict
]
set used_no_repl
[
expr
{
$new
_used - $mem_not_counted_for_evict
}]
set delta
[
expr
{(
$used
_no_repl - $client_buf
)
-
(
$orig
_used_no_repl - $orig_client_buf
)}]
assert
{[
$master
dbsize
]
== 100
}
assert
{
$slave
_buf > 2*1024*1024
}
;
# some of the data may have been pushed to the OS buffers
assert
{
$delta
< 50*1024 && $delta > -50*1024
}
;
# 1 byte unaccounted for, with 1M commands will consume some 1MB
$master client kill type slave
set killed_used
[
s -1 used_memory
]
set killed_slave_buf
[
s -1 mem_clients_slaves
]
set killed_mem_not_counted_for_evict
[
s -1 mem_not_counted_for_evict
]
set killed_used_no_repl
[
expr
{
$killed
_used - $killed_mem_not_counted_for_evict
}]
set delta_no_repl
[
expr
{
$killed
_used_no_repl - $used_no_repl
}]
assert
{
$killed
_slave_buf == 0
}
assert
{
$delta
_no_repl > -50*1024 && $delta_no_repl < 50*1024
}
;
# 1 byte unaccounted for, with 1M commands will consume some 1MB
}
}
}
test
{
slave buffer are counted correctly
}
{
# we wanna use many small commands, and we don't wanna wait long
# so we need to use a pipeline
(
redis_deferring_client
)
# that may cause query buffer to fill and induce eviction, so we disable it
test_slave_buffers 1000000 10 0 1
}
test
{
slave buffer don't induce eviction
}
{
# test again with fewer
(
and bigger
)
commands without pipeline, but with eviction
test_slave_buffers 100000 100 1 0
}
tests/unit/memefficiency.tcl
View file @
77a7ec72
...
@@ -41,7 +41,7 @@ start_server {tags {"defrag"}} {
...
@@ -41,7 +41,7 @@ start_server {tags {"defrag"}} {
test
"Active defrag"
{
test
"Active defrag"
{
r config set activedefrag no
r config set activedefrag no
r config set active-defrag-threshold-lower 5
r config set active-defrag-threshold-lower 5
r config set active-defrag-cycle-min
2
5
r config set active-defrag-cycle-min
6
5
r config set active-defrag-cycle-max 75
r config set active-defrag-cycle-max 75
r config set active-defrag-ignore-bytes 2mb
r config set active-defrag-ignore-bytes 2mb
r config set maxmemory 100mb
r config set maxmemory 100mb
...
@@ -66,9 +66,10 @@ start_server {tags {"defrag"}} {
...
@@ -66,9 +66,10 @@ start_server {tags {"defrag"}} {
}
}
# Wait for the active defrag to stop working.
# Wait for the active defrag to stop working.
wait_for_condition 1
0
0 100
{
wait_for_condition 1
5
0 100
{
[
s active_defrag_running
]
eq 0
[
s active_defrag_running
]
eq 0
}
else
{
}
else
{
after 120
;
# serverCron only updates the info once in 100ms
puts
[
r info memory
]
puts
[
r info memory
]
puts
[
r memory malloc-stats
]
puts
[
r memory malloc-stats
]
fail
"defrag didn't stop."
fail
"defrag didn't stop."
...
@@ -97,10 +98,15 @@ start_server {tags {"defrag"}} {
...
@@ -97,10 +98,15 @@ start_server {tags {"defrag"}} {
r config set active-defrag-ignore-bytes 2mb
r config set active-defrag-ignore-bytes 2mb
r config set maxmemory 0
r config set maxmemory 0
r config set list-max-ziplist-size 5
;
# list of 10k items will have 2000 quicklist nodes
r config set list-max-ziplist-size 5
;
# list of 10k items will have 2000 quicklist nodes
r config set stream-node-max-entries 5
r hmset hash h1 v1 h2 v2 h3 v3
r hmset hash h1 v1 h2 v2 h3 v3
r lpush list a b c d
r lpush list a b c d
r zadd zset 0 a 1 b 2 c 3 d
r zadd zset 0 a 1 b 2 c 3 d
r sadd set a b c d
r sadd set a b c d
r xadd stream * item 1 value a
r xadd stream * item 2 value b
r xgroup create stream mygroup 0
r xreadgroup GROUP mygroup Alice COUNT 1 STREAMS stream >
# create big keys with 10k items
# create big keys with 10k items
set rd
[
redis_deferring_client
]
set rd
[
redis_deferring_client
]
...
@@ -109,8 +115,9 @@ start_server {tags {"defrag"}} {
...
@@ -109,8 +115,9 @@ start_server {tags {"defrag"}} {
$rd lpush biglist
[
concat
"asdfasdfasdf"
$j
]
$rd lpush biglist
[
concat
"asdfasdfasdf"
$j
]
$rd zadd bigzset $j
[
concat
"asdfasdfasdf"
$j
]
$rd zadd bigzset $j
[
concat
"asdfasdfasdf"
$j
]
$rd sadd bigset
[
concat
"asdfasdfasdf"
$j
]
$rd sadd bigset
[
concat
"asdfasdfasdf"
$j
]
$rd xadd bigstream * item 1 value a
}
}
for
{
set j 0
}
{
$j
<
4
0000
}
{
incr j
}
{
for
{
set j 0
}
{
$j
<
5
0000
}
{
incr j
}
{
$rd read
;
# Discard replies
$rd read
;
# Discard replies
}
}
...
@@ -134,7 +141,7 @@ start_server {tags {"defrag"}} {
...
@@ -134,7 +141,7 @@ start_server {tags {"defrag"}} {
for
{
set j 0
}
{
$j
< 500000
}
{
incr j
}
{
for
{
set j 0
}
{
$j
< 500000
}
{
incr j
}
{
$rd read
;
# Discard replies
$rd read
;
# Discard replies
}
}
assert
{[
r dbsize
]
== 50000
8
}
assert
{[
r dbsize
]
== 5000
1
0
}
# create some fragmentation
# create some fragmentation
for
{
set j 0
}
{
$j
< 500000
}
{
incr j 2
}
{
for
{
set j 0
}
{
$j
< 500000
}
{
incr j 2
}
{
...
@@ -143,7 +150,7 @@ start_server {tags {"defrag"}} {
...
@@ -143,7 +150,7 @@ start_server {tags {"defrag"}} {
for
{
set j 0
}
{
$j
< 500000
}
{
incr j 2
}
{
for
{
set j 0
}
{
$j
< 500000
}
{
incr j 2
}
{
$rd read
;
# Discard replies
$rd read
;
# Discard replies
}
}
assert
{[
r dbsize
]
== 25000
8
}
assert
{[
r dbsize
]
== 2500
1
0
}
# start defrag
# start defrag
after 120
;
# serverCron only updates the info once in 100ms
after 120
;
# serverCron only updates the info once in 100ms
...
@@ -155,6 +162,7 @@ start_server {tags {"defrag"}} {
...
@@ -155,6 +162,7 @@ start_server {tags {"defrag"}} {
r config set latency-monitor-threshold 5
r config set latency-monitor-threshold 5
r latency reset
r latency reset
set digest
[
r debug digest
]
catch
{
r config set activedefrag yes
}
e
catch
{
r config set activedefrag yes
}
e
if
{
!
[
string match
{
DISABLED*
}
$e
]}
{
if
{
!
[
string match
{
DISABLED*
}
$e
]}
{
# wait for the active defrag to start working
(
decision once a second
)
# wait for the active defrag to start working
(
decision once a second
)
...
@@ -168,6 +176,7 @@ start_server {tags {"defrag"}} {
...
@@ -168,6 +176,7 @@ start_server {tags {"defrag"}} {
wait_for_condition 500 100
{
wait_for_condition 500 100
{
[
s active_defrag_running
]
eq 0
[
s active_defrag_running
]
eq 0
}
else
{
}
else
{
after 120
;
# serverCron only updates the info once in 100ms
puts
[
r info memory
]
puts
[
r info memory
]
puts
[
r memory malloc-stats
]
puts
[
r memory malloc-stats
]
fail
"defrag didn't stop."
fail
"defrag didn't stop."
...
@@ -193,9 +202,11 @@ start_server {tags {"defrag"}} {
...
@@ -193,9 +202,11 @@ start_server {tags {"defrag"}} {
# due to high fragmentation, 10hz, and active-defrag-cycle-max set to 75,
# due to high fragmentation, 10hz, and active-defrag-cycle-max set to 75,
# we expect max latency to be not much higher than 75ms
# we expect max latency to be not much higher than 75ms
assert
{
$max
_latency <= 80
}
assert
{
$max
_latency <= 80
}
}
else
{
set _
""
}
}
}
{}
# verify the data isn't corrupted or changed
set newdigest
[
r debug digest
]
assert
{
$digest
eq $newdigest
}
r save
;
# saving an rdb iterates over all the data / pointers
}
{
OK
}
}
}
}
}
tests/unit/pendingquerybuf.tcl
0 → 100644
View file @
77a7ec72
proc info_memory
{
r property
}
{
if
{[
regexp
"
\r\n
$property:
(.*?)
\r\n
"
[
{*}
$r
info memory
]
_ value
]}
{
set _ $value
}
}
proc prepare_value
{
size
}
{
set _v
"c"
for
{
set i 1
}
{
$i
< $size
}
{
incr i
}
{
append _v 0
}
return $_v
}
start_server
{
tags
{
"wait"
}}
{
start_server
{}
{
set slave
[
srv 0 client
]
set slave_host
[
srv 0 host
]
set slave_port
[
srv 0 port
]
set master
[
srv -1 client
]
set master_host
[
srv -1 host
]
set master_port
[
srv -1 port
]
test
"pending querybuf: check size of pending_querybuf after set a big value"
{
$slave slaveof $master_host $master_port
set _v
[
prepare_value
[
expr 32*1024*1024
]]
$master set key $_v
after 2000
set m_usedmemory
[
info_memory $master used_memory
]
set s_usedmemory
[
info_memory $slave used_memory
]
if
{
$s_usedmemory > $m_usedmemory + 10*1024*1024
}
{
fail
"the used_memory of slave is too larger than master.Master:
$m
_usedmemory Slave:
$s
_usedmemory"
}
}
}}
tests/unit/scan.tcl
View file @
77a7ec72
...
@@ -246,7 +246,7 @@ start_server {tags {"scan"}} {
...
@@ -246,7 +246,7 @@ start_server {tags {"scan"}} {
array set found
{}
array set found
{}
# Populate the set
# Populate the set
set numele
[
expr
{
10
0
+
[
randomInt 1000
]}]
set numele
[
expr
{
10
1
+
[
randomInt 1000
]}]
for
{
set j 0
}
{
$j
< $numele
}
{
incr j
}
{
for
{
set j 0
}
{
$j
< $numele
}
{
incr j
}
{
r sadd set $j
r sadd set $j
if
{
$j
>= 100
}
{
if
{
$j
>= 100
}
{
...
...
tests/unit/scripting.tcl
View file @
77a7ec72
...
@@ -517,7 +517,7 @@ start_server {tags {"scripting"}} {
...
@@ -517,7 +517,7 @@ start_server {tags {"scripting"}} {
# Note: keep this test at the end of this server stanza because it
# Note: keep this test at the end of this server stanza because it
# kills the server.
# kills the server.
test
{
SHUTDOWN NOSAVE can kill a timedout script anyway
}
{
test
{
SHUTDOWN NOSAVE can kill a timedout script anyway
}
{
# The server
s
ould be still unresponding to normal commands.
# The server
c
ould be still unresponding to normal commands.
catch
{
r ping
}
e
catch
{
r ping
}
e
assert_match
{
BUSY*
}
$e
assert_match
{
BUSY*
}
$e
catch
{
r shutdown nosave
}
catch
{
r shutdown nosave
}
...
...
tests/unit/slowlog.tcl
View file @
77a7ec72
...
@@ -78,4 +78,14 @@ start_server {tags {"slowlog"} overrides {slowlog-log-slower-than 1000000}} {
...
@@ -78,4 +78,14 @@ start_server {tags {"slowlog"} overrides {slowlog-log-slower-than 1000000}} {
set e
[
lindex
[
r slowlog get
]
0
]
set e
[
lindex
[
r slowlog get
]
0
]
assert_equal
{
lastentry_client
}
[
lindex $e 5
]
assert_equal
{
lastentry_client
}
[
lindex $e 5
]
}
}
test
{
SLOWLOG - can be disabled
}
{
r config set slowlog-log-slower-than 1
r slowlog reset
assert_equal
[
r slowlog len
]
1
r config set slowlog-log-slower-than -1
r slowlog reset
r debug sleep 0.2
assert_equal
[
r slowlog len
]
0
}
}
}
Prev
1
2
3
4
5
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment