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
36c17a53
Commit
36c17a53
authored
Jan 07, 2011
by
antirez
Browse files
source reshaped a bit to play well with a bgsaving thread, still work to do, does not compile.
parent
cb9b35c8
Changes
8
Hide whitespace changes
Inline
Side-by-side
TODO
View file @
36c17a53
...
@@ -15,6 +15,8 @@ DISKSTORE TODO
...
@@ -15,6 +15,8 @@ DISKSTORE TODO
* Check that 00/00 and ff/ff exist at startup, otherwise exit with error.
* Check that 00/00 and ff/ff exist at startup, otherwise exit with error.
* Implement sync flush option, where data is written synchronously on disk when a command is executed.
* Implement sync flush option, where data is written synchronously on disk when a command is executed.
* Implement MULTI/EXEC as transaction abstract API to diskstore.c, with transaction_start, transaction_end, and a journal to recover.
* Implement MULTI/EXEC as transaction abstract API to diskstore.c, with transaction_start, transaction_end, and a journal to recover.
* Stop BGSAVE thread on shutdown and any other condition where the child is killed during normal bgsave.
* Use a mutex to log on the file, so that we don't get overlapping messages, or even better make sure to use a single write against it.
REPLICATION
REPLICATION
===========
===========
...
...
src/aof.c
View file @
36c17a53
...
@@ -585,10 +585,7 @@ void aofRemoveTempFile(pid_t childpid) {
...
@@ -585,10 +585,7 @@ void aofRemoveTempFile(pid_t childpid) {
/* 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
exitcode
,
int
bysignal
)
{
int
exitcode
=
WEXITSTATUS
(
statloc
);
int
bysignal
=
WIFSIGNALED
(
statloc
);
if
(
!
bysignal
&&
exitcode
==
0
)
{
if
(
!
bysignal
&&
exitcode
==
0
)
{
int
fd
;
int
fd
;
char
tmpfile
[
256
];
char
tmpfile
[
256
];
...
@@ -636,7 +633,7 @@ void backgroundRewriteDoneHandler(int statloc) {
...
@@ -636,7 +633,7 @@ void backgroundRewriteDoneHandler(int statloc) {
}
else
{
}
else
{
redisLog
(
REDIS_WARNING
,
redisLog
(
REDIS_WARNING
,
"Background append only file rewriting terminated by signal %d"
,
"Background append only file rewriting terminated by signal %d"
,
WTERMSIG
(
statloc
)
);
bysitnal
);
}
}
cleanup:
cleanup:
sdsfree
(
server
.
bgrewritebuf
);
sdsfree
(
server
.
bgrewritebuf
);
...
...
src/db.c
View file @
36c17a53
...
@@ -379,30 +379,6 @@ void typeCommand(redisClient *c) {
...
@@ -379,30 +379,6 @@ void typeCommand(redisClient *c) {
addReplyStatus
(
c
,
type
);
addReplyStatus
(
c
,
type
);
}
}
void
saveCommand
(
redisClient
*
c
)
{
if
(
server
.
bgsavechildpid
!=
-
1
)
{
addReplyError
(
c
,
"Background save already in progress"
);
return
;
}
if
(
rdbSave
(
server
.
dbfilename
)
==
REDIS_OK
)
{
addReply
(
c
,
shared
.
ok
);
}
else
{
addReply
(
c
,
shared
.
err
);
}
}
void
bgsaveCommand
(
redisClient
*
c
)
{
if
(
server
.
bgsavechildpid
!=
-
1
)
{
addReplyError
(
c
,
"Background save already in progress"
);
return
;
}
if
(
rdbSaveBackground
(
server
.
dbfilename
)
==
REDIS_OK
)
{
addReplyStatus
(
c
,
"Background saving started"
);
}
else
{
addReply
(
c
,
shared
.
err
);
}
}
void
shutdownCommand
(
redisClient
*
c
)
{
void
shutdownCommand
(
redisClient
*
c
)
{
if
(
prepareForShutdown
()
==
REDIS_OK
)
if
(
prepareForShutdown
()
==
REDIS_OK
)
exit
(
0
);
exit
(
0
);
...
...
src/diskstore.c
View file @
36c17a53
...
@@ -349,11 +349,16 @@ void dsFlushDb(int dbid) {
...
@@ -349,11 +349,16 @@ void dsFlushDb(int dbid) {
}
}
}
}
int
dsRdbSave
(
char
*
filename
)
{
void
*
dsRdbSave
_thread
(
void
*
arg
)
{
char
tmpfile
[
256
];
char
tmpfile
[
256
]
,
*
filename
=
(
char
*
)
arg
;
int
j
,
i
;
int
j
,
i
;
time_t
now
=
time
(
NULL
);
time_t
now
=
time
(
NULL
);
/* Change state to ACTIVE, to signal there is a saving thead working. */
pthread_mutex_lock
(
&
server
.
bgsavethread_mutex
);
server
.
bgsavethread_state
=
REDIS_BGSAVE_THREAD_ACTIVE
;
pthread_mutex_unlock
(
&
server
.
bgsavethread_mutex
);
snprintf
(
tmpfile
,
256
,
"temp-%d.rdb"
,
(
int
)
getpid
());
snprintf
(
tmpfile
,
256
,
"temp-%d.rdb"
,
(
int
)
getpid
());
fp
=
fopen
(
tmpfile
,
"w"
);
fp
=
fopen
(
tmpfile
,
"w"
);
if
(
!
fp
)
{
if
(
!
fp
)
{
...
@@ -377,6 +382,7 @@ int dsRdbSave(char *filename) {
...
@@ -377,6 +382,7 @@ int dsRdbSave(char *filename) {
fflush
(
fp
);
fflush
(
fp
);
fsync
(
fileno
(
fp
));
fsync
(
fileno
(
fp
));
fclose
(
fp
);
fclose
(
fp
);
zfree
(
filename
);
/* Use RENAME to make sure the DB file is changed atomically only
/* Use RENAME to make sure the DB file is changed atomically only
* if the generate DB file is ok. */
* if the generate DB file is ok. */
...
@@ -386,12 +392,24 @@ int dsRdbSave(char *filename) {
...
@@ -386,12 +392,24 @@ int dsRdbSave(char *filename) {
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
redisLog
(
REDIS_NOTICE
,
"DB saved on disk"
);
redisLog
(
REDIS_NOTICE
,
"DB saved on disk"
);
server
.
dirty
=
0
;
server
.
lastsave
=
time
(
NULL
);
return
REDIS_OK
;
return
REDIS_OK
;
werr:
werr:
zfree
(
filename
);
fclose
(
fp
);
fclose
(
fp
);
unlink
(
tmpfile
);
unlink
(
tmpfile
);
redisLog
(
REDIS_WARNING
,
"Write error saving DB on disk: %s"
,
strerror
(
errno
));
redisLog
(
REDIS_WARNING
,
"Write error saving DB on disk: %s"
,
strerror
(
errno
));
}
}
int
dsRdbSave
(
char
*
filename
)
{
pthread_t
thread
;
if
(
pthread_create
(
&
thread
,
NULL
,
dsRdbSave_thread
,
zstrdup
(
filename
))
!=
0
)
{
redisLog
(
REDIS_WARNING
,
"Can't create diskstore BGSAVE thread: %s"
,
strerror
(
errno
));
return
REDIS_ERR
;
}
else
{
server
.
bgsavethread
=
thread
;
return
REDIS_OK
;
}
}
src/dscache.c
View file @
36c17a53
...
@@ -132,6 +132,7 @@ void dsInit(void) {
...
@@ -132,6 +132,7 @@ void dsInit(void) {
server
.
io_ready_clients
=
listCreate
();
server
.
io_ready_clients
=
listCreate
();
pthread_mutex_init
(
&
server
.
io_mutex
,
NULL
);
pthread_mutex_init
(
&
server
.
io_mutex
,
NULL
);
pthread_cond_init
(
&
server
.
io_condvar
,
NULL
);
pthread_cond_init
(
&
server
.
io_condvar
,
NULL
);
pthread_mutex_init
(
&
server
.
bgsavethread_mutex
,
NULL
);
server
.
io_active_threads
=
0
;
server
.
io_active_threads
=
0
;
if
(
pipe
(
pipefds
)
==
-
1
)
{
if
(
pipe
(
pipefds
)
==
-
1
)
{
redisLog
(
REDIS_WARNING
,
"Unable to intialized DS: pipe(2): %s. Exiting."
redisLog
(
REDIS_WARNING
,
"Unable to intialized DS: pipe(2): %s. Exiting."
...
...
src/rdb.c
View file @
36c17a53
...
@@ -496,22 +496,23 @@ werr:
...
@@ -496,22 +496,23 @@ werr:
int
rdbSaveBackground
(
char
*
filename
)
{
int
rdbSaveBackground
(
char
*
filename
)
{
pid_t
childpid
;
pid_t
childpid
;
if
(
server
.
bgsavechildpid
!=
-
1
)
return
REDIS_ERR
;
if
(
server
.
bgsavechildpid
!=
-
1
||
server
.
bgsavethread
!=
(
pthread_t
)
-
1
)
return
REDIS_ERR
;
server
.
dirty_before_bgsave
=
server
.
dirty
;
server
.
dirty_before_bgsave
=
server
.
dirty
;
if
(
server
.
ds_enabled
)
{
cacheForcePointInTime
();
return
dsRdbSave
(
filename
);
}
if
((
childpid
=
fork
())
==
0
)
{
if
((
childpid
=
fork
())
==
0
)
{
int
retval
;
int
retval
;
/* Child */
/* Child */
if
(
server
.
ipfd
>
0
)
close
(
server
.
ipfd
);
if
(
server
.
ipfd
>
0
)
close
(
server
.
ipfd
);
if
(
server
.
sofd
>
0
)
close
(
server
.
sofd
);
if
(
server
.
sofd
>
0
)
close
(
server
.
sofd
);
if
(
server
.
ds_enabled
)
{
retval
=
rdbSave
(
filename
);
cacheForcePointInTime
();
dsRdbSave
(
filename
);
}
else
{
rdbSave
(
filename
);
}
_exit
((
retval
==
REDIS_OK
)
?
0
:
1
);
_exit
((
retval
==
REDIS_OK
)
?
0
:
1
);
}
else
{
}
else
{
/* Parent */
/* Parent */
...
@@ -950,10 +951,7 @@ eoferr: /* unexpected end of file is handled here with a fatal exit */
...
@@ -950,10 +951,7 @@ eoferr: /* unexpected end of file is handled here with a fatal exit */
}
}
/* A background saving child (BGSAVE) terminated its work. Handle this. */
/* A background saving child (BGSAVE) terminated its work. Handle this. */
void
backgroundSaveDoneHandler
(
int
statloc
)
{
void
backgroundSaveDoneHandler
(
int
exitcode
,
int
bysignal
)
{
int
exitcode
=
WEXITSTATUS
(
statloc
);
int
bysignal
=
WIFSIGNALED
(
statloc
);
if
(
!
bysignal
&&
exitcode
==
0
)
{
if
(
!
bysignal
&&
exitcode
==
0
)
{
redisLog
(
REDIS_NOTICE
,
redisLog
(
REDIS_NOTICE
,
"Background saving terminated with success"
);
"Background saving terminated with success"
);
...
@@ -963,11 +961,37 @@ void backgroundSaveDoneHandler(int statloc) {
...
@@ -963,11 +961,37 @@ void backgroundSaveDoneHandler(int statloc) {
redisLog
(
REDIS_WARNING
,
"Background saving error"
);
redisLog
(
REDIS_WARNING
,
"Background saving error"
);
}
else
{
}
else
{
redisLog
(
REDIS_WARNING
,
redisLog
(
REDIS_WARNING
,
"Background saving terminated by signal %d"
,
WTERMSIG
(
statloc
)
);
"Background saving terminated by signal %d"
,
bysignal
);
rdbRemoveTempFile
(
server
.
bgsavechildpid
);
rdbRemoveTempFile
(
server
.
bgsavechildpid
);
}
}
server
.
bgsavechildpid
=
-
1
;
server
.
bgsavechildpid
=
-
1
;
server
.
bgsavethread
=
(
pthread_t
)
-
1
;
server
.
bgsavethread_state
=
REDIS_BGSAVE_THREAD_UNACTIVE
;
/* Possibly there are slaves waiting for a BGSAVE in order to be served
/* Possibly there are slaves waiting for a BGSAVE in order to be served
* (the first stage of SYNC is a bulk transfer of dump.rdb) */
* (the first stage of SYNC is a bulk transfer of dump.rdb) */
updateSlavesWaitingBgsave
(
exitcode
==
0
?
REDIS_OK
:
REDIS_ERR
);
updateSlavesWaitingBgsave
(
exitcode
==
0
?
REDIS_OK
:
REDIS_ERR
);
}
}
void
saveCommand
(
redisClient
*
c
)
{
if
(
server
.
bgsavechildpid
!=
-
1
||
server
.
bgsavethread
!=
(
pthread
-
t
)
-
1
)
{
addReplyError
(
c
,
"Background save already in progress"
);
return
;
}
if
(
rdbSave
(
server
.
dbfilename
)
==
REDIS_OK
)
{
addReply
(
c
,
shared
.
ok
);
}
else
{
addReply
(
c
,
shared
.
err
);
}
}
void
bgsaveCommand
(
redisClient
*
c
)
{
if
(
server
.
bgsavechildpid
!=
-
1
||
server
.
bgsavethread
!=
(
pthread
-
t
)
-
1
)
{
addReplyError
(
c
,
"Background save already in progress"
);
return
;
}
if
(
rdbSaveBackground
(
server
.
dbfilename
)
==
REDIS_OK
)
{
addReplyStatus
(
c
,
"Background saving started"
);
}
else
{
addReply
(
c
,
shared
.
err
);
}
}
src/redis.c
View file @
36c17a53
...
@@ -589,13 +589,31 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
...
@@ -589,13 +589,31 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
pid_t
pid
;
pid_t
pid
;
if
((
pid
=
wait3
(
&
statloc
,
WNOHANG
,
NULL
))
!=
0
)
{
if
((
pid
=
wait3
(
&
statloc
,
WNOHANG
,
NULL
))
!=
0
)
{
int
exitcode
=
WEXITSTATUS
(
statloc
);
int
bysignal
=
0
;
if
(
WIFSIGNALED
(
statloc
))
bysignal
=
WTERMSIG
(
statloc
);
if
(
pid
==
server
.
bgsavechildpid
)
{
if
(
pid
==
server
.
bgsavechildpid
)
{
backgroundSaveDoneHandler
(
statloc
);
backgroundSaveDoneHandler
(
exitcode
,
bysignal
);
}
else
{
}
else
{
backgroundRewriteDoneHandler
(
statloc
);
backgroundRewriteDoneHandler
(
exitcode
,
bysignal
);
}
}
updateDictResizePolicy
();
updateDictResizePolicy
();
}
}
if
(
server
.
bgsavethread
!=
(
pthread_t
)
-
1
)
{
int
state
;
pthread_mutex_lock
(
&
server
.
bgsavethread_mutex
);
state
=
server
.
bgsavethread_state
;
pthread_mutex_unlock
(
&
server
.
bgsavethread_mutex
);
if
(
state
==
REDIS_BGSAVE_DONE_OK
||
state
==
REDIS_BGSAVE_DONE_ERR
)
{
backgroundSaveDoneHandler
(
(
state
==
REDIS_BGSAVE_DONE_OK
)
?
0
:
1
,
0
);
}
}
}
else
if
(
!
server
.
ds_enabled
)
{
}
else
if
(
!
server
.
ds_enabled
)
{
/* 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 */
...
@@ -867,6 +885,8 @@ void initServer() {
...
@@ -867,6 +885,8 @@ void initServer() {
server
.
cronloops
=
0
;
server
.
cronloops
=
0
;
server
.
bgsavechildpid
=
-
1
;
server
.
bgsavechildpid
=
-
1
;
server
.
bgrewritechildpid
=
-
1
;
server
.
bgrewritechildpid
=
-
1
;
server
.
bgsavethread_state
=
REDIS_BGSAVE_THREAD_UNACTIVE
;
server
.
bgsavethread
=
(
pthread_t
)
-
1
;
server
.
bgrewritebuf
=
sdsempty
();
server
.
bgrewritebuf
=
sdsempty
();
server
.
aofbuf
=
sdsempty
();
server
.
aofbuf
=
sdsempty
();
server
.
lastsave
=
time
(
NULL
);
server
.
lastsave
=
time
(
NULL
);
...
...
src/redis.h
View file @
36c17a53
...
@@ -203,6 +203,12 @@
...
@@ -203,6 +203,12 @@
#define REDIS_MAXMEMORY_ALLKEYS_RANDOM 4
#define REDIS_MAXMEMORY_ALLKEYS_RANDOM 4
#define REDIS_MAXMEMORY_NO_EVICTION 5
#define REDIS_MAXMEMORY_NO_EVICTION 5
/* Diskstore background saving thread states */
#define REDIS_BGSAVE_THREAD_UNACTIVE 0
#define REDIS_BGSAVE_THREAD_ACTIVE 1
#define REDIS_BGSAVE_THREAD_DONE_OK 2
#define REDIS_BGSAVE_THREAD_DONE_ERR 3
/* We can print the stacktrace, so our assert is defined this way: */
/* We can print the stacktrace, so our assert is defined this way: */
#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
#define redisPanic(_e) _redisPanic(#_e,__FILE__,__LINE__),_exit(1)
#define redisPanic(_e) _redisPanic(#_e,__FILE__,__LINE__),_exit(1)
...
@@ -390,25 +396,30 @@ struct redisServer {
...
@@ -390,25 +396,30 @@ struct redisServer {
int
appendfsync
;
int
appendfsync
;
int
no_appendfsync_on_rewrite
;
int
no_appendfsync_on_rewrite
;
int
shutdown_asap
;
int
shutdown_asap
;
int
activerehashing
;
char
*
requirepass
;
/* Persistence */
time_t
lastfsync
;
time_t
lastfsync
;
int
appendfd
;
int
appendfd
;
int
appendseldb
;
int
appendseldb
;
char
*
pidfile
;
char
*
pidfile
;
pid_t
bgsavechildpid
;
pid_t
bgsavechildpid
;
pid_t
bgrewritechildpid
;
pid_t
bgrewritechildpid
;
int
bgsavethread_state
;
pthread_mutex_t
bgsavethread_mutex
;
pthread_t
bgsavethread
;
sds
bgrewritebuf
;
/* buffer taken by parent during oppend only rewrite */
sds
bgrewritebuf
;
/* buffer taken by parent during oppend only rewrite */
sds
aofbuf
;
/* AOF buffer, written before entering the event loop */
sds
aofbuf
;
/* AOF buffer, written before entering the event loop */
struct
saveparam
*
saveparams
;
struct
saveparam
*
saveparams
;
int
saveparamslen
;
int
saveparamslen
;
char
*
dbfilename
;
int
rdbcompression
;
char
*
appendfilename
;
/* Logging */
char
*
logfile
;
char
*
logfile
;
int
syslog_enabled
;
int
syslog_enabled
;
char
*
syslog_ident
;
char
*
syslog_ident
;
int
syslog_facility
;
int
syslog_facility
;
char
*
dbfilename
;
char
*
appendfilename
;
char
*
requirepass
;
int
rdbcompression
;
int
activerehashing
;
/* Replication related */
/* Replication related */
int
isslave
;
int
isslave
;
/* Slave specific fields */
/* Slave specific fields */
...
@@ -745,7 +756,7 @@ int rdbSaveObject(FILE *fp, robj *o);
...
@@ -745,7 +756,7 @@ int rdbSaveObject(FILE *fp, robj *o);
off_t
rdbSavedObjectLen
(
robj
*
o
);
off_t
rdbSavedObjectLen
(
robj
*
o
);
off_t
rdbSavedObjectPages
(
robj
*
o
);
off_t
rdbSavedObjectPages
(
robj
*
o
);
robj
*
rdbLoadObject
(
int
type
,
FILE
*
fp
);
robj
*
rdbLoadObject
(
int
type
,
FILE
*
fp
);
void
backgroundSaveDoneHandler
(
int
statloc
);
void
backgroundSaveDoneHandler
(
int
exitcode
,
int
bysignal
)
{
int
rdbSaveKeyValuePair
(
FILE
*
fp
,
redisDb
*
db
,
robj
*
key
,
robj
*
val
,
time_t
now
);
int
rdbSaveKeyValuePair
(
FILE
*
fp
,
redisDb
*
db
,
robj
*
key
,
robj
*
val
,
time_t
now
);
int
rdbLoadType
(
FILE
*
fp
);
int
rdbLoadType
(
FILE
*
fp
);
time_t
rdbLoadTime
(
FILE
*
fp
);
time_t
rdbLoadTime
(
FILE
*
fp
);
...
@@ -759,7 +770,7 @@ int rewriteAppendOnlyFileBackground(void);
...
@@ -759,7 +770,7 @@ int rewriteAppendOnlyFileBackground(void);
int
loadAppendOnlyFile
(
char
*
filename
);
int
loadAppendOnlyFile
(
char
*
filename
);
void
stopAppendOnly
(
void
);
void
stopAppendOnly
(
void
);
int
startAppendOnly
(
void
);
int
startAppendOnly
(
void
);
void
backgroundRewriteDoneHandler
(
int
statloc
);
void
backgroundRewriteDoneHandler
(
int
exitcode
,
int
bysignal
);
/* Sorted sets data type */
/* Sorted sets data type */
zskiplist
*
zslCreate
(
void
);
zskiplist
*
zslCreate
(
void
);
...
...
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