提交 83833637 编辑于 作者: Levi Tamasi's avatar Levi Tamasi 提交者: Facebook GitHub Bot
浏览文件

Maintain the set of linked SSTs in BlobFileMetaData (#6945)

Summary:
The `FileMetaData` objects associated with table files already contain the
number of the oldest blob file referenced by the SST in question. This patch
adds the inverse mapping to `BlobFileMetaData`, namely the set of table file
numbers for which the oldest blob file link points to the given blob file (these
are referred to as *linked SSTs*). This mapping will be used by the GC logic.

Implementation-wise, the patch builds on the `BlobFileMetaDataDelta`
functionality introduced in https://github.com/facebook/rocksdb/pull/6835: newly linked/unlinked SSTs are
accumulated in `BlobFileMetaDataDelta`, and the changes to the linked SST set
are applied in one shot when the new `Version` is saved. The patch also reworks
the blob file related consistency checks in `VersionBuilder` so they validate the
consistency of the forward table file -> blob file links and the backward blob file ->
table file links for blob files that are part of the `Version`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/6945

Test Plan: `make check`

Reviewed By: riversand963

Differential Revision: D21912228

Pulled By: ltamasi

fbshipit-source-id: c5bc7acf6e729a8fccbb12672dd5cd00f6f000f8
上级 717749f4
...@@ -38,8 +38,15 @@ std::string BlobFileMetaData::DebugString() const { ...@@ -38,8 +38,15 @@ std::string BlobFileMetaData::DebugString() const {
std::ostream& operator<<(std::ostream& os, const BlobFileMetaData& meta) { std::ostream& operator<<(std::ostream& os, const BlobFileMetaData& meta) {
const auto& shared_meta = meta.GetSharedMeta(); const auto& shared_meta = meta.GetSharedMeta();
assert(shared_meta); assert(shared_meta);
os << (*shared_meta);
os << (*shared_meta) << " garbage_blob_count: " << meta.GetGarbageBlobCount() os << " linked_ssts: {";
for (uint64_t file_number : meta.GetLinkedSsts()) {
os << ' ' << file_number;
}
os << " }";
os << " garbage_blob_count: " << meta.GetGarbageBlobCount()
<< " garbage_blob_bytes: " << meta.GetGarbageBlobBytes(); << " garbage_blob_bytes: " << meta.GetGarbageBlobBytes();
return os; return os;
......
...@@ -5,12 +5,13 @@ ...@@ -5,12 +5,13 @@
#pragma once #pragma once
#include "rocksdb/rocksdb_namespace.h"
#include <cassert> #include <cassert>
#include <iosfwd> #include <iosfwd>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_set>
#include "rocksdb/rocksdb_namespace.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
...@@ -90,11 +91,15 @@ std::ostream& operator<<(std::ostream& os, ...@@ -90,11 +91,15 @@ std::ostream& operator<<(std::ostream& os,
class BlobFileMetaData { class BlobFileMetaData {
public: public:
using LinkedSsts = std::unordered_set<uint64_t>;
static std::shared_ptr<BlobFileMetaData> Create( static std::shared_ptr<BlobFileMetaData> Create(
std::shared_ptr<SharedBlobFileMetaData> shared_meta, std::shared_ptr<SharedBlobFileMetaData> shared_meta,
uint64_t garbage_blob_count, uint64_t garbage_blob_bytes) { LinkedSsts linked_ssts, uint64_t garbage_blob_count,
return std::shared_ptr<BlobFileMetaData>(new BlobFileMetaData( uint64_t garbage_blob_bytes) {
std::move(shared_meta), garbage_blob_count, garbage_blob_bytes)); return std::shared_ptr<BlobFileMetaData>(
new BlobFileMetaData(std::move(shared_meta), std::move(linked_ssts),
garbage_blob_count, garbage_blob_bytes));
} }
BlobFileMetaData(const BlobFileMetaData&) = delete; BlobFileMetaData(const BlobFileMetaData&) = delete;
...@@ -128,6 +133,8 @@ class BlobFileMetaData { ...@@ -128,6 +133,8 @@ class BlobFileMetaData {
return shared_meta_->GetChecksumValue(); return shared_meta_->GetChecksumValue();
} }
const LinkedSsts& GetLinkedSsts() const { return linked_ssts_; }
uint64_t GetGarbageBlobCount() const { return garbage_blob_count_; } uint64_t GetGarbageBlobCount() const { return garbage_blob_count_; }
uint64_t GetGarbageBlobBytes() const { return garbage_blob_bytes_; } uint64_t GetGarbageBlobBytes() const { return garbage_blob_bytes_; }
...@@ -135,8 +142,10 @@ class BlobFileMetaData { ...@@ -135,8 +142,10 @@ class BlobFileMetaData {
private: private:
BlobFileMetaData(std::shared_ptr<SharedBlobFileMetaData> shared_meta, BlobFileMetaData(std::shared_ptr<SharedBlobFileMetaData> shared_meta,
uint64_t garbage_blob_count, uint64_t garbage_blob_bytes) LinkedSsts linked_ssts, uint64_t garbage_blob_count,
uint64_t garbage_blob_bytes)
: shared_meta_(std::move(shared_meta)), : shared_meta_(std::move(shared_meta)),
linked_ssts_(std::move(linked_ssts)),
garbage_blob_count_(garbage_blob_count), garbage_blob_count_(garbage_blob_count),
garbage_blob_bytes_(garbage_blob_bytes) { garbage_blob_bytes_(garbage_blob_bytes) {
assert(shared_meta_); assert(shared_meta_);
...@@ -145,6 +154,7 @@ class BlobFileMetaData { ...@@ -145,6 +154,7 @@ class BlobFileMetaData {
} }
std::shared_ptr<SharedBlobFileMetaData> shared_meta_; std::shared_ptr<SharedBlobFileMetaData> shared_meta_;
LinkedSsts linked_ssts_;
uint64_t garbage_blob_count_; uint64_t garbage_blob_count_;
uint64_t garbage_blob_bytes_; uint64_t garbage_blob_bytes_;
}; };
......
...@@ -90,7 +90,8 @@ class VersionBuilder::Rep { ...@@ -90,7 +90,8 @@ class VersionBuilder::Rep {
public: public:
bool IsEmpty() const { bool IsEmpty() const {
return !shared_meta_ && !additional_garbage_count_ && return !shared_meta_ && !additional_garbage_count_ &&
!additional_garbage_bytes_; !additional_garbage_bytes_ && newly_linked_ssts_.empty() &&
newly_unlinked_ssts_.empty();
} }
std::shared_ptr<SharedBlobFileMetaData> GetSharedMeta() const { std::shared_ptr<SharedBlobFileMetaData> GetSharedMeta() const {
...@@ -105,6 +106,14 @@ class VersionBuilder::Rep { ...@@ -105,6 +106,14 @@ class VersionBuilder::Rep {
return additional_garbage_bytes_; return additional_garbage_bytes_;
} }
const std::unordered_set<uint64_t>& GetNewlyLinkedSsts() const {
return newly_linked_ssts_;
}
const std::unordered_set<uint64_t>& GetNewlyUnlinkedSsts() const {
return newly_unlinked_ssts_;
}
void SetSharedMeta(std::shared_ptr<SharedBlobFileMetaData> shared_meta) { void SetSharedMeta(std::shared_ptr<SharedBlobFileMetaData> shared_meta) {
assert(!shared_meta_); assert(!shared_meta_);
assert(shared_meta); assert(shared_meta);
...@@ -117,10 +126,44 @@ class VersionBuilder::Rep { ...@@ -117,10 +126,44 @@ class VersionBuilder::Rep {
additional_garbage_bytes_ += bytes; additional_garbage_bytes_ += bytes;
} }
void LinkSst(uint64_t sst_file_number) {
assert(newly_linked_ssts_.find(sst_file_number) ==
newly_linked_ssts_.end());
// Reconcile with newly unlinked SSTs on the fly. (Note: an SST can be
// linked to and unlinked from the same blob file in the case of a trivial
// move.)
auto it = newly_unlinked_ssts_.find(sst_file_number);
if (it != newly_unlinked_ssts_.end()) {
newly_unlinked_ssts_.erase(it);
} else {
newly_linked_ssts_.emplace(sst_file_number);
}
}
void UnlinkSst(uint64_t sst_file_number) {
assert(newly_unlinked_ssts_.find(sst_file_number) ==
newly_unlinked_ssts_.end());
// Reconcile with newly linked SSTs on the fly. (Note: an SST can be
// linked to and unlinked from the same blob file in the case of a trivial
// move.)
auto it = newly_linked_ssts_.find(sst_file_number);
if (it != newly_linked_ssts_.end()) {
newly_linked_ssts_.erase(it);
} else {
newly_unlinked_ssts_.emplace(sst_file_number);
}
}
private: private:
std::shared_ptr<SharedBlobFileMetaData> shared_meta_; std::shared_ptr<SharedBlobFileMetaData> shared_meta_;
uint64_t additional_garbage_count_ = 0; uint64_t additional_garbage_count_ = 0;
uint64_t additional_garbage_bytes_ = 0; uint64_t additional_garbage_bytes_ = 0;
std::unordered_set<uint64_t> newly_linked_ssts_;
std::unordered_set<uint64_t> newly_unlinked_ssts_;
}; };
const FileOptions& file_options_; const FileOptions& file_options_;
...@@ -212,29 +255,19 @@ class VersionBuilder::Rep { ...@@ -212,29 +255,19 @@ class VersionBuilder::Rep {
return false; return false;
} }
Status CheckConsistencyOfOldestBlobFileReference( using ExpectedLinkedSsts =
const VersionStorageInfo* vstorage, uint64_t blob_file_number) const { std::unordered_map<uint64_t, BlobFileMetaData::LinkedSsts>;
assert(vstorage);
// TODO: remove this check once we actually start recoding metadata for static void UpdateExpectedLinkedSsts(
// blob files in the MANIFEST. uint64_t table_file_number, uint64_t blob_file_number,
if (vstorage->GetBlobFiles().empty()) { ExpectedLinkedSsts* expected_linked_ssts) {
return Status::OK(); assert(expected_linked_ssts);
}
if (blob_file_number == kInvalidBlobFileNumber) { if (blob_file_number == kInvalidBlobFileNumber) {
return Status::OK(); return;
} }
if (!IsBlobFileInVersion(blob_file_number)) { (*expected_linked_ssts)[blob_file_number].emplace(table_file_number);
std::ostringstream oss;
oss << "Blob file #" << blob_file_number
<< " is not part of this version";
return Status::Corruption("VersionBuilder", oss.str());
}
return Status::OK();
} }
Status CheckConsistency(VersionStorageInfo* vstorage) { Status CheckConsistency(VersionStorageInfo* vstorage) {
...@@ -245,9 +278,13 @@ class VersionBuilder::Rep { ...@@ -245,9 +278,13 @@ class VersionBuilder::Rep {
return Status::OK(); return Status::OK();
} }
#endif #endif
// Make sure the files are sorted correctly and that the oldest blob file // Make sure the files are sorted correctly and that the links between
// reference for each table file points to a valid blob file in this // table files and blob files are consistent. The latter is checked using
// version. // the following mapping, which is built using the forward links
// (table file -> blob file), and is subsequently compared with the inverse
// mapping stored in the BlobFileMetaData objects.
ExpectedLinkedSsts expected_linked_ssts;
for (int level = 0; level < num_levels_; level++) { for (int level = 0; level < num_levels_; level++) {
auto& level_files = vstorage->LevelFiles(level); auto& level_files = vstorage->LevelFiles(level);
...@@ -256,19 +293,14 @@ class VersionBuilder::Rep { ...@@ -256,19 +293,14 @@ class VersionBuilder::Rep {
} }
assert(level_files[0]); assert(level_files[0]);
Status s = CheckConsistencyOfOldestBlobFileReference( UpdateExpectedLinkedSsts(level_files[0]->fd.GetNumber(),
vstorage, level_files[0]->oldest_blob_file_number); level_files[0]->oldest_blob_file_number,
if (!s.ok()) { &expected_linked_ssts);
return s;
}
for (size_t i = 1; i < level_files.size(); i++) { for (size_t i = 1; i < level_files.size(); i++) {
assert(level_files[i]); assert(level_files[i]);
s = CheckConsistencyOfOldestBlobFileReference( UpdateExpectedLinkedSsts(level_files[i]->fd.GetNumber(),
vstorage, level_files[i]->oldest_blob_file_number); level_files[i]->oldest_blob_file_number,
if (!s.ok()) { &expected_linked_ssts);
return s;
}
auto f1 = level_files[i - 1]; auto f1 = level_files[i - 1];
auto f2 = level_files[i]; auto f2 = level_files[i];
...@@ -328,17 +360,27 @@ class VersionBuilder::Rep { ...@@ -328,17 +360,27 @@ class VersionBuilder::Rep {
// Make sure that all blob files in the version have non-garbage data. // Make sure that all blob files in the version have non-garbage data.
const auto& blob_files = vstorage->GetBlobFiles(); const auto& blob_files = vstorage->GetBlobFiles();
for (const auto& pair : blob_files) { for (const auto& pair : blob_files) {
const uint64_t blob_file_number = pair.first;
const auto& blob_file_meta = pair.second; const auto& blob_file_meta = pair.second;
assert(blob_file_meta); assert(blob_file_meta);
if (blob_file_meta->GetGarbageBlobCount() >= if (blob_file_meta->GetGarbageBlobCount() >=
blob_file_meta->GetTotalBlobCount()) { blob_file_meta->GetTotalBlobCount()) {
std::ostringstream oss; std::ostringstream oss;
oss << "Blob file #" << blob_file_meta->GetBlobFileNumber() oss << "Blob file #" << blob_file_number
<< " consists entirely of garbage"; << " consists entirely of garbage";
return Status::Corruption("VersionBuilder", oss.str()); return Status::Corruption("VersionBuilder", oss.str());
} }
if (blob_file_meta->GetLinkedSsts() !=
expected_linked_ssts[blob_file_number]) {
std::ostringstream oss;
oss << "Links are inconsistent between table files and blob file #"
<< blob_file_number;
return Status::Corruption("VersionBuilder", oss.str());
}
} }
Status ret_s; Status ret_s;
...@@ -430,6 +472,28 @@ class VersionBuilder::Rep { ...@@ -430,6 +472,28 @@ class VersionBuilder::Rep {
return base_vstorage_->GetFileLocation(file_number).GetLevel(); return base_vstorage_->GetFileLocation(file_number).GetLevel();
} }
uint64_t GetOldestBlobFileNumberForTableFile(int level,
uint64_t file_number) const {
assert(level < num_levels_);
const auto& added_files = levels_[level].added_files;
auto it = added_files.find(file_number);
if (it != added_files.end()) {
const FileMetaData* const meta = it->second;
assert(meta);
return meta->oldest_blob_file_number;
}
assert(base_vstorage_);
const FileMetaData* const meta =
base_vstorage_->GetFileMetaDataByNumber(file_number);
assert(meta);
return meta->oldest_blob_file_number;
}
Status ApplyFileDeletion(int level, uint64_t file_number) { Status ApplyFileDeletion(int level, uint64_t file_number) {
assert(level != VersionStorageInfo::FileLocation::Invalid().GetLevel()); assert(level != VersionStorageInfo::FileLocation::Invalid().GetLevel());
...@@ -463,6 +527,14 @@ class VersionBuilder::Rep { ...@@ -463,6 +527,14 @@ class VersionBuilder::Rep {
return Status::OK(); return Status::OK();
} }
const uint64_t blob_file_number =
GetOldestBlobFileNumberForTableFile(level, file_number);
if (blob_file_number != kInvalidBlobFileNumber &&
IsBlobFileInVersion(blob_file_number)) {
blob_file_meta_deltas_[blob_file_number].UnlinkSst(file_number);
}
auto& level_state = levels_[level]; auto& level_state = levels_[level];
auto& add_files = level_state.added_files; auto& add_files = level_state.added_files;
...@@ -523,6 +595,13 @@ class VersionBuilder::Rep { ...@@ -523,6 +595,13 @@ class VersionBuilder::Rep {
assert(add_files.find(file_number) == add_files.end()); assert(add_files.find(file_number) == add_files.end());
add_files.emplace(file_number, f); add_files.emplace(file_number, f);
const uint64_t blob_file_number = f->oldest_blob_file_number;
if (blob_file_number != kInvalidBlobFileNumber &&
IsBlobFileInVersion(blob_file_number)) {
blob_file_meta_deltas_[blob_file_number].LinkSst(file_number);
}
table_file_levels_[file_number] = level; table_file_levels_[file_number] = level;
return Status::OK(); return Status::OK();
...@@ -537,7 +616,27 @@ class VersionBuilder::Rep { ...@@ -537,7 +616,27 @@ class VersionBuilder::Rep {
} }
} }
// Delete files // Note: we process the blob file related changes first because the
// table file addition/deletion logic depends on the blob files
// already being there.
// Add new blob files
for (const auto& blob_file_addition : edit->GetBlobFileAdditions()) {
const Status s = ApplyBlobFileAddition(blob_file_addition);
if (!s.ok()) {
return s;
}
}
// Increase the amount of garbage for blob files affected by GC
for (const auto& blob_file_garbage : edit->GetBlobFileGarbages()) {
const Status s = ApplyBlobFileGarbage(blob_file_garbage);
if (!s.ok()) {
return s;
}
}
// Delete table files
for (const auto& deleted_file : edit->GetDeletedFiles()) { for (const auto& deleted_file : edit->GetDeletedFiles()) {
const int level = deleted_file.first; const int level = deleted_file.first;
const uint64_t file_number = deleted_file.second; const uint64_t file_number = deleted_file.second;
...@@ -548,7 +647,7 @@ class VersionBuilder::Rep { ...@@ -548,7 +647,7 @@ class VersionBuilder::Rep {
} }
} }
// Add new files // Add new table files
for (const auto& new_file : edit->GetNewFiles()) { for (const auto& new_file : edit->GetNewFiles()) {
const int level = new_file.first; const int level = new_file.first;
const FileMetaData& meta = new_file.second; const FileMetaData& meta = new_file.second;
...@@ -559,23 +658,28 @@ class VersionBuilder::Rep { ...@@ -559,23 +658,28 @@ class VersionBuilder::Rep {
} }
} }
// Add new blob files return Status::OK();
for (const auto& blob_file_addition : edit->GetBlobFileAdditions()) { }
const Status s = ApplyBlobFileAddition(blob_file_addition);
if (!s.ok()) { static BlobFileMetaData::LinkedSsts ApplyLinkedSstChanges(
return s; const BlobFileMetaData::LinkedSsts& base,
} const std::unordered_set<uint64_t>& newly_linked,
const std::unordered_set<uint64_t>& newly_unlinked) {
BlobFileMetaData::LinkedSsts result(base);
for (uint64_t sst_file_number : newly_unlinked) {
assert(result.find(sst_file_number) != result.end());
result.erase(sst_file_number);
} }
// Increase the amount of garbage for blob files affected by GC for (uint64_t sst_file_number : newly_linked) {
for (const auto& blob_file_garbage : edit->GetBlobFileGarbages()) { assert(result.find(sst_file_number) == result.end());
const Status s = ApplyBlobFileGarbage(blob_file_garbage);
if (!s.ok()) { result.emplace(sst_file_number);
return s;
}
} }
return Status::OK(); return result;
} }
static std::shared_ptr<BlobFileMetaData> CreateMetaDataForNewBlobFile( static std::shared_ptr<BlobFileMetaData> CreateMetaDataForNewBlobFile(
...@@ -583,9 +687,11 @@ class VersionBuilder::Rep { ...@@ -583,9 +687,11 @@ class VersionBuilder::Rep {
auto shared_meta = delta.GetSharedMeta(); auto shared_meta = delta.GetSharedMeta();
assert(shared_meta); assert(shared_meta);
auto meta = BlobFileMetaData::Create(std::move(shared_meta), assert(delta.GetNewlyUnlinkedSsts().empty());
delta.GetAdditionalGarbageCount(),
delta.GetAdditionalGarbageBytes()); auto meta = BlobFileMetaData::Create(
std::move(shared_meta), delta.GetNewlyLinkedSsts(),
delta.GetAdditionalGarbageCount(), delta.GetAdditionalGarbageBytes());
return meta; return meta;
} }
...@@ -604,8 +710,12 @@ class VersionBuilder::Rep { ...@@ -604,8 +710,12 @@ class VersionBuilder::Rep {
auto shared_meta = base_meta->GetSharedMeta(); auto shared_meta = base_meta->GetSharedMeta();
assert(shared_meta); assert(shared_meta);
auto linked_ssts = ApplyLinkedSstChanges(base_meta->GetLinkedSsts(),
delta.GetNewlyLinkedSsts(),
delta.GetNewlyUnlinkedSsts());
auto meta = BlobFileMetaData::Create( auto meta = BlobFileMetaData::Create(
std::move(shared_meta), std::move(shared_meta), std::move(linked_ssts),
base_meta->GetGarbageBlobCount() + delta.GetAdditionalGarbageCount(), base_meta->GetGarbageBlobCount() + delta.GetAdditionalGarbageCount(),
base_meta->GetGarbageBlobBytes() + delta.GetAdditionalGarbageBytes()); base_meta->GetGarbageBlobBytes() + delta.GetAdditionalGarbageBytes());
...@@ -618,7 +728,8 @@ class VersionBuilder::Rep { ...@@ -618,7 +728,8 @@ class VersionBuilder::Rep {
assert(vstorage); assert(vstorage);
assert(meta); assert(meta);
if (meta->GetGarbageBlobCount() < meta->GetTotalBlobCount()) { if (meta->GetGarbageBlobCount() < meta->GetTotalBlobCount() ||
!meta->GetLinkedSsts().empty()) {
vstorage->AddBlobFile(meta); vstorage->AddBlobFile(meta);
} }
} }
......
...@@ -4,8 +4,11 @@ ...@@ -4,8 +4,11 @@
// (found in the LICENSE.Apache file in the root directory). // (found in the LICENSE.Apache file in the root directory).
#include <cstring> #include <cstring>
#include <iomanip>
#include <memory> #include <memory>
#include <sstream>
#include <string> #include <string>
#include "db/version_edit.h" #include "db/version_edit.h"
#include "db/version_set.h" #include "db/version_set.h"
#include "logging/logging.h" #include "logging/logging.h"
...@@ -80,13 +83,15 @@ class VersionBuilderTest : public testing::Test { ...@@ -80,13 +83,15 @@ class VersionBuilderTest : public testing::Test {
void AddBlob(uint64_t blob_file_number, uint64_t total_blob_count, void AddBlob(uint64_t blob_file_number, uint64_t total_blob_count,
uint64_t total_blob_bytes, std::string checksum_method, uint64_t total_blob_bytes, std::string checksum_method,
std::string checksum_value, uint64_t garbage_blob_count, std::string checksum_value,
uint64_t garbage_blob_bytes) { BlobFileMetaData::LinkedSsts linked_ssts,
uint64_t garbage_blob_count, uint64_t garbage_blob_bytes) {
auto shared_meta = SharedBlobFileMetaData::Create( auto shared_meta = SharedBlobFileMetaData::Create(
blob_file_number, total_blob_count, total_blob_bytes, blob_file_number, total_blob_count, total_blob_bytes,
std::move(checksum_method), std::move(checksum_value)); std::move(checksum_method), std::move(checksum_value));
auto meta = BlobFileMetaData::Create( auto meta =
std::move(shared_meta), garbage_blob_count, garbage_blob_bytes); BlobFileMetaData::Create(std::move(shared_meta), std::move(linked_ssts),
garbage_blob_count, garbage_blob_bytes);
vstorage_.AddBlobFile(std::move(meta)); vstorage_.AddBlobFile(std::move(meta));
} }
...@@ -642,6 +647,7 @@ TEST_F(VersionBuilderTest, ApplyBlobFileAddition) { ...@@ -642,6 +647,7 @@ TEST_F(VersionBuilderTest, ApplyBlobFileAddition) {
ASSERT_EQ(new_meta->GetTotalBlobBytes(), total_blob_bytes); ASSERT_EQ(new_meta->GetTotalBlobBytes(), total_blob_bytes);
ASSERT_EQ(new_meta->GetChecksumMethod(), checksum_method); ASSERT_EQ(new_meta->GetChecksumMethod(), checksum_method);
ASSERT_EQ(new_meta->GetChecksumValue(), checksum_value); ASSERT_EQ(new_meta->GetChecksumValue(), checksum_value);
ASSERT_TRUE(new_meta->GetLinkedSsts().empty());
ASSERT_EQ(new_meta->GetGarbageBlobCount(), 0); ASSERT_EQ(new_meta->GetGarbageBlobCount(), 0);
ASSERT_EQ(new_meta->GetGarbageBlobBytes(), 0); ASSERT_EQ(new_meta->GetGarbageBlobBytes(), 0);
} }
...@@ -658,7 +664,8 @@ TEST_F(VersionBuilderTest, ApplyBlobFileAdditionAlreadyInBase) { ...@@ -658,7 +664,8 @@ TEST_F(VersionBuilderTest, ApplyBlobFileAdditionAlreadyInBase) {
constexpr uint64_t garbage_blob_bytes = 456789; constexpr uint64_t garbage_blob_bytes = 456789;