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
f03fe802
Commit
f03fe802
authored
Jan 07, 2011
by
antirez
Browse files
diskstore BGSAVE should work now
parent
5b8ce853
Changes
5
Hide whitespace changes
Inline
Side-by-side
TODO
View file @
f03fe802
...
...
@@ -20,6 +20,7 @@ DISKSTORE TODO
* Fix RANDOMKEY to really do something interesting
* Fix DBSIZE to really do something interesting
* Add a DEBUG command to check if an entry is or not in memory currently
* Prevent io jobs from running while there is a BGSAVE thread.
REPLICATION
===========
...
...
src/diskstore.c
View file @
f03fe802
...
...
@@ -295,6 +295,17 @@ int dsExists(redisDb *db, robj *key) {
return
access
(
buf
,
R_OK
)
==
0
;
}
int
dsGetDbidFromFilename
(
char
*
path
)
{
char
id
[
64
];
char
*
p
=
strchr
(
path
,
'_'
);
int
len
=
(
p
-
path
);
redisAssert
(
p
!=
NULL
&&
len
<
64
);
memcpy
(
id
,
path
,
len
);
id
[
len
]
=
'\0'
;
return
atoi
(
id
);
}
void
dsFlushOneDir
(
char
*
path
,
int
dbid
)
{
DIR
*
dir
;
struct
dirent
*
dp
,
de
;
...
...
@@ -313,17 +324,8 @@ void dsFlushOneDir(char *path, int dbid) {
if
(
dp
->
d_name
[
0
]
==
'.'
)
continue
;
/* Check if we need to remove this entry accordingly to the
* DB number */
if
(
dbid
!=
-
1
)
{
char
id
[
64
];
char
*
p
=
strchr
(
dp
->
d_name
,
'_'
);
int
len
=
(
p
-
dp
->
d_name
);
redisAssert
(
p
!=
NULL
&&
len
<
64
);
memcpy
(
id
,
dp
->
d_name
,
len
);
id
[
len
]
=
'\0'
;
if
(
atoi
(
id
)
!=
dbid
)
continue
;
/* skip this file */
}
* DB number. */
if
(
dbid
!=
-
1
&&
dsGetDbidFromFilename
(
dp
->
d_name
))
continue
;
/* Finally unlink the file */
snprintf
(
buf
,
1024
,
"%s/%s"
,
path
,
dp
->
d_name
);
...
...
@@ -357,14 +359,13 @@ void dsRdbSaveSetState(int state) {
void
*
dsRdbSave_thread
(
void
*
arg
)
{
char
tmpfile
[
256
],
*
filename
=
(
char
*
)
arg
;
int
j
,
i
;
time_t
now
=
time
(
NULL
)
;
struct
dirent
*
dp
,
de
;
int
j
,
i
,
last_dbid
=
-
1
;
FILE
*
fp
;
/* 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
);
redisLog
(
REDIS_NOTICE
,
"Diskstore BGSAVE thread started"
);
dsRdbSaveSetState
(
REDIS_BGSAVE_THREAD_ACTIVE
);
snprintf
(
tmpfile
,
256
,
"temp-%d.rdb"
,
(
int
)
getpid
());
fp
=
fopen
(
tmpfile
,
"w"
);
...
...
@@ -378,18 +379,71 @@ void *dsRdbSave_thread(void *arg) {
sleep
(
5
);
#if 0
/* Scan all diskstore dirs looking for keys */
for
(
j
=
0
;
j
<
256
;
j
++
)
{
for
(
i
=
0
;
i
<
256
;
i
++
)
{
snprintf(buf,1024,"%s/%02x/%02x",server.ds_path,j,i);
/* Write the SELECT DB opcode */
if (rdbSaveType(fp,REDIS_SELECTDB) == -1) goto werr;
if (rdbSaveLen(fp,j) == -1) goto werr;
DIR
*
dir
;
char
buf
[
1024
];
/* For every directory, collect all the keys */
snprintf
(
buf
,
sizeof
(
buf
),
"%s/%02x/%02x"
,
server
.
ds_path
,
j
,
i
);
if
((
dir
=
opendir
(
buf
))
==
NULL
)
{
redisLog
(
REDIS_WARNING
,
"Disk store can't open dir %s: %s"
,
buf
,
strerror
(
errno
));
goto
werr
;
}
while
(
1
)
{
char
buf
[
1024
];
int
dbid
;
FILE
*
entryfp
;
readdir_r
(
dir
,
&
de
,
&
dp
);
if
(
dp
==
NULL
)
break
;
if
(
dp
->
d_name
[
0
]
==
'.'
)
continue
;
/* Emit the SELECT DB opcode if needed. */
dbid
=
dsGetDbidFromFilename
(
dp
->
d_name
);
if
(
dbid
!=
last_dbid
)
{
last_dbid
=
dbid
;
if
(
rdbSaveType
(
fp
,
REDIS_SELECTDB
)
==
-
1
)
goto
werr
;
if
(
rdbSaveLen
(
fp
,
dbid
)
==
-
1
)
goto
werr
;
}
/* Let's copy this file into the target .rdb */
snprintf
(
buf
,
sizeof
(
buf
),
"%s/%02x/%02x/%s"
,
server
.
ds_path
,
j
,
i
,
dp
->
d_name
);
if
((
entryfp
=
fopen
(
buf
,
"r"
))
==
NULL
)
{
redisLog
(
REDIS_WARNING
,
"Can't open %s: %s"
,
buf
,
strerror
(
errno
));
closedir
(
dir
);
goto
werr
;
}
while
(
1
)
{
int
nread
=
fread
(
buf
,
1
,
sizeof
(
buf
),
entryfp
);
if
(
nread
==
0
)
{
if
(
ferror
(
entryfp
))
{
redisLog
(
REDIS_WARNING
,
"Error reading from file entry while performing BGSAVE for diskstore: %s"
,
strerror
(
errno
));
closedir
(
dir
);
goto
werr
;
}
else
{
break
;
}
}
if
(
fwrite
(
buf
,
1
,
nread
,
fp
)
!=
(
unsigned
)
nread
)
{
closedir
(
dir
);
goto
werr
;
}
}
fclose
(
entryfp
);
}
closedir
(
dir
);
}
}
#endif
/* Output the end of file opcode */
if
(
rdbSaveType
(
fp
,
REDIS_EOF
)
==
-
1
)
goto
werr
;
/* Make sure data will not remain on the OS's output buffers */
fflush
(
fp
);
...
...
@@ -405,7 +459,7 @@ void *dsRdbSave_thread(void *arg) {
dsRdbSaveSetState
(
REDIS_BGSAVE_THREAD_DONE_ERR
);
return
NULL
;
}
redisLog
(
REDIS_NOTICE
,
"DB saved on disk"
);
redisLog
(
REDIS_NOTICE
,
"DB saved on disk
by diskstore thread
"
);
dsRdbSaveSetState
(
REDIS_BGSAVE_THREAD_DONE_OK
);
return
NULL
;
...
...
src/dscache.c
View file @
f03fe802
...
...
@@ -732,6 +732,9 @@ int cacheScheduleIOPushJobs(int flags) {
listNode
*
ln
;
int
jobs
,
topush
=
0
,
pushed
=
0
;
/* Don't push new jobs if there is a threaded BGSAVE in progress. */
if
(
server
.
bgsavethread
!=
(
pthread_t
)
-
1
)
return
0
;
/* Sync stuff on disk, but only if we have less
* than MAX_IO_JOBS_QUEUE IO jobs. */
lockThreadedIO
();
...
...
src/redis.c
View file @
f03fe802
...
...
@@ -583,7 +583,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
if
((
server
.
maxidletime
&&
!
(
loops
%
100
))
||
server
.
bpop_blocked_clients
)
closeTimedoutClients
();
/* 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
)
{
int
statloc
;
pid_t
pid
;
...
...
@@ -601,6 +601,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
}
updateDictResizePolicy
();
}
}
else
if
(
server
.
bgsavethread
!=
(
pthread_t
)
-
1
)
{
if
(
server
.
bgsavethread
!=
(
pthread_t
)
-
1
)
{
int
state
;
...
...
src/redis.h
View file @
f03fe802
...
...
@@ -761,6 +761,8 @@ int rdbSaveKeyValuePair(FILE *fp, redisDb *db, robj *key, robj *val, time_t now)
int
rdbLoadType
(
FILE
*
fp
);
time_t
rdbLoadTime
(
FILE
*
fp
);
robj
*
rdbLoadStringObject
(
FILE
*
fp
);
int
rdbSaveType
(
FILE
*
fp
,
unsigned
char
type
);
int
rdbSaveLen
(
FILE
*
fp
,
uint32_t
len
);
/* AOF persistence */
void
flushAppendOnlyFile
(
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