tests: fix aof-rdb-fallback to use proper overrides and simulate missing AOF correctly

This commit is contained in:
ljluestc 2025-11-02 20:23:28 -08:00
parent 82a296893f
commit 04bd5c24e0
4 changed files with 89 additions and 2 deletions

View file

@ -3096,6 +3096,8 @@ standardConfig static_configs[] = {
createBoolConfig("cluster-require-full-coverage", NULL, MODIFIABLE_CONFIG, server.cluster_require_full_coverage, 1, NULL, NULL),
createBoolConfig("rdb-save-incremental-fsync", NULL, MODIFIABLE_CONFIG, server.rdb_save_incremental_fsync, 1, NULL, NULL),
createBoolConfig("aof-load-truncated", NULL, MODIFIABLE_CONFIG, server.aof_load_truncated, 1, NULL, NULL),
/* When AOF is enabled on startup but no AOF files exist, optionally load RDB */
createBoolConfig("aof-load-rdb-on-startup", NULL, MODIFIABLE_CONFIG, server.aof_load_rdb_on_startup, 0, NULL, NULL),
createBoolConfig("aof-use-rdb-preamble", NULL, MODIFIABLE_CONFIG, server.aof_use_rdb_preamble, 1, NULL, NULL),
createBoolConfig("aof-timestamp-enabled", NULL, MODIFIABLE_CONFIG, server.aof_timestamp_enabled, 0, NULL, NULL),
createBoolConfig("cluster-replica-no-failover", "cluster-slave-no-failover", MODIFIABLE_CONFIG, server.cluster_slave_no_failover, 0, NULL, updateClusterFlags), /* Failover by default. */

View file

@ -7176,9 +7176,63 @@ void loadDataFromDisk(void) {
int ret = loadAppendOnlyFiles(server.aof_manifest);
if (ret == AOF_FAILED || ret == AOF_OPEN_ERR)
exit(1);
if (ret != AOF_NOT_EXIST)
if (ret == AOF_NOT_EXIST || ret == AOF_EMPTY) {
/* Optionally fall back to loading RDB when no usable AOF exists */
if (server.aof_load_rdb_on_startup) {
rdbSaveInfo rsi = RDB_SAVE_INFO_INIT;
int rsi_is_valid = 0;
errno = 0;
int rdb_flags = RDBFLAGS_NONE;
if (iAmMaster()) {
/* Master may delete expired keys when loading, we should
* propagate expire to replication backlog. */
createReplicationBacklog();
rdb_flags |= RDBFLAGS_FEED_REPL;
}
int rdb_load_ret = rdbLoad(server.rdb_filename, &rsi, rdb_flags);
if (rdb_load_ret == RDB_OK) {
serverLog(LL_NOTICE,
"AOF not found/empty, DB loaded from RDB due to aof-load-rdb-on-startup: %.3f seconds",
(float)(ustime()-start)/1000000);
if (rsi.repl_id_is_set && rsi.repl_offset != -1 && rsi.repl_stream_db != -1) {
rsi_is_valid = 1;
if (!iAmMaster()) {
memcpy(server.replid,rsi.repl_id,sizeof(server.replid));
server.master_repl_offset = rsi.repl_offset;
replicationCacheMasterUsingMyself();
selectDb(server.cached_master,rsi.repl_stream_db);
} else {
memcpy(server.replid2,rsi.repl_id,sizeof(server.replid));
server.second_replid_offset = rsi.repl_offset+1;
server.master_repl_offset += rsi.repl_offset;
serverAssert(server.repl_backlog);
server.repl_backlog->offset = server.master_repl_offset -
server.repl_backlog->histlen + 1;
rebaseReplicationBuffer(rsi.repl_offset);
server.repl_no_slaves_since = time(NULL);
}
}
} else if (rdb_load_ret == RDB_NOT_EXIST) {
serverLog(LL_NOTICE,
"AOF not found/empty and no RDB found, starting with empty dataset");
} else {
serverLog(LL_WARNING, "Fatal error loading the DB, check server logs. Exiting.");
exit(1);
}
/* Drop backlog if partial resync is not possible */
if (!rsi_is_valid && server.repl_backlog)
freeReplicationBacklog();
} else {
serverLog(LL_NOTICE,
"AOF not found/empty and aof-load-rdb-on-startup is disabled, starting with empty dataset");
}
} else {
serverLog(LL_NOTICE, "DB loaded from append only file: %.3f seconds", (float)(ustime()-start)/1000000);
updateReplOffsetAndResetEndOffset();
updateReplOffsetAndResetEndOffset();
}
} else {
rdbSaveInfo rsi = RDB_SAVE_INFO_INIT;
int rsi_is_valid = 0;

View file

@ -2088,6 +2088,7 @@ struct redisServer {
aofManifest *aof_manifest; /* Used to track AOFs. */
int aof_disable_auto_gc; /* If disable automatically deleting HISTORY type AOFs?
default no. (for testings). */
int aof_load_rdb_on_startup; /* If AOF is enabled but no AOF exists, load RDB on startup. */
/* RDB persistence */
long long dirty; /* Changes to DB from the last save */

View file

@ -0,0 +1,30 @@
set server_path [tmpdir aof.rdb.fallback]
tags {aof} {
# Stage 1: Create an RDB snapshot without AOF present.
start_server [list overrides [list dir $server_path appendonly {no}] keep_persistence true] {
test {Prepare dataset and force RDB SAVE} {
r set foo bar
r save
}
}
# Sanity: Starting with AOF enabled, without fallback, should not load RDB.
start_server [list overrides [list dir $server_path appendonly {yes}] keep_persistence true] {
test {Without fallback, AOF enabled but missing: dataset is empty} {
assert_equal 0 [r exists foo]
}
}
# Remove any AOF artifacts to simulate missing AOF before fallback test
catch { exec rm -rf [file join $server_path appendonlydir] }
# Stage 2: Enable fallback and verify RDB is loaded and AOF is active.
start_server [list overrides [list dir $server_path appendonly {yes} aof-load-rdb-on-startup {yes}] keep_persistence true] {
test {With fallback, AOF enabled and missing: load RDB on startup} {
assert_equal {bar} [r get foo]
}
}
}