diff --git a/HISTORY.md b/HISTORY.md index ba89774c5..25c1d7999 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -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. diff --git a/db/db_secondary_test.cc b/db/db_secondary_test.cc index 178844ff7..902f1ec2c 100644 --- a/db/db_secondary_test.cc +++ b/db/db_secondary_test.cc @@ -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_; diff --git a/db/version_edit_handler.cc b/db/version_edit_handler.cc index 7a2996a59..5631cda48 100644 --- a/db/version_edit_handler.cc +++ b/db/version_edit_handler.cc @@ -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_; } }