Skip to content

Commit 1778627

Browse files
committed
MB-39292: 2/n Order set_collections with warm-up
Delay the acceptance of a new manifest from ns_server whilst warm-up has yet to progress far enough. This ensures that set_collections follows the loading of any previously given manifest and KV can assert that the new manifest is a valid successor. Without this change KV can accept a manifest and then proceed to load an older one from disk and fail within warm-up as we cannot assign the older manifest over the new one. Change-Id: Ief2235b875001a77d9a184bb0b598e7fefbc1f5f Reviewed-on: http://review.couchbase.org/c/kv_engine/+/138166 Tested-by: Build Bot <[email protected]> Reviewed-by: Dave Rigby <[email protected]>
1 parent d9478ef commit 1778627

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

engines/ep/src/kv_bucket.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,6 +2628,16 @@ void KVBucket::initializeExpiryPager(Configuration& config) {
26282628

26292629
cb::engine_error KVBucket::setCollections(std::string_view manifest,
26302630
const void* cookie) {
2631+
// Only allow a new manifest once warmup has progressed past vbucket warmup
2632+
// 1) This means any prior manifest has been loaded
2633+
// 2) All vbuckets can have the new manifest applied
2634+
if (cookie && maybeWaitForVBucketWarmup(cookie)) {
2635+
EP_LOG_INFO("KVBucket::setCollections blocking for warmup cookie:{}",
2636+
cookie);
2637+
return cb::engine_error(cb::engine_errc::would_block,
2638+
"KVBucket::setCollections waiting for warmup");
2639+
}
2640+
26312641
// Inhibit VB state changes whilst updating the vbuckets
26322642
LockHolder lh(vbsetMutex);
26332643

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,11 +1254,19 @@ TEST_F(CollectionsWarmupTest, MB_38125) {
12541254
resetEngineAndEnableWarmup();
12551255

12561256
CollectionsManifest cm(CollectionEntry::fruit);
1257-
setCollections(cookie, std::string{cm});
1257+
1258+
// Cannot set the manifest yet - command follows ewouldblock pattern
1259+
auto status = engine->set_collection_manifest(cookie, std::string{cm});
1260+
EXPECT_EQ(cb::engine_errc::would_block, status);
1261+
cookie_to_mock_cookie(cookie)->status = ENGINE_FAILED;
12581262

12591263
// Now get the engine warmed up
12601264
runReadersUntilWarmedUp();
12611265

1266+
// cookie now notified and setCollections can go ahead
1267+
EXPECT_EQ(ENGINE_SUCCESS, cookie_to_mock_cookie(cookie)->status);
1268+
setCollections(cookie, std::string{cm});
1269+
12621270
auto vb = store->getVBucket(vbid);
12631271

12641272
// Fruit is enabled
@@ -1275,7 +1283,11 @@ TEST_F(CollectionsWarmupTest, LockedVBStateDuringManifestUpdate) {
12751283
// complete warmup
12761284
CollectionsManifest cm;
12771285
cm.remove(CollectionEntry::defaultC);
1278-
setCollections(cookie, std::string{cm});
1286+
1287+
// Cannot set the manifest yet - command follows ewouldblock pattern
1288+
auto status = engine->set_collection_manifest(cookie, std::string{cm});
1289+
EXPECT_EQ(cb::engine_errc::would_block, status);
1290+
cookie_to_mock_cookie(cookie)->status = ENGINE_FAILED;
12791291

12801292
auto* mockEPBucket = dynamic_cast<MockEPBucket*>(engine->getKVBucket());
12811293
mockEPBucket->setCollectionsManagerPreSetStateAtWarmupHook([this]() {
@@ -1288,6 +1300,10 @@ TEST_F(CollectionsWarmupTest, LockedVBStateDuringManifestUpdate) {
12881300
});
12891301

12901302
runReadersUntilWarmedUp();
1303+
1304+
// cookie now notified and setCollections can go ahead
1305+
EXPECT_EQ(ENGINE_SUCCESS, cookie_to_mock_cookie(cookie)->status);
1306+
setCollections(cookie, std::string{cm});
12911307
}
12921308

12931309
/**

engines/ep/tests/module_tests/evp_store_single_threaded_test.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,14 @@ cb::engine_errc SingleThreadedKVBucketTest::setCollections(
389389
}
390390

391391
auto& lpAuxioQ = *task_executor->getLpTaskQ()[AUXIO_TASK_IDX];
392+
393+
cookie_to_mock_cookie(c)->status = ENGINE_FAILED;
394+
392395
runNextTask(lpAuxioQ);
396+
397+
// Cookie now success
398+
EXPECT_EQ(ENGINE_SUCCESS, cookie_to_mock_cookie(c)->status);
399+
393400
status = engine->set_collection_manifest(c, json);
394401
EXPECT_EQ(cb::engine_errc::success, status);
395402
return status;

0 commit comments

Comments
 (0)