From 0d0efcfce76e36090efdc6ae09e83ad59e0ac48b Mon Sep 17 00:00:00 2001 From: Meng Xu Date: Wed, 12 Aug 2020 10:36:31 -0700 Subject: [PATCH 1/7] FR:Fix incorrect ASSERT:batchIndex starts at 1 instead of 0 --- fdbserver/RestoreController.actor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdbserver/RestoreController.actor.cpp b/fdbserver/RestoreController.actor.cpp index 7f231b2de0..c6bf575fb2 100644 --- a/fdbserver/RestoreController.actor.cpp +++ b/fdbserver/RestoreController.actor.cpp @@ -81,7 +81,7 @@ ACTOR Future sampleBackups(Reference self, RestoreC .detail("SampleID", req.id) .detail("BatchIndex", req.batchIndex) .detail("Samples", req.samples.size()); - ASSERT(req.batchIndex < self->batch.size()); + ASSERT(req.batchIndex <= self->batch.size()); // batchIndex starts from 1 Reference batch = self->batch[req.batchIndex]; if (batch->sampleMsgs.find(req.id) != batch->sampleMsgs.end()) { From cc1059be754ab168a65fb5d900ee422c77a39da9 Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Wed, 12 Aug 2020 19:05:01 +0000 Subject: [PATCH 2/7] Make logging of server trace ID consistent with other code --- fdbclient/NativeAPI.actor.cpp | 40 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/fdbclient/NativeAPI.actor.cpp b/fdbclient/NativeAPI.actor.cpp index a33c6cef1c..5d9e8a4082 100644 --- a/fdbclient/NativeAPI.actor.cpp +++ b/fdbclient/NativeAPI.actor.cpp @@ -645,7 +645,7 @@ DatabaseContext::DatabaseContext(Reference trLogInfo, doub cx->transactionBytesRead += bytes; cx->transactionKeysRead += result.size(); - + if( trLogInfo ) { trLogInfo->addLog(FdbClientLogEvents::EventGetRange(startTime, cx->clientLocality.dcId(), now()-startTime, bytes, begin.getKey(), end.getKey())); } @@ -2324,11 +2324,11 @@ Future> getRange( Database const& cx, Future } bool DatabaseContext::debugUseTags = false; -const std::vector DatabaseContext::debugTransactionTagChoices = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t" }; +const std::vector DatabaseContext::debugTransactionTagChoices = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t" }; void debugAddTags(Transaction *tr) { int numTags = deterministicRandom()->randomInt(0, CLIENT_KNOBS->MAX_TAGS_PER_TRANSACTION+1); - for(int i = 0; i < numTags; ++i) { + for(int i = 0; i < numTags; ++i) { TransactionTag tag; if(deterministicRandom()->random01() < 0.7) { tag = TransactionTagRef(deterministicRandom()->randomChoice(DatabaseContext::debugTransactionTagChoices)); @@ -3351,7 +3351,7 @@ void Transaction::setOption( FDBTransactionOptions::Option option, Optionalidentifier) - .detail("ServerTraceID", info.debugID.get().toString()); + .detail("ServerTraceID", info.debugID.get().first()); } break; @@ -3387,7 +3387,7 @@ void Transaction::setOption( FDBTransactionOptions::Option option, Optionalidentifier.empty()) { TraceEvent(SevInfo, "TransactionBeingTraced") .detail("DebugTransactionID", trLogInfo->identifier) - .detail("ServerTraceID", info.debugID.get().toString()); + .detail("ServerTraceID", info.debugID.get().first()); } break; @@ -3630,7 +3630,7 @@ Future Transaction::getReadVersion(uint32_t flags) { case TransactionPriority::DEFAULT: flags |= GetReadVersionRequest::PRIORITY_DEFAULT; ++cx->transactionDefaultReadVersions; - break; + break; case TransactionPriority::BATCH: flags |= GetReadVersionRequest::PRIORITY_BATCH; ++cx->transactionBatchReadVersions; @@ -3906,7 +3906,7 @@ ACTOR Future>> getReadHotRanges(Database cx, K } } } - + ACTOR Future< std::pair, int> > waitStorageMetrics( Database cx, KeyRange keys, From 3ac6996844a0343a17946f04ca2c1708428b870f Mon Sep 17 00:00:00 2001 From: Xin Dong Date: Wed, 12 Aug 2020 14:27:34 -0700 Subject: [PATCH 3/7] Increased some knobs to throttle the spammy read hot logging. Also added more details inside the read hot log to make it useful --- fdbclient/NativeAPI.actor.cpp | 8 +-- fdbclient/NativeAPI.actor.h | 2 +- fdbclient/StorageServerInterface.h | 23 +++++++- fdbserver/DataDistributionTracker.actor.cpp | 9 ++-- fdbserver/Knobs.cpp | 12 ++--- fdbserver/StorageMetrics.actor.h | 52 ++++++++++--------- .../workloads/ReadHotDetection.actor.cpp | 4 +- 7 files changed, 69 insertions(+), 41 deletions(-) diff --git a/fdbclient/NativeAPI.actor.cpp b/fdbclient/NativeAPI.actor.cpp index a33c6cef1c..f815d7b4d4 100644 --- a/fdbclient/NativeAPI.actor.cpp +++ b/fdbclient/NativeAPI.actor.cpp @@ -3862,7 +3862,7 @@ ACTOR Future< StorageMetrics > extractMetrics( Future>> getReadHotRanges(Database cx, KeyRange keys) { +ACTOR Future>> getReadHotRanges(Database cx, KeyRange keys) { loop { int64_t shardLimit = 100; // Shard limit here does not really matter since this function is currently only used // to find the read-hot sub ranges within a read-hot shard. @@ -3889,7 +3889,7 @@ ACTOR Future>> getReadHotRanges(Database cx, K } wait(waitForAll(fReplies)); - Standalone> results; + Standalone> results; for (int i = 0; i < nLocs; i++) results.append(results.arena(), fReplies[i].get().readHotRanges.begin(), @@ -3906,7 +3906,7 @@ ACTOR Future>> getReadHotRanges(Database cx, K } } } - + ACTOR Future< std::pair, int> > waitStorageMetrics( Database cx, KeyRange keys, @@ -3994,7 +3994,7 @@ ACTOR Future>> waitDataDistributionMetricsLis } } -Future>> Transaction::getReadHotRanges(KeyRange const& keys) { +Future>> Transaction::getReadHotRanges(KeyRange const& keys) { return ::getReadHotRanges(cx, keys); } diff --git a/fdbclient/NativeAPI.actor.h b/fdbclient/NativeAPI.actor.h index 103a78a4f5..55e464b0c7 100644 --- a/fdbclient/NativeAPI.actor.h +++ b/fdbclient/NativeAPI.actor.h @@ -261,7 +261,7 @@ public: // Pass a negative value for `shardLimit` to indicate no limit on the shard number. Future< StorageMetrics > getStorageMetrics( KeyRange const& keys, int shardLimit ); Future< Standalone> > splitStorageMetrics( KeyRange const& keys, StorageMetrics const& limit, StorageMetrics const& estimated ); - Future>> getReadHotRanges(KeyRange const& keys); + Future>> getReadHotRanges(KeyRange const& keys); // If checkWriteConflictRanges is true, existing write conflict ranges will be searched for this key void set( const KeyRef& key, const ValueRef& value, bool addConflictRange = true ); diff --git a/fdbclient/StorageServerInterface.h b/fdbclient/StorageServerInterface.h index 7492999d64..ca89abe9a3 100644 --- a/fdbclient/StorageServerInterface.h +++ b/fdbclient/StorageServerInterface.h @@ -423,9 +423,30 @@ struct SplitMetricsRequest { } }; +// Should always be used inside a `Standalone`. +struct ReadHotRangeWithMetrics { + KeyRangeRef keys; + double density; + double readBandwidth; + + ReadHotRangeWithMetrics() {} + ReadHotRangeWithMetrics(KeyRangeRef const& keys, double density, double readBandwidth) + : keys(keys), density(density), readBandwidth(readBandwidth) {} + + ReadHotRangeWithMetrics(Arena& arena, const ReadHotRangeWithMetrics& rhs) + : keys(arena, rhs.keys), density(rhs.density), readBandwidth(rhs.readBandwidth) {} + + int expectedSize() { return keys.expectedSize() + sizeof(density) + sizeof(readBandwidth); } + + template + void serialize(Ar& ar) { + serializer(ar, keys, density, readBandwidth); + } +}; + struct ReadHotSubRangeReply { constexpr static FileIdentifier file_identifier = 10424537; - Standalone> readHotRanges; + Standalone> readHotRanges; template void serialize(Ar& ar) { diff --git a/fdbserver/DataDistributionTracker.actor.cpp b/fdbserver/DataDistributionTracker.actor.cpp index 5e8574e594..f12d46659c 100644 --- a/fdbserver/DataDistributionTracker.actor.cpp +++ b/fdbserver/DataDistributionTracker.actor.cpp @@ -299,11 +299,14 @@ ACTOR Future readHotDetector(DataDistributionTracker* self) { state Transaction tr(self->cx); loop { try { - Standalone> readHotRanges = wait(tr.getReadHotRanges(keys)); + Standalone> readHotRanges = wait(tr.getReadHotRanges(keys)); for (auto& keyRange : readHotRanges) { TraceEvent("ReadHotRangeLog") - .detail("KeyRangeBegin", keyRange.begin) - .detail("KeyRangeEnd", keyRange.end); + .detail("ReadDensity", keyRange.density) + .detail("ReadBandwidth", keyRange.readBandwidth) + .detail("ReadDensityThreshold", SERVER_KNOBS->SHARD_MAX_READ_DENSITY_RATIO) + .detail("KeyRangeBegin", keyRange.keys.begin) + .detail("KeyRangeEnd", keyRange.keys.end); } break; } catch (Error& e) { diff --git a/fdbserver/Knobs.cpp b/fdbserver/Knobs.cpp index f63cee653a..1577244db3 100644 --- a/fdbserver/Knobs.cpp +++ b/fdbserver/Knobs.cpp @@ -144,17 +144,17 @@ void ServerKnobs::initialize(bool randomize, ClientKnobs* clientKnobs, bool isSi init( SHARD_BYTES_PER_SQRT_BYTES, 45 ); if( buggifySmallShards ) SHARD_BYTES_PER_SQRT_BYTES = 0;//Approximately 10000 bytes per shard init( MAX_SHARD_BYTES, 500000000 ); init( KEY_SERVER_SHARD_BYTES, 500000000 ); - init( SHARD_MAX_READ_DENSITY_RATIO, 2.0); + init( SHARD_MAX_READ_DENSITY_RATIO, 8.0); /* The bytesRead/byteSize radio. Will be declared as read hot when larger than this. 2.0 was chosen to avoid reporting table scan as read hot. */ - init ( SHARD_READ_HOT_BANDWITH_MIN_PER_KSECONDS, 166667 * 1000); + init ( SHARD_READ_HOT_BANDWITH_MIN_PER_KSECONDS, 1666667 * 1000); /* - The read bandwidth of a given shard needs to be larger than this value in order to be evaluated if it's read hot. The roughly 167KB per second is calculated as following: - - Heuristic data suggests that each storage process can do max 50K read operations per second + The read bandwidth of a given shard needs to be larger than this value in order to be evaluated if it's read hot. The roughly 1.67MB per second is calculated as following: + - Heuristic data suggests that each storage process can do max 500K read operations per second - Each read has a minimum cost of EMPTY_READ_PENALTY, which is 20 bytes - - Thus that gives a minimum 1MB per second - - But to be conservative, set that number to be 1/6 of 1MB, which is roughly 166,667 bytes per second + - Thus that gives a minimum 10MB per second + - But to be conservative, set that number to be 1/6 of 10MB, which is roughly 1,666,667 bytes per second Shard with a read bandwidth smaller than this value will never be too busy to handle the reads. */ init( SHARD_MAX_BYTES_READ_PER_KSEC_JITTER, 0.1 ); diff --git a/fdbserver/StorageMetrics.actor.h b/fdbserver/StorageMetrics.actor.h index 41f51ac227..f4c58f2da6 100644 --- a/fdbserver/StorageMetrics.actor.h +++ b/fdbserver/StorageMetrics.actor.h @@ -416,9 +416,10 @@ struct StorageServerMetrics { // Given a read hot shard, this function will divide the shard into chunks and find those chunks whose // readBytes/sizeBytes exceeds the `readDensityRatio`. Please make sure to run unit tests // `StorageMetricsSampleTests.txt` after change made. - std::vector getReadHotRanges(KeyRangeRef shard, double readDensityRatio, int64_t baseChunkSize, - int64_t minShardReadBandwidthPerKSeconds) { - std::vector toReturn; + std::vector getReadHotRanges(KeyRangeRef shard, double readDensityRatio, + int64_t baseChunkSize, + int64_t minShardReadBandwidthPerKSeconds) { + std::vector toReturn; double shardSize = (double)byteSample.getEstimate(shard); int64_t shardReadBandwidth = bytesReadSample.getEstimate(shard); if (shardReadBandwidth * SERVER_KNOBS->STORAGE_METRICS_AVERAGE_INTERVAL_PER_KSECONDS <= @@ -428,7 +429,9 @@ struct StorageServerMetrics { if (shardSize <= baseChunkSize) { // Shard is small, use it as is if (bytesReadSample.getEstimate(shard) > (readDensityRatio * shardSize)) { - toReturn.push_back(shard); + toReturn.emplace_back(shard, bytesReadSample.getEstimate(shard) / shardSize, + bytesReadSample.getEstimate(shard) / + SERVER_KNOBS->STORAGE_METRICS_AVERAGE_INTERVAL); } return toReturn; } @@ -450,14 +453,15 @@ struct StorageServerMetrics { if (bytesReadSample.getEstimate(KeyRangeRef(beginKey, *endKey)) > (readDensityRatio * std::max(baseChunkSize, byteSample.getEstimate(KeyRangeRef(beginKey, *endKey))))) { auto range = KeyRangeRef(beginKey, *endKey); - if (!toReturn.empty() && toReturn.back().end == range.begin) { + if (!toReturn.empty() && toReturn.back().keys.end == range.begin) { // in case two consecutive chunks both are over the ratio, merge them. - auto updatedTail = KeyRangeRef(toReturn.back().begin, *endKey); + range = KeyRangeRef(toReturn.back().keys.begin, *endKey); toReturn.pop_back(); - toReturn.push_back(updatedTail); - } else { - toReturn.push_back(range); } + toReturn.emplace_back( + range, + (double)bytesReadSample.getEstimate(range) / std::max(baseChunkSize, byteSample.getEstimate(range)), + bytesReadSample.getEstimate(range) / SERVER_KNOBS->STORAGE_METRICS_AVERAGE_INTERVAL); } beginKey = *endKey; endKey = byteSample.sample.index(byteSample.sample.sumTo(byteSample.sample.lower_bound(beginKey)) + @@ -468,10 +472,10 @@ struct StorageServerMetrics { void getReadHotRanges(ReadHotSubRangeRequest req) { ReadHotSubRangeReply reply; - std::vector v = getReadHotRanges(req.keys, SERVER_KNOBS->SHARD_MAX_READ_DENSITY_RATIO, - SERVER_KNOBS->READ_HOT_SUB_RANGE_CHUNK_SIZE, - SERVER_KNOBS->SHARD_READ_HOT_BANDWITH_MIN_PER_KSECONDS); - reply.readHotRanges = VectorRef(v.data(), v.size()); + auto _ranges = getReadHotRanges(req.keys, SERVER_KNOBS->SHARD_MAX_READ_DENSITY_RATIO, + SERVER_KNOBS->READ_HOT_SUB_RANGE_CHUNK_SIZE, + SERVER_KNOBS->SHARD_READ_HOT_BANDWITH_MIN_PER_KSECONDS); + reply.readHotRanges = VectorRef(_ranges.data(), _ranges.size()); req.reply.send(reply); } @@ -515,11 +519,11 @@ TEST_CASE("/fdbserver/StorageMetricSample/readHotDetect/simple") { ssm.byteSample.sample.insert(LiteralStringRef("But"), 100 * sampleUnit); ssm.byteSample.sample.insert(LiteralStringRef("Cat"), 300 * sampleUnit); - vector t = + std::vector t = ssm.getReadHotRanges(KeyRangeRef(LiteralStringRef("A"), LiteralStringRef("C")), 2.0, 200 * sampleUnit, 0); - ASSERT(t.size() == 1 && (*t.begin()).begin == LiteralStringRef("Bah") && - (*t.begin()).end == LiteralStringRef("Bob")); + ASSERT(t.size() == 1 && (*t.begin()).keys.begin == LiteralStringRef("Bah") && + (*t.begin()).keys.end == LiteralStringRef("Bob")); return Void(); } @@ -546,12 +550,12 @@ TEST_CASE("/fdbserver/StorageMetricSample/readHotDetect/moreThanOneRange") { ssm.byteSample.sample.insert(LiteralStringRef("Cat"), 300 * sampleUnit); ssm.byteSample.sample.insert(LiteralStringRef("Dah"), 300 * sampleUnit); - vector t = + std::vector t = ssm.getReadHotRanges(KeyRangeRef(LiteralStringRef("A"), LiteralStringRef("D")), 2.0, 200 * sampleUnit, 0); - ASSERT(t.size() == 2 && (*t.begin()).begin == LiteralStringRef("Bah") && - (*t.begin()).end == LiteralStringRef("Bob")); - ASSERT(t.at(1).begin == LiteralStringRef("Cat") && t.at(1).end == LiteralStringRef("Dah")); + ASSERT(t.size() == 2 && (*t.begin()).keys.begin == LiteralStringRef("Bah") && + (*t.begin()).keys.end == LiteralStringRef("Bob")); + ASSERT(t.at(1).keys.begin == LiteralStringRef("Cat") && t.at(1).keys.end == LiteralStringRef("Dah")); return Void(); } @@ -579,12 +583,12 @@ TEST_CASE("/fdbserver/StorageMetricSample/readHotDetect/consecutiveRanges") { ssm.byteSample.sample.insert(LiteralStringRef("Cat"), 300 * sampleUnit); ssm.byteSample.sample.insert(LiteralStringRef("Dah"), 300 * sampleUnit); - vector t = + std::vector t = ssm.getReadHotRanges(KeyRangeRef(LiteralStringRef("A"), LiteralStringRef("D")), 2.0, 200 * sampleUnit, 0); - ASSERT(t.size() == 2 && (*t.begin()).begin == LiteralStringRef("Bah") && - (*t.begin()).end == LiteralStringRef("But")); - ASSERT(t.at(1).begin == LiteralStringRef("Cat") && t.at(1).end == LiteralStringRef("Dah")); + ASSERT(t.size() == 2 && (*t.begin()).keys.begin == LiteralStringRef("Bah") && + (*t.begin()).keys.end == LiteralStringRef("But")); + ASSERT(t.at(1).keys.begin == LiteralStringRef("Cat") && t.at(1).keys.end == LiteralStringRef("Dah")); return Void(); } diff --git a/fdbserver/workloads/ReadHotDetection.actor.cpp b/fdbserver/workloads/ReadHotDetection.actor.cpp index d6c589e059..bf2fb14c1b 100644 --- a/fdbserver/workloads/ReadHotDetection.actor.cpp +++ b/fdbserver/workloads/ReadHotDetection.actor.cpp @@ -99,7 +99,7 @@ struct ReadHotDetectionWorkload : TestWorkload { // TraceEvent("RHDCheckPhaseLog") // .detail("KeyRangeSize", sm.bytes) // .detail("KeyRangeReadBandwith", sm.bytesReadPerKSecond); - Standalone> keyRanges = wait(tr.getReadHotRanges(self->wholeRange)); + Standalone> keyRanges = wait(tr.getReadHotRanges(self->wholeRange)); // TraceEvent("RHDCheckPhaseLog") // .detail("KeyRangesSize", keyRanges.size()) // .detail("ReadKey", self->readKey.printable().c_str()) @@ -107,7 +107,7 @@ struct ReadHotDetectionWorkload : TestWorkload { // .detail("KeyRangesBackEndKey", keyRanges.back().end); // Loose check. for (auto kr : keyRanges) { - if (kr.contains(self->readKey)) { + if (kr.keys.contains(self->readKey)) { self->passed = true; } } From b17667323e66de44702bfe7020eff10c1eee97f8 Mon Sep 17 00:00:00 2001 From: Xin Dong Date: Wed, 12 Aug 2020 15:15:25 -0700 Subject: [PATCH 4/7] Resolve review comments --- fdbserver/Knobs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdbserver/Knobs.cpp b/fdbserver/Knobs.cpp index 1577244db3..89202aed0d 100644 --- a/fdbserver/Knobs.cpp +++ b/fdbserver/Knobs.cpp @@ -144,9 +144,9 @@ void ServerKnobs::initialize(bool randomize, ClientKnobs* clientKnobs, bool isSi init( SHARD_BYTES_PER_SQRT_BYTES, 45 ); if( buggifySmallShards ) SHARD_BYTES_PER_SQRT_BYTES = 0;//Approximately 10000 bytes per shard init( MAX_SHARD_BYTES, 500000000 ); init( KEY_SERVER_SHARD_BYTES, 500000000 ); - init( SHARD_MAX_READ_DENSITY_RATIO, 8.0); + init( SHARD_MAX_READ_DENSITY_RATIO, 8.0); if (randomize && BUGGIFY) SHARD_MAX_READ_DENSITY_RATIO = 2.0; /* - The bytesRead/byteSize radio. Will be declared as read hot when larger than this. 2.0 was chosen to avoid reporting table scan as read hot. + The bytesRead/byteSize radio. Will be declared as read hot when larger than this. 8.0 was chosen to avoid reporting table scan as read hot. */ init ( SHARD_READ_HOT_BANDWITH_MIN_PER_KSECONDS, 1666667 * 1000); /* From ddec93c504f1a243abab705a00719f4dd41528c3 Mon Sep 17 00:00:00 2001 From: Xin Dong Date: Wed, 12 Aug 2020 15:47:32 -0700 Subject: [PATCH 5/7] Update fdbclient/StorageServerInterface.h Co-authored-by: Jingyu Zhou --- fdbclient/StorageServerInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdbclient/StorageServerInterface.h b/fdbclient/StorageServerInterface.h index ca89abe9a3..eb6fbf1d38 100644 --- a/fdbclient/StorageServerInterface.h +++ b/fdbclient/StorageServerInterface.h @@ -429,7 +429,7 @@ struct ReadHotRangeWithMetrics { double density; double readBandwidth; - ReadHotRangeWithMetrics() {} + ReadHotRangeWithMetrics() = default; ReadHotRangeWithMetrics(KeyRangeRef const& keys, double density, double readBandwidth) : keys(keys), density(density), readBandwidth(readBandwidth) {} From e13e7c57257780e2d61fc3beb462fb4208f78244 Mon Sep 17 00:00:00 2001 From: Xin Dong Date: Wed, 12 Aug 2020 15:48:01 -0700 Subject: [PATCH 6/7] Update fdbserver/workloads/ReadHotDetection.actor.cpp Co-authored-by: Jingyu Zhou --- fdbserver/workloads/ReadHotDetection.actor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdbserver/workloads/ReadHotDetection.actor.cpp b/fdbserver/workloads/ReadHotDetection.actor.cpp index bf2fb14c1b..1cae565d23 100644 --- a/fdbserver/workloads/ReadHotDetection.actor.cpp +++ b/fdbserver/workloads/ReadHotDetection.actor.cpp @@ -106,7 +106,7 @@ struct ReadHotDetectionWorkload : TestWorkload { // .detail("KeyRangesBackBeginKey", keyRanges.back().begin) // .detail("KeyRangesBackEndKey", keyRanges.back().end); // Loose check. - for (auto kr : keyRanges) { + for (const auto& kr : keyRanges) { if (kr.keys.contains(self->readKey)) { self->passed = true; } From ced4f8c49f8d6e99229d879bbcdfcb17540a1804 Mon Sep 17 00:00:00 2001 From: Meng Xu Date: Wed, 12 Aug 2020 22:18:28 -0700 Subject: [PATCH 7/7] fix: getReadHotRanges should be const function --- fdbserver/StorageMetrics.actor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdbserver/StorageMetrics.actor.h b/fdbserver/StorageMetrics.actor.h index a975668665..46b83eccc9 100644 --- a/fdbserver/StorageMetrics.actor.h +++ b/fdbserver/StorageMetrics.actor.h @@ -421,7 +421,7 @@ struct StorageServerMetrics { // `StorageMetricsSampleTests.txt` after change made. std::vector getReadHotRanges(KeyRangeRef shard, double readDensityRatio, int64_t baseChunkSize, - int64_t minShardReadBandwidthPerKSeconds) { + int64_t minShardReadBandwidthPerKSeconds) const { std::vector toReturn; double shardSize = (double)byteSample.getEstimate(shard);