Skip to content

Commit 0b2ae88

Browse files
jimwwalkerdaverigby
authored andcommitted
MB-32361: Trigger compaction when a drop collection is persisted
When the flusher has persisted the end of a collection it is safe to trigger the compactor to reclaim that resource. Change-Id: I5989e965c2c378ed793edcd0e931f7b045068699 Reviewed-on: http://review.couchbase.org/102848 Tested-by: Build Bot <[email protected]> Reviewed-by: Ben Huddleston <[email protected]>
1 parent 7bd59bc commit 0b2ae88

File tree

8 files changed

+63
-25
lines changed

8 files changed

+63
-25
lines changed

engines/ep/src/collections/flush.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "collections/flush.h"
1919
#include "collections/collection_persisted_stats.h"
2020
#include "collections/vbucket_manifest.h"
21+
#include "ep_bucket.h"
2122
#include "item.h"
2223

2324
void Collections::VB::Flush::processManifestChange(const queued_item& item) {
@@ -83,4 +84,13 @@ void Collections::VB::Flush::setPersistedHighSeqno(const DocKey& key,
8384
mutated.insert(key.getCollectionID());
8485
manifest.lock(key).setPersistedHighSeqno(value);
8586
}
87+
}
88+
89+
void Collections::VB::Flush::checkAndTriggerPurge(Vbid vbid,
90+
EPBucket& bucket) const {
91+
if (!deletedCollections.empty()) {
92+
CompactionConfig config;
93+
config.db_file_id = vbid;
94+
bucket.scheduleCompaction(vbid, config, nullptr);
95+
}
8696
}

engines/ep/src/collections/flush.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <unordered_set>
2424
#include <vector>
2525

