Fix backup/checkpoint stress test failure #12227
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes this type of stress test failure that could happen in either checkpoint or backup. Example failure messages are like this:
Failure in a backup/restore operation with: Corruption: 0x00000000000001D5000000000000012B00000000000000FD exists in original db but not in restore
A checkpoint operation failed with: Corruption: 0x0000000000000365000000000000012B0000000000000067 exists in original db but not in checkpoint /...
The internal task has an example test command to quickly reproduce this type of error.
The common symptom of these test failures are these expected keys do not exist in the original db either. The root cause is
TestCheckpoint
andTestBackupRestore
both use the expected state as a proxy for the state of the original db when it comes to check a key's existence.rocksdb/db_stress_tool/db_stress_test_base.cc
Line 1838 in 0758271
This
ExpectedState::Exists
API returns true if a key has a pending write, such as a pending put. In usual case, this pending put should either soon materialize to an actual write whenPendingExpectedValue::Commit
is called to reflect a successful write to the DB, or test should be safely terminated if write to DB fails. All of which happens while a key is locked. So checkpoint and backup usually won't see the discrepancy between db and expected state caused by pending writes. However, the external file ingestion test currently has a path that will proceed the test after a failed ingestion caused by injected errors, leaving the pending put in the expected state.rocksdb/db_stress_tool/no_batched_ops_stress.cc
Lines 1577 to 1589 in 0758271
I think a proper and future proof fix for this is to explicitly rollback a pending state when a db write operation failed so that expected state do not diverge from db in the first place. I added a
PendingExpectedValue::Rollback
API so that we don't implicitly depend on thread termination to prevent test failures. Another place that could cause same divergence as external file ingestion isPreloadDbAndReopenAsReadOnly
.rocksdb/db_stress_tool/db_stress_test_base.cc
Lines 616 to 619 in 0758271