From 6478526597601b23455fef75a3a87f030bd12bd2 Mon Sep 17 00:00:00 2001 From: Binbin Date: Sat, 7 Sep 2024 23:27:59 +0800 Subject: [PATCH] Fix aof base suffix when modifying aof-use-rdb-preamble during rewrite (#886) If we modify aof-use-rdb-preamble in the middle of rewrite, we may get a wrong aof base suffix. This is because the suffix is concatenated by the main process afterwards, and it may be different from the beginning. We cache this value when we start the rewrite. Signed-off-by: Binbin --- src/aof.c | 9 ++++---- src/server.h | 1 + tests/integration/aof-multi-part.tcl | 32 ++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/aof.c b/src/aof.c index b0b277c06d..f48c8bd1bc 100644 --- a/src/aof.c +++ b/src/aof.c @@ -423,7 +423,7 @@ void aofManifestFreeAndUpdate(aofManifest *am) { * appendonly.aof.1.base.aof (server.aof_use_rdb_preamble is no) * appendonly.aof.1.base.rdb (server.aof_use_rdb_preamble is yes) */ -sds getNewBaseFileNameAndMarkPreAsHistory(aofManifest *am) { +sds getNewBaseFileNameAndMarkPreAsHistory(aofManifest *am, int aof_use_rdb_preamble) { serverAssert(am != NULL); if (am->base_aof_info) { serverAssert(am->base_aof_info->file_type == AOF_FILE_TYPE_BASE); @@ -431,7 +431,7 @@ sds getNewBaseFileNameAndMarkPreAsHistory(aofManifest *am) { listAddNodeHead(am->history_aof_list, am->base_aof_info); } - char *format_suffix = server.aof_use_rdb_preamble ? RDB_FORMAT_SUFFIX : AOF_FORMAT_SUFFIX; + char *format_suffix = aof_use_rdb_preamble ? RDB_FORMAT_SUFFIX : AOF_FORMAT_SUFFIX; aofInfo *ai = aofInfoCreate(); ai->file_name = sdscatprintf(sdsempty(), "%s.%lld%s%s", server.aof_filename, ++am->curr_base_file_seq, @@ -712,7 +712,7 @@ void aofOpenIfNeededOnServerStart(void) { /* If we start with an empty dataset, we will force create a BASE file. */ size_t incr_aof_len = listLength(server.aof_manifest->incr_aof_list); if (!server.aof_manifest->base_aof_info && !incr_aof_len) { - sds base_name = getNewBaseFileNameAndMarkPreAsHistory(server.aof_manifest); + sds base_name = getNewBaseFileNameAndMarkPreAsHistory(server.aof_manifest, server.aof_use_rdb_preamble); sds base_filepath = makePath(server.aof_dirname, base_name); if (rewriteAppendOnlyFile(base_filepath) != C_OK) { exit(1); @@ -2445,6 +2445,7 @@ int rewriteAppendOnlyFileBackground(void) { serverLog(LL_NOTICE, "Background append only file rewriting started by pid %ld", (long)childpid); server.aof_rewrite_scheduled = 0; server.aof_rewrite_time_start = time(NULL); + server.aof_rewrite_use_rdb_preamble = server.aof_use_rdb_preamble; return C_OK; } return C_OK; /* unreached */ @@ -2557,7 +2558,7 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { /* Get a new BASE file name and mark the previous (if we have) * as the HISTORY type. */ - sds new_base_filename = getNewBaseFileNameAndMarkPreAsHistory(temp_am); + sds new_base_filename = getNewBaseFileNameAndMarkPreAsHistory(temp_am, server.aof_rewrite_use_rdb_preamble); serverAssert(new_base_filename != NULL); new_base_filepath = makePath(server.aof_dirname, new_base_filename); diff --git a/src/server.h b/src/server.h index 5d47951dab..2e070b0b25 100644 --- a/src/server.h +++ b/src/server.h @@ -1939,6 +1939,7 @@ struct valkeyServer { int aof_last_write_errno; /* Valid if aof write/fsync status is ERR */ int aof_load_truncated; /* Don't stop on unexpected AOF EOF. */ int aof_use_rdb_preamble; /* Specify base AOF to use RDB encoding on AOF rewrites. */ + int aof_rewrite_use_rdb_preamble; /* Base AOF to use RDB encoding on AOF rewrites start. */ _Atomic int aof_bio_fsync_status; /* Status of AOF fsync in bio job. */ _Atomic int aof_bio_fsync_errno; /* Errno of AOF fsync in bio job. */ aofManifest *aof_manifest; /* Used to track AOFs. */ diff --git a/tests/integration/aof-multi-part.tcl b/tests/integration/aof-multi-part.tcl index 977bb11e4c..5c4f24b7d4 100644 --- a/tests/integration/aof-multi-part.tcl +++ b/tests/integration/aof-multi-part.tcl @@ -746,6 +746,38 @@ tags {"external:skip"} { clean_aof_persistence $aof_dirpath } + test {Changing aof-use-rdb-preamble during rewrite process} { + start_server_aof [list dir $server_path aof-use-rdb-preamble no] { + wait_done_loading r + + assert_equal 1 [check_file_exist $aof_dirpath "${aof_basename}.1${::base_aof_sufix}${::aof_format_suffix}"] + + assert_aof_manifest_content $aof_manifest_file { + {file appendonly.aof.1.base.aof seq 1 type b} + {file appendonly.aof.1.incr.aof seq 1 type i} + } + + r set foo bar + r config set rdb-key-save-delay 1000000 + r bgrewriteaof + wait_for_condition 100 10 { + [s aof_rewrite_in_progress] eq 1 + } else { + fail "aof rewrite did not start in time" + } + r config set aof-use-rdb-preamble yes + r config set rdb-key-save-delay 0 + waitForBgrewriteaof r + + assert_aof_manifest_content $aof_manifest_file { + {file appendonly.aof.2.base.aof seq 2 type b} + {file appendonly.aof.2.incr.aof seq 2 type i} + } + } + + clean_aof_persistence $aof_dirpath + } + # Test Part 2 # # To test whether the AOFRW behaves as expected during the server run.