]>
git.saurik.com Git - redis.git/blob - src/redis-check-aof.c
11 sprintf(__buf, __VA_ARGS__); \
12 sprintf(error, "0x%16llx: %s", (long long)epos, __buf); \
15 static char error
[1024];
18 int consumeNewline(char *buf
) {
19 if (strncmp(buf
,"\r\n",2) != 0) {
20 ERROR("Expected \\r\\n, got: %02x%02x",buf
[0],buf
[1]);
26 int readLong(FILE *fp
, char prefix
, long *target
) {
29 if (fgets(buf
,sizeof(buf
),fp
) == NULL
) {
32 if (buf
[0] != prefix
) {
33 ERROR("Expected prefix '%c', got: '%c'",buf
[0],prefix
);
36 *target
= strtol(buf
+1,&eptr
,10);
37 return consumeNewline(eptr
);
40 int readBytes(FILE *fp
, char *target
, long length
) {
43 real
= fread(target
,1,length
,fp
);
45 ERROR("Expected to read %ld bytes, got %ld bytes",length
,real
);
51 int readString(FILE *fp
, char** target
) {
54 if (!readLong(fp
,'$',&len
)) {
58 /* Increase length to also consume \r\n */
60 *target
= (char*)malloc(len
);
61 if (!readBytes(fp
,*target
,len
)) {
64 if (!consumeNewline(*target
+len
-2)) {
67 (*target
)[len
-2] = '\0';
71 int readArgc(FILE *fp
, long *target
) {
72 return readLong(fp
,'*',target
);
75 off_t
process(FILE *fp
) {
82 if (!multi
) pos
= ftello(fp
);
83 if (!readArgc(fp
, &argc
)) break;
85 for (i
= 0; i
< argc
; i
++) {
86 if (!readString(fp
,&str
)) break;
88 if (strcasecmp(str
, "multi") == 0) {
90 ERROR("Unexpected MULTI");
93 } else if (strcasecmp(str
, "exec") == 0) {
95 ERROR("Unexpected EXEC");
103 /* Stop if the loop did not finish */
110 if (feof(fp
) && multi
&& strlen(error
) == 0) {
111 ERROR("Reached EOF before reading EXEC for MULTI");
113 if (strlen(error
) > 0) {
114 printf("%s\n", error
);
119 int main(int argc
, char **argv
) {
124 printf("Usage: %s [--fix] <file.aof>\n", argv
[0]);
126 } else if (argc
== 2) {
128 } else if (argc
== 3) {
129 if (strcmp(argv
[1],"--fix") != 0) {
130 printf("Invalid argument: %s\n", argv
[1]);
136 printf("Invalid arguments\n");
140 FILE *fp
= fopen(filename
,"r+");
142 printf("Cannot open file: %s\n", filename
);
146 struct redis_stat sb
;
147 if (redis_fstat(fileno(fp
),&sb
) == -1) {
148 printf("Cannot stat file: %s\n", filename
);
152 off_t size
= sb
.st_size
;
154 printf("Empty file: %s\n", filename
);
158 off_t pos
= process(fp
);
159 off_t diff
= size
-pos
;
160 printf("AOF analyzed: size=%lld, ok_up_to=%lld, diff=%lld\n",
161 (long long) size
, (long long) pos
, (long long) diff
);
165 printf("This will shrink the AOF from %lld bytes, with %lld bytes, to %lld bytes\n",(long long)size
,(long long)diff
,(long long)pos
);
166 printf("Continue? [y/N]: ");
167 if (fgets(buf
,sizeof(buf
),stdin
) == NULL
||
168 strncasecmp(buf
,"y",1) != 0) {
169 printf("Aborting...\n");
172 if (ftruncate(fileno(fp
), pos
) == -1) {
173 printf("Failed to truncate AOF\n");
176 printf("Successfully truncated AOF\n");
179 printf("AOF is not valid\n");
183 printf("AOF is valid\n");