Skip to content

Commit d541aaa

Browse files
committed
MB-41747: Reset the cached couch handle
With the introduction of a cache containing the vbucket files we would reuse the couchstore handle every time we tried to write to the database. That would work in the case where no errors occur, but in the case for commit failures the data was already written to the disk and the internal datastructures in the couchstore handle referenced the new data (and it would be included in the next commit). On flush failures we would try to "roll back" the changes we did and previously this worked due to the fact that we would "drop" the couchstore instance every time we would try to add data to the instance. This patch resets the database handle every time it is fetched from the cache. Ideally it should only be reset on failures which would require it to do so, but that should be tracked in its own MB. Change-Id: I5f4809d9b5e266bb02a3c011e7316162201bab54 Reviewed-on: http://review.couchbase.org/c/kv_engine/+/138740 Tested-by: Build Bot <[email protected]> Reviewed-by: Jim Walker <[email protected]>
1 parent ddf3879 commit d541aaa

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,6 +2125,16 @@ CouchKVStore::OpenForWriteResult CouchKVStore::openDbForWrite(Vbid vbucketId) {
21252125
closeOnUnlock};
21262126
}
21272127

2128+
// MB-41747: couchstore_commit (and maybe other commands) may have returned
2129+
// an error and we don't really know the internal state. (in the case
2130+
// of a failing couchstore_commit the documents has been written to the
2131+
// database file and is linked from the internal data structures in the
2132+
// database handle and will be present in the _NEXT_ call to
2133+
// couchstore_commit. On the other hand our "flusher" tries to "roll back"
2134+
// these changes. This used to work before we added the cache, as each
2135+
// call would open the database file again. Until we've identified all
2136+
// cases lets reset the handle before returning the instance.
2137+
cb::couchstore::seek(*dbHolder->getDb(), cb::couchstore::Direction::End);
21282138
return {COUCHSTORE_SUCCESS, std::move(dbHolder), closeOnUnlock};
21292139
}
21302140

engines/ep/tests/module_tests/dcp_stream_test.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3838,6 +3838,19 @@ TEST_P(STPassiveStreamCouchstoreTest, VBStateNotLostAfterFlushFailure) {
38383838
// engine
38393839
replaceCouchKVStore(dynamic_cast<CouchKVStoreConfig&>(nonConstConfig),
38403840
*couchstore_get_default_file_ops());
3841+
3842+
// MB-41747: Make sure that we don't have a an on-disk-prepare as
3843+
// part of the internal database handle used by the underlying storage
3844+
// which will be written to disk (and purged as part of commit)
3845+
auto res = store->getLockedVBucket(vbid);
3846+
ASSERT_TRUE(res.owns_lock());
3847+
auto& underlying = *store->getRWUnderlying(vbid);
3848+
3849+
CompactionConfig cc;
3850+
cc.vbid = vbid;
3851+
auto context = std::make_shared<CompactionContext>(cc, 1);
3852+
underlying.compactDB(res.getLock(), context);
3853+
EXPECT_EQ(0, underlying.getVBucketState(vbid)->onDiskPrepares);
38413854
}
38423855

38433856
/**

0 commit comments

Comments
 (0)