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
fc7ecd8d
Commit
fc7ecd8d
authored
Jul 10, 2017
by
antirez
Browse files
AOF check utility: ability to check files with RDB preamble.
parent
6b0670da
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/Makefile
View file @
fc7ecd8d
...
@@ -144,14 +144,13 @@ endif
...
@@ -144,14 +144,13 @@ endif
REDIS_SERVER_NAME
=
redis-server
REDIS_SERVER_NAME
=
redis-server
REDIS_SENTINEL_NAME
=
redis-sentinel
REDIS_SENTINEL_NAME
=
redis-sentinel
REDIS_SERVER_OBJ
=
adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o
REDIS_SERVER_OBJ
=
adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o
redis-check-aof.o
geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o
REDIS_CLI_NAME
=
redis-cli
REDIS_CLI_NAME
=
redis-cli
REDIS_CLI_OBJ
=
anet.o adlist.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o
REDIS_CLI_OBJ
=
anet.o adlist.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o
REDIS_BENCHMARK_NAME
=
redis-benchmark
REDIS_BENCHMARK_NAME
=
redis-benchmark
REDIS_BENCHMARK_OBJ
=
ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o
REDIS_BENCHMARK_OBJ
=
ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o
REDIS_CHECK_RDB_NAME
=
redis-check-rdb
REDIS_CHECK_RDB_NAME
=
redis-check-rdb
REDIS_CHECK_AOF_NAME
=
redis-check-aof
REDIS_CHECK_AOF_NAME
=
redis-check-aof
REDIS_CHECK_AOF_OBJ
=
redis-check-aof.o
all
:
$(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME)
all
:
$(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME)
@
echo
""
@
echo
""
...
@@ -207,6 +206,10 @@ $(REDIS_SENTINEL_NAME): $(REDIS_SERVER_NAME)
...
@@ -207,6 +206,10 @@ $(REDIS_SENTINEL_NAME): $(REDIS_SERVER_NAME)
$(REDIS_CHECK_RDB_NAME)
:
$(REDIS_SERVER_NAME)
$(REDIS_CHECK_RDB_NAME)
:
$(REDIS_SERVER_NAME)
$(REDIS_INSTALL)
$(REDIS_SERVER_NAME)
$(REDIS_CHECK_RDB_NAME)
$(REDIS_INSTALL)
$(REDIS_SERVER_NAME)
$(REDIS_CHECK_RDB_NAME)
# redis-check-aof
$(REDIS_CHECK_AOF_NAME)
:
$(REDIS_SERVER_NAME)
$(REDIS_INSTALL)
$(REDIS_SERVER_NAME)
$(REDIS_CHECK_AOF_NAME)
# redis-cli
# redis-cli
$(REDIS_CLI_NAME)
:
$(REDIS_CLI_OBJ)
$(REDIS_CLI_NAME)
:
$(REDIS_CLI_OBJ)
$(REDIS_LD)
-o
$@
$^
../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o
$(FINAL_LIBS)
$(REDIS_LD)
-o
$@
$^
../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o
$(FINAL_LIBS)
...
@@ -215,10 +218,6 @@ $(REDIS_CLI_NAME): $(REDIS_CLI_OBJ)
...
@@ -215,10 +218,6 @@ $(REDIS_CLI_NAME): $(REDIS_CLI_OBJ)
$(REDIS_BENCHMARK_NAME)
:
$(REDIS_BENCHMARK_OBJ)
$(REDIS_BENCHMARK_NAME)
:
$(REDIS_BENCHMARK_OBJ)
$(REDIS_LD)
-o
$@
$^
../deps/hiredis/libhiredis.a
$(FINAL_LIBS)
$(REDIS_LD)
-o
$@
$^
../deps/hiredis/libhiredis.a
$(FINAL_LIBS)
# redis-check-aof
$(REDIS_CHECK_AOF_NAME)
:
$(REDIS_CHECK_AOF_OBJ)
$(REDIS_LD)
-o
$@
$^
$(FINAL_LIBS)
dict-benchmark
:
dict.c zmalloc.c sds.c siphash.c
dict-benchmark
:
dict.c zmalloc.c sds.c siphash.c
$(REDIS_CC)
$(FINAL_CFLAGS)
$^
-D
DICT_BENCHMARK_MAIN
-o
$@
$(FINAL_LIBS)
$(REDIS_CC)
$(FINAL_CFLAGS)
$^
-D
DICT_BENCHMARK_MAIN
-o
$@
$(FINAL_LIBS)
...
...
src/rdb.c
View file @
fc7ecd8d
...
@@ -61,7 +61,7 @@ void rdbCheckThenExit(int linenum, char *reason, ...) {
...
@@ -61,7 +61,7 @@ void rdbCheckThenExit(int linenum, char *reason, ...) {
if
(
!
rdbCheckMode
)
{
if
(
!
rdbCheckMode
)
{
serverLog
(
LL_WARNING
,
"%s"
,
msg
);
serverLog
(
LL_WARNING
,
"%s"
,
msg
);
char
*
argv
[
2
]
=
{
""
,
server
.
rdb_filename
};
char
*
argv
[
2
]
=
{
""
,
server
.
rdb_filename
};
redis_check_rdb_main
(
2
,
argv
);
redis_check_rdb_main
(
2
,
argv
,
NULL
);
}
else
{
}
else
{
rdbCheckError
(
"%s"
,
msg
);
rdbCheckError
(
"%s"
,
msg
);
}
}
...
...
src/redis-check-aof.c
View file @
fc7ecd8d
...
@@ -28,13 +28,8 @@
...
@@ -28,13 +28,8 @@
* POSSIBILITY OF SUCH DAMAGE.
* POSSIBILITY OF SUCH DAMAGE.
*/
*/
#include "fmacros.h"
#include "server.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include "config.h"
#define ERROR(...) { \
#define ERROR(...) { \
char __buf[1024]; \
char __buf[1024]; \
...
@@ -60,7 +55,7 @@ int readLong(FILE *fp, char prefix, long *target) {
...
@@ -60,7 +55,7 @@ int readLong(FILE *fp, char prefix, long *target) {
return
0
;
return
0
;
}
}
if
(
buf
[
0
]
!=
prefix
)
{
if
(
buf
[
0
]
!=
prefix
)
{
ERROR
(
"Expected prefix '%c', got: '%c'"
,
buf
[
0
],
prefix
);
ERROR
(
"Expected prefix '%c', got: '%c'"
,
prefix
,
buf
[
0
]
);
return
0
;
return
0
;
}
}
*
target
=
strtol
(
buf
+
1
,
&
eptr
,
10
);
*
target
=
strtol
(
buf
+
1
,
&
eptr
,
10
);
...
@@ -87,7 +82,7 @@ int readString(FILE *fp, char** target) {
...
@@ -87,7 +82,7 @@ int readString(FILE *fp, char** target) {
/* Increase length to also consume \r\n */
/* Increase length to also consume \r\n */
len
+=
2
;
len
+=
2
;
*
target
=
(
char
*
)
malloc
(
len
);
*
target
=
(
char
*
)
z
malloc
(
len
);
if
(
!
readBytes
(
fp
,
*
target
,
len
))
{
if
(
!
readBytes
(
fp
,
*
target
,
len
))
{
return
0
;
return
0
;
}
}
...
@@ -127,12 +122,12 @@ off_t process(FILE *fp) {
...
@@ -127,12 +122,12 @@ off_t process(FILE *fp) {
}
}
}
}
}
}
free
(
str
);
z
free
(
str
);
}
}
/* Stop if the loop did not finish */
/* Stop if the loop did not finish */
if
(
i
<
argc
)
{
if
(
i
<
argc
)
{
if
(
str
)
free
(
str
);
if
(
str
)
z
free
(
str
);
break
;
break
;
}
}
}
}
...
@@ -146,7 +141,7 @@ off_t process(FILE *fp) {
...
@@ -146,7 +141,7 @@ off_t process(FILE *fp) {
return
pos
;
return
pos
;
}
}
int
main
(
int
argc
,
char
**
argv
)
{
int
redis_check_aof_
main
(
int
argc
,
char
**
argv
)
{
char
*
filename
;
char
*
filename
;
int
fix
=
0
;
int
fix
=
0
;
...
@@ -185,6 +180,25 @@ int main(int argc, char **argv) {
...
@@ -185,6 +180,25 @@ int main(int argc, char **argv) {
exit
(
1
);
exit
(
1
);
}
}
/* This AOF file may have an RDB preamble. Check this to start, and if this
* is the case, start processing the RDB part. */
if
(
size
>=
8
)
{
/* There must be at least room for the RDB header. */
char
sig
[
5
];
int
has_preamble
=
fread
(
sig
,
sizeof
(
sig
),
1
,
fp
)
==
1
&&
memcmp
(
sig
,
"REDIS"
,
sizeof
(
sig
))
==
0
;
rewind
(
fp
);
if
(
has_preamble
)
{
printf
(
"The AOF appears to start with an RDB preamble.
\n
"
"Checking the RDB preamble to start:
\n
"
);
if
(
redis_check_rdb_main
(
argc
,
argv
,
fp
)
==
C_ERR
)
{
printf
(
"RDB preamble of AOF file is not sane, aborting.
\n
"
);
exit
(
1
);
}
else
{
printf
(
"RDB preamble is OK, proceding with AOF tail...
\n
"
);
}
}
}
off_t
pos
=
process
(
fp
);
off_t
pos
=
process
(
fp
);
off_t
diff
=
size
-
pos
;
off_t
diff
=
size
-
pos
;
printf
(
"AOF analyzed: size=%lld, ok_up_to=%lld, diff=%lld
\n
"
,
printf
(
"AOF analyzed: size=%lld, ok_up_to=%lld, diff=%lld
\n
"
,
...
@@ -214,5 +228,5 @@ int main(int argc, char **argv) {
...
@@ -214,5 +228,5 @@ int main(int argc, char **argv) {
}
}
fclose
(
fp
);
fclose
(
fp
);
return
0
;
exit
(
0
)
;
}
}
src/redis-check-rdb.c
View file @
fc7ecd8d
...
@@ -173,16 +173,18 @@ void rdbCheckSetupSignals(void) {
...
@@ -173,16 +173,18 @@ void rdbCheckSetupSignals(void) {
}
}
/* Check the specified RDB file. Return 0 if the RDB looks sane, otherwise
/* Check the specified RDB file. Return 0 if the RDB looks sane, otherwise
* 1 is returned. */
* 1 is returned.
int
redis_check_rdb
(
char
*
rdbfilename
)
{
* The file is specified as a filename in 'rdbfilename' if 'fp' is not NULL,
* otherwise the already open file 'fp' is checked. */
int
redis_check_rdb
(
char
*
rdbfilename
,
FILE
*
fp
)
{
uint64_t
dbid
;
uint64_t
dbid
;
int
type
,
rdbver
;
int
type
,
rdbver
;
char
buf
[
1024
];
char
buf
[
1024
];
long
long
expiretime
,
now
=
mstime
();
long
long
expiretime
,
now
=
mstime
();
FILE
*
fp
;
static
rio
rdb
;
/* Pointed by global struct riostate. */
static
rio
rdb
;
/* Pointed by global struct riostate. */
if
((
fp
=
fopen
(
rdbfilename
,
"r"
))
==
NULL
)
return
1
;
int
closefile
=
(
fp
==
NULL
);
if
(
fp
==
NULL
&&
(
fp
=
fopen
(
rdbfilename
,
"r"
))
==
NULL
)
return
1
;
rioInitWithFile
(
&
rdb
,
fp
);
rioInitWithFile
(
&
rdb
,
fp
);
rdbstate
.
rio
=
&
rdb
;
rdbstate
.
rio
=
&
rdb
;
...
@@ -310,7 +312,7 @@ int redis_check_rdb(char *rdbfilename) {
...
@@ -310,7 +312,7 @@ int redis_check_rdb(char *rdbfilename) {
}
}
}
}
fclose
(
fp
);
if
(
closefile
)
fclose
(
fp
);
return
0
;
return
0
;
eoferr:
/* unexpected end of file is handled here with a fatal exit */
eoferr:
/* unexpected end of file is handled here with a fatal exit */
...
@@ -323,12 +325,19 @@ eoferr: /* unexpected end of file is handled here with a fatal exit */
...
@@ -323,12 +325,19 @@ eoferr: /* unexpected end of file is handled here with a fatal exit */
}
}
/* RDB check main: called form redis.c when Redis is executed with the
/* RDB check main: called form redis.c when Redis is executed with the
* redis-check-rdb alias.
* redis-check-rdb alias
, on during RDB loading errors
.
*
*
* The function never returns, but exits with the status code according
* The function works in two ways: can be called with argc/argv as a
* to success (RDB is sane) or error (RDB is corrupted). */
* standalone executable, or called with a non NULL 'fp' argument if we
int
redis_check_rdb_main
(
int
argc
,
char
**
argv
)
{
* already have an open file to check. This happens when the function
if
(
argc
!=
2
)
{
* is used to check an RDB preamble inside an AOF file.
*
* When called with fp = NULL, the function never returns, but exits with the
* status code according to success (RDB is sane) or error (RDB is corrupted).
* Otherwise if called with a non NULL fp, the function returns C_OK or
* C_ERR depending on the success or failure. */
int
redis_check_rdb_main
(
int
argc
,
char
**
argv
,
FILE
*
fp
)
{
if
(
argc
!=
2
&&
fp
==
NULL
)
{
fprintf
(
stderr
,
"Usage: %s <rdb-file-name>
\n
"
,
argv
[
0
]);
fprintf
(
stderr
,
"Usage: %s <rdb-file-name>
\n
"
,
argv
[
0
]);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -341,10 +350,11 @@ int redis_check_rdb_main(int argc, char **argv) {
...
@@ -341,10 +350,11 @@ int redis_check_rdb_main(int argc, char **argv) {
rdbCheckMode
=
1
;
rdbCheckMode
=
1
;
rdbCheckInfo
(
"Checking RDB file %s"
,
argv
[
1
]);
rdbCheckInfo
(
"Checking RDB file %s"
,
argv
[
1
]);
rdbCheckSetupSignals
();
rdbCheckSetupSignals
();
int
retval
=
redis_check_rdb
(
argv
[
1
]);
int
retval
=
redis_check_rdb
(
argv
[
1
]
,
fp
);
if
(
retval
==
0
)
{
if
(
retval
==
0
)
{
rdbCheckInfo
(
"
\\
o/ RDB looks OK!
\\
o/"
);
rdbCheckInfo
(
"
\\
o/ RDB looks OK!
\\
o/"
);
rdbShowGenericInfo
();
rdbShowGenericInfo
();
}
}
if
(
fp
)
return
(
retval
==
0
)
?
C_OK
:
C_ERR
;
exit
(
retval
);
exit
(
retval
);
}
}
src/server.c
View file @
fc7ecd8d
...
@@ -3711,11 +3711,13 @@ int main(int argc, char **argv) {
...
@@ -3711,11 +3711,13 @@ int main(int argc, char **argv) {
initSentinel
();
initSentinel
();
}
}
/* Check if we need to start in redis-check-rdb mode. We just execute
/* Check if we need to start in redis-check-rdb
/aof
mode. We just execute
* the program main. However the program is part of the Redis executable
* the program main. However the program is part of the Redis executable
* so that we can easily execute an RDB check on loading errors. */
* so that we can easily execute an RDB check on loading errors. */
if
(
strstr
(
argv
[
0
],
"redis-check-rdb"
)
!=
NULL
)
if
(
strstr
(
argv
[
0
],
"redis-check-rdb"
)
!=
NULL
)
redis_check_rdb_main
(
argc
,
argv
);
redis_check_rdb_main
(
argc
,
argv
,
NULL
);
else
if
(
strstr
(
argv
[
0
],
"redis-check-aof"
)
!=
NULL
)
redis_check_aof_main
(
argc
,
argv
);
if
(
argc
>=
2
)
{
if
(
argc
>=
2
)
{
j
=
1
;
/* First option to parse in argv[] */
j
=
1
;
/* First option to parse in argv[] */
...
...
src/server.h
View file @
fc7ecd8d
...
@@ -1770,9 +1770,10 @@ void sentinelTimer(void);
...
@@ -1770,9 +1770,10 @@ void sentinelTimer(void);
char
*
sentinelHandleConfiguration
(
char
**
argv
,
int
argc
);
char
*
sentinelHandleConfiguration
(
char
**
argv
,
int
argc
);
void
sentinelIsRunning
(
void
);
void
sentinelIsRunning
(
void
);
/* redis-check-rdb */
/* redis-check-rdb & aof */
int
redis_check_rdb
(
char
*
rdbfilename
);
int
redis_check_rdb
(
char
*
rdbfilename
,
FILE
*
fp
);
int
redis_check_rdb_main
(
int
argc
,
char
**
argv
);
int
redis_check_rdb_main
(
int
argc
,
char
**
argv
,
FILE
*
fp
);
int
redis_check_aof_main
(
int
argc
,
char
**
argv
);
/* Scripting */
/* Scripting */
void
scriptingInit
(
int
setup
);
void
scriptingInit
(
int
setup
);
...
...
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