diff --git a/HISTORY.md b/HISTORY.md index 769c9131fa..cf27d16371 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,6 +7,7 @@ * For users of dictionary compression with ZSTD v0.7.0+, we now reuse the same digested dictionary when compressing each of an SST file's data blocks for faster compression speeds. * For all users of dictionary compression who set `cache_index_and_filter_blocks == true`, we now store dictionary data used for decompression in the block cache for better control over memory usage. For users of ZSTD v1.1.4+ who compile with -DZSTD_STATIC_LINKING_ONLY, this includes a digested dictionary, which is used to increase decompression speed. * Add support for block checksums verification for external SST files before ingestion. +* Add a place holder in manifest which indicate a record from future that can be safely ignored. ### Public API Change * Disallow CompactionFilter::IgnoreSnapshots() = false, because it is not very useful and the behavior is confusing. The filter will filter everything if there is no snapshot declared by the time the compaction starts. However, users can define a snapshot after the compaction starts and before it finishes and this new snapshot won't be repeatable, because after the compaction finishes, some keys may be dropped. diff --git a/db/version_edit.cc b/db/version_edit.cc index 7fa291f5f4..01ec44515a 100644 --- a/db/version_edit.cc +++ b/db/version_edit.cc @@ -44,6 +44,9 @@ enum Tag : uint32_t { kInAtomicGroup = 300, }; +// Mask for an identified tag from the future which can be safely ignored. +uint32_t kTagSafeIgnoreMask = 1 << 13; + enum CustomTag : uint32_t { kTerminate = 1, // The end of customized fields kNeedCompaction = 2, @@ -501,7 +504,21 @@ Status VersionEdit::DecodeFrom(const Slice& src) { break; default: - msg = "unknown tag"; + if (tag & kTagSafeIgnoreMask) { + // Tag from future which can be safely ignored. + // The next field must be the length of the entry. + uint32_t field_len; + if (!GetVarint32(&input, &field_len) || + static_cast(field_len) > input.size()) { + if (!msg) { + msg = "safely ignoreable tag length error"; + } + } else { + input.remove_prefix(static_cast(field_len)); + } + } else { + msg = "unknown tag"; + } break; } }