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
c1b27012
Commit
c1b27012
authored
Jul 27, 2011
by
antirez
Browse files
Merge remote-tracking branch 'origin/2.2' into 2.2
parents
62e6f6c2
5960ac9d
Changes
17
Hide whitespace changes
Inline
Side-by-side
00-RELEASENOTES
View file @
c1b27012
...
@@ -12,6 +12,22 @@ for 2.0.
...
@@ -12,6 +12,22 @@ for 2.0.
CHANGELOG
CHANGELOG
---------
---------
What's new in Redis 2.2.12
==========================
* The Slowlog feature was backported to Redis 2.2.
* A number of fixes related blocking operations on lists when mixed with
AOF and Replication.
* Fixed bad interactions between EXPIRE, EXPIREAT, and in general volatile
keys when AOF is enabled. More details in the Redis Google Group here:
http://groups.google.com/group/redis-db/browse_frm/thread/5a931fefb88b16d5?tvc=1
* no more allocation stats info in INFO.
* colorized make for 2.2 as well.
* Fixed a problem with AOF when it is stopped via CONFIG SET appendonly no.
* Warn the user enabling VM that VM is deprecated and discouraged.
* prepareForShutdown() fixed for correctness.
* Close the listening sockets on exit for faster restarts.
What's new in Redis 2.2.11
What's new in Redis 2.2.11
==========================
==========================
...
...
redis.conf
View file @
c1b27012
...
@@ -314,10 +314,13 @@ slowlog-log-slower-than 10000
...
@@ -314,10 +314,13 @@ slowlog-log-slower-than 10000
# There is no limit to this length. Just be aware that it will consume memory.
# There is no limit to this length. Just be aware that it will consume memory.
# You can reclaim memory used by the slow log with SLOWLOG RESET.
# You can reclaim memory used by the slow log with SLOWLOG RESET.
slowlog
-
log
-
len
1024
slowlog
-
max
-
len
1024
################################ VIRTUAL MEMORY ###############################
################################ VIRTUAL MEMORY ###############################
### WARNING! Virtual Memory is deprecated in Redis 2.4
### The use of Virtual Memory is strongly discouraged.
# Virtual Memory allows Redis to work with datasets bigger than the actual
# Virtual Memory allows Redis to work with datasets bigger than the actual
# amount of RAM needed to hold the whole dataset in memory.
# amount of RAM needed to hold the whole dataset in memory.
# In order to do so very used keys are taken in memory while the other keys
# In order to do so very used keys are taken in memory while the other keys
...
...
src/Makefile
View file @
c1b27012
...
@@ -5,6 +5,19 @@
...
@@ -5,6 +5,19 @@
release_hdr
:=
$(
shell
sh
-c
'./mkreleasehdr.sh'
)
release_hdr
:=
$(
shell
sh
-c
'./mkreleasehdr.sh'
)
uname_S
:=
$(
shell
sh
-c
'uname -s 2>/dev/null || echo not'
)
uname_S
:=
$(
shell
sh
-c
'uname -s 2>/dev/null || echo not'
)
OPTIMIZATION
?=
-O2
OPTIMIZATION
?=
-O2
CCCOLOR
=
"
\0
33[34m"
LINKCOLOR
=
"
\0
33[34;1m"
SRCCOLOR
=
"
\0
33[33m"
BINCOLOR
=
"
\0
33[37;1m"
MAKECOLOR
=
"
\0
33[32;1m"
ENDCOLOR
=
"
\0
33[0m"
ifndef
V
QUIET_CC
=
@printf
' %b %b\n'
$(CCCOLOR)
CC
$(ENDCOLOR)
$(SRCCOLOR)$@$(ENDCOLOR)
;
QUIET_LINK
=
@printf
' %b %b\n'
$(LINKCOLOR)
LINK
$(ENDCOLOR)
$(BINCOLOR)$@$(ENDCOLOR)
;
endif
ifeq
($(uname_S),SunOS)
ifeq
($(uname_S),SunOS)
CFLAGS
?=
-std
=
c99
-pedantic
$(OPTIMIZATION)
-Wall
-W
-D__EXTENSIONS__
-D_XPG6
CFLAGS
?=
-std
=
c99
-pedantic
$(OPTIMIZATION)
-Wall
-W
-D__EXTENSIONS__
-D_XPG6
CCLINK
?=
-ldl
-lnsl
-lsocket
-lm
-lpthread
CCLINK
?=
-ldl
-lnsl
-lsocket
-lm
-lpthread
...
@@ -111,33 +124,36 @@ zipmap.o: zipmap.c zmalloc.h
...
@@ -111,33 +124,36 @@ zipmap.o: zipmap.c zmalloc.h
zmalloc.o
:
zmalloc.c config.h zmalloc.h
zmalloc.o
:
zmalloc.c config.h zmalloc.h
dependencies
:
dependencies
:
@
printf
'%b %b\n'
$(MAKECOLOR)
MAKE
$(ENDCOLOR)
$(BINCOLOR)
hiredis
$(ENDCOLOR)
cd
../deps/hiredis
&&
$(MAKE)
static
ARCH
=
"
$(ARCH)
"
cd
../deps/hiredis
&&
$(MAKE)
static
ARCH
=
"
$(ARCH)
"
@
printf
'%b %b\n'
$(MAKECOLOR)
MAKE
$(ENDCOLOR)
$(BINCOLOR)
linenoise
$(ENDCOLOR)
cd
../deps/linenoise
&&
$(MAKE)
ARCH
=
"
$(ARCH)
"
cd
../deps/linenoise
&&
$(MAKE)
ARCH
=
"
$(ARCH)
"
redis-server
:
$(OBJ)
redis-server
:
$(OBJ)
$(CC)
-o
$(PRGNAME)
$(CCOPT)
$(DEBUG)
$(OBJ)
$(QUIET_LINK)
$(CC)
-o
$(PRGNAME)
$(CCOPT)
$(DEBUG)
$(OBJ)
redis-benchmark
:
dependencies $(BENCHOBJ)
redis-benchmark
:
dependencies $(BENCHOBJ)
cd
../deps/hiredis
&&
$(MAKE)
static
@
printf
'%b %b\n'
$(MAKECOLOR)
MAKE
$(ENDCOLOR)
$(BINCOLOR)
hiredis
$(ENDCOLOR)
$(CC)
-o
$(BENCHPRGNAME)
$(CCOPT)
$(DEBUG)
$(BENCHOBJ)
../deps/hiredis/libhiredis.a
cd
../deps/hiredis
&&
$(MAKE)
static
ARCH
=
"
$(ARCH)
"
$(QUIET_LINK)$(CC)
-o
$(BENCHPRGNAME)
$(CCOPT)
$(DEBUG)
$(BENCHOBJ)
../deps/hiredis/libhiredis.a
redis-benchmark.o
:
redis-benchmark.o
:
$(CC)
-c
$(CFLAGS)
-I
../deps/hiredis
$(DEBUG)
$(COMPILE_TIME)
$<
$(QUIET_CC)
$(CC)
-c
$(CFLAGS)
-I
../deps/hiredis
$(DEBUG)
$(COMPILE_TIME)
$<
redis-cli
:
dependencies $(CLIOBJ)
redis-cli
:
dependencies $(CLIOBJ)
$(CC)
-o
$(CLIPRGNAME)
$(CCOPT)
$(DEBUG)
$(CLIOBJ)
../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o
$(QUIET_LINK)
$(CC)
-o
$(CLIPRGNAME)
$(CCOPT)
$(DEBUG)
$(CLIOBJ)
../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o
redis-cli.o
:
redis-cli.o
:
$(CC)
-c
$(CFLAGS)
-I
../deps/hiredis
-I
../deps/linenoise
$(DEBUG)
$(COMPILE_TIME)
$<
$(QUIET_CC)
$(CC)
-c
$(CFLAGS)
-I
../deps/hiredis
-I
../deps/linenoise
$(DEBUG)
$(COMPILE_TIME)
$<
redis-check-dump
:
$(CHECKDUMPOBJ)
redis-check-dump
:
$(CHECKDUMPOBJ)
$(CC)
-o
$(CHECKDUMPPRGNAME)
$(CCOPT)
$(DEBUG)
$(CHECKDUMPOBJ)
$(QUIET_LINK)
$(CC)
-o
$(CHECKDUMPPRGNAME)
$(CCOPT)
$(DEBUG)
$(CHECKDUMPOBJ)
redis-check-aof
:
$(CHECKAOFOBJ)
redis-check-aof
:
$(CHECKAOFOBJ)
$(CC)
-o
$(CHECKAOFPRGNAME)
$(CCOPT)
$(DEBUG)
$(CHECKAOFOBJ)
$(QUIET_LINK)
$(CC)
-o
$(CHECKAOFPRGNAME)
$(CCOPT)
$(DEBUG)
$(CHECKAOFOBJ)
.c.o
:
.c.o
:
$(CC)
-c
$(CFLAGS)
$(DEBUG)
$(COMPILE_TIME)
$<
$(QUIET_CC)
$(CC)
-c
$(CFLAGS)
$(DEBUG)
$(COMPILE_TIME)
$<
clean
:
clean
:
rm
-rf
$(PRGNAME)
$(BENCHPRGNAME)
$(CLIPRGNAME)
$(CHECKDUMPPRGNAME)
$(CHECKAOFPRGNAME)
*
.o
*
.gcda
*
.gcno
*
.gcov
rm
-rf
$(PRGNAME)
$(BENCHPRGNAME)
$(CLIPRGNAME)
$(CHECKDUMPPRGNAME)
$(CHECKAOFPRGNAME)
*
.o
*
.gcda
*
.gcno
*
.gcov
...
...
src/aof.c
View file @
c1b27012
...
@@ -19,15 +19,15 @@ void stopAppendOnly(void) {
...
@@ -19,15 +19,15 @@ void stopAppendOnly(void) {
server
.
appendseldb
=
-
1
;
server
.
appendseldb
=
-
1
;
server
.
appendonly
=
0
;
server
.
appendonly
=
0
;
/* rewrite operation in progress? kill it, wait child exit */
/* rewrite operation in progress? kill it, wait child exit */
if
(
server
.
bg
sav
echildpid
!=
-
1
)
{
if
(
server
.
bg
rewrit
echildpid
!=
-
1
)
{
int
statloc
;
int
statloc
;
if
(
kill
(
server
.
bg
sav
echildpid
,
SIGKILL
)
!=
-
1
)
if
(
kill
(
server
.
bg
rewrit
echildpid
,
SIGKILL
)
!=
-
1
)
wait3
(
&
statloc
,
0
,
NULL
);
wait3
(
&
statloc
,
0
,
NULL
);
/* reset the buffer accumulating changes while the child saves */
/* reset the buffer accumulating changes while the child saves */
sdsfree
(
server
.
bgrewritebuf
);
sdsfree
(
server
.
bgrewritebuf
);
server
.
bgrewritebuf
=
sdsempty
();
server
.
bgrewritebuf
=
sdsempty
();
server
.
bg
sav
echildpid
=
-
1
;
server
.
bg
rewrit
echildpid
=
-
1
;
}
}
}
}
...
...
src/config.c
View file @
c1b27012
...
@@ -30,6 +30,7 @@ void loadServerConfig(char *filename) {
...
@@ -30,6 +30,7 @@ void loadServerConfig(char *filename) {
char
buf
[
REDIS_CONFIGLINE_MAX
+
1
],
*
err
=
NULL
;
char
buf
[
REDIS_CONFIGLINE_MAX
+
1
],
*
err
=
NULL
;
int
linenum
=
0
;
int
linenum
=
0
;
sds
line
=
NULL
;
sds
line
=
NULL
;
int
really_use_vm
=
0
;
if
(
filename
[
0
]
==
'-'
&&
filename
[
1
]
==
'\0'
)
if
(
filename
[
0
]
==
'-'
&&
filename
[
1
]
==
'\0'
)
fp
=
stdin
;
fp
=
stdin
;
...
@@ -243,6 +244,10 @@ void loadServerConfig(char *filename) {
...
@@ -243,6 +244,10 @@ void loadServerConfig(char *filename) {
if
((
server
.
vm_enabled
=
yesnotoi
(
argv
[
1
]))
==
-
1
)
{
if
((
server
.
vm_enabled
=
yesnotoi
(
argv
[
1
]))
==
-
1
)
{
err
=
"argument must be 'yes' or 'no'"
;
goto
loaderr
;
err
=
"argument must be 'yes' or 'no'"
;
goto
loaderr
;
}
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"really-use-vm"
)
&&
argc
==
2
)
{
if
((
really_use_vm
=
yesnotoi
(
argv
[
1
]))
==
-
1
)
{
err
=
"argument must be 'yes' or 'no'"
;
goto
loaderr
;
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"vm-swap-file"
)
&&
argc
==
2
)
{
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"vm-swap-file"
)
&&
argc
==
2
)
{
zfree
(
server
.
vm_swap_file
);
zfree
(
server
.
vm_swap_file
);
server
.
vm_swap_file
=
zstrdup
(
argv
[
1
]);
server
.
vm_swap_file
=
zstrdup
(
argv
[
1
]);
...
@@ -303,6 +308,7 @@ void loadServerConfig(char *filename) {
...
@@ -303,6 +308,7 @@ void loadServerConfig(char *filename) {
sdsfree
(
line
);
sdsfree
(
line
);
}
}
if
(
fp
!=
stdin
)
fclose
(
fp
);
if
(
fp
!=
stdin
)
fclose
(
fp
);
if
(
server
.
vm_enabled
&&
!
really_use_vm
)
goto
vm_warning
;
return
;
return
;
loaderr:
loaderr:
...
@@ -311,6 +317,15 @@ loaderr:
...
@@ -311,6 +317,15 @@ loaderr:
fprintf
(
stderr
,
">>> '%s'
\n
"
,
line
);
fprintf
(
stderr
,
">>> '%s'
\n
"
,
line
);
fprintf
(
stderr
,
"%s
\n
"
,
err
);
fprintf
(
stderr
,
"%s
\n
"
,
err
);
exit
(
1
);
exit
(
1
);
vm_warning:
fprintf
(
stderr
,
"
\n
ARE YOU SURE YOU WANT TO USE VM?
\n\n
"
);
fprintf
(
stderr
,
"Redis Virtual Memory is going to be deprecated soon,
\n
"
);
fprintf
(
stderr
,
"we think you should NOT use it, but use Redis only if
\n
"
);
fprintf
(
stderr
,
"your data is suitable for an in-memory database.
\n
"
);
fprintf
(
stderr
,
"If you *really* want VM add this in the config file:
\n
"
);
fprintf
(
stderr
,
"
\n
really-use-vm yes
\n\n
"
);
exit
(
1
);
}
}
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
...
...
src/db.c
View file @
c1b27012
...
@@ -455,6 +455,9 @@ int expireIfNeeded(redisDb *db, robj *key) {
...
@@ -455,6 +455,9 @@ int expireIfNeeded(redisDb *db, robj *key) {
if
(
when
<
0
)
return
0
;
/* No expire for this key */
if
(
when
<
0
)
return
0
;
/* No expire for this key */
/* Don't expire anything while loading. It will be done later. */
if
(
server
.
loading
)
return
0
;
/* If we are running in the context of a slave, return ASAP:
/* If we are running in the context of a slave, return ASAP:
* the slave key expiration is controlled by the master that will
* the slave key expiration is controlled by the master that will
* send us synthesized DEL operations for expired keys.
* send us synthesized DEL operations for expired keys.
...
@@ -492,10 +495,24 @@ void expireGenericCommand(redisClient *c, robj *key, robj *param, long offset) {
...
@@ -492,10 +495,24 @@ void expireGenericCommand(redisClient *c, robj *key, robj *param, long offset) {
addReply
(
c
,
shared
.
czero
);
addReply
(
c
,
shared
.
czero
);
return
;
return
;
}
}
if
(
seconds
<=
0
)
{
/* EXPIRE with negative TTL, or EXPIREAT with a timestamp into the past
if
(
dbDelete
(
c
->
db
,
key
))
server
.
dirty
++
;
* should never be executed as a DEL when load the AOF or in the context
addReply
(
c
,
shared
.
cone
);
* of a slave instance.
*
* Instead we take the other branch of the IF statement setting an expire
* (possibly in the past) and wait for an explicit DEL from the master. */
if
(
seconds
<=
0
&&
!
server
.
loading
&&
!
server
.
masterhost
)
{
robj
*
aux
;
redisAssert
(
dbDelete
(
c
->
db
,
key
));
server
.
dirty
++
;
/* Replicate/AOF this as an explicit DEL. */
aux
=
createStringObject
(
"DEL"
,
3
);
rewriteClientCommandVector
(
c
,
2
,
aux
,
key
);
decrRefCount
(
aux
);
touchWatchedKey
(
c
->
db
,
key
);
touchWatchedKey
(
c
->
db
,
key
);
addReply
(
c
,
shared
.
cone
);
return
;
return
;
}
else
{
}
else
{
time_t
when
=
time
(
NULL
)
+
seconds
;
time_t
when
=
time
(
NULL
)
+
seconds
;
...
...
src/multi.c
View file @
c1b27012
...
@@ -24,14 +24,14 @@ void freeClientMultiState(redisClient *c) {
...
@@ -24,14 +24,14 @@ void freeClientMultiState(redisClient *c) {
}
}
/* Add a new command into the MULTI commands queue */
/* Add a new command into the MULTI commands queue */
void
queueMultiCommand
(
redisClient
*
c
,
struct
redisCommand
*
cmd
)
{
void
queueMultiCommand
(
redisClient
*
c
)
{
multiCmd
*
mc
;
multiCmd
*
mc
;
int
j
;
int
j
;
c
->
mstate
.
commands
=
zrealloc
(
c
->
mstate
.
commands
,
c
->
mstate
.
commands
=
zrealloc
(
c
->
mstate
.
commands
,
sizeof
(
multiCmd
)
*
(
c
->
mstate
.
count
+
1
));
sizeof
(
multiCmd
)
*
(
c
->
mstate
.
count
+
1
));
mc
=
c
->
mstate
.
commands
+
c
->
mstate
.
count
;
mc
=
c
->
mstate
.
commands
+
c
->
mstate
.
count
;
mc
->
cmd
=
cmd
;
mc
->
cmd
=
c
->
cmd
;
mc
->
argc
=
c
->
argc
;
mc
->
argc
=
c
->
argc
;
mc
->
argv
=
zmalloc
(
sizeof
(
robj
*
)
*
c
->
argc
);
mc
->
argv
=
zmalloc
(
sizeof
(
robj
*
)
*
c
->
argc
);
memcpy
(
mc
->
argv
,
c
->
argv
,
sizeof
(
robj
*
)
*
c
->
argc
);
memcpy
(
mc
->
argv
,
c
->
argv
,
sizeof
(
robj
*
)
*
c
->
argc
);
...
@@ -78,6 +78,7 @@ void execCommand(redisClient *c) {
...
@@ -78,6 +78,7 @@ void execCommand(redisClient *c) {
int
j
;
int
j
;
robj
**
orig_argv
;
robj
**
orig_argv
;
int
orig_argc
;
int
orig_argc
;
struct
redisCommand
*
orig_cmd
;
if
(
!
(
c
->
flags
&
REDIS_MULTI
))
{
if
(
!
(
c
->
flags
&
REDIS_MULTI
))
{
addReplyError
(
c
,
"EXEC without MULTI"
);
addReplyError
(
c
,
"EXEC without MULTI"
);
...
@@ -105,18 +106,22 @@ void execCommand(redisClient *c) {
...
@@ -105,18 +106,22 @@ void execCommand(redisClient *c) {
unwatchAllKeys
(
c
);
/* Unwatch ASAP otherwise we'll waste CPU cycles */
unwatchAllKeys
(
c
);
/* Unwatch ASAP otherwise we'll waste CPU cycles */
orig_argv
=
c
->
argv
;
orig_argv
=
c
->
argv
;
orig_argc
=
c
->
argc
;
orig_argc
=
c
->
argc
;
orig_cmd
=
c
->
cmd
;
addReplyMultiBulkLen
(
c
,
c
->
mstate
.
count
);
addReplyMultiBulkLen
(
c
,
c
->
mstate
.
count
);
for
(
j
=
0
;
j
<
c
->
mstate
.
count
;
j
++
)
{
for
(
j
=
0
;
j
<
c
->
mstate
.
count
;
j
++
)
{
c
->
argc
=
c
->
mstate
.
commands
[
j
].
argc
;
c
->
argc
=
c
->
mstate
.
commands
[
j
].
argc
;
c
->
argv
=
c
->
mstate
.
commands
[
j
].
argv
;
c
->
argv
=
c
->
mstate
.
commands
[
j
].
argv
;
call
(
c
,
c
->
mstate
.
commands
[
j
].
cmd
);
c
->
cmd
=
c
->
mstate
.
commands
[
j
].
cmd
;
call
(
c
);
/* Commands may alter argc/argv, restore mstate. */
/* Commands may alter argc/argv, restore mstate. */
c
->
mstate
.
commands
[
j
].
argc
=
c
->
argc
;
c
->
mstate
.
commands
[
j
].
argc
=
c
->
argc
;
c
->
mstate
.
commands
[
j
].
argv
=
c
->
argv
;
c
->
mstate
.
commands
[
j
].
argv
=
c
->
argv
;
c
->
mstate
.
commands
[
j
].
cmd
=
c
->
cmd
;
}
}
c
->
argv
=
orig_argv
;
c
->
argv
=
orig_argv
;
c
->
argc
=
orig_argc
;
c
->
argc
=
orig_argc
;
c
->
cmd
=
orig_cmd
;
freeClientMultiState
(
c
);
freeClientMultiState
(
c
);
initClientMultiState
(
c
);
initClientMultiState
(
c
);
c
->
flags
&=
~
(
REDIS_MULTI
|
REDIS_DIRTY_CAS
);
c
->
flags
&=
~
(
REDIS_MULTI
|
REDIS_DIRTY_CAS
);
...
...
src/networking.c
View file @
c1b27012
...
@@ -31,6 +31,7 @@ redisClient *createClient(int fd) {
...
@@ -31,6 +31,7 @@ redisClient *createClient(int fd) {
c
->
reqtype
=
0
;
c
->
reqtype
=
0
;
c
->
argc
=
0
;
c
->
argc
=
0
;
c
->
argv
=
NULL
;
c
->
argv
=
NULL
;
c
->
cmd
=
NULL
;
c
->
multibulklen
=
0
;
c
->
multibulklen
=
0
;
c
->
bulklen
=
-
1
;
c
->
bulklen
=
-
1
;
c
->
sentlen
=
0
;
c
->
sentlen
=
0
;
...
@@ -444,6 +445,7 @@ static void freeClientArgv(redisClient *c) {
...
@@ -444,6 +445,7 @@ static void freeClientArgv(redisClient *c) {
for
(
j
=
0
;
j
<
c
->
argc
;
j
++
)
for
(
j
=
0
;
j
<
c
->
argc
;
j
++
)
decrRefCount
(
c
->
argv
[
j
]);
decrRefCount
(
c
->
argv
[
j
]);
c
->
argc
=
0
;
c
->
argc
=
0
;
c
->
cmd
=
NULL
;
}
}
void
freeClient
(
redisClient
*
c
)
{
void
freeClient
(
redisClient
*
c
)
{
...
@@ -896,4 +898,3 @@ void rewriteClientCommandVector(redisClient *c, int argc, ...) {
...
@@ -896,4 +898,3 @@ void rewriteClientCommandVector(redisClient *c, int argc, ...) {
c
->
argc
=
argc
;
c
->
argc
=
argc
;
va_end
(
ap
);
va_end
(
ap
);
}
}
src/redis.c
View file @
c1b27012
...
@@ -677,7 +677,7 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
...
@@ -677,7 +677,7 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
readQueryFromClient
,
c
);
readQueryFromClient
,
c
);
cmd
=
lookupCommand
(
c
->
argv
[
0
]
->
ptr
);
cmd
=
lookupCommand
(
c
->
argv
[
0
]
->
ptr
);
redisAssert
(
cmd
!=
NULL
);
redisAssert
(
cmd
!=
NULL
);
call
(
c
,
cmd
);
call
(
c
);
resetClient
(
c
);
resetClient
(
c
);
/* There may be more data to process in the input buffer. */
/* There may be more data to process in the input buffer. */
if
(
c
->
querybuf
&&
sdslen
(
c
->
querybuf
)
>
0
)
if
(
c
->
querybuf
&&
sdslen
(
c
->
querybuf
)
>
0
)
...
@@ -958,18 +958,18 @@ struct redisCommand *lookupCommandByCString(char *s) {
...
@@ -958,18 +958,18 @@ struct redisCommand *lookupCommandByCString(char *s) {
}
}
/* Call() is the core of Redis execution of a command */
/* Call() is the core of Redis execution of a command */
void
call
(
redisClient
*
c
,
struct
redisCommand
*
cmd
)
{
void
call
(
redisClient
*
c
)
{
long
long
dirty
,
start
=
ustime
(),
duration
;
long
long
dirty
,
start
=
ustime
(),
duration
;
dirty
=
server
.
dirty
;
dirty
=
server
.
dirty
;
cmd
->
proc
(
c
);
c
->
cmd
->
proc
(
c
);
dirty
=
server
.
dirty
-
dirty
;
dirty
=
server
.
dirty
-
dirty
;
duration
=
ustime
()
-
start
;
duration
=
ustime
()
-
start
;
slowlogPushEntryIfNeeded
(
c
->
argv
,
c
->
argc
,
duration
);
slowlogPushEntryIfNeeded
(
c
->
argv
,
c
->
argc
,
duration
);
if
(
server
.
appendonly
&&
dirty
)
if
(
server
.
appendonly
&&
dirty
)
feedAppendOnlyFile
(
cmd
,
c
->
db
->
id
,
c
->
argv
,
c
->
argc
);
feedAppendOnlyFile
(
c
->
cmd
,
c
->
db
->
id
,
c
->
argv
,
c
->
argc
);
if
((
dirty
||
cmd
->
flags
&
REDIS_CMD_FORCE_REPLICATION
)
&&
if
((
dirty
||
c
->
cmd
->
flags
&
REDIS_CMD_FORCE_REPLICATION
)
&&
listLength
(
server
.
slaves
))
listLength
(
server
.
slaves
))
replicationFeedSlaves
(
server
.
slaves
,
c
->
db
->
id
,
c
->
argv
,
c
->
argc
);
replicationFeedSlaves
(
server
.
slaves
,
c
->
db
->
id
,
c
->
argv
,
c
->
argc
);
if
(
listLength
(
server
.
monitors
))
if
(
listLength
(
server
.
monitors
))
...
@@ -986,8 +986,6 @@ void call(redisClient *c, struct redisCommand *cmd) {
...
@@ -986,8 +986,6 @@ void call(redisClient *c, struct redisCommand *cmd) {
* and other operations can be performed by the caller. Otherwise
* and other operations can be performed by the caller. Otherwise
* if 0 is returned the client was destroied (i.e. after QUIT). */
* if 0 is returned the client was destroied (i.e. after QUIT). */
int
processCommand
(
redisClient
*
c
)
{
int
processCommand
(
redisClient
*
c
)
{
struct
redisCommand
*
cmd
;
/* The QUIT command is handled separately. Normal command procs will
/* The QUIT command is handled separately. Normal command procs will
* go through checking for replication and QUIT will cause trouble
* go through checking for replication and QUIT will cause trouble
* when FORCE_REPLICATION is enabled and would be implemented in
* when FORCE_REPLICATION is enabled and would be implemented in
...
@@ -999,21 +997,22 @@ int processCommand(redisClient *c) {
...
@@ -999,21 +997,22 @@ int processCommand(redisClient *c) {
}
}
/* Now lookup the command and check ASAP about trivial error conditions
/* Now lookup the command and check ASAP about trivial error conditions
* such wrong arity, bad command name and so forth. */
* such
as
wrong arity, bad command name and so forth. */
cmd
=
lookupCommand
(
c
->
argv
[
0
]
->
ptr
);
c
->
cmd
=
lookupCommand
(
c
->
argv
[
0
]
->
ptr
);
if
(
!
cmd
)
{
if
(
!
c
->
cmd
)
{
addReplyErrorFormat
(
c
,
"unknown command '%s'"
,
addReplyErrorFormat
(
c
,
"unknown command '%s'"
,
(
char
*
)
c
->
argv
[
0
]
->
ptr
);
(
char
*
)
c
->
argv
[
0
]
->
ptr
);
return
REDIS_OK
;
return
REDIS_OK
;
}
else
if
((
cmd
->
arity
>
0
&&
cmd
->
arity
!=
c
->
argc
)
||
}
else
if
((
c
->
cmd
->
arity
>
0
&&
c
->
cmd
->
arity
!=
c
->
argc
)
||
(
c
->
argc
<
-
cmd
->
arity
))
{
(
c
->
argc
<
-
c
->
cmd
->
arity
))
{
addReplyErrorFormat
(
c
,
"wrong number of arguments for '%s' command"
,
addReplyErrorFormat
(
c
,
"wrong number of arguments for '%s' command"
,
cmd
->
name
);
c
->
cmd
->
name
);
return
REDIS_OK
;
return
REDIS_OK
;
}
}
/* Check if the user is authenticated */
/* Check if the user is authenticated */
if
(
server
.
requirepass
&&
!
c
->
authenticated
&&
cmd
->
proc
!=
authCommand
)
{
if
(
server
.
requirepass
&&
!
c
->
authenticated
&&
c
->
cmd
->
proc
!=
authCommand
)
{
addReplyError
(
c
,
"operation not permitted"
);
addReplyError
(
c
,
"operation not permitted"
);
return
REDIS_OK
;
return
REDIS_OK
;
}
}
...
@@ -1024,7 +1023,7 @@ int processCommand(redisClient *c) {
...
@@ -1024,7 +1023,7 @@ int processCommand(redisClient *c) {
* keys in the dataset). If there are not the only thing we can do
* keys in the dataset). If there are not the only thing we can do
* is returning an error. */
* is returning an error. */
if
(
server
.
maxmemory
)
freeMemoryIfNeeded
();
if
(
server
.
maxmemory
)
freeMemoryIfNeeded
();
if
(
server
.
maxmemory
&&
(
cmd
->
flags
&
REDIS_CMD_DENYOOM
)
&&
if
(
server
.
maxmemory
&&
(
c
->
cmd
->
flags
&
REDIS_CMD_DENYOOM
)
&&
zmalloc_used_memory
()
>
server
.
maxmemory
)
zmalloc_used_memory
()
>
server
.
maxmemory
)
{
{
addReplyError
(
c
,
"command not allowed when used memory > 'maxmemory'"
);
addReplyError
(
c
,
"command not allowed when used memory > 'maxmemory'"
);
...
@@ -1034,8 +1033,10 @@ int processCommand(redisClient *c) {
...
@@ -1034,8 +1033,10 @@ int processCommand(redisClient *c) {
/* Only allow SUBSCRIBE and UNSUBSCRIBE in the context of Pub/Sub */
/* Only allow SUBSCRIBE and UNSUBSCRIBE in the context of Pub/Sub */
if
((
dictSize
(
c
->
pubsub_channels
)
>
0
||
listLength
(
c
->
pubsub_patterns
)
>
0
)
if
((
dictSize
(
c
->
pubsub_channels
)
>
0
||
listLength
(
c
->
pubsub_patterns
)
>
0
)
&&
&&
cmd
->
proc
!=
subscribeCommand
&&
cmd
->
proc
!=
unsubscribeCommand
&&
c
->
cmd
->
proc
!=
subscribeCommand
&&
cmd
->
proc
!=
psubscribeCommand
&&
cmd
->
proc
!=
punsubscribeCommand
)
{
c
->
cmd
->
proc
!=
unsubscribeCommand
&&
c
->
cmd
->
proc
!=
psubscribeCommand
&&
c
->
cmd
->
proc
!=
punsubscribeCommand
)
{
addReplyError
(
c
,
"only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context"
);
addReplyError
(
c
,
"only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context"
);
return
REDIS_OK
;
return
REDIS_OK
;
}
}
...
@@ -1044,7 +1045,7 @@ int processCommand(redisClient *c) {
...
@@ -1044,7 +1045,7 @@ int processCommand(redisClient *c) {
* we are a slave with a broken link with master. */
* we are a slave with a broken link with master. */
if
(
server
.
masterhost
&&
server
.
replstate
!=
REDIS_REPL_CONNECTED
&&
if
(
server
.
masterhost
&&
server
.
replstate
!=
REDIS_REPL_CONNECTED
&&
server
.
repl_serve_stale_data
==
0
&&
server
.
repl_serve_stale_data
==
0
&&
cmd
->
proc
!=
infoCommand
&&
cmd
->
proc
!=
slaveofCommand
)
c
->
cmd
->
proc
!=
infoCommand
&&
c
->
cmd
->
proc
!=
slaveofCommand
)
{
{
addReplyError
(
c
,
addReplyError
(
c
,
"link with MASTER is down and slave-serve-stale-data is set to no"
);
"link with MASTER is down and slave-serve-stale-data is set to no"
);
...
@@ -1052,22 +1053,22 @@ int processCommand(redisClient *c) {
...
@@ -1052,22 +1053,22 @@ int processCommand(redisClient *c) {
}
}
/* Loading DB? Return an error if the command is not INFO */
/* Loading DB? Return an error if the command is not INFO */
if
(
server
.
loading
&&
cmd
->
proc
!=
infoCommand
)
{
if
(
server
.
loading
&&
c
->
cmd
->
proc
!=
infoCommand
)
{
addReply
(
c
,
shared
.
loadingerr
);
addReply
(
c
,
shared
.
loadingerr
);
return
REDIS_OK
;
return
REDIS_OK
;
}
}
/* Exec the command */
/* Exec the command */
if
(
c
->
flags
&
REDIS_MULTI
&&
if
(
c
->
flags
&
REDIS_MULTI
&&
cmd
->
proc
!=
execCommand
&&
cmd
->
proc
!=
discardCommand
&&
c
->
cmd
->
proc
!=
execCommand
&&
c
->
cmd
->
proc
!=
discardCommand
&&
cmd
->
proc
!=
multiCommand
&&
cmd
->
proc
!=
watchCommand
)
c
->
cmd
->
proc
!=
multiCommand
&&
c
->
cmd
->
proc
!=
watchCommand
)
{
{
queueMultiCommand
(
c
,
cmd
);
queueMultiCommand
(
c
);
addReply
(
c
,
shared
.
queued
);
addReply
(
c
,
shared
.
queued
);
}
else
{
}
else
{
if
(
server
.
vm_enabled
&&
server
.
vm_max_threads
>
0
&&
if
(
server
.
vm_enabled
&&
server
.
vm_max_threads
>
0
&&
blockClientOnSwappedKeys
(
c
,
cmd
))
return
REDIS_ERR
;
blockClientOnSwappedKeys
(
c
))
return
REDIS_ERR
;
call
(
c
,
cmd
);
call
(
c
);
}
}
return
REDIS_OK
;
return
REDIS_OK
;
}
}
...
@@ -1075,20 +1076,29 @@ int processCommand(redisClient *c) {
...
@@ -1075,20 +1076,29 @@ int processCommand(redisClient *c) {
/*================================== Shutdown =============================== */
/*================================== Shutdown =============================== */
int
prepareForShutdown
()
{
int
prepareForShutdown
()
{
redisLog
(
REDIS_WARNING
,
"User requested shutdown
, saving DB
..."
);
redisLog
(
REDIS_WARNING
,
"User requested shutdown..."
);
/* Kill the saving child if there is a background saving in progress.
/* Kill the saving child if there is a background saving in progress.
We want to avoid race conditions, for instance our saving child may
We want to avoid race conditions, for instance our saving child may
overwrite the synchronous saving did by SHUTDOWN. */
overwrite the synchronous saving did by SHUTDOWN. */
if
(
server
.
bgsavechildpid
!=
-
1
)
{
if
(
server
.
bgsavechildpid
!=
-
1
)
{
redisLog
(
REDIS_WARNING
,
"There is a
live
saving
child
. Killing it!"
);
redisLog
(
REDIS_WARNING
,
"There is a
child
saving
an .rdb
. Killing it!"
);
kill
(
server
.
bgsavechildpid
,
SIGKILL
);
kill
(
server
.
bgsavechildpid
,
SIGKILL
);
rdbRemoveTempFile
(
server
.
bgsavechildpid
);
rdbRemoveTempFile
(
server
.
bgsavechildpid
);
}
}
if
(
server
.
appendonly
)
{
if
(
server
.
appendonly
)
{
/* Kill the AOF saving child as the AOF we already have may be longer
* but contains the full dataset anyway. */
if
(
server
.
bgrewritechildpid
!=
-
1
)
{
redisLog
(
REDIS_WARNING
,
"There is a child rewriting the AOF. Killing it!"
);
kill
(
server
.
bgrewritechildpid
,
SIGKILL
);
}
/* Append only file: fsync() the AOF and exit */
/* Append only file: fsync() the AOF and exit */
redisLog
(
REDIS_NOTICE
,
"Calling fsync() on the AOF file."
);
aof_fsync
(
server
.
appendfd
);
aof_fsync
(
server
.
appendfd
);
if
(
server
.
vm_enabled
)
unlink
(
server
.
vm_swap_file
);
}
}
else
if
(
server
.
saveparamslen
>
0
)
{
if
(
server
.
saveparamslen
>
0
)
{
redisLog
(
REDIS_NOTICE
,
"Saving the final RDB snapshot before exiting."
);
/* Snapshotting. Perform a SYNC SAVE and exit */
/* Snapshotting. Perform a SYNC SAVE and exit */
if
(
rdbSave
(
server
.
dbfilename
)
!=
REDIS_OK
)
{
if
(
rdbSave
(
server
.
dbfilename
)
!=
REDIS_OK
)
{
/* Ooops.. error saving! The best we can do is to continue
/* Ooops.. error saving! The best we can do is to continue
...
@@ -1096,14 +1106,23 @@ int prepareForShutdown() {
...
@@ -1096,14 +1106,23 @@ int prepareForShutdown() {
* in the next cron() Redis will be notified that the background
* in the next cron() Redis will be notified that the background
* saving aborted, handling special stuff like slaves pending for
* saving aborted, handling special stuff like slaves pending for
* synchronization... */
* synchronization... */
redisLog
(
REDIS_WARNING
,
"Error trying to save the DB, can't exit"
);
redisLog
(
REDIS_WARNING
,
"Error trying to save the DB, can't exit
.
"
);
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
}
else
{
redisLog
(
REDIS_WARNING
,
"Not saving DB."
);
}
}
if
(
server
.
daemonize
)
unlink
(
server
.
pidfile
);
if
(
server
.
vm_enabled
)
{
redisLog
(
REDIS_WARNING
,
"Server exit now, bye bye..."
);
redisLog
(
REDIS_NOTICE
,
"Removing the swap file."
);
unlink
(
server
.
vm_swap_file
);
}
if
(
server
.
daemonize
)
{
redisLog
(
REDIS_NOTICE
,
"Removing the pid file."
);
unlink
(
server
.
pidfile
);
}
/* Close the listening sockets. Apparently this allows faster restarts. */
if
(
server
.
ipfd
!=
-
1
)
close
(
server
.
ipfd
);
if
(
server
.
sofd
!=
-
1
)
close
(
server
.
sofd
);
redisLog
(
REDIS_WARNING
,
"Redis is now ready to exit, bye bye..."
);
return
REDIS_OK
;
return
REDIS_OK
;
}
}
...
@@ -1176,8 +1195,8 @@ sds genRedisInfoString(void) {
...
@@ -1176,8 +1195,8 @@ sds genRedisInfoString(void) {
"lru_clock:%ld
\r\n
"
"lru_clock:%ld
\r\n
"
"used_cpu_sys:%.2f
\r\n
"
"used_cpu_sys:%.2f
\r\n
"
"used_cpu_user:%.2f
\r\n
"
"used_cpu_user:%.2f
\r\n
"
"used_cpu_sys_children
s
:%.2f
\r\n
"
"used_cpu_sys_children:%.2f
\r\n
"
"used_cpu_user_children
s
:%.2f
\r\n
"
"used_cpu_user_children:%.2f
\r\n
"
"connected_clients:%d
\r\n
"
"connected_clients:%d
\r\n
"
"connected_slaves:%d
\r\n
"
"connected_slaves:%d
\r\n
"
"client_longest_output_list:%lu
\r\n
"
"client_longest_output_list:%lu
\r\n
"
...
@@ -1335,18 +1354,6 @@ sds genRedisInfoString(void) {
...
@@ -1335,18 +1354,6 @@ sds genRedisInfoString(void) {
);
);
}
}
info
=
sdscat
(
info
,
"allocation_stats:"
);
for
(
j
=
0
;
j
<=
ZMALLOC_MAX_ALLOC_STAT
;
j
++
)
{
size_t
count
=
zmalloc_allocations_for_size
(
j
);
if
(
count
)
{
if
(
info
[
sdslen
(
info
)
-
1
]
!=
':'
)
info
=
sdscatlen
(
info
,
","
,
1
);
info
=
sdscatprintf
(
info
,
"%s%d=%zu"
,
(
j
==
ZMALLOC_MAX_ALLOC_STAT
)
?
">="
:
""
,
j
,
count
);
}
}
info
=
sdscat
(
info
,
"
\r\n
"
);
for
(
j
=
0
;
j
<
server
.
dbnum
;
j
++
)
{
for
(
j
=
0
;
j
<
server
.
dbnum
;
j
++
)
{
long
long
keys
,
vkeys
;
long
long
keys
,
vkeys
;
...
...
src/redis.h
View file @
c1b27012
...
@@ -314,6 +314,7 @@ typedef struct redisClient {
...
@@ -314,6 +314,7 @@ typedef struct redisClient {
sds
querybuf
;
sds
querybuf
;
int
argc
;
int
argc
;
robj
**
argv
;
robj
**
argv
;
struct
redisCommand
*
cmd
;
int
reqtype
;
int
reqtype
;
int
multibulklen
;
/* number of multi bulk arguments left to read */
int
multibulklen
;
/* number of multi bulk arguments left to read */
long
bulklen
;
/* length of bulk argument in multi bulk request */
long
bulklen
;
/* length of bulk argument in multi bulk request */
...
@@ -700,7 +701,7 @@ void popGenericCommand(redisClient *c, int where);
...
@@ -700,7 +701,7 @@ void popGenericCommand(redisClient *c, int where);
void
unwatchAllKeys
(
redisClient
*
c
);
void
unwatchAllKeys
(
redisClient
*
c
);
void
initClientMultiState
(
redisClient
*
c
);
void
initClientMultiState
(
redisClient
*
c
);
void
freeClientMultiState
(
redisClient
*
c
);
void
freeClientMultiState
(
redisClient
*
c
);
void
queueMultiCommand
(
redisClient
*
c
,
struct
redisCommand
*
cmd
);
void
queueMultiCommand
(
redisClient
*
c
);
void
touchWatchedKey
(
redisDb
*
db
,
robj
*
key
);
void
touchWatchedKey
(
redisDb
*
db
,
robj
*
key
);
void
touchWatchedKeysOnFlush
(
int
dbid
);
void
touchWatchedKeysOnFlush
(
int
dbid
);
...
@@ -788,7 +789,7 @@ int processCommand(redisClient *c);
...
@@ -788,7 +789,7 @@ int processCommand(redisClient *c);
void
setupSignalHandlers
(
void
);
void
setupSignalHandlers
(
void
);
struct
redisCommand
*
lookupCommand
(
sds
name
);
struct
redisCommand
*
lookupCommand
(
sds
name
);
struct
redisCommand
*
lookupCommandByCString
(
char
*
s
);
struct
redisCommand
*
lookupCommandByCString
(
char
*
s
);
void
call
(
redisClient
*
c
,
struct
redisCommand
*
cmd
);
void
call
(
redisClient
*
c
);
int
prepareForShutdown
();
int
prepareForShutdown
();
void
redisLog
(
int
level
,
const
char
*
fmt
,
...);
void
redisLog
(
int
level
,
const
char
*
fmt
,
...);
void
usage
();
void
usage
();
...
@@ -819,7 +820,7 @@ void vmReopenSwapFile(void);
...
@@ -819,7 +820,7 @@ void vmReopenSwapFile(void);
int
vmFreePage
(
off_t
page
);
int
vmFreePage
(
off_t
page
);
void
zunionInterBlockClientOnSwappedKeys
(
redisClient
*
c
,
struct
redisCommand
*
cmd
,
int
argc
,
robj
**
argv
);
void
zunionInterBlockClientOnSwappedKeys
(
redisClient
*
c
,
struct
redisCommand
*
cmd
,
int
argc
,
robj
**
argv
);
void
execBlockClientOnSwappedKeys
(
redisClient
*
c
,
struct
redisCommand
*
cmd
,
int
argc
,
robj
**
argv
);
void
execBlockClientOnSwappedKeys
(
redisClient
*
c
,
struct
redisCommand
*
cmd
,
int
argc
,
robj
**
argv
);
int
blockClientOnSwappedKeys
(
redisClient
*
c
,
struct
redisCommand
*
cmd
);
int
blockClientOnSwappedKeys
(
redisClient
*
c
);
int
dontWaitForSwappedKey
(
redisClient
*
c
,
robj
*
key
);
int
dontWaitForSwappedKey
(
redisClient
*
c
,
robj
*
key
);
void
handleClientsBlockedOnSwappedKey
(
redisDb
*
db
,
robj
*
key
);
void
handleClientsBlockedOnSwappedKey
(
redisDb
*
db
,
robj
*
key
);
vmpointer
*
vmSwapObjectBlocking
(
robj
*
val
);
vmpointer
*
vmSwapObjectBlocking
(
robj
*
val
);
...
...
src/t_list.c
View file @
c1b27012
...
@@ -904,6 +904,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
...
@@ -904,6 +904,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
if
(
listTypeLength
(
o
)
!=
0
)
{
if
(
listTypeLength
(
o
)
!=
0
)
{
/* If the list contains elements fall back to the usual
/* If the list contains elements fall back to the usual
* non-blocking POP operation */
* non-blocking POP operation */
struct
redisCommand
*
orig_cmd
;
robj
*
argv
[
2
],
**
orig_argv
;
robj
*
argv
[
2
],
**
orig_argv
;
int
orig_argc
;
int
orig_argc
;
...
@@ -911,6 +912,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
...
@@ -911,6 +912,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
* popGenericCommand() as the command takes a single key. */
* popGenericCommand() as the command takes a single key. */
orig_argv
=
c
->
argv
;
orig_argv
=
c
->
argv
;
orig_argc
=
c
->
argc
;
orig_argc
=
c
->
argc
;
orig_cmd
=
c
->
cmd
;
argv
[
1
]
=
c
->
argv
[
j
];
argv
[
1
]
=
c
->
argv
[
j
];
c
->
argv
=
argv
;
c
->
argv
=
argv
;
c
->
argc
=
2
;
c
->
argc
=
2
;
...
@@ -928,6 +930,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
...
@@ -928,6 +930,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
/* Fix the client structure with the original stuff */
/* Fix the client structure with the original stuff */
c
->
argv
=
orig_argv
;
c
->
argv
=
orig_argv
;
c
->
argc
=
orig_argc
;
c
->
argc
=
orig_argc
;
c
->
cmd
=
orig_cmd
;
return
;
return
;
}
}
...
...
src/version.h
View file @
c1b27012
#define REDIS_VERSION "2.2.1
1
"
#define REDIS_VERSION "2.2.1
2
"
src/vm.c
View file @
c1b27012
...
@@ -1064,11 +1064,11 @@ void execBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int
...
@@ -1064,11 +1064,11 @@ void execBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int
*
*
* Return 1 if the client is marked as blocked, 0 if the client can
* Return 1 if the client is marked as blocked, 0 if the client can
* continue as the keys it is going to access appear to be in memory. */
* continue as the keys it is going to access appear to be in memory. */
int
blockClientOnSwappedKeys
(
redisClient
*
c
,
struct
redisCommand
*
cmd
)
{
int
blockClientOnSwappedKeys
(
redisClient
*
c
)
{
if
(
cmd
->
vm_preload_proc
!=
NULL
)
{
if
(
c
->
cmd
->
vm_preload_proc
!=
NULL
)
{
cmd
->
vm_preload_proc
(
c
,
cmd
,
c
->
argc
,
c
->
argv
);
c
->
cmd
->
vm_preload_proc
(
c
,
c
->
cmd
,
c
->
argc
,
c
->
argv
);
}
else
{
}
else
{
waitForMultipleSwappedKeys
(
c
,
cmd
,
c
->
argc
,
c
->
argv
);
waitForMultipleSwappedKeys
(
c
,
c
->
cmd
,
c
->
argc
,
c
->
argv
);
}
}
/* If the client was blocked for at least one key, mark it as blocked. */
/* If the client was blocked for at least one key, mark it as blocked. */
...
...
src/zmalloc.c
View file @
c1b27012
...
@@ -55,16 +55,13 @@
...
@@ -55,16 +55,13 @@
#define update_zmalloc_stat_alloc(__n,__size) do { \
#define update_zmalloc_stat_alloc(__n,__size) do { \
size_t _n = (__n); \
size_t _n = (__n); \
size_t _stat_slot = (__size < ZMALLOC_MAX_ALLOC_STAT) ? __size : ZMALLOC_MAX_ALLOC_STAT; \
if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
if (zmalloc_thread_safe) { \
if (zmalloc_thread_safe) { \
pthread_mutex_lock(&used_memory_mutex); \
pthread_mutex_lock(&used_memory_mutex); \
used_memory += _n; \
used_memory += _n; \
zmalloc_allocations[_stat_slot]++; \
pthread_mutex_unlock(&used_memory_mutex); \
pthread_mutex_unlock(&used_memory_mutex); \
} else { \
} else { \
used_memory += _n; \
used_memory += _n; \
zmalloc_allocations[_stat_slot]++; \
} \
} \
} while(0)
} while(0)
...
@@ -83,8 +80,6 @@
...
@@ -83,8 +80,6 @@
static
size_t
used_memory
=
0
;
static
size_t
used_memory
=
0
;
static
int
zmalloc_thread_safe
=
0
;
static
int
zmalloc_thread_safe
=
0
;
pthread_mutex_t
used_memory_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
pthread_mutex_t
used_memory_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
/* Note that malloc_allocations elements are initialized to zero by C */
size_t
zmalloc_allocations
[
ZMALLOC_MAX_ALLOC_STAT
+
1
];
static
void
zmalloc_oom
(
size_t
size
)
{
static
void
zmalloc_oom
(
size_t
size
)
{
fprintf
(
stderr
,
"zmalloc: Out of memory trying to allocate %zu bytes
\n
"
,
fprintf
(
stderr
,
"zmalloc: Out of memory trying to allocate %zu bytes
\n
"
,
...
@@ -185,11 +180,6 @@ size_t zmalloc_used_memory(void) {
...
@@ -185,11 +180,6 @@ size_t zmalloc_used_memory(void) {
return
um
;
return
um
;
}
}
size_t
zmalloc_allocations_for_size
(
size_t
size
)
{
if
(
size
>
ZMALLOC_MAX_ALLOC_STAT
)
return
0
;
return
zmalloc_allocations
[
size
];
}
void
zmalloc_enable_thread_safeness
(
void
)
{
void
zmalloc_enable_thread_safeness
(
void
)
{
zmalloc_thread_safe
=
1
;
zmalloc_thread_safe
=
1
;
}
}
...
...
src/zmalloc.h
View file @
c1b27012
...
@@ -40,8 +40,5 @@ size_t zmalloc_used_memory(void);
...
@@ -40,8 +40,5 @@ size_t zmalloc_used_memory(void);
void
zmalloc_enable_thread_safeness
(
void
);
void
zmalloc_enable_thread_safeness
(
void
);
float
zmalloc_get_fragmentation_ratio
(
void
);
float
zmalloc_get_fragmentation_ratio
(
void
);
size_t
zmalloc_get_rss
(
void
);
size_t
zmalloc_get_rss
(
void
);
size_t
zmalloc_allocations_for_size
(
size_t
size
);
#define ZMALLOC_MAX_ALLOC_STAT 256
#endif
/* _ZMALLOC_H */
#endif
/* _ZMALLOC_H */
tests/integration/aof.tcl
View file @
c1b27012
...
@@ -101,4 +101,22 @@ tags {"aof"} {
...
@@ -101,4 +101,22 @@ tags {"aof"} {
assert_equal 1
[
$client
scard set
]
assert_equal 1
[
$client
scard set
]
}
}
}
}
## Test that EXPIREAT is loaded correctly
create_aof
{
append_to_aof
[
formatCommand rpush list foo
]
append_to_aof
[
formatCommand expireat list 1000
]
append_to_aof
[
formatCommand rpush list bar
]
}
start_server_aof
[
list dir $server_path
]
{
test
"AOF+EXPIRE: Server should have been started"
{
assert_equal 1
[
is_alive $srv
]
}
test
"AOF+EXPIRE: List should be empty"
{
set client
[
redis
[
dict get $srv host
]
[
dict get $srv port
]]
assert_equal 0
[
$client
llen list
]
}
}
}
}
tests/test_helper.tcl
View file @
c1b27012
...
@@ -128,7 +128,7 @@ proc execute_everything {} {
...
@@ -128,7 +128,7 @@ proc execute_everything {} {
execute_tests
"unit/slowlog"
execute_tests
"unit/slowlog"
# run tests with VM enabled
# run tests with VM enabled
set ::global_overrides
{
vm-enabled yes
}
set ::global_overrides
{
vm-enabled
yes really-use-vm
yes
}
execute_tests
"unit/protocol"
execute_tests
"unit/protocol"
execute_tests
"unit/basic"
execute_tests
"unit/basic"
execute_tests
"unit/type/list"
execute_tests
"unit/type/list"
...
...
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