@@ -202,6 +202,8 @@ std::string to_string(CouchKVStore::ReadVBStateStatus status) {
202202 switch (status) {
203203 case CouchKVStore::ReadVBStateStatus::Success:
204204 return " Success" ;
205+ case CouchKVStore::ReadVBStateStatus::NotFound:
206+ return " NotFound" ;
205207 case CouchKVStore::ReadVBStateStatus::JsonInvalid:
206208 return " JsonInvalid" ;
207209 case CouchKVStore::ReadVBStateStatus::CorruptSnapshot:
@@ -1472,7 +1474,11 @@ CompactDBStatus CouchKVStore::compactDBInternal(
14721474 delta.count (),
14731475 [this , &vbid, hook_ctx](Db& db) {
14741476 auto [status, state] = readVBState (&db, vbid);
1475- if (status != ReadVBStateStatus::Success) {
1477+ // @TODO MB-51037: We probably shouldn't fail compactions
1478+ // externally if a vBucket state does not exist in the
1479+ // header we have picked up....
1480+ if (status != ReadVBStateStatus::Success &&
1481+ status != ReadVBStateStatus::NotFound) {
14761482 return COUCHSTORE_ERROR_CANCEL;
14771483 }
14781484 hook_ctx->highCompletedSeqno =
@@ -1490,7 +1496,11 @@ CompactDBStatus CouchKVStore::compactDBInternal(
14901496 },
14911497 [this , &vbid, &prepareStats, &purge_seqno](Db& db) {
14921498 auto [status, state] = readVBState (&db, vbid);
1493- if (status != ReadVBStateStatus::Success) {
1499+ // @TODO MB-51037: We probably shouldn't fail compactions
1500+ // externally if a vBucket state does not exist in the
1501+ // header we have picked up....
1502+ if (status != ReadVBStateStatus::Success &&
1503+ status != ReadVBStateStatus::NotFound) {
14941504 return COUCHSTORE_ERROR_CANCEL;
14951505 }
14961506 prepareStats.onDiskPrepares = state.onDiskPrepares ;
@@ -3290,10 +3300,7 @@ CouchKVStore::ReadVBStateResult CouchKVStore::readVBState(Db* db,
32903300 " CouchKVStore::readVBState: '_local/vbstate' not found "
32913301 " for {}" ,
32923302 vbId);
3293-
3294- // Read was successful, the state just didn't exist. Return success
3295- // and a default constructed vbucket_state
3296- return {ReadVBStateStatus::Success, {}};
3303+ return {ReadVBStateStatus::NotFound, {}};
32973304 }
32983305
32993306 if (couchStoreStatus != COUCHSTORE_SUCCESS) {
@@ -3394,6 +3401,12 @@ CouchKVStore::ReadVBStateResult CouchKVStore::readVBStateAndUpdateCache(
33943401 }
33953402 }
33963403
3404+ // @TODO MB-51413: NotFound should probably not load a state, but for now
3405+ // we'd segfault higher up the stack during initialize if we don't allow it.
3406+ if (res.status == ReadVBStateStatus::NotFound) {
3407+ res.status = ReadVBStateStatus::Success;
3408+ }
3409+
33973410 if (res.status == ReadVBStateStatus::Success) {
33983411 // For the case where a local doc does not exist, readVBState actually
33993412 // returns Success as the read was successful. It also returns a default
@@ -4242,7 +4255,11 @@ vbucket_state CouchKVStore::getPersistedVBucketState(Vbid vbid) const {
42424255 }
42434256
42444257 const auto res = readVBState (db, vbid);
4245- if (res.status != ReadVBStateStatus::Success) {
4258+ // @TODO MB-51413 Expand the status returned by this. NotFound is valid
4259+ // in certain circumstances and we should neither throw nor return the
4260+ // default constructed vbucket_state.
4261+ if (res.status != ReadVBStateStatus::Success &&
4262+ res.status != ReadVBStateStatus::NotFound) {
42464263 throw std::logic_error (
42474264 " CouchKVStore::getPersistedVBucketState: readVBState error:" +
42484265 to_string (res.status ) +
0 commit comments