Fix a bug of secondary instance sequence going backward (#8653)
Summary: Recent refactor of `ReactiveVersionSet::ReadAndApply()` uses `ManifestTailer` whose `Iterate()` method can cause the db's `last_sequence_` to go backward. Consequently, read requests can see out-dated data. For example, latest changes to the primary will not be seen on the secondary even after a `TryCatchUpWithPrimary()` if no new write batches are read from the WALs and no new MANIFEST entries are read from the MANIFEST. Fix the bug so that `VersionEditHandler::CheckIterationResult` will never decrease `last_sequence_`, `last_allocated_sequence_` and `last_published_sequence_`. Pull Request resolved: https://github.com/facebook/rocksdb/pull/8653 Test Plan: make check Reviewed By: jay-zhuang Differential Revision: D30272084 Pulled By: riversand963 fbshipit-source-id: c6a49c534b2509b93ef62d8936ed0acd5b860eaa
This commit is contained in:
parent
785faf2d07
commit
f235f4b0a3
@ -2,6 +2,7 @@
|
||||
## Unreleased
|
||||
### Bug Fixes
|
||||
* Allow secondary instance to refresh iterator. Assign read seq after referencing SuperVersion.
|
||||
* Fixed a bug of secondary instance's last_sequence going backward, and reads on the secondary fail to see recent updates from the primary.
|
||||
|
||||
### New Features
|
||||
* RemoteCompaction's interface now includes `db_name`, `db_id`, `session_id`, which could help the user uniquely identify compaction job between db instances and sessions.
|
||||
|
@ -560,6 +560,39 @@ TEST_F(DBSecondaryTest, OpenAsSecondaryWALTailing) {
|
||||
verify_db_func("new_foo_value_1", "new_bar_value");
|
||||
}
|
||||
|
||||
TEST_F(DBSecondaryTest, SecondaryTailingBug_ISSUE_8467) {
|
||||
Options options;
|
||||
options.env = env_;
|
||||
Reopen(options);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
ASSERT_OK(Put("foo", "foo_value" + std::to_string(i)));
|
||||
ASSERT_OK(Put("bar", "bar_value" + std::to_string(i)));
|
||||
}
|
||||
|
||||
Options options1;
|
||||
options1.env = env_;
|
||||
options1.max_open_files = -1;
|
||||
OpenSecondary(options1);
|
||||
|
||||
const auto verify_db = [&](const std::string& foo_val,
|
||||
const std::string& bar_val) {
|
||||
std::string value;
|
||||
ReadOptions ropts;
|
||||
Status s = db_secondary_->Get(ropts, "foo", &value);
|
||||
ASSERT_OK(s);
|
||||
ASSERT_EQ(foo_val, value);
|
||||
|
||||
s = db_secondary_->Get(ropts, "bar", &value);
|
||||
ASSERT_OK(s);
|
||||
ASSERT_EQ(bar_val, value);
|
||||
};
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
ASSERT_OK(db_secondary_->TryCatchUpWithPrimary());
|
||||
verify_db("foo_value2", "bar_value2");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DBSecondaryTest, RefreshIterator) {
|
||||
Options options;
|
||||
options.env = env_;
|
||||
|
@ -427,11 +427,20 @@ void VersionEditHandler::CheckIterationResult(const log::Reader& reader,
|
||||
assert(version_set_->manifest_file_size_ > 0);
|
||||
version_set_->next_file_number_.store(
|
||||
version_edit_params_.next_file_number_ + 1);
|
||||
version_set_->last_allocated_sequence_ =
|
||||
version_edit_params_.last_sequence_;
|
||||
version_set_->last_published_sequence_ =
|
||||
version_edit_params_.last_sequence_;
|
||||
version_set_->last_sequence_ = version_edit_params_.last_sequence_;
|
||||
SequenceNumber last_seq = version_edit_params_.last_sequence_;
|
||||
assert(last_seq != kMaxSequenceNumber);
|
||||
if (last_seq != kMaxSequenceNumber &&
|
||||
last_seq > version_set_->last_allocated_sequence_.load()) {
|
||||
version_set_->last_allocated_sequence_.store(last_seq);
|
||||
}
|
||||
if (last_seq != kMaxSequenceNumber &&
|
||||
last_seq > version_set_->last_published_sequence_.load()) {
|
||||
version_set_->last_published_sequence_.store(last_seq);
|
||||
}
|
||||
if (last_seq != kMaxSequenceNumber &&
|
||||
last_seq > version_set_->last_sequence_.load()) {
|
||||
version_set_->last_sequence_.store(last_seq);
|
||||
}
|
||||
version_set_->prev_log_number_ = version_edit_params_.prev_log_number_;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user