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
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