26+
class EPBucket;
27+
2628
namespace Collections {
2729
namespace VB {
2830

@@ -88,6 +90,14 @@ class Flush {
8890
*/
8991
void setPersistedHighSeqno(const DocKey& key, uint64_t value);
9092

93+
/**
94+
* Check to see if this flush should trigger a collection purge which if
95+
* true schedules a task which will iterate the vbucket's documents removing
96+
* those of any dropped collections. The actual task currently scheduled is
97+
* compaction.
98+
*/
99+
void checkAndTriggerPurge(Vbid vbid, EPBucket& bucket) const;
100+
91101
private:
92102
/**
93103
* Keep track of only the collections that have had a insert/delete in

engines/ep/src/ep_bucket.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ std::pair<bool, size_t> EPBucket::flushVBucket(Vbid vbid) {
469469
stats.cumulativeFlushTime.fetch_add(trans_time);
470470
stats.flusher_todo.store(0);
471471
stats.totalPersistVBState++;
472+
473+
sef.getCollectionFlush().checkAndTriggerPurge(vb->getId(), *this);
472474
}
473475

474476
rwUnderlying->pendingTasks();

engines/ep/tests/module_tests/collections/evp_store_collections_eraser_test.cc

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ class CollectionsEraserTest
3737
SingleThreadedKVBucketTest::TearDown();
3838
}
3939

40-
void runEraser() {
41-
runCompaction();
42-
}
43-
4440
bool isFullEviction() const {
4541
return GetParam().find("item_eviction_policy=full_eviction") !=
4642
std::string::npos;
@@ -79,7 +75,7 @@ TEST_P(CollectionsEraserTest, basic) {
7975
// Deleted, but still exists in the manifest
8076
EXPECT_TRUE(vb->lockCollections().exists(CollectionEntry::dairy));
8177

82-
runEraser();
78+
runCollectionsEraser();
8379

8480
EXPECT_EQ(0, vb->getNumItems());
8581

@@ -119,7 +115,7 @@ TEST_P(CollectionsEraserTest, basic_2_collections) {
119115

120116
flush_vbucket_to_disk(vbid, 2 /* 2 x system */);
121117

122-
runEraser();
118+
runCollectionsEraser();
123119

124120
EXPECT_EQ(0, vb->getNumItems());
125121

@@ -159,7 +155,7 @@ TEST_P(CollectionsEraserTest, basic_3_collections) {
159155

160156
flush_vbucket_to_disk(vbid, 1 /* 1 x system */);
161157

162-
runEraser();
158+
runCollectionsEraser();
163159

164160
EXPECT_EQ(2, vb->getNumItems());
165161

@@ -200,7 +196,7 @@ TEST_P(CollectionsEraserTest, basic_4_collections) {
200196

201197
flush_vbucket_to_disk(vbid, 3 /* 3x system (2 deletes, 1 create) */);
202198

203-
runEraser();
199+
runCollectionsEraser();
204200

205201
EXPECT_EQ(0, vb->getNumItems());
206202

@@ -233,7 +229,7 @@ TEST_P(CollectionsEraserTest, default_Destroy) {
233229

234230
flush_vbucket_to_disk(vbid, 1 /* 1 x system */);
235231

236-
runEraser();
232+
runCollectionsEraser();
237233

238234
EXPECT_EQ(0, vb->getNumItems());
239235

@@ -287,7 +283,7 @@ TEST_P(CollectionsEraserTest, erase_and_reset) {
287283

288284
flush_vbucket_to_disk(vbid, 3 /* 3x system (2 deletes, 1 create) */);
289285

290-
runEraser();
286+
runCollectionsEraser();
291287

292288
EXPECT_EQ(0, vb->getNumItems());
293289

engines/ep/tests/module_tests/collections/evp_store_collections_test.cc

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -864,14 +864,14 @@ TEST_F(CollectionsWarmupTest, warmupIgnoreLogicallyDeleted) {
864864
vb->lockCollections().getItemCount(CollectionEntry::meat));
865865
} // VBucketPtr scope ends
866866

867+
// Ensure collection purge has executed
868+
runCollectionsEraser();
869+
867870
resetEngineAndWarmup();
868871

869872
EXPECT_EQ(0, store->getVBucket(vbid)->ht.getNumInMemoryItems());
870-
// Eraser hasn't ran, but the collection deletion will have resulted in
871-
// the stat document being removed
872-
EXPECT_EQ(0,
873-
store->getVBucket(vbid)->lockCollections().getItemCount(
874-
CollectionEntry::meat));
873+
EXPECT_FALSE(store->getVBucket(vbid)->lockCollections().exists(
874+
CollectionEntry::meat));
875875
}
876876

877877
//
@@ -912,17 +912,17 @@ TEST_F(CollectionsWarmupTest, warmupIgnoreLogicallyDeletedDefault) {
912912
CollectionEntry::defaultC));
913913
} // VBucketPtr scope ends
914914

915+
// Ensure collection purge has executed
916+
runCollectionsEraser();
917+
915918
resetEngineAndWarmup();
916919

917920
EXPECT_EQ(0, store->getVBucket(vbid)->ht.getNumInMemoryItems());
918-
// Eraser hasn't ran, but the collection deletion will have resulted in
919-
// the stat document being removed
920-
EXPECT_EQ(0,
921-
store->getVBucket(vbid)->lockCollections().getItemCount(
922-
CollectionEntry::defaultC));
923-
EXPECT_EQ(0,
924-
store->getVBucket(vbid)->lockCollections().getPersistedHighSeqno(
925-
CollectionEntry::defaultC));
921+
// meat collection still exists
922+
EXPECT_TRUE(store->getVBucket(vbid)->lockCollections().exists(
923+
CollectionEntry::meat));
924+
EXPECT_TRUE(store->getVBucket(vbid)->lockCollections().isCollectionOpen(
925+
CollectionEntry::meat));
926926
}
927927

928928
TEST_F(CollectionsWarmupTest, warmupManifestUidLoadsOnCreate) {
@@ -942,6 +942,10 @@ TEST_F(CollectionsWarmupTest, warmupManifestUidLoadsOnCreate) {
942942
// validate the manifest uid comes back
943943
EXPECT_EQ(0xface2,
944944
store->getVBucket(vbid)->lockCollections().getManifestUid());
945+
EXPECT_TRUE(store->getVBucket(vbid)->lockCollections().exists(
946+
CollectionEntry::meat));
947+
EXPECT_TRUE(store->getVBucket(vbid)->lockCollections().isCollectionOpen(
948+
CollectionEntry::meat));
945949
}
946950

947951
TEST_F(CollectionsWarmupTest, warmupManifestUidLoadsOnDelete) {

engines/ep/tests/module_tests/evp_store_rollback_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@
3838
#include <mcbp/protocol/framebuilder.h>
3939
#include <memcached/server_cookie_iface.h>
4040

41-
class RollbackTest : public EPBucketTest,
41+
class RollbackTest : public SingleThreadedEPBucketTest,
4242
public ::testing::WithParamInterface<
4343
std::tuple<std::string, std::string>> {
4444
void SetUp() override {
4545
config_string += "item_eviction_policy=" + std::get<0>(GetParam());
46-
EPBucketTest::SetUp();
46+
SingleThreadedEPBucketTest::SetUp();
4747
if (std::get<1>(GetParam()) == "pending") {
4848
vbStateAtRollback = vbucket_state_pending;
4949
} else {

engines/ep/tests/module_tests/evp_store_single_threaded_test.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,15 @@ void SingleThreadedKVBucketTest::runCompaction(uint64_t purgeBeforeTime,
284284
"Compact DB file 0");
285285
}
286286

287+
void SingleThreadedKVBucketTest::runCollectionsEraser() {
288+
ASSERT_TRUE(engine->getConfiguration().getBucketType() == "persistent")
289+
<< "No support for ephemeral collections erase";
290+
// run the compaction task. assuming it was scheduled by the test, will
291+
// fail the runNextTask expect if not scheduled.
292+
runNextTask(*task_executor->getLpTaskQ()[WRITER_TASK_IDX],
293+
"Compact DB file 0");
294+
}
295+
287296
/*
288297
* MB-31175
289298
* The following test checks to see that when we call handleSlowStream in an

engines/ep/tests/module_tests/evp_store_single_threaded_test.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ class SingleThreadedKVBucketTest : public KVBucketTest {
9898
void runCompaction(uint64_t purgeBeforeTime = 0,
9999
uint64_t purgeBeforeSeq = 0);
100100

101+
/**
102+
* Run the task responsible for iterating the documents and erasing them
103+
* For persistent buckets integrated into compaction.
104+
* For ephemeral buckets integrated into stale item removal task
105+
*/
106+
void runCollectionsEraser();
107+
101108
protected:
102109
void SetUp() override;
103110

0 commit comments

Comments
 (0)