Skip to content

Commit 51684ab

Browse files
committed
MB-41942: Merge branch '6.5.2' into mad-hatter
* 6.5.2: MB-41942: Persist the VB state earlier during warmup Change-Id: Ia5967038242f9f7a9e9c25afca50f639c9a8d394
2 parents 1228ca1 + 41a54a2 commit 51684ab

File tree

4 files changed

+129
-4
lines changed

4 files changed

+129
-4
lines changed

engines/ep/src/ep_bucket.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,10 +1907,6 @@ bool EPBucket::maybeEnableTraffic() {
19071907
}
19081908

19091909
void EPBucket::warmupCompleted() {
1910-
// Snapshot VBucket state after warmup to ensure Failover table is
1911-
// persisted.
1912-
scheduleVBStatePersist();
1913-
19141910
if (engine.getConfiguration().getAlogPath().length() > 0) {
19151911
if (engine.getConfiguration().isAccessScannerEnabled()) {
19161912
{

engines/ep/src/warmup.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,12 @@ void Warmup::createVBuckets(uint16_t shardId) {
10631063
} else {
10641064
vb->failovers->createEntry(vbs.lastSnapStart);
10651065
}
1066+
1067+
// MB-41942: Persist the latest VB state to ensure that the
1068+
// FailoverTable is correct if we write any new seqnos during
1069+
// warmup (e.g. due to expiration)
1070+
vb->checkpointManager->queueSetVBState(*vb);
1071+
10661072
auto entry = vb->failovers->getLatestEntry();
10671073
EP_LOG_INFO(
10681074
"Warmup::createVBuckets: {} created new failover entry "

engines/ep/tests/module_tests/evp_store_single_threaded_test.cc

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "tests/test_fileops.h"
5353
#include "vbucket_bgfetch_item.h"
5454
#include "vbucket_state.h"
55+
#include "warmup.h"
5556

5657
#include "../couchstore/src/internal.h"
5758

@@ -5038,6 +5039,126 @@ void STParamPersistentBucketTest::testAbortDoesNotIncrementOpsDelete(
50385039
EXPECT_EQ(0, vb.opsDelete);
50395040
}
50405041

5042+
void STParamPersistentBucketTest::testFailoverTableEntryPersistedAtWarmup(
5043+
std::function<void()> testFunction) {
5044+
// 1) Store something so we can expire it later
5045+
engine->getKVBucket()->setVBucketState(vbid, vbucket_state_active);
5046+
auto vb = engine->getKVBucket()->getVBucket(vbid);
5047+
5048+
// Grab initialUuid for testing
5049+
auto initialUuid = vb->failovers->getLatestUUID();
5050+
5051+
auto key = makeStoredDocKey("key");
5052+
store_item(vbid, key, "value", 1 /*expiryTime*/);
5053+
flushVBucketToDiskIfPersistent(vbid, 1);
5054+
EXPECT_EQ(1, vb->getHighSeqno());
5055+
5056+
// 2) Restart as though we had an unclean shutdown (creating a new failover
5057+
// table entry) and run the warmup up to the point of completion.
5058+
vb.reset();
5059+
resetEngineAndEnableWarmup();
5060+
5061+
auto& readerQueue = *task_executor->getLpTaskQ()[READER_TASK_IDX];
5062+
auto* warmup = engine->getKVBucket()->getWarmup();
5063+
ASSERT_TRUE(warmup);
5064+
5065+
// Warmup - load everything but don't run the complete phase which schedules
5066+
// persistence of the vBucket state (new failover entry)
5067+
while (warmup->getWarmupState() != WarmupState::State::Done) {
5068+
runNextTask(readerQueue);
5069+
}
5070+
5071+
// 3) Test
5072+
testFunction();
5073+
5074+
// New high seqno
5075+
vb = engine->getKVBucket()->getVBucket(vbid);
5076+
EXPECT_EQ(2, vb->getHighSeqno());
5077+
5078+
// Flush the expiry
5079+
flushVBucketToDiskIfPersistent(vbid, 1);
5080+
5081+
// Verify that the item has been expired
5082+
auto options = static_cast<get_options_t>(
5083+
QUEUE_BG_FETCH | HONOR_STATES | TRACK_REFERENCE | DELETE_TEMP |
5084+
HIDE_LOCKED_CAS | TRACK_STATISTICS);
5085+
auto gv = store->get(key, vbid, cookie, options);
5086+
5087+
if (gv.getStatus() == ENGINE_EWOULDBLOCK) {
5088+
runBGFetcherTask();
5089+
gv = store->get(key, vbid, cookie, options);
5090+
}
5091+
5092+
EXPECT_EQ(ENGINE_KEY_ENOENT, gv.getStatus());
5093+
5094+
// Get our new uuid now
5095+
auto secondUuid = vb->failovers->getLatestUUID();
5096+
ASSERT_NE(initialUuid, secondUuid);
5097+
5098+
// "Complete" the warmup or the test will get stuck shutting down, we won't
5099+
// actually flush the new vb state though so we're still testing as though
5100+
// this didn't happen
5101+
runNextTask(readerQueue);
5102+
5103+
// 4) Restart again
5104+
vb.reset();
5105+
resetEngineAndWarmup();
5106+
5107+
// 5) The test - uuid should have both of the previous entries
5108+
vb = engine->getKVBucket()->getVBucket(vbid);
5109+
5110+
auto failovers = vb->failovers->getFailoverLog();
5111+
auto itr = std::find_if(failovers.begin(),
5112+
failovers.end(),
5113+
[&initialUuid](const auto& failoverEntry) {
5114+
return failoverEntry.uuid == initialUuid;
5115+
});
5116+
EXPECT_NE(itr, failovers.end());
5117+
5118+
itr = std::find_if(failovers.begin(),
5119+
failovers.end(),
5120+
[&secondUuid](const auto& failoverEntry) {
5121+
return failoverEntry.uuid == secondUuid;
5122+
});
5123+
EXPECT_NE(itr, failovers.end());
5124+
5125+
EXPECT_EQ(2, vb->getHighSeqno());
5126+
gv = store->get(key, vbid, cookie, options);
5127+
5128+
if (gv.getStatus() == ENGINE_EWOULDBLOCK) {
5129+
runBGFetcherTask();
5130+
gv = store->get(key, vbid, cookie, options);
5131+
}
5132+
}
5133+
5134+
TEST_P(STParamPersistentBucketTest,
5135+
TestExpiryDueToCompactionPersistsFailoverTableEntryDuringWarmup) {
5136+
testFailoverTableEntryPersistedAtWarmup([this]() {
5137+
CompactionConfig config;
5138+
engine->compactDB(vbid, config, cookie);
5139+
std::string taskDescription =
5140+
"Compact DB file " + std::to_string(vbid.get());
5141+
runNextTask(*task_executor->getLpTaskQ()[WRITER_TASK_IDX],
5142+
taskDescription);
5143+
});
5144+
}
5145+
5146+
TEST_P(STParamPersistentBucketTest,
5147+
TestExpiryDueToGetPersistsFailoverTableEntryDuringWarmup) {
5148+
testFailoverTableEntryPersistedAtWarmup([this]() {
5149+
auto options = static_cast<get_options_t>(
5150+
QUEUE_BG_FETCH | HONOR_STATES | TRACK_REFERENCE | DELETE_TEMP |
5151+
HIDE_LOCKED_CAS | TRACK_STATISTICS);
5152+
auto key = makeStoredDocKey("key");
5153+
auto gv = store->get(key, vbid, cookie, options);
5154+
5155+
if (gv.getStatus() == ENGINE_EWOULDBLOCK) {
5156+
runBGFetcherTask();
5157+
gv = store->get(key, vbid, cookie, options);
5158+
}
5159+
});
5160+
}
5161+
50415162
TEST_P(STParamPersistentBucketTest, AbortDoesNotIncrementOpsDelete) {
50425163
testAbortDoesNotIncrementOpsDelete(true /*flusherDedup*/);
50435164
}

engines/ep/tests/module_tests/evp_store_single_threaded_test.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,4 +373,6 @@ class STParamPersistentBucketTest : public STParameterizedBucketTest {
373373
* @param dropDeletes compaction config param
374374
*/
375375
void testCompactionPersistedDeletes(bool dropDeletes);
376+
377+
void testFailoverTableEntryPersistedAtWarmup(std::function<void()>);
376378
};

0 commit comments

Comments
 (0)