Skip to content

Commit 4aef3a8

Browse files
jimwwalkerdaverigby
authored andcommitted
MB-15009: Allow stored value age to be changed by cbepctl
Update the flush_param handling so the config value can be changed. Update how the defrag ages are configured on the visitor, rather than wait for a full visit cycle, update the values for each task run, this means for very large hash-tables changes to the age values are realised much more quickly. Change-Id: I89ef8defbb4759a2b0a1a45eab9e26c310f5b27f Reviewed-on: http://review.couchbase.org/106931 Well-Formed: Build Bot <[email protected]> Reviewed-by: Dave Rigby <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 37cf721 commit 4aef3a8

File tree

7 files changed

+48
-38
lines changed

7 files changed

+48
-38
lines changed

engines/ep/benchmarks/defragmenter_bench.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,12 @@ class DefragmentBench : public benchmark::Fixture {
101101
std::chrono::milliseconds chunk_duration) {
102102
// Create and run visitor for the specified number of iterations, with
103103
// the given age.
104-
DefragmentVisitor visitor(age_threshold,
105-
DefragmenterTask::getMaxValueSize(
106-
get_mock_server_api()->alloc_hooks),
107-
age_threshold);
104+
DefragmentVisitor visitor(DefragmenterTask::getMaxValueSize(
105+
get_mock_server_api()->alloc_hooks));
106+
107+
visitor.setBlobAgeThreshold(age_threshold);
108+
visitor.setStoredValueAgeThreshold(age_threshold);
109+
108110
// Need to run 10 passes; so we allow the deframenter to defrag at
109111
// least once (given the age_threshold may be up to 10).
110112
const size_t passes = 10;

engines/ep/management/cbepctl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ Available params for "set":
188188
defragmenter_age_threshold - How old (measured in number of defragmenter
189189
passes) must a document be to be considered
190190
for defragmentation.
191+
defragmenter_stored_value_age_threshold - How old (measured in number of defragmenter
192+
passes) must a StoredValue (key + meta) be to be considered
193+
for defragmentation.
191194
defragmenter_chunk_duration - Maximum time (in ms) defragmentation task
192195
will run for before being paused (and
193196
resumed at the next defragmenter_interval).

engines/ep/src/defragmenter.cc

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,8 @@ bool DefragmenterTask::run(void) {
4040
// then resume from where we last were, otherwise create a new visitor
4141
// starting from the beginning.
4242
if (!prAdapter) {
43-
boost::optional<uint8_t> storedValueAge;
44-
45-
// Only defragment persistent buckets because the HashTable defrag
46-
// method doesn't yet know how to maintain the ephemeral seqno
47-
// linked-list
48-
if (engine->getConfiguration().getBucketType() == "persistent") {
49-
storedValueAge = getStoredValueAgeThreshold();
50-
}
51-
5243
auto visitor = std::make_unique<DefragmentVisitor>(
53-
getAgeThreshold(),
54-
getMaxValueSize(alloc_hooks),
55-
storedValueAge);
44+
getMaxValueSize(alloc_hooks));
5645

5746
prAdapter =
5847
std::make_unique<PauseResumeVBAdapter>(std::move(visitor));
@@ -83,6 +72,13 @@ bool DefragmenterTask::run(void) {
8372
const auto start = ProcessClock::now();
8473
const auto deadline = start + getChunkDuration();
8574
visitor.setDeadline(deadline);
75+
visitor.setBlobAgeThreshold(getAgeThreshold());
76+
// Only defragment StoredValues of persistent buckets because the
77+
// HashTable defrag method doesn't yet know how to maintain the
78+
// ephemeral seqno linked-list
79+
if (engine->getConfiguration().getBucketType() == "persistent") {
80+
visitor.setStoredValueAgeThreshold(getStoredValueAgeThreshold());
81+
}
8682
visitor.clearStats();
8783

8884
// Do it - set off the visitor.

engines/ep/src/defragmenter_visitor.cc

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,11 @@
1919

2020
// DegragmentVisitor implementation ///////////////////////////////////////////
2121

22-
DefragmentVisitor::DefragmentVisitor(uint8_t age_threshold_,
23-
size_t max_size_class,
24-
boost::optional<uint8_t> sv_age_threshold)
22+
DefragmentVisitor::DefragmentVisitor(size_t max_size_class)
2523
: max_size_class(max_size_class),
26-
age_threshold(age_threshold_),
2724
defrag_count(0),
2825
visited_count(0),
29-
currentVb(nullptr),
30-
sv_age_threshold(sv_age_threshold) {
26+
currentVb(nullptr) {
3127
}
3228

3329
DefragmentVisitor::~DefragmentVisitor() {
@@ -37,6 +33,14 @@ void DefragmentVisitor::setDeadline(ProcessClock::time_point deadline) {
3733
progressTracker.setDeadline(deadline);
3834
}
3935

36+
void DefragmentVisitor::setBlobAgeThreshold(uint8_t age) {
37+
age_threshold = age;
38+
}
39+
40+
void DefragmentVisitor::setStoredValueAgeThreshold(uint8_t age) {
41+
sv_age_threshold = age;
42+
}
43+
4044
bool DefragmentVisitor::visit(const HashTable::HashBucketLock& lh,
4145
StoredValue& v) {
4246
const size_t value_len = v.valuelen();

engines/ep/src/defragmenter_visitor.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,24 @@
3131
*/
3232
class DefragmentVisitor : public VBucketAwareHTVisitor {
3333
public:
34-
DefragmentVisitor(uint8_t age_threshold_,
35-
size_t max_size_class,
36-
boost::optional<uint8_t> sv_age_threshold);
34+
DefragmentVisitor(size_t max_size_class);
3735

3836
~DefragmentVisitor();
3937

4038
// Set the deadline at which point the visitor will pause visiting.
4139
void setDeadline(ProcessClock::time_point deadline_);
4240

41+
/**
42+
* Set the age at which Blobs are defragged 0 - 255
43+
*/
44+
void setBlobAgeThreshold(uint8_t age);
45+
46+
/**
47+
* Set the age at which StoredValues are defragged - by default SV
48+
* defragging is off until an age is set (0-255)
49+
*/
50+
void setStoredValueAgeThreshold(uint8_t age);
51+
4352
// Implementation of HashTableVisitor interface:
4453
virtual bool visit(const HashTable::HashBucketLock& lh,
4554
StoredValue& v) override;
@@ -68,7 +77,7 @@ class DefragmentVisitor : public VBucketAwareHTVisitor {
6877
const size_t max_size_class;
6978

7079
// How old a blob must be to consider it for defragmentation.
71-
const uint8_t age_threshold;
80+
uint8_t age_threshold{0};
7281

7382
/* Runtime state */
7483

engines/ep/src/ep_engine.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,10 @@ protocol_binary_response_status EventuallyPersistentEngine::setFlushParam(
592592
std::stoull(valz));
593593
} else if (strcmp(keyz, "defragmenter_age_threshold") == 0) {
594594
getConfiguration().setDefragmenterAgeThreshold(std::stoull(valz));
595+
} else if (strcmp(keyz, "defragmenter_stored_value_age_threshold") ==
596+
0) {
597+
getConfiguration().setDefragmenterStoredValueAgeThreshold(
598+
std::stoull(valz));
595599
} else if (strcmp(keyz, "defragmenter_chunk_duration") == 0) {
596600
getConfiguration().setDefragmenterChunkDuration(std::stoull(valz));
597601
} else if (strcmp(keyz, "defragmenter_run") == 0) {

engines/ep/tests/module_tests/defragmenter_test.cc

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -252,21 +252,15 @@ TEST_P(DefragmenterTest, DISABLED_MappedMemory) {
252252
// 3. Enable defragmenter and trigger defragmentation
253253
AllocHooks::enable_thread_cache(false);
254254

255-
// Setup the StoredValue de-frag age only if in StoredValue mode
256-
boost::optional<uint8_t> storedValueAge;
257-
if (isModeStoredValue()) {
258-
storedValueAge = 0; // Use zero so all SV's get moved.
259-
}
260-
261255
auto defragVisitor = std::make_unique<DefragmentVisitor>(
262-
0,
263256
DefragmenterTask::getMaxValueSize(
264-
get_mock_server_api()->alloc_hooks),
265-
storedValueAge);
257+
get_mock_server_api()->alloc_hooks));
266258

267259
if (isModeStoredValue()) {
268260
// Force visiting of every item by setting a large deadline
269261
defragVisitor->setDeadline(ProcessClock::now() + std::chrono::hours(5));
262+
// And set the age, which enables SV defragging
263+
defragVisitor->setStoredValueAgeThreshold(0);
270264
}
271265

272266
PauseResumeVBAdapter prAdapter(std::move(defragVisitor));
@@ -363,10 +357,8 @@ TEST_P(DefragmenterTest, DISABLED_RefCountMemUsage) {
363357
AllocHooks::enable_thread_cache(false);
364358

365359
PauseResumeVBAdapter prAdapter(std::make_unique<DefragmentVisitor>(
366-
0,
367360
DefragmenterTask::getMaxValueSize(
368-
get_mock_server_api()->alloc_hooks),
369-
boost::optional<uint8_t>{/*no sv defragging*/}));
361+
get_mock_server_api()->alloc_hooks)));
370362
prAdapter.visit(*vbucket);
371363

372364
AllocHooks::enable_thread_cache(true);

0 commit comments

Comments
 (0)