Ensure writes to WAL tail during FlushWAL(true /* sync */) will be synced#10560
Ensure writes to WAL tail during FlushWAL(true /* sync */) will be synced#10560ajkr wants to merge 5 commits intofacebook:mainfrom
FlushWAL(true /* sync */) will be synced#10560Conversation
|
@ajkr has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
|
@ajkr has updated the pull request. You must reimport the pull request before landing. |
|
@ajkr has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
|
@ajkr has updated the pull request. You must reimport the pull request before landing. |
|
@ajkr has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
|
@ajkr has updated the pull request. You must reimport the pull request before landing. |
|
@ajkr has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
db/db_impl/db_impl.cc
Outdated
There was a problem hiding this comment.
Can we add an assertion as below?
if (wal.GetPreSyncSize() == wal.writer->file()->GetFlushedSize()) {
// Fully synced
logs_to_free_.push_back(wal.ReleaseWriter());
it = logs_.erase(it);
} else if (wal.GetPreSyncSize() < wal.writer->file()->GetFlushedSize()) {
wal.FinishSync();
++it;
} else {
assert(false);
}There was a problem hiding this comment.
Done, though slightly differently as that gives me fear of infinite loop
There was a problem hiding this comment.
@ajkr It might be noob question. How is it ensured that no other thread is writing to this wal file at this point.
There was a problem hiding this comment.
It looks like wal.number < logs_.back().number tells us the log is inactive because a newer one exists, and we only append to the newest (active) WAL.
ajkr
left a comment
There was a problem hiding this comment.
Thanks for the review!
db/db_impl/db_impl.cc
Outdated
There was a problem hiding this comment.
Done, though slightly differently as that gives me fear of infinite loop
8e48be3 to
6c3d5ae
Compare
|
@ajkr has updated the pull request. You must reimport the pull request before landing. |
|
@ajkr has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
…synced (facebook#10560) Summary: WAL append and switch can both happen between `FlushWAL(true /* sync */)`'s sync operations and its call to `MarkLogsSynced()`. We permit this since locks need to be released for the sync operations. Such an appended/switched WAL is both inactive and incompletely synced at the time `MarkLogsSynced()` processes it. Prior to this PR, `MarkLogsSynced()` assumed all inactive WALs were fully synced and removed them from consideration for future syncs. That was wrong in the scenario described above and led to the latest append(s) never being synced. This PR changes `MarkLogsSynced()` to only remove inactive WALs from consideration for which all flushed data has been synced. Pull Request resolved: facebook#10560 Test Plan: repro unit test for the scenario described above. Without this PR, it fails on "key2" not found Reviewed By: riversand963 Differential Revision: D38957391 Pulled By: ajkr fbshipit-source-id: da77175eba97ff251a4219b227b3bb2d4843ed26
…synced (facebook#10560) Summary: WAL append and switch can both happen between `FlushWAL(true /* sync */)`'s sync operations and its call to `MarkLogsSynced()`. We permit this since locks need to be released for the sync operations. Such an appended/switched WAL is both inactive and incompletely synced at the time `MarkLogsSynced()` processes it. Prior to this PR, `MarkLogsSynced()` assumed all inactive WALs were fully synced and removed them from consideration for future syncs. That was wrong in the scenario described above and led to the latest append(s) never being synced. This PR changes `MarkLogsSynced()` to only remove inactive WALs from consideration for which all flushed data has been synced. Pull Request resolved: facebook#10560 Test Plan: repro unit test for the scenario described above. Without this PR, it fails on "key2" not found Reviewed By: riversand963 Differential Revision: D38957391 Pulled By: ajkr fbshipit-source-id: da77175eba97ff251a4219b227b3bb2d4843ed26
…synced (facebook#10560) (#357) Summary: WAL append and switch can both happen between `FlushWAL(true /* sync */)`'s sync operations and its call to `MarkLogsSynced()`. We permit this since locks need to be released for the sync operations. Such an appended/switched WAL is both inactive and incompletely synced at the time `MarkLogsSynced()` processes it. Prior to this PR, `MarkLogsSynced()` assumed all inactive WALs were fully synced and removed them from consideration for future syncs. That was wrong in the scenario described above and led to the latest append(s) never being synced. This PR changes `MarkLogsSynced()` to only remove inactive WALs from consideration for which all flushed data has been synced. Pull Request resolved: facebook#10560 Test Plan: repro unit test for the scenario described above. Without this PR, it fails on "key2" not found Reviewed By: riversand963 Differential Revision: D38957391 Pulled By: ajkr fbshipit-source-id: da77175eba97ff251a4219b227b3bb2d4843ed26 Co-authored-by: Andrew Kryczka <andrewkr@fb.com>
| if (logs_.size() > 1) { | ||
| if (wal.number < logs_.back().number) { | ||
| // Inactive WAL | ||
| if (immutable_db_options_.track_and_verify_wals_in_manifest && |
There was a problem hiding this comment.
line 1537 to 1541 should be moved to if block at line 1541
There was a problem hiding this comment.
I thought the WAL tracking was designed to allow a WAL's synced size to grow over multiple manifest entries. For some time we were even tracking the active WAL's synced size so this was a requirement. If you are confident this logic causes errors, though, I will look deeper into this.
…synced (facebook#10560) Summary: WAL append and switch can both happen between `FlushWAL(true /* sync */)`'s sync operations and its call to `MarkLogsSynced()`. We permit this since locks need to be released for the sync operations. Such an appended/switched WAL is both inactive and incompletely synced at the time `MarkLogsSynced()` processes it. Prior to this PR, `MarkLogsSynced()` assumed all inactive WALs were fully synced and removed them from consideration for future syncs. That was wrong in the scenario described above and led to the latest append(s) never being synced. This PR changes `MarkLogsSynced()` to only remove inactive WALs from consideration for which all flushed data has been synced. Pull Request resolved: facebook#10560 Test Plan: repro unit test for the scenario described above. Without this PR, it fails on "key2" not found Reviewed By: riversand963 Differential Revision: D38957391 Pulled By: ajkr fbshipit-source-id: da77175eba97ff251a4219b227b3bb2d4843ed26
#358) * Ensure writes to WAL tail during `FlushWAL(true /* sync */)` will be synced (facebook#10560) Summary: WAL append and switch can both happen between `FlushWAL(true /* sync */)`'s sync operations and its call to `MarkLogsSynced()`. We permit this since locks need to be released for the sync operations. Such an appended/switched WAL is both inactive and incompletely synced at the time `MarkLogsSynced()` processes it. Prior to this PR, `MarkLogsSynced()` assumed all inactive WALs were fully synced and removed them from consideration for future syncs. That was wrong in the scenario described above and led to the latest append(s) never being synced. This PR changes `MarkLogsSynced()` to only remove inactive WALs from consideration for which all flushed data has been synced. Pull Request resolved: facebook#10560 Test Plan: repro unit test for the scenario described above. Without this PR, it fails on "key2" not found Reviewed By: riversand963 Differential Revision: D38957391 Pulled By: ajkr fbshipit-source-id: da77175eba97ff251a4219b227b3bb2d4843ed26 * comment out test Signed-off-by: Connor1996 <zbk602423539@gmail.com> --------- Signed-off-by: Connor1996 <zbk602423539@gmail.com> Co-authored-by: Andrew Kryczka <andrewkr@fb.com>
|
@ajkr If the memtable is switched after the population of log_context->writer but before a writer writes to the Write-Ahead Log , is there a chance of a race condition occurring? If this race condition does occur, the presync size will be the same as the flush size, resulting in the release of the log while writer is still writing to it. |
Summary: Our `FileSystem` for simulating unsynced data loss should not sync during `Close()` because it masks bugs where we forgot to sync as long as we closed the file. Pull Request resolved: #12528 Test Plan: Peeled back #10560 fix and verified it is caught much faster now (few seconds vs. ???) with command like ``` $ TEST_TMPDIR=./ python3 tools/db_crashtest.py blackbox --disable_wal=0 --max_key=1000 --write_buffer_size=131072 --max_bytes_for_level_base=524288 --target_file_size_base=131072 --interval=3 --sync_fault_injection=1 --enable_blob_files=0 --manual_wal_flush_one_in=10 --sync_wal_one_in=0 --get_live_files_one_in=0 --get_sorted_wal_files_one_in=0 --backup_one_in=0 --checkpoint_one_in=0 --write_fault_one_in=0 --read_fault_one_in=0 --open_write_fault_one_in=0 --compact_range_one_in=0 --compact_files_one_in=0 --open_read_fault_one_in=0 --get_property_one_in=0 --writepercent=100 -readpercent=0 -prefixpercent=0 -delpercent=0 -delrangepercent=0 -iterpercent=0 ``` Reviewed By: anand1976 Differential Revision: D56033250 Pulled By: ajkr fbshipit-source-id: 6bbf480d79a06c46f08f6214010937f6654af5ca
|
@ajkr do you think the scenario described above is valid ? |
WAL append and switch can both happen between
FlushWAL(true /* sync */)'s sync operations and its call toMarkLogsSynced(). We permit this since locks need to be released for the sync operations. Such an appended/switched WAL is both inactive and incompletely synced at the timeMarkLogsSynced()processes it.Prior to this PR,
MarkLogsSynced()assumed all inactive WALs were fully synced and removed them from consideration for future syncs. That was wrong in the scenario described above and led to the latest append(s) never being synced. This PR changesMarkLogsSynced()to only remove inactive WALs from consideration for which all flushed data has been synced.Test Plan: repro unit test for the scenario described above. Without this PR, it fails on "key2" not found