Add option to verify block checksums of output files#14103
Add option to verify block checksums of output files#14103jaykorean wants to merge 7 commits intofacebook:mainfrom
Conversation
|
@jaykorean has imported this pull request. If you are a Meta employee, you can view this in D86357924. |
include/rocksdb/advanced_options.h
Outdated
| // Default: 0 (kVerifyNone) | ||
| // | ||
| // Dynamically changeable through SetOptions() API | ||
| uint32_t verify_output_option = VerifyOutputOptions::kVerifyNone; |
There was a problem hiding this comment.
I believe it's standard to use the enum type as the type of the field even if it's a bitwise enum. But probably has to be mutable as a uint32_t, which is probably worth mentioning in the "dynamically changeable" part with the change of type.
include/rocksdb/advanced_options.h
Outdated
| // Bitmask enum for verify output options during compaction. | ||
| // This allows fine-grained control over what verification is performed | ||
| // on compaction output files and when it's enabled. | ||
| enum VerifyOutputOptions : uint32_t { |
There was a problem hiding this comment.
Avoid enum (without class) unless it's already scoped in something limited already. rocksdb:: is a big scope.
See https://softwareengineering.stackexchange.com/a/204566 for how to avoid excessive casting.
options/cf_options.cc
Outdated
| OptionTypeFlags::kMutable}}, | ||
| {"verify_output_option", | ||
| {offsetof(struct MutableCFOptions, verify_output_option), | ||
| OptionType::kInt32T, OptionVerificationType::kNormal, |
| if (should_verify) { | ||
| if (verify_output_option & | ||
| VerifyOutputOptions::kVerifyBlockChecksum) { | ||
| s = table_reader_ptr->VerifyChecksum( |
There was a problem hiding this comment.
If we are also iterating, a lot of this work is redundant (but not filter blocks). Can we avoid it? Perhaps we can have a variant of VerifyChecksum that only verifies metadata blocks? (I'm not too concerned about double-verifying index blocks.)
include/rocksdb/advanced_options.h
Outdated
| // Default: 0 (kVerifyNone) | ||
| // | ||
| // Dynamically changeable through SetOptions() API | ||
| uint32_t verify_output_option = VerifyOutputOptions::kVerifyNone; |
There was a problem hiding this comment.
I feel like verify_output_flags and VerifyOutputFlags would be a better name. (Everything in an Options is an option.)
| @@ -704,6 +724,13 @@ struct AdvancedColumnFamilyOptions { | |||
| // Dynamically changeable through SetOptions() API | |||
| bool paranoid_file_checks = false; | |||
There was a problem hiding this comment.
I think we should deprecate this option, talk about the equivalence in the new option, and how the two are reconciled until the removal of this one.
There was a problem hiding this comment.
I agree that we should deprecate this option, but I'd like to do that as a follow up.
include/rocksdb/advanced_options.h
Outdated
|
|
||
| // First set of bits: type of verifications | ||
| kVerifyBlockChecksum = 1 << 0, // Verify block checksums | ||
| kVerifyIteration = 1 << 1, // Verify iteration (full key/value hashing) |
There was a problem hiding this comment.
I suggest more detail, like, "Verify iteration and full key/value hash matches one computed while generating the file."
9226130 to
6d56c04
Compare
6d56c04 to
14bc02f
Compare
| }); | ||
| SyncPoint::GetInstance()->EnableProcessing(); | ||
| const bool is_enabled_for_remote_compaction = | ||
| !!(verify_output_flags & VerifyOutputFlags::kEnableForRemoteCompaction); |
There was a problem hiding this comment.
Not sure if this !! is any better than doing != VerifyOutputFlags::kVerifyNone, but I just did it to make the line shorter...
| }); | ||
| SyncPoint::GetInstance()->EnableProcessing(); | ||
| const bool is_enabled_for_remote_compaction = | ||
| !!(verify_output_flags & VerifyOutputFlags::kEnableForRemoteCompaction); |
| kVerifyAll = 0xFFFFFFFF, | ||
| }; | ||
|
|
||
| inline VerifyOutputFlags operator|(VerifyOutputFlags lhs, |
There was a problem hiding this comment.
I think ideally we would just see here something like DEFINE_OPERATORS_FOR_FLAGS_ENUM_CLASS(VerifyOutputFlags); and put the details in another header (data_structure.h?) to keep this one from getting bloated with boilerplate. Same with SizeApproximationFlags in db.h
There was a problem hiding this comment.
Let me do this as a follow up.
db/compaction/compaction_job.cc
Outdated
| s = iter->status(); | ||
| } | ||
| if (s.ok() && !validator.CompareValidator(output_file.validator)) { | ||
| s = Status::Corruption("Paranoid checksums do not match"); |
There was a problem hiding this comment.
I know it's not yours, but I would prefer something like "Key-value checksum of compaction output doesn't match what was computed when written"
65e6e5c to
5bf275f
Compare
|
@jaykorean merged this pull request in 5879f8b. |
Summary: For all compactions, RocksDB performs a lightweight sanity check on output SST files before installation (in `CompactionJob::VerifyOutputFiles()`). However, this lightweight check may not catch corruption that is small enough to allow the SST files to still be opened. There is an existing feature, `paranoid_file_check`, which opens the SST file, iterates through all keys, and checks the hash of each key. While this provides the ultimate level of data integrity checking, it comes at a high computational cost. In this PR, we introduce a new mutable CF option, `verify_output_flags`. The `verify_output_flags` is a bitmask enum that allows users to select various verification types, including block checksum verification, full key iteration, and file checksum verification (to be added in subsequent PRs). Note that the existing `paranoid_file_check` option is equivalent to a full key iteration check. Block-level checksum verification is much lighter than the full key iteration check. Please note that the previously deprecated `verify_checksums_in_compaction` option (removed in version 5.3.0) was for verifying the checksum of **input SST files**. RocksDB continues to perform this verification for both local and remote compactions, and this behavior remains unchanged. In contrast, this PR focuses on verifying the **output SST files**. ## To follow up - File-level Checksum verification for output SST files - Deprecate `paranoid_file_checks` option in favor of the new option - Add to stress test / db_bench Pull Request resolved: #14103 Test Plan: New Unit Test added. The corruption is both detected by `paranoid_file_check` and various types of verification set by this new option, `verify_output_flags` ``` ./compaction_service_test --gtest_filter="*CompactionServiceTest.CorruptedOutput*" ``` Reviewed By: pdillinger Differential Revision: D86357924 Pulled By: jaykorean fbshipit-source-id: a9e04798f249c7e977231e179622a0830d6675fe
Summary: One of the follow ups from #14103. Users will have the option to verify file checksums for all compaction output files before they are installed. This feature helps prevent corrupted SST files from being added to the LSM tree. Pull Request resolved: #14433 Test Plan: Unit test added Reviewed By: archang19 Differential Revision: D95648000 Pulled By: jaykorean fbshipit-source-id: 512f3c1a7449b96a660865531f3537624c89a9cc
Summary
For all compactions, RocksDB performs a lightweight sanity check on output SST files before installation (in
CompactionJob::VerifyOutputFiles()). However, this lightweight check may not catch corruption that is small enough to allow the SST files to still be opened.There is an existing feature,
paranoid_file_check, which opens the SST file, iterates through all keys, and checks the hash of each key. While this provides the ultimate level of data integrity checking, it comes at a high computational cost.In this PR, we introduce a new mutable CF option,
verify_output_flags. Theverify_output_flagsis a bitmask enum that allows users to select various verification types, including block checksum verification, full key iteration, and file checksum verification (to be added in subsequent PRs). Note that the existingparanoid_file_checkoption is equivalent to a full key iteration check. Block-level checksum verification is much lighter than the full key iteration check.Please note that the previously deprecated
verify_checksums_in_compactionoption (removed in version 5.3.0) was for verifying the checksum of input SST files. RocksDB continues to perform this verification for both local and remote compactions, and this behavior remains unchanged. In contrast, this PR focuses on verifying the output SST files.To follow up
paranoid_file_checksoption in favor of the new optionTest Plan
New Unit Test added. The corruption is both detected by
paranoid_file_checkand various types of verification set by this new option,verify_output_flags