summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/db.c18
-rw-r--r--tests/integration/aof.tcl46
-rw-r--r--tests/integration/rdb.tcl2
-rw-r--r--tests/integration/replication.tcl42
-rw-r--r--tests/unit/other.tcl20
5 files changed, 114 insertions, 14 deletions
diff --git a/src/db.c b/src/db.c
index 5b46b70ef..eaf45e9e3 100644
--- a/src/db.c
+++ b/src/db.c
@@ -602,18 +602,11 @@ void flushAllDataAndResetRDB(int flags) {
server.dirty += emptyData(-1,flags,NULL);
if (server.child_type == CHILD_TYPE_RDB) killRDBChild();
if (server.saveparamslen > 0) {
- /* Normally rdbSave() will reset dirty, but we don't want this here
- * as otherwise FLUSHALL will not be replicated nor put into the AOF. */
- int saved_dirty = server.dirty;
rdbSaveInfo rsi, *rsiptr;
rsiptr = rdbPopulateSaveInfo(&rsi);
rdbSave(SLAVE_REQ_NONE,server.rdb_filename,rsiptr);
- server.dirty = saved_dirty;
}
- /* Without that extra dirty++, when db was already empty, FLUSHALL will
- * not be replicated nor put into the AOF. */
- server.dirty++;
#if defined(USE_JEMALLOC)
/* jemalloc 5 doesn't release pages back to the OS when there's no traffic.
* for large databases, flushdb blocks for long anyway, so a bit more won't
@@ -632,7 +625,13 @@ void flushdbCommand(client *c) {
if (getFlushCommandFlags(c,&flags) == C_ERR) return;
/* flushdb should not flush the functions */
server.dirty += emptyData(c->db->id,flags | EMPTYDB_NOFUNCTIONS,NULL);
+
+ /* Without the forceCommandPropagation, when DB was already empty,
+ * FLUSHDB will not be replicated nor put into the AOF. */
+ forceCommandPropagation(c, PROPAGATE_REPL | PROPAGATE_AOF);
+
addReply(c,shared.ok);
+
#if defined(USE_JEMALLOC)
/* jemalloc 5 doesn't release pages back to the OS when there's no traffic.
* for large databases, flushdb blocks for long anyway, so a bit more won't
@@ -650,6 +649,11 @@ void flushallCommand(client *c) {
if (getFlushCommandFlags(c,&flags) == C_ERR) return;
/* flushall should not flush the functions */
flushAllDataAndResetRDB(flags | EMPTYDB_NOFUNCTIONS);
+
+ /* Without the forceCommandPropagation, when DBs were already empty,
+ * FLUSHALL will not be replicated nor put into the AOF. */
+ forceCommandPropagation(c, PROPAGATE_REPL | PROPAGATE_AOF);
+
addReply(c,shared.ok);
}
diff --git a/tests/integration/aof.tcl b/tests/integration/aof.tcl
index 3d8c08c51..1f73fc341 100644
--- a/tests/integration/aof.tcl
+++ b/tests/integration/aof.tcl
@@ -632,4 +632,50 @@ tags {"aof external:skip"} {
} result
assert_match "*Failed to truncate AOF*to timestamp*because it is not the last file*" $result
}
+
+ start_server {overrides {appendonly yes appendfsync always}} {
+ test {FLUSHDB / FLUSHALL should persist in AOF} {
+ set aof [get_last_incr_aof_path r]
+
+ r set key value
+ r flushdb
+ r set key value2
+ r flushdb
+
+ # DB is empty
+ r flushdb
+ r flushdb
+ r flushdb
+
+ r set key value
+ r flushall
+ r set key value2
+ r flushall
+
+ # DBs are empty.
+ r flushall
+ r flushall
+ r flushall
+
+ # Assert that each FLUSHDB command is persisted even the DB is empty.
+ # Assert that each FLUSHALL command is persisted even the DBs are empty.
+ assert_aof_content $aof {
+ {select *}
+ {set key value}
+ {flushdb}
+ {set key value2}
+ {flushdb}
+ {flushdb}
+ {flushdb}
+ {flushdb}
+ {set key value}
+ {flushall}
+ {set key value2}
+ {flushall}
+ {flushall}
+ {flushall}
+ {flushall}
+ }
+ }
+ }
}
diff --git a/tests/integration/rdb.tcl b/tests/integration/rdb.tcl
index 652431ee7..326a17350 100644
--- a/tests/integration/rdb.tcl
+++ b/tests/integration/rdb.tcl
@@ -278,7 +278,7 @@ start_server {overrides {save ""}} {
set current_save_keys_total [s current_save_keys_total]
if {$::verbose} {
- puts "Keys before bgsave start: current_save_keys_total"
+ puts "Keys before bgsave start: $current_save_keys_total"
}
# on each iteration, we will write some key to the server to trigger copy-on-write, and
diff --git a/tests/integration/replication.tcl b/tests/integration/replication.tcl
index 44915be1b..d60c91918 100644
--- a/tests/integration/replication.tcl
+++ b/tests/integration/replication.tcl
@@ -225,11 +225,45 @@ start_server {tags {"repl external:skip"}} {
}
}
- test {FLUSHALL should replicate} {
+ test {FLUSHDB / FLUSHALL should replicate} {
+ set repl [attach_to_replication_stream]
+
+ r -1 set key value
+ r -1 flushdb
+
+ r -1 set key value2
+ r -1 flushall
+
+ wait_for_ofs_sync [srv 0 client] [srv -1 client]
+ assert_equal [r -1 dbsize] 0
+ assert_equal [r 0 dbsize] 0
+
+ # DB is empty.
+ r -1 flushdb
+ r -1 flushdb
+ r -1 flushdb
+
+ # DBs are empty.
r -1 flushall
- if {$::valgrind} {after 2000}
- list [r -1 dbsize] [r 0 dbsize]
- } {0 0}
+ r -1 flushall
+ r -1 flushall
+
+ # Assert that each FLUSHDB command is replicated even the DB is empty.
+ # Assert that each FLUSHALL command is replicated even the DBs are empty.
+ assert_replication_stream $repl {
+ {set key value}
+ {flushdb}
+ {set key value2}
+ {flushall}
+ {flushdb}
+ {flushdb}
+ {flushdb}
+ {flushall}
+ {flushall}
+ {flushall}
+ }
+ close_replication_stream $repl
+ }
test {ROLE in master reports master with a slave} {
set res [r -1 role]
diff --git a/tests/unit/other.tcl b/tests/unit/other.tcl
index bd220a145..2ae09b5b7 100644
--- a/tests/unit/other.tcl
+++ b/tests/unit/other.tcl
@@ -38,9 +38,25 @@ start_server {tags {"other"}} {
}
}
+ start_server {overrides {save ""} tags {external:skip}} {
+ test {FLUSHALL should not reset the dirty counter if we disable save} {
+ r set key value
+ r flushall
+ assert_morethan [s rdb_changes_since_last_save] 0
+ }
+
+ test {FLUSHALL should reset the dirty counter to 0 if we enable save} {
+ r config set save "3600 1 300 100 60 10000"
+ r set key value
+ r flushall
+ assert_equal [s rdb_changes_since_last_save] 0
+ }
+ }
+
test {BGSAVE} {
- r flushdb
- waitForBgsave r
+ # Use FLUSHALL instead of FLUSHDB, FLUSHALL do a foreground save
+ # and reset the dirty counter to 0, so we won't trigger an unexpected bgsave.
+ r flushall
r save
r set x 10
r bgsave