Skip to content

Commit 42543b6

Browse files
riversand963tabokie
authored andcommitted
Fix race condition between file purge and backup/checkpoint (facebook#10187)
Summary: Resolves facebook#10129 I extracted this fix from facebook#7516 since it's also already a bug in main branch, and we want to separate it from the main part of the PR. There can be a race condition between two threads. Thread 1 executes `DBImpl::FindObsoleteFiles()` while thread 2 executes `GetSortedWals()`. ``` Time thread 1 thread 2 | mutex_.lock | read disable_delete_obsolete_files_ | ... | wait on log_sync_cv and release mutex_ | mutex_.lock | ++disable_delete_obsolete_files_ | mutex_.unlock | mutex_.lock | while (pending_purge_obsolete_files > 0) { bg_cv.wait;} | wake up with mutex_ locked | compute WALs tracked by MANIFEST | mutex_.unlock | wake up with mutex_ locked | ++pending_purge_obsolete_files_ | mutex_.unlock | | delete obsolete WAL | WAL missing but tracked in MANIFEST. V ``` The fix proposed eliminates the possibility of the above by increasing `pending_purge_obsolete_files_` before `FindObsoleteFiles()` can possibly release the mutex. Pull Request resolved: facebook#10187 Test Plan: make check Reviewed By: ltamasi Differential Revision: D37214235 Pulled By: riversand963 fbshipit-source-id: 556ab1b58ae6d19150169dfac4db08195c797184 Signed-off-by: tabokie <[email protected]>
1 parent 9e56a18 commit 42543b6

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

HISTORY.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Fix unprotected concurrent accesses to `WritableFileWriter::filesize_` by `DB::SyncWAL()` and `DB::Put()` in two write queue mode.
66
* Fix a bug in WAL tracking. Before this PR (#10087), calling `SyncWAL()` on the only WAL file of the db will not log the event in MANIFEST, thus allowing a subsequent `DB::Open` even if the WAL file is missing or corrupted.
77
* Fixed a possible corruption for users of `manual_wal_flush` and/or `FlushWAL(true /* sync */)`, together with `track_and_verify_wals_in_manifest == true`. For those users, losing unsynced data (e.g., due to power loss) could make future DB opens fail with a `Status::Corruption` complaining about missing WAL data.
8+
* Fix a bug in which backup/checkpoint can include a WAL deleted by RocksDB.
89

910
### Public API changes
1011
* Remove ReadOptions::iter_start_seqnum which has been deprecated.

db/db_impl/db_impl_files.cc

+17-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "logging/logging.h"
2020
#include "port/port.h"
2121
#include "util/autovector.h"
22+
#include "util/defer.h"
2223

2324
namespace ROCKSDB_NAMESPACE {
2425

@@ -252,6 +253,22 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
252253
job_context->blob_delete_files);
253254
}
254255

256+
// Before potentially releasing mutex and waiting on condvar, increment
257+
// pending_purge_obsolete_files_ so that another thread executing
258+
// `GetSortedWals` will wait until this thread finishes execution since the
259+
// other thread will be waiting for `pending_purge_obsolete_files_`.
260+
// pending_purge_obsolete_files_ MUST be decremented if there is nothing to
261+
// delete.
262+
++pending_purge_obsolete_files_;
263+
264+
Defer cleanup([job_context, this]() {
265+
assert(job_context != nullptr);
266+
if (!job_context->HaveSomethingToDelete()) {
267+
mutex_.AssertHeld();
268+
--pending_purge_obsolete_files_;
269+
}
270+
});
271+
255272
// logs_ is empty when called during recovery, in which case there can't yet
256273
// be any tracked obsolete logs
257274
if (!alive_log_files_.empty() && !logs_.empty()) {
@@ -308,9 +325,6 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
308325
job_context->logs_to_free = logs_to_free_;
309326
job_context->log_recycle_files.assign(log_recycle_files_.begin(),
310327
log_recycle_files_.end());
311-
if (job_context->HaveSomethingToDelete()) {
312-
++pending_purge_obsolete_files_;
313-
}
314328
logs_to_free_.clear();
315329
}
316330

0 commit comments

Comments
 (0)