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
959d6035
Unverified
Commit
959d6035
authored
Apr 20, 2021
by
Oran Agra
Committed by
GitHub
Apr 20, 2021
Browse files
Merge 6.2.2 release
Release 6.2.2
parents
92bde124
aa730ef1
Changes
119
Hide whitespace changes
Inline
Side-by-side
src/t_zset.c
View file @
959d6035
...
...
@@ -388,9 +388,8 @@ unsigned long zslDeleteRangeByScore(zskiplist *zsl, zrangespec *range, dict *dic
x
=
zsl
->
header
;
for
(
i
=
zsl
->
level
-
1
;
i
>=
0
;
i
--
)
{
while
(
x
->
level
[
i
].
forward
&&
(
range
->
minex
?
x
->
level
[
i
].
forward
->
score
<=
range
->
min
:
x
->
level
[
i
].
forward
->
score
<
range
->
min
))
while
(
x
->
level
[
i
].
forward
&&
!
zslValueGteMin
(
x
->
level
[
i
].
forward
->
score
,
range
))
x
=
x
->
level
[
i
].
forward
;
update
[
i
]
=
x
;
}
...
...
@@ -399,9 +398,7 @@ unsigned long zslDeleteRangeByScore(zskiplist *zsl, zrangespec *range, dict *dic
x
=
x
->
level
[
0
].
forward
;
/* Delete nodes while in range. */
while
(
x
&&
(
range
->
maxex
?
x
->
score
<
range
->
max
:
x
->
score
<=
range
->
max
))
{
while
(
x
&&
zslValueLteMax
(
x
->
score
,
range
))
{
zskiplistNode
*
next
=
x
->
level
[
0
].
forward
;
zslDeleteNode
(
zsl
,
x
,
update
);
dictDelete
(
dict
,
x
->
ele
);
...
...
@@ -1279,9 +1276,7 @@ int zsetScore(robj *zobj, sds member, double *score) {
/* Add a new element or update the score of an existing element in a sorted
* set, regardless of its encoding.
*
* The set of flags change the command behavior. They are passed with an integer
* pointer since the function will clear the flags and populate them with
* other flags to indicate different conditions.
* The set of flags change the command behavior.
*
* The input flags are the following:
*
...
...
@@ -1323,19 +1318,19 @@ int zsetScore(robj *zobj, sds member, double *score) {
*
* The function does not take ownership of the 'ele' SDS string, but copies
* it if needed. */
int
zsetAdd
(
robj
*
zobj
,
double
score
,
sds
ele
,
int
*
flags
,
double
*
newscore
)
{
int
zsetAdd
(
robj
*
zobj
,
double
score
,
sds
ele
,
int
in_flags
,
int
*
out_
flags
,
double
*
newscore
)
{
/* Turn options into simple to check vars. */
int
incr
=
(
*
flags
&
ZADD_INCR
)
!=
0
;
int
nx
=
(
*
flags
&
ZADD_NX
)
!=
0
;
int
xx
=
(
*
flags
&
ZADD_XX
)
!=
0
;
int
gt
=
(
*
flags
&
ZADD_GT
)
!=
0
;
int
lt
=
(
*
flags
&
ZADD_LT
)
!=
0
;
*
flags
=
0
;
/* We'll return our response flags. */
int
incr
=
(
in_
flags
&
ZADD_
IN_
INCR
)
!=
0
;
int
nx
=
(
in_
flags
&
ZADD_
IN_
NX
)
!=
0
;
int
xx
=
(
in_
flags
&
ZADD_
IN_
XX
)
!=
0
;
int
gt
=
(
in_
flags
&
ZADD_
IN_
GT
)
!=
0
;
int
lt
=
(
in_
flags
&
ZADD_
IN_
LT
)
!=
0
;
*
out_
flags
=
0
;
/* We'll return our response flags. */
double
curscore
;
/* NaN as input is an error regardless of all the other parameters. */
if
(
isnan
(
score
))
{
*
flags
=
ZADD_NAN
;
*
out_
flags
=
ZADD_
OUT_
NAN
;
return
0
;
}
...
...
@@ -1346,7 +1341,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) {
if
((
eptr
=
zzlFind
(
zobj
->
ptr
,
ele
,
&
curscore
))
!=
NULL
)
{
/* NX? Return, same element already exists. */
if
(
nx
)
{
*
flags
|=
ZADD_NOP
;
*
out_
flags
|=
ZADD_
OUT_
NOP
;
return
1
;
}
...
...
@@ -1354,22 +1349,24 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) {
if
(
incr
)
{
score
+=
curscore
;
if
(
isnan
(
score
))
{
*
flags
|=
ZADD_NAN
;
*
out_
flags
|=
ZADD_
OUT_
NAN
;
return
0
;
}
if
(
newscore
)
*
newscore
=
score
;
}
/* GT/LT? Only update if score is greater/less than current. */
if
((
lt
&&
score
>=
curscore
)
||
(
gt
&&
score
<=
curscore
))
{
*
out_flags
|=
ZADD_OUT_NOP
;
return
1
;
}
if
(
newscore
)
*
newscore
=
score
;
/* Remove and re-insert when score changed. */
if
(
score
!=
curscore
&&
/* LT? Only update if score is less than current. */
(
!
lt
||
score
<
curscore
)
&&
/* GT? Only update if score is greater than current. */
(
!
gt
||
score
>
curscore
))
{
if
(
score
!=
curscore
)
{
zobj
->
ptr
=
zzlDelete
(
zobj
->
ptr
,
eptr
);
zobj
->
ptr
=
zzlInsert
(
zobj
->
ptr
,
ele
,
score
);
*
flags
|=
ZADD_UPDATED
;
*
out_
flags
|=
ZADD_
OUT_
UPDATED
;
}
return
1
;
}
else
if
(
!
xx
)
{
...
...
@@ -1380,10 +1377,10 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) {
sdslen
(
ele
)
>
server
.
zset_max_ziplist_value
)
zsetConvert
(
zobj
,
OBJ_ENCODING_SKIPLIST
);
if
(
newscore
)
*
newscore
=
score
;
*
flags
|=
ZADD_ADDED
;
*
out_
flags
|=
ZADD_
OUT_
ADDED
;
return
1
;
}
else
{
*
flags
|=
ZADD_NOP
;
*
out_
flags
|=
ZADD_
OUT_
NOP
;
return
1
;
}
}
else
if
(
zobj
->
encoding
==
OBJ_ENCODING_SKIPLIST
)
{
...
...
@@ -1395,45 +1392,48 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) {
if
(
de
!=
NULL
)
{
/* NX? Return, same element already exists. */
if
(
nx
)
{
*
flags
|=
ZADD_NOP
;
*
out_
flags
|=
ZADD_
OUT_
NOP
;
return
1
;
}
curscore
=
*
(
double
*
)
dictGetVal
(
de
);
/* Prepare the score for the increment if needed. */
if
(
incr
)
{
score
+=
curscore
;
if
(
isnan
(
score
))
{
*
flags
|=
ZADD_NAN
;
*
out_
flags
|=
ZADD_
OUT_
NAN
;
return
0
;
}
if
(
newscore
)
*
newscore
=
score
;
}
/* GT/LT? Only update if score is greater/less than current. */
if
((
lt
&&
score
>=
curscore
)
||
(
gt
&&
score
<=
curscore
))
{
*
out_flags
|=
ZADD_OUT_NOP
;
return
1
;
}
if
(
newscore
)
*
newscore
=
score
;
/* Remove and re-insert when score changes. */
if
(
score
!=
curscore
&&
/* LT? Only update if score is less than current. */
(
!
lt
||
score
<
curscore
)
&&
/* GT? Only update if score is greater than current. */
(
!
gt
||
score
>
curscore
))
{
if
(
score
!=
curscore
)
{
znode
=
zslUpdateScore
(
zs
->
zsl
,
curscore
,
ele
,
score
);
/* Note that we did not removed the original element from
* the hash table representing the sorted set, so we just
* update the score. */
dictGetVal
(
de
)
=
&
znode
->
score
;
/* Update score ptr. */
*
flags
|=
ZADD_UPDATED
;
*
out_
flags
|=
ZADD_
OUT_
UPDATED
;
}
return
1
;
}
else
if
(
!
xx
)
{
ele
=
sdsdup
(
ele
);
znode
=
zslInsert
(
zs
->
zsl
,
score
,
ele
);
serverAssert
(
dictAdd
(
zs
->
dict
,
ele
,
&
znode
->
score
)
==
DICT_OK
);
*
flags
|=
ZADD_ADDED
;
*
out_
flags
|=
ZADD_
OUT_
ADDED
;
if
(
newscore
)
*
newscore
=
score
;
return
1
;
}
else
{
*
flags
|=
ZADD_NOP
;
*
out_
flags
|=
ZADD_
OUT_
NOP
;
return
1
;
}
}
else
{
...
...
@@ -1636,7 +1636,7 @@ static int _zsetZiplistValidateIntegrity(unsigned char *p, void *userdata) {
return
1
;
}
/* Validate the integrity of the data str
a
cture.
/* Validate the integrity of the data str
u
cture.
* when `deep` is 0, only the integrity of the header is validated.
* when `deep` is 1, we scan all the entries one by one. */
int
zsetZiplistValidateIntegrity
(
unsigned
char
*
zl
,
size_t
size
,
int
deep
)
{
...
...
@@ -1712,7 +1712,7 @@ void zaddGenericCommand(client *c, int flags) {
robj
*
zobj
;
sds
ele
;
double
score
=
0
,
*
scores
=
NULL
;
int
j
,
elements
;
int
j
,
elements
,
ch
=
0
;
int
scoreidx
=
0
;
/* The following vars are used in order to track what the command actually
* did during the execution, to reply to the client and to trigger the
...
...
@@ -1727,23 +1727,22 @@ void zaddGenericCommand(client *c, int flags) {
scoreidx
=
2
;
while
(
scoreidx
<
c
->
argc
)
{
char
*
opt
=
c
->
argv
[
scoreidx
]
->
ptr
;
if
(
!
strcasecmp
(
opt
,
"nx"
))
flags
|=
ZADD_NX
;
else
if
(
!
strcasecmp
(
opt
,
"xx"
))
flags
|=
ZADD_XX
;
else
if
(
!
strcasecmp
(
opt
,
"ch"
))
flags
|=
ZADD_CH
;
else
if
(
!
strcasecmp
(
opt
,
"incr"
))
flags
|=
ZADD_INCR
;
else
if
(
!
strcasecmp
(
opt
,
"gt"
))
flags
|=
ZADD_GT
;
else
if
(
!
strcasecmp
(
opt
,
"lt"
))
flags
|=
ZADD_LT
;
if
(
!
strcasecmp
(
opt
,
"nx"
))
flags
|=
ZADD_
IN_
NX
;
else
if
(
!
strcasecmp
(
opt
,
"xx"
))
flags
|=
ZADD_
IN_
XX
;
else
if
(
!
strcasecmp
(
opt
,
"ch"
))
ch
=
1
;
/* Return num of elements added or updated. */
else
if
(
!
strcasecmp
(
opt
,
"incr"
))
flags
|=
ZADD_
IN_
INCR
;
else
if
(
!
strcasecmp
(
opt
,
"gt"
))
flags
|=
ZADD_
IN_
GT
;
else
if
(
!
strcasecmp
(
opt
,
"lt"
))
flags
|=
ZADD_
IN_
LT
;
else
break
;
scoreidx
++
;
}
/* Turn options into simple to check vars. */
int
incr
=
(
flags
&
ZADD_INCR
)
!=
0
;
int
nx
=
(
flags
&
ZADD_NX
)
!=
0
;
int
xx
=
(
flags
&
ZADD_XX
)
!=
0
;
int
ch
=
(
flags
&
ZADD_CH
)
!=
0
;
int
gt
=
(
flags
&
ZADD_GT
)
!=
0
;
int
lt
=
(
flags
&
ZADD_LT
)
!=
0
;
int
incr
=
(
flags
&
ZADD_IN_INCR
)
!=
0
;
int
nx
=
(
flags
&
ZADD_IN_NX
)
!=
0
;
int
xx
=
(
flags
&
ZADD_IN_XX
)
!=
0
;
int
gt
=
(
flags
&
ZADD_IN_GT
)
!=
0
;
int
lt
=
(
flags
&
ZADD_IN_LT
)
!=
0
;
/* After the options, we expect to have an even number of args, since
* we expect any number of score-element pairs. */
...
...
@@ -1801,17 +1800,17 @@ void zaddGenericCommand(client *c, int flags) {
for
(
j
=
0
;
j
<
elements
;
j
++
)
{
double
newscore
;
score
=
scores
[
j
];
int
retflags
=
flags
;
int
retflags
=
0
;
ele
=
c
->
argv
[
scoreidx
+
1
+
j
*
2
]
->
ptr
;
int
retval
=
zsetAdd
(
zobj
,
score
,
ele
,
&
retflags
,
&
newscore
);
int
retval
=
zsetAdd
(
zobj
,
score
,
ele
,
flags
,
&
retflags
,
&
newscore
);
if
(
retval
==
0
)
{
addReplyError
(
c
,
nanerr
);
goto
cleanup
;
}
if
(
retflags
&
ZADD_ADDED
)
added
++
;
if
(
retflags
&
ZADD_UPDATED
)
updated
++
;
if
(
!
(
retflags
&
ZADD_NOP
))
processed
++
;
if
(
retflags
&
ZADD_
OUT_
ADDED
)
added
++
;
if
(
retflags
&
ZADD_
OUT_
UPDATED
)
updated
++
;
if
(
!
(
retflags
&
ZADD_
OUT_
NOP
))
processed
++
;
score
=
newscore
;
}
server
.
dirty
+=
(
added
+
updated
);
...
...
@@ -1836,11 +1835,11 @@ cleanup:
}
void
zaddCommand
(
client
*
c
)
{
zaddGenericCommand
(
c
,
ZADD_NONE
);
zaddGenericCommand
(
c
,
ZADD_
IN_
NONE
);
}
void
zincrbyCommand
(
client
*
c
)
{
zaddGenericCommand
(
c
,
ZADD_INCR
);
zaddGenericCommand
(
c
,
ZADD_
IN_
INCR
);
}
void
zremCommand
(
client
*
c
)
{
...
...
@@ -2577,8 +2576,8 @@ void zunionInterDiffGenericCommand(client *c, robj *dstkey, int numkeysIndex, in
return
;
if
(
setnum
<
1
)
{
addReplyError
(
c
,
"at least 1 input key is needed for
ZUNIONSTORE/ZINTERSTORE/ZDIFFSTORE"
);
addReplyError
Format
(
c
,
"at least 1 input key is needed for
%s"
,
c
->
cmd
->
name
);
return
;
}
...
...
@@ -2941,7 +2940,7 @@ static void zrangeResultEmitCBufferForStore(zrange_result_handler *handler,
double
newscore
;
int
retflags
=
0
;
sds
ele
=
sdsnewlen
(
value
,
value_length_in_bytes
);
int
retval
=
zsetAdd
(
handler
->
dstobj
,
score
,
ele
,
&
retflags
,
&
newscore
);
int
retval
=
zsetAdd
(
handler
->
dstobj
,
score
,
ele
,
ZADD_IN_NONE
,
&
retflags
,
&
newscore
);
sdsfree
(
ele
);
serverAssert
(
retval
);
}
...
...
@@ -2952,7 +2951,7 @@ static void zrangeResultEmitLongLongForStore(zrange_result_handler *handler,
double
newscore
;
int
retflags
=
0
;
sds
ele
=
sdsfromlonglong
(
value
);
int
retval
=
zsetAdd
(
handler
->
dstobj
,
score
,
ele
,
&
retflags
,
&
newscore
);
int
retval
=
zsetAdd
(
handler
->
dstobj
,
score
,
ele
,
ZADD_IN_NONE
,
&
retflags
,
&
newscore
);
sdsfree
(
ele
);
serverAssert
(
retval
);
}
...
...
src/tls.c
View file @
959d6035
...
...
@@ -147,7 +147,7 @@ void tlsInit(void) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
OPENSSL_config
(
NULL
);
#else
OPENSSL_init_crypto
(
OPENSSL_INIT_LOAD_CONFIG
,
NULL
);
OPENSSL_init_crypto
(
OPENSSL_INIT_LOAD_CONFIG
|
OPENSSL_INIT_ATFORK
,
NULL
);
#endif
ERR_load_crypto_strings
();
SSL_load_error_strings
();
...
...
@@ -164,11 +164,43 @@ void tlsInit(void) {
pending_list
=
listCreate
();
}
void
tlsCleanup
(
void
)
{
if
(
redis_tls_ctx
)
{
SSL_CTX_free
(
redis_tls_ctx
);
redis_tls_ctx
=
NULL
;
}
if
(
redis_tls_client_ctx
)
{
SSL_CTX_free
(
redis_tls_client_ctx
);
redis_tls_client_ctx
=
NULL
;
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
OPENSSL_cleanup
();
#endif
}
/* Callback for passing a keyfile password stored as an sds to OpenSSL */
static
int
tlsPasswordCallback
(
char
*
buf
,
int
size
,
int
rwflag
,
void
*
u
)
{
UNUSED
(
rwflag
);
const
char
*
pass
=
u
;
size_t
pass_len
;
if
(
!
pass
)
return
-
1
;
pass_len
=
strlen
(
pass
);
if
(
pass_len
>
(
size_t
)
size
)
return
-
1
;
memcpy
(
buf
,
pass
,
pass_len
);
return
(
int
)
pass_len
;
}
/* Create a *base* SSL_CTX using the SSL configuration provided. The base context
* includes everything that's common for both client-side and server-side connections.
*/
static
SSL_CTX
*
createSSLContext
(
redisTLSContextConfig
*
ctx_config
,
int
protocols
,
const
char
*
cert_file
,
const
char
*
key_file
)
{
static
SSL_CTX
*
createSSLContext
(
redisTLSContextConfig
*
ctx_config
,
int
protocols
,
int
client
)
{
const
char
*
cert_file
=
client
?
ctx_config
->
client_cert_file
:
ctx_config
->
cert_file
;
const
char
*
key_file
=
client
?
ctx_config
->
client_key_file
:
ctx_config
->
key_file
;
const
char
*
key_file_pass
=
client
?
ctx_config
->
client_key_file_pass
:
ctx_config
->
key_file_pass
;
char
errbuf
[
256
];
SSL_CTX
*
ctx
=
NULL
;
...
...
@@ -200,6 +232,9 @@ static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocol
SSL_CTX_set_mode
(
ctx
,
SSL_MODE_ENABLE_PARTIAL_WRITE
|
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
);
SSL_CTX_set_verify
(
ctx
,
SSL_VERIFY_PEER
|
SSL_VERIFY_FAIL_IF_NO_PEER_CERT
,
NULL
);
SSL_CTX_set_default_passwd_cb
(
ctx
,
tlsPasswordCallback
);
SSL_CTX_set_default_passwd_cb_userdata
(
ctx
,
(
void
*
)
key_file_pass
);
if
(
SSL_CTX_use_certificate_chain_file
(
ctx
,
cert_file
)
<=
0
)
{
ERR_error_string_n
(
ERR_get_error
(),
errbuf
,
sizeof
(
errbuf
));
serverLog
(
LL_WARNING
,
"Failed to load certificate: %s: %s"
,
cert_file
,
errbuf
);
...
...
@@ -266,7 +301,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
if
(
protocols
==
-
1
)
goto
error
;
/* Create server side/generla context */
ctx
=
createSSLContext
(
ctx_config
,
protocols
,
ctx_config
->
cert_file
,
ctx_config
->
key_file
);
ctx
=
createSSLContext
(
ctx_config
,
protocols
,
0
);
if
(
!
ctx
)
goto
error
;
if
(
ctx_config
->
session_caching
)
{
...
...
@@ -317,7 +352,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
/* If a client-side certificate is configured, create an explicit client context */
if
(
ctx_config
->
client_cert_file
&&
ctx_config
->
client_key_file
)
{
client_ctx
=
createSSLContext
(
ctx_config
,
protocols
,
ctx_config
->
client_cert_file
,
ctx_config
->
client_key_file
);
client_ctx
=
createSSLContext
(
ctx_config
,
protocols
,
1
);
if
(
!
client_ctx
)
goto
error
;
}
...
...
@@ -948,6 +983,9 @@ sds connTLSGetPeerCert(connection *conn_) {
void
tlsInit
(
void
)
{
}
void
tlsCleanup
(
void
)
{
}
int
tlsConfigure
(
redisTLSContextConfig
*
ctx_config
)
{
UNUSED
(
ctx_config
);
return
C_OK
;
...
...
src/util.c
View file @
959d6035
...
...
@@ -946,9 +946,10 @@ static void test_ll2string(void) {
}
#define UNUSED(x) (void)(x)
int
utilTest
(
int
argc
,
char
**
argv
)
{
int
utilTest
(
int
argc
,
char
**
argv
,
int
accurate
)
{
UNUSED
(
argc
);
UNUSED
(
argv
);
UNUSED
(
accurate
);
test_string2ll
();
test_string2l
();
...
...
src/util.h
View file @
959d6035
...
...
@@ -66,7 +66,7 @@ long getTimeZone(void);
int
pathIsBaseName
(
char
*
path
);
#ifdef REDIS_TEST
int
utilTest
(
int
argc
,
char
**
argv
);
int
utilTest
(
int
argc
,
char
**
argv
,
int
accurate
);
#endif
#endif
src/version.h
View file @
959d6035
#define REDIS_VERSION "6.2.
1
"
#define REDIS_VERSION_NUM 0x0006020
1
#define REDIS_VERSION "6.2.
2
"
#define REDIS_VERSION_NUM 0x0006020
2
src/ziplist.c
View file @
959d6035
...
...
@@ -1472,7 +1472,7 @@ void ziplistRepr(unsigned char *zl) {
printf
(
"{end}
\n\n
"
);
}
/* Validate the integrity of the data str
a
cture.
/* Validate the integrity of the data str
u
cture.
* when `deep` is 0, only the integrity of the header is validated.
* when `deep` is 1, we scan all the entries one by one. */
int
ziplistValidateIntegrity
(
unsigned
char
*
zl
,
size_t
size
,
int
deep
,
...
...
@@ -1823,15 +1823,17 @@ static size_t strEntryBytesLarge(size_t slen) {
return
slen
+
zipStorePrevEntryLength
(
NULL
,
ZIP_BIG_PREVLEN
)
+
zipStoreEntryEncoding
(
NULL
,
0
,
slen
);
}
int
ziplistTest
(
int
argc
,
char
**
argv
)
{
/* ./redis-server test ziplist <randomseed> --accurate */
int
ziplistTest
(
int
argc
,
char
**
argv
,
int
accurate
)
{
unsigned
char
*
zl
,
*
p
;
unsigned
char
*
entry
;
unsigned
int
elen
;
long
long
value
;
int
iteration
;
/* If an argument is given, use it as the random seed. */
if
(
argc
=
=
2
)
srand
(
atoi
(
argv
[
1
]));
if
(
argc
>
=
4
)
srand
(
atoi
(
argv
[
3
]));
zl
=
createIntList
();
ziplistRepr
(
zl
);
...
...
@@ -2339,7 +2341,8 @@ int ziplistTest(int argc, char **argv) {
unsigned
int
slen
;
long
long
sval
;
for
(
i
=
0
;
i
<
20000
;
i
++
)
{
iteration
=
accurate
?
20000
:
20
;
for
(
i
=
0
;
i
<
iteration
;
i
++
)
{
zl
=
ziplistNew
();
ref
=
listCreate
();
listSetFreeMethod
(
ref
,(
void
(
*
)(
void
*
))
sdsfree
);
...
...
@@ -2405,15 +2408,17 @@ int ziplistTest(int argc, char **argv) {
printf
(
"Stress with variable ziplist size:
\n
"
);
{
unsigned
long
long
start
=
usec
();
stress
(
ZIPLIST_HEAD
,
100000
,
16384
,
256
);
stress
(
ZIPLIST_TAIL
,
100000
,
16384
,
256
);
int
maxsize
=
accurate
?
16384
:
16
;
stress
(
ZIPLIST_HEAD
,
100000
,
maxsize
,
256
);
stress
(
ZIPLIST_TAIL
,
100000
,
maxsize
,
256
);
printf
(
"Done. usec=%lld
\n\n
"
,
usec
()
-
start
);
}
/* Benchmarks */
{
zl
=
ziplistNew
();
for
(
int
i
=
0
;
i
<
100000
;
i
++
)
{
iteration
=
accurate
?
100000
:
100
;
for
(
int
i
=
0
;
i
<
iteration
;
i
++
)
{
char
buf
[
4096
]
=
"asdf"
;
zl
=
ziplistPush
(
zl
,
(
unsigned
char
*
)
buf
,
4
,
ZIPLIST_TAIL
);
zl
=
ziplistPush
(
zl
,
(
unsigned
char
*
)
buf
,
40
,
ZIPLIST_TAIL
);
...
...
@@ -2462,7 +2467,8 @@ int ziplistTest(int argc, char **argv) {
{
char
data
[
ZIP_BIG_PREVLEN
];
zl
=
ziplistNew
();
for
(
int
i
=
0
;
i
<
100000
;
i
++
)
{
iteration
=
accurate
?
100000
:
100
;
for
(
int
i
=
0
;
i
<
iteration
;
i
++
)
{
zl
=
ziplistPush
(
zl
,
(
unsigned
char
*
)
data
,
ZIP_BIG_PREVLEN
-
4
,
ZIPLIST_TAIL
);
}
unsigned
long
long
start
=
usec
();
...
...
src/ziplist.h
View file @
959d6035
...
...
@@ -67,7 +67,7 @@ void ziplistRandomPairs(unsigned char *zl, unsigned int count, ziplistEntry *key
unsigned
int
ziplistRandomPairsUnique
(
unsigned
char
*
zl
,
unsigned
int
count
,
ziplistEntry
*
keys
,
ziplistEntry
*
vals
);
#ifdef REDIS_TEST
int
ziplistTest
(
int
argc
,
char
*
argv
[]);
int
ziplistTest
(
int
argc
,
char
*
argv
[]
,
int
accurate
);
#endif
#endif
/* _ZIPLIST_H */
src/zipmap.c
View file @
959d6035
...
...
@@ -374,7 +374,7 @@ size_t zipmapBlobLen(unsigned char *zm) {
return
totlen
;
}
/* Validate the integrity of the data str
a
cture.
/* Validate the integrity of the data str
u
cture.
* when `deep` is 0, only the integrity of the header is validated.
* when `deep` is 1, we scan all the entries one by one. */
int
zipmapValidateIntegrity
(
unsigned
char
*
zm
,
size_t
size
,
int
deep
)
{
...
...
@@ -473,11 +473,12 @@ static void zipmapRepr(unsigned char *p) {
}
#define UNUSED(x) (void)(x)
int
zipmapTest
(
int
argc
,
char
*
argv
[])
{
int
zipmapTest
(
int
argc
,
char
*
argv
[]
,
int
accurate
)
{
unsigned
char
*
zm
;
UNUSED
(
argc
);
UNUSED
(
argv
);
UNUSED
(
accurate
);
zm
=
zipmapNew
();
...
...
@@ -532,6 +533,7 @@ int zipmapTest(int argc, char *argv[]) {
printf
(
" %d:%.*s => %d:%.*s
\n
"
,
klen
,
klen
,
key
,
vlen
,
vlen
,
value
);
}
}
zfree
(
zm
);
return
0
;
}
#endif
src/zipmap.h
View file @
959d6035
...
...
@@ -48,7 +48,7 @@ void zipmapRepr(unsigned char *p);
int
zipmapValidateIntegrity
(
unsigned
char
*
zm
,
size_t
size
,
int
deep
);
#ifdef REDIS_TEST
int
zipmapTest
(
int
argc
,
char
*
argv
[]);
int
zipmapTest
(
int
argc
,
char
*
argv
[]
,
int
accurate
);
#endif
#endif
src/zmalloc.c
View file @
959d6035
...
...
@@ -414,9 +414,9 @@ size_t zmalloc_get_rss(void) {
if
(
sysctl
(
mib
,
4
,
&
info
,
&
infolen
,
NULL
,
0
)
==
0
)
#if defined(__FreeBSD__)
return
(
size_t
)
info
.
ki_rssize
;
return
(
size_t
)
info
.
ki_rssize
*
getpagesize
()
;
#else
return
(
size_t
)
info
.
kp_vm_rssize
;
return
(
size_t
)
info
.
kp_vm_rssize
*
getpagesize
()
;
#endif
return
0L
;
...
...
@@ -436,7 +436,7 @@ size_t zmalloc_get_rss(void) {
mib
[
4
]
=
sizeof
(
info
);
mib
[
5
]
=
1
;
if
(
sysctl
(
mib
,
4
,
&
info
,
&
infolen
,
NULL
,
0
)
==
0
)
return
(
size_t
)
info
.
p_vm_rssize
;
return
(
size_t
)
info
.
p_vm_rssize
*
getpagesize
()
;
return
0L
;
}
...
...
@@ -613,6 +613,11 @@ size_t zmalloc_get_smap_bytes_by_field(char *field, long pid) {
}
#endif
/* Return the total number bytes in pages marked as Private Dirty.
*
* Note: depending on the platform and memory footprint of the process, this
* call can be slow, exceeding 1000ms!
*/
size_t
zmalloc_get_private_dirty
(
long
pid
)
{
return
zmalloc_get_smap_bytes_by_field
(
"Private_Dirty:"
,
pid
);
}
...
...
@@ -675,11 +680,12 @@ size_t zmalloc_get_memory_size(void) {
#ifdef REDIS_TEST
#define UNUSED(x) ((void)(x))
int
zmalloc_test
(
int
argc
,
char
**
argv
)
{
int
zmalloc_test
(
int
argc
,
char
**
argv
,
int
accurate
)
{
void
*
ptr
;
UNUSED
(
argc
);
UNUSED
(
argv
);
UNUSED
(
accurate
);
printf
(
"Malloc prefix size: %d
\n
"
,
(
int
)
PREFIX_SIZE
);
printf
(
"Initial used memory: %zu
\n
"
,
zmalloc_used_memory
());
ptr
=
zmalloc
(
123
);
...
...
src/zmalloc.h
View file @
959d6035
...
...
@@ -71,12 +71,21 @@
*/
#ifndef ZMALLOC_LIB
#define ZMALLOC_LIB "libc"
#if !defined(NO_MALLOC_USABLE_SIZE) && \
(defined(__GLIBC__) || defined(__FreeBSD__) || \
defined(USE_MALLOC_USABLE_SIZE))
/* Includes for malloc_usable_size() */
#ifdef __FreeBSD__
#include <malloc_np.h>
#else
#include <malloc.h>
#endif
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) malloc_usable_size(p)
#endif
#endif
...
...
@@ -126,7 +135,7 @@ size_t zmalloc_usable_size(void *ptr);
#endif
#ifdef REDIS_TEST
int
zmalloc_test
(
int
argc
,
char
**
argv
);
int
zmalloc_test
(
int
argc
,
char
**
argv
,
int
accurate
);
#endif
#endif
/* __ZMALLOC_H */
tests/assets/nodefaultuser.acl
0 → 100644
View file @
959d6035
user alice on nopass ~* +@all
user bob on nopass ~* &* +@all
\ No newline at end of file
tests/assets/user.acl
View file @
959d6035
user alice on allcommands allkeys >alice
user bob on -@all +@set +acl ~set* >bob
\ No newline at end of file
user bob on -@all +@set +acl ~set* >bob
user default on nopass ~* +@all
tests/cluster/cluster.tcl
View file @
959d6035
...
...
@@ -4,6 +4,10 @@
# This software is released under the BSD License. See the COPYING file for
# more information.
# Track cluster configuration as created by create_cluster below
set ::cluster_master_nodes 0
set ::cluster_replica_nodes 0
# Returns a parsed CLUSTER NODES output as a list of dictionaries.
proc get_cluster_nodes id
{
set lines
[
split
[
R $id cluster nodes
]
"
\r\n
"
]
...
...
@@ -120,6 +124,9 @@ proc create_cluster {masters slaves} {
cluster_allocate_slaves $masters $slaves
}
assert_cluster_state ok
set ::cluster_master_nodes $masters
set ::cluster_replica_nodes $slaves
}
# Set the cluster node-timeout to all the reachalbe nodes.
...
...
@@ -143,3 +150,28 @@ proc cluster_write_test {id} {
}
$cluster close
}
# Check if cluster configuration is consistent.
proc cluster_config_consistent
{}
{
for
{
set j 0
}
{
$j
< $::cluster_master_nodes + $::cluster_replica_nodes
}
{
incr j
}
{
if
{
$j
== 0
}
{
set base_cfg
[
R $j cluster slots
]
}
else
{
set cfg
[
R $j cluster slots
]
if
{
$cfg
!= $base_cfg
}
{
return 0
}
}
}
return 1
}
# Wait for cluster configuration to propagate and be consistent across nodes.
proc wait_for_cluster_propagation
{}
{
wait_for_condition 50 100
{
[
cluster_config_consistent
]
eq 1
}
else
{
fail
"cluster config did not reach a consistent state"
}
}
tests/cluster/tests/04-resharding.tcl
View file @
959d6035
...
...
@@ -54,7 +54,17 @@ proc process_is_running {pid} {
set numkeys 50000
set numops 200000
set cluster
[
redis_cluster 127.0.0.1:
[
get_instance_attrib redis 0 port
]]
set start_node_port
[
get_instance_attrib redis 0 port
]
set cluster
[
redis_cluster 127.0.0.1:$start_node_port
]
if
{
$::tls
}
{
# setup a non-TLS cluster client to the TLS cluster
set plaintext_port
[
get_instance_attrib redis 0 plaintext-port
]
set cluster_plaintext
[
redis_cluster 127.0.0.1:$plaintext_port 0
]
puts
"Testing TLS cluster on start node 127.0.0.1:
$start
_node_port, plaintext port
$plaintext
_port"
}
else
{
set cluster_plaintext $cluster
puts
"Testing using non-TLS cluster"
}
catch
{
unset content
}
array set content
{}
set tribpid
{}
...
...
@@ -94,8 +104,11 @@ test "Cluster consistency during live resharding" {
# This way we are able to stress Lua -> Redis command invocation
# as well, that has tests to prevent Lua to write into wrong
# hash slots.
if
{
$listid
% 2
}
{
# We also use both TLS and plaintext connections.
if
{
$listid
% 3 == 0
}
{
$cluster rpush $key $ele
}
elseif
{
$listid
% 3 == 1
}
{
$cluster_plaintext rpush $key $ele
}
else
{
$cluster eval
{
redis.call
(
"rpush"
,KEYS
[
1
]
,ARGV
[
1
])}
1 $key $ele
}
...
...
tests/cluster/tests/12-replica-migration-2.tcl
View file @
959d6035
...
...
@@ -29,6 +29,12 @@ test "Each master should have at least two replicas attached" {
}
}
test
"Set allow-replica-migration yes"
{
foreach_redis_id id
{
R $id CONFIG SET cluster-allow-replica-migration yes
}
}
set master0_id
[
dict get
[
get_myself 0
]
id
]
test
"Resharding all the master #0 slots away from it"
{
set output
[
exec
\
...
...
tests/cluster/tests/12.1-replica-migration-3.tcl
0 → 100644
View file @
959d6035
# Replica migration test #2.
#
# Check that if 'cluster-allow-replica-migration' is set to 'no', slaves do not
# migrate when master becomes empty.
source
"../tests/includes/init-tests.tcl"
# Create a cluster with 5 master and 15 slaves, to make sure there are no
# empty masters and make rebalancing simpler to handle during the test.
test
"Create a 5 nodes cluster"
{
create_cluster 5 15
}
test
"Cluster is up"
{
assert_cluster_state ok
}
test
"Each master should have at least two replicas attached"
{
foreach_redis_id id
{
if
{
$id
< 5
}
{
wait_for_condition 1000 50
{
[
llength
[
lindex
[
R 0 role
]
2
]]
>= 2
}
else
{
fail
"Master #
$id
does not have 2 slaves as expected"
}
}
}
}
test
"Set allow-replica-migration no"
{
foreach_redis_id id
{
R $id CONFIG SET cluster-allow-replica-migration no
}
}
set master0_id
[
dict get
[
get_myself 0
]
id
]
test
"Resharding all the master #0 slots away from it"
{
set output
[
exec
\
../../../src/redis-cli --cluster rebalance
\
127.0.0.1:
[
get_instance_attrib redis 0 port
]
\
{*}
[
rediscli_tls_config
"../../../tests"
]
\
--cluster-weight $
{
master0_id
}
=0 >@ stdout
]
}
test
"Wait cluster to be stable"
{
wait_for_condition 1000 50
{
[
catch
{
exec ../../../src/redis-cli --cluster
\
check 127.0.0.1:
[
get_instance_attrib redis 0 port
]
\
{*}
[
rediscli_tls_config
"../../../tests"
]
\
}]
== 0
}
else
{
fail
"Cluster doesn't stabilize"
}
}
test
"Master #0 stil should have its replicas"
{
assert
{
[
llength
[
lindex
[
R 0 role
]
2
]]
>= 2
}
}
test
"Each master should have at least two replicas attached"
{
foreach_redis_id id
{
if
{
$id
< 5
}
{
wait_for_condition 1000 50
{
[
llength
[
lindex
[
R 0 role
]
2
]]
>= 2
}
else
{
fail
"Master #
$id
does not have 2 slaves as expected"
}
}
}
}
tests/cluster/tests/15-cluster-slots.tcl
View file @
959d6035
...
...
@@ -48,3 +48,16 @@ test "client can handle keys with hash tag" {
$cluster set foo
{
tag
}
bar
$cluster close
}
if
{
$::tls
}
{
test
{
CLUSTER SLOTS from non-TLS client in TLS cluster
}
{
set slots_tls
[
R 0 cluster slots
]
set host
[
get_instance_attrib redis 0 host
]
set plaintext_port
[
get_instance_attrib redis 0 plaintext-port
]
set client_plain
[
redis $host $plaintext_port 0 0
]
set slots_plain
[
$client
_plain cluster slots
]
$client_plain close
# Compare the ports in the first row
assert_no_match
[
lindex $slots_tls 0 3 1
]
[
lindex $slots_plain 0 3 1
]
}
}
tests/cluster/tests/17-diskless-load-swapdb.tcl
View file @
959d6035
...
...
@@ -36,7 +36,7 @@ test "Right to restore backups when fail to diskless load " {
# Write a key that belongs to slot 0
set slot0_key
"06S"
$master set $slot0_key 1
after 100
wait_for_ofs_sync $master $replica
assert_equal
{
1
}
[
$replica
get $slot0_key
]
assert_equal $slot0_key
[
$replica
CLUSTER GETKEYSINSLOT 0 1
]
...
...
@@ -73,6 +73,13 @@ test "Right to restore backups when fail to diskless load " {
# Kill master, abort full sync
kill_instance redis $master_id
# Start full sync, wait till the replica detects the disconnection
wait_for_condition 500 10
{
[
s $replica_id loading
]
eq 0
}
else
{
fail
"Fail to full sync"
}
# Replica keys and keys to slots map still both are right
assert_equal
{
1
}
[
$replica
get $slot0_key
]
assert_equal $slot0_key
[
$replica
CLUSTER GETKEYSINSLOT 0 1
]
...
...
tests/cluster/tests/19-cluster-nodes-slots.tcl
View file @
959d6035
...
...
@@ -37,26 +37,35 @@ set master2 [Rn 1]
test
"Continuous slots distribution"
{
assert_match
"* 0-8191*"
[
$master1
CLUSTER NODES
]
assert_match
"* 8192-16383*"
[
$master2
CLUSTER NODES
]
assert_match
"*0 8191*"
[
$master1
CLUSTER SLOTS
]
assert_match
"*8192 16383*"
[
$master2
CLUSTER SLOTS
]
$master1 CLUSTER DELSLOTS 4096
assert_match
"* 0-4095 4097-8191*"
[
$master1
CLUSTER NODES
]
assert_match
"*0 4095*4097 8191*"
[
$master1
CLUSTER SLOTS
]
$master2 CLUSTER DELSLOTS 12288
assert_match
"* 8192-12287 12289-16383*"
[
$master2
CLUSTER NODES
]
assert_match
"*8192 12287*12289 16383*"
[
$master2
CLUSTER SLOTS
]
}
test
"Discontinuous slots distribution"
{
# Remove middle slots
$master1 CLUSTER DELSLOTS 4092 4094
assert_match
"* 0-4091 4093 4095 4097-8191*"
[
$master1
CLUSTER NODES
]
assert_match
"*0 4091*4093 4093*4095 4095*4097 8191*"
[
$master1
CLUSTER SLOTS
]
$master2 CLUSTER DELSLOTS 12284 12286
assert_match
"* 8192-12283 12285 12287 12289-16383*"
[
$master2
CLUSTER NODES
]
assert_match
"*8192 12283*12285 12285*12287 12287*12289 16383*"
[
$master2
CLUSTER SLOTS
]
# Remove head slots
$master1 CLUSTER DELSLOTS 0 2
assert_match
"* 1 3-4091 4093 4095 4097-8191*"
[
$master1
CLUSTER NODES
]
assert_match
"*1 1*3 4091*4093 4093*4095 4095*4097 8191*"
[
$master1
CLUSTER SLOTS
]
# Remove tail slots
$master2 CLUSTER DELSLOTS 16380 16382 16383
assert_match
"* 8192-12283 12285 12287 12289-16379 16381*"
[
$master2
CLUSTER NODES
]
assert_match
"*8192 12283*12285 12285*12287 12287*12289 16379*16381 16381*"
[
$master2
CLUSTER SLOTS
]
}
Prev
1
2
3
4
5
6
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