Skip to content

Commit e96e4fb

Browse files
committed
Two important fixes to append only file: zero length values and expires. A pretty neat new test to check consistency of randomly build datasets against snapshotting and AOF.
1 parent 71c2b46 commit e96e4fb

File tree

3 files changed

+63
-16
lines changed

3 files changed

+63
-16
lines changed

redis.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -5868,7 +5868,8 @@ static int fwriteBulk(FILE *fp, robj *obj) {
58685868
obj = getDecodedObject(obj);
58695869
snprintf(buf,sizeof(buf),"$%ld\r\n",(long)sdslen(obj->ptr));
58705870
if (fwrite(buf,strlen(buf),1,fp) == 0) goto err;
5871-
if (fwrite(obj->ptr,sdslen(obj->ptr),1,fp) == 0) goto err;
5871+
if (sdslen(obj->ptr) && fwrite(obj->ptr,sdslen(obj->ptr),1,fp) == 0)
5872+
goto err;
58725873
if (fwrite("\r\n",2,1,fp) == 0) goto err;
58735874
decrRefCount(obj);
58745875
return 1;
@@ -5997,7 +5998,7 @@ static int rewriteAppendOnlyFile(char *filename) {
59975998
}
59985999
/* Save the expire time */
59996000
if (expiretime != -1) {
6000-
char cmd[]="*3\r\n$6\r\nEXPIRE\r\n";
6001+
char cmd[]="*3\r\n$8\r\nEXPIREAT\r\n";
60016002
/* If this key is already expired skip it */
60026003
if (expiretime < now) continue;
60036004
if (fwrite(cmd,sizeof(cmd)-1,1,fp) == 0) goto werr;
@@ -6026,7 +6027,7 @@ static int rewriteAppendOnlyFile(char *filename) {
60266027
werr:
60276028
fclose(fp);
60286029
unlink(tmpfile);
6029-
redisLog(REDIS_WARNING,"Write error writing append only fileon disk: %s", strerror(errno));
6030+
redisLog(REDIS_WARNING,"Write error writing append only file on disk: %s", strerror(errno));
60306031
if (di) dictReleaseIterator(di);
60316032
return REDIS_ERR;
60326033
}

test-redis.tcl

+56-11
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ proc waitForBgsave r {
6565
}
6666
}
6767

68+
proc waitForBgrewriteaof r {
69+
while 1 {
70+
set i [$r info]
71+
if {[string match {*bgrewriteaof_in_progress:1*} $i]} {
72+
puts -nonewline "\nWaiting for background AOF rewrite to finish... "
73+
flush stdout
74+
after 1000
75+
} else {
76+
break
77+
}
78+
}
79+
}
80+
6881
proc randomInt {max} {
6982
expr {int(rand()*$max)}
7083
}
@@ -154,17 +167,36 @@ proc createComplexDataset {r ops} {
154167

155168
proc datasetDigest r {
156169
set keys [lsort [split [$r keys *] " "]]
157-
set digest [::sha1::sha1 -hex $keys]
170+
set digest {}
158171
foreach k $keys {
159172
set t [$r type $k]
160-
switch t {
161-
{string} {set aux [::sha1::sha1 -hex [$r get $k]]} \
162-
{list} {set aux [::sha1::sha1 -hex [$r lrange $k 0 -1]]} \
163-
{set} {set aux [::sha1::sha1 -hex [$r smembers $k]]} \
164-
{zset} {set aux [::sha1::sha1 -hex [$r zrange $k 0 -1]]}
173+
switch $t {
174+
{string} {
175+
set aux [::sha1::sha1 -hex [$r get $k]]
176+
} {list} {
177+
if {[$r llen $k] == 0} {
178+
set aux {}
179+
} else {
180+
set aux [::sha1::sha1 -hex [$r lrange $k 0 -1]]
181+
}
182+
} {set} {
183+
if {[$r scard $k] == 0} {
184+
set aux {}
185+
} else {
186+
set aux [::sha1::sha1 -hex [lsort [$r smembers $k]]]
187+
}
188+
} {zset} {
189+
if {[$r zcard $k] == 0} {
190+
set aux {}
191+
} else {
192+
set aux [::sha1::sha1 -hex [$r zrange $k 0 -1]]
193+
}
194+
} default {
195+
error "Type not supported"
196+
}
165197
}
166-
append aux $digest
167-
set digest [::sha1::sha1 -hex $aux]
198+
if {$aux eq {}} continue
199+
set digest [::sha1::sha1 -hex [join [list $aux $digest $k] "\n"]]
168200
}
169201
return $digest
170202
}
@@ -1392,17 +1424,30 @@ proc main {server port} {
13921424
set sha1_after [datasetDigest $r]
13931425
expr {$sha1 eq $sha1_after}
13941426
} {1}
1427+
1428+
test {Same dataset digest if saving/reloading as AOF?} {
1429+
$r bgrewriteaof
1430+
waitForBgrewriteaof $r
1431+
$r debug loadaof
1432+
set sha1_after [datasetDigest $r]
1433+
expr {$sha1 eq $sha1_after}
1434+
} {1}
13951435
}
13961436

1397-
test {EXPIRES after a reload} {
1437+
test {EXPIRES after a reload (snapshot + append only file)} {
13981438
$r flushdb
13991439
$r set x 10
14001440
$r expire x 1000
14011441
$r save
14021442
$r debug reload
14031443
set ttl [$r ttl x]
1404-
expr {$ttl > 900 && $ttl <= 1000}
1405-
} {1}
1444+
set e1 [expr {$ttl > 900 && $ttl <= 1000}]
1445+
$r bgrewriteaof
1446+
waitForBgrewriteaof $r
1447+
set ttl [$r ttl x]
1448+
set e2 [expr {$ttl > 900 && $ttl <= 1000}]
1449+
list $e1 $e2
1450+
} {1 1}
14061451

14071452
# Leave the user with a clean DB before to exit
14081453
test {FLUSHDB} {

utils/redis-sha1.rb

+3-2
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,6 @@ def redisSha1(opts={})
4747

4848
host = ARGV[0] || "127.0.0.1"
4949
port = ARGV[1] || "6379"
50-
puts "Performing SHA1 of Redis server #{host} #{port}"
51-
p "Dataset SHA1: #{redisSha1(:host => host, :port => port.to_i)}"
50+
db = ARGV[2] || "0"
51+
puts "Performing SHA1 of Redis server #{host} #{port} DB: #{db}"
52+
p "Dataset SHA1: #{redisSha1(:host => host, :port => port.to_i, :db => db)}"

0 commit comments

Comments
 (0)