Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
61751a4d
Commit
61751a4d
authored
Jun 10, 2011
by
antirez
Browse files
AOF auto rewrite backported to 2.4
parent
4dfecf64
Changes
6
Hide whitespace changes
Inline
Side-by-side
redis.conf
View file @
61751a4d
...
@@ -292,6 +292,26 @@ appendfsync everysec
...
@@ -292,6 +292,26 @@ appendfsync everysec
# "no" that is the safest pick from the point of view of durability.
# "no" that is the safest pick from the point of view of durability.
no
-
appendfsync
-
on
-
rewrite
no
no
-
appendfsync
-
on
-
rewrite
no
# Automatic rewrite of the append only file.
# Redis is able to automatically rewrite the log file implicitly calling
# BGREWRITEAOF when the AOF log size will growth by the specified percentage.
#
# This is how it works: Redis remembers the size of the AOF file after the
# latest rewrite (or if no rewrite happened since the restart, the size of
# the AOF at startup is used).
#
# This base size is compared to the current size. If the current size is
# bigger than the specified percentage, the rewrite is triggered. Also
# you need to specify a minimal size for the AOF file to be rewritten, this
# is useful to avoid rewriting the AOF file even if the percentage increase
# is reached but it is still pretty small.
#
# Specify a precentage of zero in order to disable the automatic AOF
# rewrite feature.
auto
-
aof
-
rewrite
-
percentage
100
auto
-
aof
-
rewrite
-
min
-
size
64
mb
################################ VIRTUAL MEMORY ###############################
################################ VIRTUAL MEMORY ###############################
### WARNING! Virtual Memory is deprecated in Redis 2.4
### WARNING! Virtual Memory is deprecated in Redis 2.4
...
...
src/aof.c
View file @
61751a4d
...
@@ -8,6 +8,8 @@
...
@@ -8,6 +8,8 @@
#include <sys/resource.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <sys/wait.h>
void
aofUpdateCurrentSize
(
void
);
/* Called when the user switches from "appendonly yes" to "appendonly no"
/* Called when the user switches from "appendonly yes" to "appendonly no"
* at runtime using the CONFIG command. */
* at runtime using the CONFIG command. */
void
stopAppendOnly
(
void
)
{
void
stopAppendOnly
(
void
)
{
...
@@ -19,15 +21,15 @@ void stopAppendOnly(void) {
...
@@ -19,15 +21,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
;
}
}
}
}
...
@@ -82,6 +84,7 @@ void flushAppendOnlyFile(void) {
...
@@ -82,6 +84,7 @@ void flushAppendOnlyFile(void) {
}
}
sdsfree
(
server
.
aofbuf
);
sdsfree
(
server
.
aofbuf
);
server
.
aofbuf
=
sdsempty
();
server
.
aofbuf
=
sdsempty
();
server
.
appendonly_current_size
+=
nwritten
;
/* Don't Fsync if no-appendfsync-on-rewrite is set to yes and we have
/* Don't Fsync if no-appendfsync-on-rewrite is set to yes and we have
* childs performing heavy I/O on disk. */
* childs performing heavy I/O on disk. */
...
@@ -221,6 +224,7 @@ int loadAppendOnlyFile(char *filename) {
...
@@ -221,6 +224,7 @@ int loadAppendOnlyFile(char *filename) {
long
loops
=
0
;
long
loops
=
0
;
if
(
fp
&&
redis_fstat
(
fileno
(
fp
),
&
sb
)
!=
-
1
&&
sb
.
st_size
==
0
)
{
if
(
fp
&&
redis_fstat
(
fileno
(
fp
),
&
sb
)
!=
-
1
&&
sb
.
st_size
==
0
)
{
server
.
appendonly_current_size
=
0
;
fclose
(
fp
);
fclose
(
fp
);
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
...
@@ -311,6 +315,8 @@ int loadAppendOnlyFile(char *filename) {
...
@@ -311,6 +315,8 @@ int loadAppendOnlyFile(char *filename) {
freeFakeClient
(
fakeClient
);
freeFakeClient
(
fakeClient
);
server
.
appendonly
=
appendonly
;
server
.
appendonly
=
appendonly
;
stopLoading
();
stopLoading
();
aofUpdateCurrentSize
();
server
.
auto_aofrewrite_base_size
=
server
.
appendonly_current_size
;
return
REDIS_OK
;
return
REDIS_OK
;
readerr:
readerr:
...
@@ -633,9 +639,10 @@ int rewriteAppendOnlyFileBackground(void) {
...
@@ -633,9 +639,10 @@ int rewriteAppendOnlyFileBackground(void) {
void
bgrewriteaofCommand
(
redisClient
*
c
)
{
void
bgrewriteaofCommand
(
redisClient
*
c
)
{
if
(
server
.
bgrewritechildpid
!=
-
1
)
{
if
(
server
.
bgrewritechildpid
!=
-
1
)
{
addReplyError
(
c
,
"Background append only file rewriting already in progress"
);
addReplyError
(
c
,
"Background append only file rewriting already in progress"
);
return
;
}
else
if
(
server
.
bgsavechildpid
!=
-
1
)
{
}
server
.
aofrewrite_scheduled
=
1
;
if
(
rewriteAppendOnlyFileBackground
()
==
REDIS_OK
)
{
addReplyStatus
(
c
,
"Background append only file rewriting scheduled"
);
}
else
if
(
rewriteAppendOnlyFileBackground
()
==
REDIS_OK
)
{
addReplyStatus
(
c
,
"Background append only file rewriting started"
);
addReplyStatus
(
c
,
"Background append only file rewriting started"
);
}
else
{
}
else
{
addReply
(
c
,
shared
.
err
);
addReply
(
c
,
shared
.
err
);
...
@@ -649,6 +656,21 @@ void aofRemoveTempFile(pid_t childpid) {
...
@@ -649,6 +656,21 @@ void aofRemoveTempFile(pid_t childpid) {
unlink
(
tmpfile
);
unlink
(
tmpfile
);
}
}
/* Update the server.appendonly_current_size filed explicitly using stat(2)
* to check the size of the file. This is useful after a rewrite or after
* a restart, normally the size is updated just adding the write length
* to the current lenght, that is much faster. */
void
aofUpdateCurrentSize
(
void
)
{
struct
redis_stat
sb
;
if
(
redis_fstat
(
server
.
appendfd
,
&
sb
)
==
-
1
)
{
redisLog
(
REDIS_WARNING
,
"Unable to check the AOF length: %s"
,
strerror
(
errno
));
}
else
{
server
.
appendonly_current_size
=
sb
.
st_size
;
}
}
/* A background append only file rewriting (BGREWRITEAOF) terminated its work.
/* A background append only file rewriting (BGREWRITEAOF) terminated its work.
* Handle this. */
* Handle this. */
void
backgroundRewriteDoneHandler
(
int
statloc
)
{
void
backgroundRewriteDoneHandler
(
int
statloc
)
{
...
@@ -692,6 +714,8 @@ void backgroundRewriteDoneHandler(int statloc) {
...
@@ -692,6 +714,8 @@ void backgroundRewriteDoneHandler(int statloc) {
if
(
server
.
appendfsync
!=
APPENDFSYNC_NO
)
aof_fsync
(
fd
);
if
(
server
.
appendfsync
!=
APPENDFSYNC_NO
)
aof_fsync
(
fd
);
server
.
appendseldb
=
-
1
;
/* Make sure it will issue SELECT */
server
.
appendseldb
=
-
1
;
/* Make sure it will issue SELECT */
redisLog
(
REDIS_NOTICE
,
"The new append only file was selected for future appends."
);
redisLog
(
REDIS_NOTICE
,
"The new append only file was selected for future appends."
);
aofUpdateCurrentSize
();
server
.
auto_aofrewrite_base_size
=
server
.
appendonly_current_size
;
}
else
{
}
else
{
/* If append only is disabled we just generate a dump in this
/* If append only is disabled we just generate a dump in this
* format. Why not? */
* format. Why not? */
...
...
src/config.c
View file @
61751a4d
...
@@ -232,6 +232,18 @@ void loadServerConfig(char *filename) {
...
@@ -232,6 +232,18 @@ void loadServerConfig(char *filename) {
err
=
"argument must be 'no', 'always' or 'everysec'"
;
err
=
"argument must be 'no', 'always' or 'everysec'"
;
goto
loaderr
;
goto
loaderr
;
}
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"auto-aof-rewrite-percentage"
)
&&
argc
==
2
)
{
server
.
auto_aofrewrite_perc
=
atoi
(
argv
[
1
]);
if
(
server
.
auto_aofrewrite_perc
<
0
)
{
err
=
"Invalid negative percentage for AOF auto rewrite"
;
goto
loaderr
;
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"auto-aof-rewrite-min-size"
)
&&
argc
==
2
)
{
server
.
auto_aofrewrite_min_size
=
memtoll
(
argv
[
1
],
NULL
);
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"requirepass"
)
&&
argc
==
2
)
{
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"requirepass"
)
&&
argc
==
2
)
{
server
.
requirepass
=
zstrdup
(
argv
[
1
]);
server
.
requirepass
=
zstrdup
(
argv
[
1
]);
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"pidfile"
)
&&
argc
==
2
)
{
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"pidfile"
)
&&
argc
==
2
)
{
...
@@ -406,6 +418,12 @@ void configSetCommand(redisClient *c) {
...
@@ -406,6 +418,12 @@ void configSetCommand(redisClient *c) {
}
}
}
}
}
}
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"auto-aof-rewrite-percentage"
))
{
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
||
ll
<
0
)
goto
badfmt
;
server
.
auto_aofrewrite_perc
=
ll
;
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"auto-aof-rewrite-min-size"
))
{
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
||
ll
<
0
)
goto
badfmt
;
server
.
auto_aofrewrite_min_size
=
ll
;
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"save"
))
{
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"save"
))
{
int
vlen
,
j
;
int
vlen
,
j
;
sds
*
v
=
sdssplitlen
(
o
->
ptr
,
sdslen
(
o
->
ptr
),
" "
,
1
,
&
vlen
);
sds
*
v
=
sdssplitlen
(
o
->
ptr
,
sdslen
(
o
->
ptr
),
" "
,
1
,
&
vlen
);
...
@@ -592,6 +610,16 @@ void configGetCommand(redisClient *c) {
...
@@ -592,6 +610,16 @@ void configGetCommand(redisClient *c) {
sdsfree
(
buf
);
sdsfree
(
buf
);
matches
++
;
matches
++
;
}
}
if
(
stringmatch
(
pattern
,
"auto-aof-rewrite-percentage"
,
0
))
{
addReplyBulkCString
(
c
,
"auto-aof-rewrite-percentage"
);
addReplyBulkLongLong
(
c
,
server
.
auto_aofrewrite_perc
);
matches
++
;
}
if
(
stringmatch
(
pattern
,
"auto-aof-rewrite-min-size"
,
0
))
{
addReplyBulkCString
(
c
,
"auto-aof-rewrite-min-size"
);
addReplyBulkLongLong
(
c
,
server
.
auto_aofrewrite_min_size
);
matches
++
;
}
if
(
stringmatch
(
pattern
,
"slave-serve-stale-data"
,
0
))
{
if
(
stringmatch
(
pattern
,
"slave-serve-stale-data"
,
0
))
{
addReplyBulkCString
(
c
,
"slave-serve-stale-data"
);
addReplyBulkCString
(
c
,
"slave-serve-stale-data"
);
addReplyBulkCString
(
c
,
server
.
repl_serve_stale_data
?
"yes"
:
"no"
);
addReplyBulkCString
(
c
,
server
.
repl_serve_stale_data
?
"yes"
:
"no"
);
...
...
src/db.c
View file @
61751a4d
...
@@ -298,9 +298,9 @@ void saveCommand(redisClient *c) {
...
@@ -298,9 +298,9 @@ void saveCommand(redisClient *c) {
void
bgsaveCommand
(
redisClient
*
c
)
{
void
bgsaveCommand
(
redisClient
*
c
)
{
if
(
server
.
bgsavechildpid
!=
-
1
)
{
if
(
server
.
bgsavechildpid
!=
-
1
)
{
addReplyError
(
c
,
"Background save already in progress"
);
addReplyError
(
c
,
"Background save already in progress"
);
return
;
}
else
if
(
server
.
bgrewritechildpid
!=
-
1
)
{
}
addReplyError
(
c
,
"Can't BGSAVE while AOF log rewriting is in progress"
);
if
(
rdbSaveBackground
(
server
.
dbfilename
)
==
REDIS_OK
)
{
}
else
if
(
rdbSaveBackground
(
server
.
dbfilename
)
==
REDIS_OK
)
{
addReplyStatus
(
c
,
"Background saving started"
);
addReplyStatus
(
c
,
"Background saving started"
);
}
else
{
}
else
{
addReply
(
c
,
shared
.
err
);
addReply
(
c
,
shared
.
err
);
...
...
src/redis.c
View file @
61751a4d
...
@@ -589,6 +589,14 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
...
@@ -589,6 +589,14 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
if
((
server
.
maxidletime
&&
!
(
loops
%
100
))
||
server
.
bpop_blocked_clients
)
if
((
server
.
maxidletime
&&
!
(
loops
%
100
))
||
server
.
bpop_blocked_clients
)
closeTimedoutClients
();
closeTimedoutClients
();
/* Start a scheduled AOF rewrite if this was requested by the user while
* a BGSAVE was in progress. */
if
(
server
.
bgsavechildpid
==
-
1
&&
server
.
bgrewritechildpid
==
-
1
&&
server
.
aofrewrite_scheduled
)
{
rewriteAppendOnlyFileBackground
();
}
/* Check if a background saving or AOF rewrite in progress terminated */
/* Check if a background saving or AOF rewrite in progress terminated */
if
(
server
.
bgsavechildpid
!=
-
1
||
server
.
bgrewritechildpid
!=
-
1
)
{
if
(
server
.
bgsavechildpid
!=
-
1
||
server
.
bgrewritechildpid
!=
-
1
)
{
int
statloc
;
int
statloc
;
...
@@ -603,9 +611,10 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
...
@@ -603,9 +611,10 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
updateDictResizePolicy
();
updateDictResizePolicy
();
}
}
}
else
{
}
else
{
time_t
now
=
time
(
NULL
);
/* If there is not a background saving in progress check if
/* If there is not a background saving in progress check if
* we have to save now */
* we have to save now */
time_t
now
=
time
(
NULL
);
for
(
j
=
0
;
j
<
server
.
saveparamslen
;
j
++
)
{
for
(
j
=
0
;
j
<
server
.
saveparamslen
;
j
++
)
{
struct
saveparam
*
sp
=
server
.
saveparams
+
j
;
struct
saveparam
*
sp
=
server
.
saveparams
+
j
;
...
@@ -617,6 +626,21 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
...
@@ -617,6 +626,21 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
break
;
break
;
}
}
}
}
/* Trigger an AOF rewrite if needed */
if
(
server
.
bgsavechildpid
==
-
1
&&
server
.
bgrewritechildpid
==
-
1
&&
server
.
auto_aofrewrite_perc
&&
server
.
appendonly_current_size
>
server
.
auto_aofrewrite_min_size
)
{
int
base
=
server
.
auto_aofrewrite_base_size
?
server
.
auto_aofrewrite_base_size
:
1
;
long
long
growth
=
(
server
.
appendonly_current_size
*
100
/
base
);
if
(
growth
>=
server
.
auto_aofrewrite_perc
)
{
redisLog
(
REDIS_NOTICE
,
"Starting automatic rewriting of AOF on %lld%% growth"
,
growth
);
rewriteAppendOnlyFileBackground
();
}
}
}
}
/* Expire a few keys per cycle, only if this is a master.
/* Expire a few keys per cycle, only if this is a master.
...
@@ -780,6 +804,10 @@ void initServerConfig() {
...
@@ -780,6 +804,10 @@ void initServerConfig() {
server
.
appendonly
=
0
;
server
.
appendonly
=
0
;
server
.
appendfsync
=
APPENDFSYNC_EVERYSEC
;
server
.
appendfsync
=
APPENDFSYNC_EVERYSEC
;
server
.
no_appendfsync_on_rewrite
=
0
;
server
.
no_appendfsync_on_rewrite
=
0
;
server
.
auto_aofrewrite_perc
=
REDIS_AUTO_AOFREWRITE_PERC
;
server
.
auto_aofrewrite_min_size
=
REDIS_AUTO_AOFREWRITE_MIN_SIZE
;
server
.
auto_aofrewrite_base_size
=
0
;
server
.
aofrewrite_scheduled
=
0
;
server
.
lastfsync
=
time
(
NULL
);
server
.
lastfsync
=
time
(
NULL
);
server
.
appendfd
=
-
1
;
server
.
appendfd
=
-
1
;
server
.
appendseldb
=
-
1
;
/* Make sure the first time will not match */
server
.
appendseldb
=
-
1
;
/* Make sure the first time will not match */
...
@@ -1255,6 +1283,17 @@ sds genRedisInfoString(void) {
...
@@ -1255,6 +1283,17 @@ sds genRedisInfoString(void) {
server
.
vm_enabled
!=
0
,
server
.
vm_enabled
!=
0
,
server
.
masterhost
==
NULL
?
"master"
:
"slave"
server
.
masterhost
==
NULL
?
"master"
:
"slave"
);
);
if
(
server
.
appendonly
)
{
info
=
sdscatprintf
(
info
,
"aof_current_size:%lld
\r\n
"
"aof_base_size:%lld
\r\n
"
"aof_pending_rewrite:%d
\r\n
"
,
(
long
long
)
server
.
appendonly_current_size
,
(
long
long
)
server
.
auto_aofrewrite_base_size
,
server
.
aofrewrite_scheduled
);
}
if
(
server
.
masterhost
)
{
if
(
server
.
masterhost
)
{
info
=
sdscatprintf
(
info
,
info
=
sdscatprintf
(
info
,
"master_host:%s
\r\n
"
"master_host:%s
\r\n
"
...
...
src/redis.h
View file @
61751a4d
...
@@ -49,6 +49,8 @@
...
@@ -49,6 +49,8 @@
#define REDIS_SHARED_INTEGERS 10000
#define REDIS_SHARED_INTEGERS 10000
#define REDIS_REPLY_CHUNK_BYTES (5*1500)
/* 5 TCP packets with default MTU */
#define REDIS_REPLY_CHUNK_BYTES (5*1500)
/* 5 TCP packets with default MTU */
#define REDIS_MAX_LOGMSG_LEN 1024
/* Default maximum length of syslog messages */
#define REDIS_MAX_LOGMSG_LEN 1024
/* Default maximum length of syslog messages */
#define REDIS_AUTO_AOFREWRITE_PERC 100
#define REDIS_AUTO_AOFREWRITE_MIN_SIZE (1024*1024)
/* Hash table parameters */
/* Hash table parameters */
#define REDIS_HT_MINFILL 10
/* Minimal hash table fill 10% */
#define REDIS_HT_MINFILL 10
/* Minimal hash table fill 10% */
...
@@ -410,6 +412,11 @@ struct redisServer {
...
@@ -410,6 +412,11 @@ struct redisServer {
int
appendonly
;
int
appendonly
;
int
appendfsync
;
int
appendfsync
;
int
no_appendfsync_on_rewrite
;
int
no_appendfsync_on_rewrite
;
int
auto_aofrewrite_perc
;
/* Rewrite AOF if % growth is > M and... */
off_t
auto_aofrewrite_min_size
;
/* the AOF file is at least N bytes. */
off_t
auto_aofrewrite_base_size
;
/* AOF size on latest startup or rewrite. */
off_t
appendonly_current_size
;
/* AOF current size. */
int
aofrewrite_scheduled
;
/* Rewrite once BGSAVE terminates. */
int
shutdown_asap
;
int
shutdown_asap
;
time_t
lastfsync
;
time_t
lastfsync
;
int
appendfd
;
int
appendfd
;
...
...
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