Skip to content

Commit fdb1a3e

Browse files
committed
Resolves #138: Collection context in the cache should always include indexes.
getUnboundCollectionContext() should always return context with indexes included. As this function plays with cache, its good to not play with how it creates collection context. Instead client of this function can make a copy and do anything with it. Otherwise, we will find interesting inconsistencies in the metadata cache.
1 parent 55fcbfd commit fdb1a3e

5 files changed

Lines changed: 22 additions & 31 deletions

File tree

src/Constants.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ const uint64_t INDEX_KEY_LENGTH_LIMIT = (uint64_t)1e4;
2727
const uint64_t FDB_KEY_LENGTH_LIMIT = (uint64_t)1e4;
2828
const uint64_t FDB_VALUE_LENGTH_LIMIT = (uint64_t)1e5;
2929

30+
const uint64_t METADATA_CACHE_SIZE = (uint64_t)100;
31+
3032
const std::string METADATA = "metadata";
3133
const std::string VERSION_KEY = "version";
3234
const std::string INDICES_KEY = "indices";

src/Constants.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ extern const uint64_t INDEX_KEY_LENGTH_LIMIT; // This is set to 10K bytes, inste
3434
extern const uint64_t FDB_KEY_LENGTH_LIMIT;
3535
extern const uint64_t FDB_VALUE_LENGTH_LIMIT;
3636

37+
// Size of metadata cache in entries, number of collections
38+
extern const uint64_t METADATA_CACHE_SIZE;
39+
3740
// KVS DocLayer internal keys
3841
extern const std::string METADATA;
3942
extern const std::string VERSION_KEY;

