Skip to content

Commit 2989b63

Browse files
jimwwalkerdaverigby
authored andcommitted
MB-54516: Handle a dropped Modify event in backfill
Backfill skips out dropped collection data, the new Modify event must be included in this. Change-Id: I1409b6caa42e63983d784ffc020e84ed5bbd259a Reviewed-on: https://review.couchbase.org/c/kv_engine/+/184088 Well-Formed: Restriction Checker Tested-by: Jim Walker <[email protected]> Reviewed-by: Dave Rigby <[email protected]>
1 parent 7722f77 commit 2989b63

File tree

3 files changed

+56
-29
lines changed

3 files changed

+56
-29
lines changed

engines/ep/src/kvstore/couch-kvstore/couch-kvstore.cc

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,18 +2830,17 @@ static int bySeqnoScanCallback(Db* db, DocInfo* docinfo, void* ctx) {
28302830

28312831
auto diskKey = makeDiskDocKey(docinfo->id);
28322832

2833-
// Determine if the key is logically deleted, if it is we skip the key
2834-
// Note that system event keys (like create scope) are never skipped here
2833+
// Determine if the key is logically deleted
28352834
auto docKey = diskKey.getDocKey();
2836-
if (!docKey.isInSystemCollection()) {
2837-
if (sctx->docFilter !=
2838-
DocumentFilter::ALL_ITEMS_AND_DROPPED_COLLECTIONS) {
2839-
if (sctx->collectionsContext.isLogicallyDeleted(docKey, byseqno)) {
2840-
sctx->lastReadSeqno = byseqno;
2841-
return COUCHSTORE_SUCCESS;
2842-
}
2835+
if (sctx->docFilter != DocumentFilter::ALL_ITEMS_AND_DROPPED_COLLECTIONS) {
2836+
if (sctx->collectionsContext.isLogicallyDeleted(docKey, byseqno)) {
2837+
sctx->lastReadSeqno = byseqno;
2838+
return COUCHSTORE_SUCCESS;
28432839
}
2840+
}
28442841

2842+
// Only do cache lookup for non-system events
2843+
if (!docKey.isInSystemCollection()) {
28452844
CacheLookup lookup(diskKey, byseqno, vbucketId);
28462845

28472846
cl.callback(lookup);

engines/ep/src/kvstore/magma-kvstore/magma-kvstore.cc

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,29 +1962,25 @@ MagmaScanResult MagmaKVStore::scanOne(
19621962
return MagmaScanResult::Next();
19631963
}
19641964

1965-
// Determine if the key is logically deleted, if it is we skip the key
1966-
// Note that system event keys (like create scope) are never skipped
1967-
// here
1968-
if (!lookup.getKey().getDocKey().isInSystemCollection()) {
1969-
if (ctx.docFilter !=
1970-
DocumentFilter::ALL_ITEMS_AND_DROPPED_COLLECTIONS) {
1971-
if (ctx.collectionsContext.isLogicallyDeleted(
1972-
lookup.getKey().getDocKey(), seqno)) {
1973-
ctx.lastReadSeqno = seqno;
1974-
if (logger->should_log(spdlog::level::TRACE)) {
1975-
logger->TRACE(
1976-
"MagmaKVStore::scanOne SKIPPED(Collection "
1977-
"Deleted) {} "
1978-
"key:{} "
1979-
"seqno:{}",
1980-
ctx.vbid,
1981-
cb::UserData{lookup.getKey().to_string()},
1982-
seqno);
1983-
}
1984-
return MagmaScanResult::Next();
1965+
// Determine if the key is logically deleted before trying cache/disk read
1966+
if (ctx.docFilter != DocumentFilter::ALL_ITEMS_AND_DROPPED_COLLECTIONS) {
1967+
if (ctx.collectionsContext.isLogicallyDeleted(
1968+
lookup.getKey().getDocKey(), seqno)) {
1969+
ctx.lastReadSeqno = seqno;
1970+
if (logger->should_log(spdlog::level::TRACE)) {
1971+
logger->TRACE(
1972+
"MagmaKVStore::scanOne SKIPPED(Collection "
1973+
"Deleted) {} key:{} seqno:{}",
1974+
ctx.vbid,
1975+
cb::UserData{lookup.getKey().to_string()},
1976+
seqno);
19851977
}
1978+
return MagmaScanResult::Next();
19861979
}
1980+
}
19871981

1982+
// system collections aren't in cache so we can skip that lookup
1983+
if (!lookup.getKey().getDocKey().isInSystemCollection()) {
19881984
ctx.getCacheCallback().callback(lookup);
19891985
if (ctx.getCacheCallback().getStatus() ==
19901986
static_cast<int>(cb::engine_errc::key_already_exists)) {

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4338,6 +4338,38 @@ TEST_P(CollectionsDcpPersistentOnly, ModifyCollection) {
43384338
vb1->lockCollections().getCanDeduplicate(fruit));
43394339
EXPECT_EQ(CanDeduplicate::Yes,
43404340
vb1->lockCollections().getCanDeduplicate(vegetable));
4341+
4342+
// Final stage of the test - drop one of the modified collections and check
4343+
// backfill does not play back the modify
4344+
cm.remove(CollectionEntry::vegetable);
4345+
setCollections(cookie, cm);
4346+
flush_vbucket_to_disk(vbid, 1);
4347+
4348+
vb0.reset();
4349+
vb1.reset();
4350+
resetEngineAndWarmup();
4351+
4352+
createDcpObjects({{nullptr, 0}});
4353+
notifyAndStepToCheckpoint(ClientOpcode::DcpSnapshotMarker, false);
4354+
4355+
// Verify that modify vegetable is not transmitted
4356+
producer->stepAndExpect(*producers, ClientOpcode::DcpSystemEvent);
4357+
EXPECT_EQ(producers->last_system_event, id::CreateCollection);
4358+
EXPECT_EQ(producers->last_collection_id, fruit.getId());
4359+
4360+
producer->stepAndExpect(*producers, ClientOpcode::DcpSystemEvent);
4361+
EXPECT_EQ(producers->last_system_event, id::ModifyCollection);
4362+
EXPECT_EQ(producers->last_collection_id, fruit.getId());
4363+
4364+
producer->stepAndExpect(*producers, ClientOpcode::DcpSystemEvent);
4365+
EXPECT_EQ(producers->last_system_event, id::DeleteCollection);
4366+
EXPECT_EQ(producers->last_collection_id, vegetable.getId());
4367+
4368+
// Reacquire replica and check the backfill events
4369+
vb1 = store->getVBucket(replicaVB);
4370+
// replica received modified state
4371+
EXPECT_EQ(CanDeduplicate::No,
4372+
vb1->lockCollections().getCanDeduplicate(fruit));
43414373
}
43424374

43434375
// Test that if the flatBuffesrSystemEventsEnabled==false a modification event

0 commit comments

Comments
 (0)