This is an automated email from the ASF dual-hosted git repository.
alexey pushed a commit to branch branch-1.17.x
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/branch-1.17.x by this push:
new d9371b11f KUDU-3535 Clear log cache while tombstoning a tablet replica.
d9371b11f is described below
commit d9371b11fee23ae23d4a00f156d43f5a0beeb0c0
Author: 宋家成 <[email protected]>
AuthorDate: Wed Dec 20 14:57:01 2023 +0800
KUDU-3535 Clear log cache while tombstoning a tablet replica.
The log cache of a replica still exists even if the replica has been
already tombstoned. This problem might take place if we decrease
the replication factor of a table with high throughput.
So we should clear the log cache while deleting the replica with
delete type TABLET_DATA_TOMBSTONED.
Change-Id: I6cf545e604f80d41e7ebd9660acfd2e928cd27a9
Reviewed-on: http://gerrit.cloudera.org:8080/20822
Reviewed-by: Alexey Serbin <[email protected]>
Tested-by: Alexey Serbin <[email protected]>
(cherry picked from commit 368225e87f77851f8cdf98fc4b7670aaac7a773e)
Reviewed-on: http://gerrit.cloudera.org:8080/21017
Reviewed-by: Marton Greber <[email protected]>
---
src/kudu/consensus/consensus_queue-test.cc | 13 +++++++++++++
src/kudu/consensus/consensus_queue.cc | 8 +++++---
src/kudu/consensus/consensus_queue.h | 2 ++
src/kudu/consensus/log_cache.cc | 11 ++++++++---
src/kudu/consensus/log_cache.h | 3 +++
5 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/src/kudu/consensus/consensus_queue-test.cc
b/src/kudu/consensus/consensus_queue-test.cc
index f3aa28a0c..cb2b4363f 100644
--- a/src/kudu/consensus/consensus_queue-test.cc
+++ b/src/kudu/consensus/consensus_queue-test.cc
@@ -44,6 +44,7 @@
#include "kudu/consensus/log-test-base.h"
#include "kudu/consensus/log.h"
#include "kudu/consensus/log_anchor_registry.h"
+#include "kudu/consensus/log_cache.h"
#include "kudu/consensus/log_util.h"
#include "kudu/consensus/metadata.pb.h"
#include "kudu/consensus/opid.pb.h"
@@ -1190,5 +1191,17 @@ TEST(ConsensusQueueUnitTest, PeerHealthStatus) {
EXPECT_EQ(HealthReportPB::FAILED_UNRECOVERABLE,
PeerMessageQueue::PeerHealthStatus(peer));
}
+// Test the log cache will be cleared if Close() is called. The method is
called while
+// tombstoning a replica, so the log cache will be cleared if a replica is
tombstoned.
+TEST_F(ConsensusQueueTest, ClearLogCacheWhileClosing) {
+ queue_->SetLeaderMode(kMinimumOpIdIndex, kMinimumTerm,
BuildRaftConfigPBForTests(3));
+ AppendReplicateMessagesToQueue(queue_.get(), clock_.get(), 1, 100);
+
+ ASSERT_LT(0, queue_->log_cache_.BytesUsed());
+ queue_->Close();
+
+ ASSERT_EQ(0, queue_->log_cache_.BytesUsed());
+}
+
} // namespace consensus
} // namespace kudu
diff --git a/src/kudu/consensus/consensus_queue.cc
b/src/kudu/consensus/consensus_queue.cc
index 135e62e09..a37860b54 100644
--- a/src/kudu/consensus/consensus_queue.cc
+++ b/src/kudu/consensus/consensus_queue.cc
@@ -1427,9 +1427,11 @@ void PeerMessageQueue::ClearUnlocked() {
void PeerMessageQueue::Close() {
raft_pool_observers_token_->Shutdown();
-
- std::lock_guard<simple_spinlock> lock(queue_lock_);
- ClearUnlocked();
+ {
+ std::lock_guard<simple_spinlock> lock(queue_lock_);
+ ClearUnlocked();
+ }
+ log_cache_.Clear();
}
int64_t PeerMessageQueue::GetQueuedOperationsSizeBytesForTests() const {
diff --git a/src/kudu/consensus/consensus_queue.h
b/src/kudu/consensus/consensus_queue.h
index 1730a416c..b6b96bfef 100644
--- a/src/kudu/consensus/consensus_queue.h
+++ b/src/kudu/consensus/consensus_queue.h
@@ -370,6 +370,7 @@ class PeerMessageQueue {
void EndWatchForSuccessor();
private:
+ FRIEND_TEST(ConsensusQueueTest, ClearLogCacheWhileClosing);
FRIEND_TEST(ConsensusQueueTest, TestQueueAdvancesCommittedIndex);
FRIEND_TEST(ConsensusQueueTest, TestQueueMovesWatermarksBackward);
FRIEND_TEST(ConsensusQueueTest, TestFollowerCommittedIndexAndMetrics);
@@ -377,6 +378,7 @@ class PeerMessageQueue {
FRIEND_TEST(ConsensusQueueUnitTest, PeerHealthStatus);
FRIEND_TEST(RaftConsensusQuorumTest,
TestReplicasEnforceTheLogMatchingProperty);
+
// Mode specifies how the queue currently behaves:
// LEADER - Means the queue tracks remote peers and replicates whatever
messages
// are appended. Observers are notified of changes.
diff --git a/src/kudu/consensus/log_cache.cc b/src/kudu/consensus/log_cache.cc
index 24281cf23..03f67fc7a 100644
--- a/src/kudu/consensus/log_cache.cc
+++ b/src/kudu/consensus/log_cache.cc
@@ -22,6 +22,7 @@
#include <mutex>
#include <ostream>
#include <string>
+#include <type_traits>
#include <utility>
#include <vector>
@@ -31,7 +32,7 @@
#include "kudu/consensus/consensus.pb.h"
#include "kudu/consensus/log.h"
-#include "kudu/consensus/log_reader.h"
+#include "kudu/consensus/log_reader.h" // IWYU pragma: keep
#include "kudu/consensus/opid.pb.h"
#include "kudu/consensus/opid_util.h"
#include "kudu/consensus/ref_counted_replicate.h"
@@ -113,8 +114,7 @@ LogCache::LogCache(const scoped_refptr<MetricEntity>&
metric_entity,
}
LogCache::~LogCache() {
- tracker_->Release(tracker_->consumption());
- cache_.clear();
+ Clear();
}
void LogCache::Init(const OpId& preceding_op) {
@@ -477,6 +477,11 @@ void LogCache::DumpToHtml(std::ostream& out) const {
out << "</table>";
}
+void LogCache::Clear() {
+ tracker_->Release(tracker_->consumption());
+ cache_.clear();
+}
+
#define INSTANTIATE_METRIC(x) \
x.Instantiate(metric_entity, 0)
LogCache::Metrics::Metrics(const scoped_refptr<MetricEntity>& metric_entity)
diff --git a/src/kudu/consensus/log_cache.h b/src/kudu/consensus/log_cache.h
index 812f50ec2..c80b32cea 100644
--- a/src/kudu/consensus/log_cache.h
+++ b/src/kudu/consensus/log_cache.h
@@ -139,6 +139,9 @@ class LogCache {
// Returns another bad Status if the log index fails to load (eg. due to an
IO error).
Status LookupOpId(int64_t op_index, OpId* op_id) const;
+ // Clear the log cache.
+ void Clear();
+
private:
FRIEND_TEST(LogCacheTest, TestAppendAndGetMessages);
FRIEND_TEST(LogCacheTest, TestGlobalMemoryLimit);