src/ExtMsg.actor.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,8 +1204,7 @@ ACTOR Future<WriteCmdResult> doDeleteCmd(Namespace ns,
12041204

12051205
// If collection not found then just return success from here.
12061206
try {
1207-
Reference<UnboundCollectionContext> _cx =
1208-
wait(ec->mm->getUnboundCollectionContext(dtr, ns, false, true, false));
1207+
Reference<UnboundCollectionContext> _cx = wait(ec->mm->getUnboundCollectionContext(dtr, ns, false, false));
12091208
cx = _cx;
12101209
} catch (Error& e) {
12111210
if (e.code() == error_code_collection_not_found)

src/MetadataManager.actor.cpp

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,8 @@ IndexInfo MetadataManager::indexInfoFromObj(const bson::BSONObj& indexObj, Refer
8686
}
8787
}
8888

89-
ACTOR static Future<std::pair<Reference<UnboundCollectionContext>, uint64_t>> constructContext(
90-
Namespace ns,
91-
Reference<DocTransaction> tr,
92-
DocumentLayer* docLayer,
93-
bool includeIndex,
94-
bool createCollectionIfAbsent) {
89+
ACTOR static Future<std::pair<Reference<UnboundCollectionContext>, uint64_t>>
90+
constructContext(Namespace ns, Reference<DocTransaction> tr, DocumentLayer* docLayer, bool createCollectionIfAbsent) {
9591
try {
9692
// The initial set of directory reads take place in a separate transaction with the same read version as `tr'.
9793
// This hopefully prevents us from accidentally RYWing a directory that `tr' itself created, and then adding it
@@ -112,20 +108,15 @@ ACTOR static Future<std::pair<Reference<UnboundCollectionContext>, uint64_t>> co
112108
state Reference<UnboundCollectionContext> cx =
113109
Reference<UnboundCollectionContext>(new UnboundCollectionContext(collectionDirectory, metadataDirectory));
114110

115-
// Only include existing indexes into the context when it's NOT building a new index.
116-
// When it's building a new index, it's unnecessary and inefficient to pass each recorded returned by a
117-
// TableScan through the existing indexes.
118-
if (includeIndex) {
119-
state Reference<UnboundCollectionContext> indexCx = Reference<UnboundCollectionContext>(
120-
new UnboundCollectionContext(indexDirectory, Reference<DirectorySubspace>()));
121-
state Reference<Plan> indexesPlan = getIndexesForCollectionPlan(indexCx, ns);
122-
std::vector<bson::BSONObj> allIndexes = wait(getIndexesTransactionally(indexesPlan, tr));
111+
state Reference<UnboundCollectionContext> indexCx = Reference<UnboundCollectionContext>(
112+
new UnboundCollectionContext(indexDirectory, Reference<DirectorySubspace>()));
113+
state Reference<Plan> indexesPlan = getIndexesForCollectionPlan(indexCx, ns);
114+
std::vector<bson::BSONObj> allIndexes = wait(getIndexesTransactionally(indexesPlan, tr));
123115

124-
for (const auto& indexObj : allIndexes) {
125-
IndexInfo index = MetadataManager::indexInfoFromObj(indexObj, cx);
126-
if (index.status != IndexInfo::IndexStatus::INVALID) {
127-
cx->addIndex(index);
128-
}
116+
for (const auto& indexObj : allIndexes) {
117+
IndexInfo index = MetadataManager::indexInfoFromObj(indexObj, cx);
118+
if (index.status != IndexInfo::IndexStatus::INVALID) {
119+
cx->addIndex(index);
129120
}
130121
}
131122

@@ -172,16 +163,15 @@ ACTOR static Future<std::pair<Reference<UnboundCollectionContext>, uint64_t>> co
172163
ACTOR static Future<Reference<UnboundCollectionContext>> assembleCollectionContext(Reference<DocTransaction> tr,
173164
Namespace ns,
174165
Reference<MetadataManager> self,
175-
bool includeIndex,
176166
bool createCollectionIfAbsent) {
177-
if (self->contexts.size() > 100)
167+
if (self->contexts.size() > DocLayerConstants::METADATA_CACHE_SIZE)
178168
self->contexts.clear();
179169

180170
auto match = self->contexts.find(ns);
181171

182172
if (match == self->contexts.end()) {
183173
std::pair<Reference<UnboundCollectionContext>, uint64_t> unboundPair =
184-
wait(constructContext(ns, tr, self->docLayer, includeIndex, createCollectionIfAbsent));
174+
wait(constructContext(ns, tr, self->docLayer, createCollectionIfAbsent));
185175

186176
// Here and below don't pollute the cache if we just created the directory, since this transaction might
187177
// not commit.
@@ -204,7 +194,7 @@ ACTOR static Future<Reference<UnboundCollectionContext>> assembleCollectionConte
204194
uint64_t version = wait(getMetadataVersion(tr, oldUnbound->metadataDirectory));
205195
if (version != oldVersion) {
206196
std::pair<Reference<UnboundCollectionContext>, uint64_t> unboundPair =
207-
wait(constructContext(ns, tr, self->docLayer, includeIndex, createCollectionIfAbsent));
197+
wait(constructContext(ns, tr, self->docLayer, createCollectionIfAbsent));
208198
if (unboundPair.second != -1) {
209199
// Create the iterator again instead of making the previous value state, because the map could have
210200
// changed during the previous wait. Either way, replace it with ours (can no longer optimize this by
@@ -231,19 +221,17 @@ Future<Reference<UnboundCollectionContext>> MetadataManager::getUnboundCollectio
231221
Reference<DocTransaction> tr,
232222
Namespace const& ns,
233223
bool allowSystemNamespace,
234-
bool includeIndex,
235224
bool createCollectionIfAbsent) {
236225
if (!allowSystemNamespace && startsWith(ns.second.c_str(), "system."))
237226
throw write_system_namespace();
238-
return assembleCollectionContext(tr, ns, Reference<MetadataManager>::addRef(this), includeIndex,
239-
createCollectionIfAbsent);
227+
return assembleCollectionContext(tr, ns, Reference<MetadataManager>::addRef(this), createCollectionIfAbsent);
240228
}
241229

242230
Future<Reference<UnboundCollectionContext>> MetadataManager::refreshUnboundCollectionContext(
243231
Reference<UnboundCollectionContext> cx,
244232
Reference<DocTransaction> tr) {
245233
return assembleCollectionContext(tr, std::make_pair(cx->databaseName(), cx->collectionName()),
246-
Reference<MetadataManager>::addRef(this), false, false);
234+
Reference<MetadataManager>::addRef(this), false);
247235
}
248236

249237
ACTOR static Future<Void> buildIndex_impl(bson::BSONObj indexObj,
@@ -254,7 +242,7 @@ ACTOR static Future<Void> buildIndex_impl(bson::BSONObj indexObj,
254242
state IndexInfo info;
255243
try {
256244
state Reference<DocTransaction> tr = ec->getOperationTransaction();
257-
state Reference<UnboundCollectionContext> mcx = wait(ec->mm->getUnboundCollectionContext(tr, ns, false, false));
245+
state Reference<UnboundCollectionContext> mcx = wait(ec->mm->getUnboundCollectionContext(tr, ns, false));
258246
info = MetadataManager::indexInfoFromObj(indexObj, mcx);
259247
info.status = IndexInfo::IndexStatus::BUILDING;
260248
info.buildId = build_id;

src/MetadataManager.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ struct MetadataManager : ReferenceCounted<MetadataManager>, NonCopyable {
4040
Future<Reference<UnboundCollectionContext>> getUnboundCollectionContext(Reference<DocTransaction> tr,
4141
Namespace const& ns,
4242
bool allowSystemNamespace = false,
43-
bool includeIndex = true,
4443
bool createCollectionIfAbsent = true);
4544
Future<Reference<UnboundCollectionContext>> refreshUnboundCollectionContext(Reference<UnboundCollectionContext> cx,
4645
Reference<DocTransaction> tr);

0 commit comments

Comments
 (0)