Skip to content

Commit 4147bef

Browse files
committed
Fix off-by-one error with removeClosedUnrefCheckpoints.limit
There is an off-by-one error in CheckpointManager::removeClosedUnrefCheckpoints() when the `limit` argumeent is used - the last unreferenced Checkpoint is not removed. This is because the early `break` from the for-loop doesn't increment `it` - as it would normally be in the for loop iteration expression - note that `it` indicates the first checkpoint to keep, *not* the last one to remove (as per std::list::splice taking the range [first, last) (i.e. last is exclusive). For example, consider 2 checkpoints where the only cursors are in the final checkpoint: 1:CLOSED, 2:OPEN ^ | Persistence cursor We should be able to remove Checkpoint 1 when limit==1 is specified, however due to the aforementioned bug we don't remove any. Change-Id: I355b5f953bb8e22993e86fff2a11f2794fa368e6 Reviewed-on: http://review.couchbase.org/111654 Reviewed-by: James Harrison <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent f37946d commit 4147bef

File tree

3 files changed

+11
-3
lines changed

3 files changed

+11
-3
lines changed

engines/ep/benchmarks/vbucket_bench.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,8 @@ BENCHMARK_DEFINE_F(CheckpointBench, QueueDirtyWithManyClosedUnrefCheckpoints)
314314
/*preLinkDocCtx*/ nullptr);
315315
}
316316

317-
// Simulate the Flusher, this makes all checkpoints eligible for removing
317+
// Simulate the Flusher, this makes all but the current checkpoint eligible
318+
// for removing (cannot remove checkpoint flusher is in).
318319
std::vector<queued_item> items;
319320
ckptMgr->getAllItemsForPersistence(items);
320321
ckptMgr->itemsPersisted();
@@ -342,7 +343,9 @@ BENCHMARK_DEFINE_F(CheckpointBench, QueueDirtyWithManyClosedUnrefCheckpoints)
342343
numUnrefItems += removed;
343344
numCkptRemoverRuns++;
344345

345-
if (numUnrefItems >= numCheckpoints) {
346+
// Once all but the last item (in last checkpoint) is removed,
347+
// break.
348+
if (numUnrefItems >= numCheckpoints - 1) {
346349
break;
347350
}
348351
}
@@ -404,6 +407,7 @@ static void FlushArguments(benchmark::internal::Benchmark* b) {
404407
BENCHMARK_REGISTER_F(MemTrackingVBucketBench, FlushVBucket)
405408
->Apply(FlushArguments);
406409

410+
// Arguments: numCheckpoints, numCkptToRemovePerIteration
407411
BENCHMARK_REGISTER_F(CheckpointBench, QueueDirtyWithManyClosedUnrefCheckpoints)
408412
->Args({1000000, 1000})
409413
->Iterations(1);

engines/ep/src/checkpoint.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,8 @@ int64_t Checkpoint::getMutationId(const CheckpointCursor& cursor) const {
374374

375375
std::ostream& operator <<(std::ostream& os, const Checkpoint& c) {
376376
os << "Checkpoint[" << &c << "] with"
377-
<< " seqno:{" << c.getLowSeqno() << "," << c.getHighSeqno() << "}"
377+
<< " id:" << c.checkpointId << " seqno:{" << c.getLowSeqno() << ","
378+
<< c.getHighSeqno() << "}"
378379
<< " snap:{" << c.getSnapshotStartSeqno() << ","
379380
<< c.getSnapshotEndSeqno() << "}"
380381
<< " state:" << to_string(c.getState()) << " items:[" << std::endl;

engines/ep/src/checkpoint_manager.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,8 @@ size_t CheckpointManager::removeClosedUnrefCheckpoints(
401401
size_t numCheckpointsRemoved = 0;
402402
// Iterate through the current checkpoints (from oldest to newest),
403403
// checking if the checkpoint can be removed.
404+
// `it` is set to the first checkpoint we want to keep - all earlier
405+
// ones are removed.
404406
auto it = checkpointList.begin();
405407
// Note terminating condition - we stop at one before the last
406408
// checkpoint - we must leave at least one checkpoint in existence.
@@ -420,6 +422,7 @@ size_t CheckpointManager::removeClosedUnrefCheckpoints(
420422
++numCheckpointsRemoved;
421423

422424
if (numCheckpointsRemoved >= limit) {
425+
++it;
423426
break;
424427
}
425428

0 commit comments

Comments
 (0)