summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2020-09-30 14:14:01 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-10-01 22:07:02 +0000
commit00cc67fc18f2ef81a2d08d962eca1f2907e3b51e (patch)
tree4efc31b9ed003da5aae9d3838dd513cb9cc5de11 /src/mongo/db/catalog
parentfa5aff14111de4fe23ae0094c597673cc4a48d3b (diff)
downloadmongo-00cc67fc18f2ef81a2d08d962eca1f2907e3b51e.tar.gz
SERVER-51228 dbHash should return SnapshotUnavailable if the _id index is not visible or ready
Diffstat (limited to 'src/mongo/db/catalog')
-rw-r--r--src/mongo/db/catalog/index_catalog_entry.h18
-rw-r--r--src/mongo/db/catalog/index_catalog_entry_impl.cpp12
-rw-r--r--src/mongo/db/catalog/index_catalog_entry_impl.h8
3 files changed, 27 insertions, 11 deletions
diff --git a/src/mongo/db/catalog/index_catalog_entry.h b/src/mongo/db/catalog/index_catalog_entry.h
index 8abc7000fdb..e34deceab01 100644
--- a/src/mongo/db/catalog/index_catalog_entry.h
+++ b/src/mongo/db/catalog/index_catalog_entry.h
@@ -137,10 +137,26 @@ public:
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths) = 0;
- // if this ready is ready for queries
+ /**
+ * Returns whether this index is ready for queries. This is potentially unsafe in that it does
+ * not consider whether the index is visible or ready in the currently storage snapshot. For
+ * that, use isReadyInMySnapshot() or isPresentInMySnapshot().
+ */
virtual bool isReady(OperationContext* const opCtx) const = 0;
/**
+ * Safely check whether this index is visible in the durable catalog in the current storage
+ * engine snapshot.
+ */
+ virtual bool isPresentInMySnapshot(OperationContext* opCtx) const = 0;
+
+ /**
+ * Safely check whether this index is visible and ready in the durable catalog in the current
+ * storage engine snapshot.
+ */
+ virtual bool isReadyInMySnapshot(OperationContext* opCtx) const = 0;
+
+ /**
* Returns true if this index is not ready, and it is not currently in the process of being
* built either.
*/
diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.cpp b/src/mongo/db/catalog/index_catalog_entry_impl.cpp
index 7787183bb59..44458a89187 100644
--- a/src/mongo/db/catalog/index_catalog_entry_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_entry_impl.cpp
@@ -76,7 +76,7 @@ IndexCatalogEntryImpl::IndexCatalogEntryImpl(OperationContext* const opCtx,
DurableCatalog::get(opCtx)->getIndexPrefix(opCtx, _catalogId, _descriptor->indexName())) {
_descriptor->_entry = this;
- _isReady = _catalogIsReady(opCtx);
+ _isReady = isReadyInMySnapshot(opCtx);
{
stdx::lock_guard<Latch> lk(_indexMultikeyPathsMutex);
@@ -131,7 +131,7 @@ bool IndexCatalogEntryImpl::isReady(OperationContext* opCtx) const {
// out-of-sync index catalog entries. To fix this, we uassert if we detect that the
// in-memory catalog is out-of-sync with the on-disk catalog.
if (opCtx->inMultiDocumentTransaction()) {
- if (!_catalogIsPresent(opCtx) || _catalogIsReady(opCtx) != _isReady) {
+ if (!isPresentInMySnapshot(opCtx) || isReadyInMySnapshot(opCtx) != _isReady) {
uasserted(ErrorCodes::SnapshotUnavailable,
str::stream() << "Unable to read from a snapshot due to pending collection"
" catalog changes; please retry the operation.");
@@ -139,7 +139,7 @@ bool IndexCatalogEntryImpl::isReady(OperationContext* opCtx) const {
}
if (kDebugBuild)
- invariant(_isReady == _catalogIsReady(opCtx));
+ invariant(_isReady == isReadyInMySnapshot(opCtx));
return _isReady;
}
@@ -270,7 +270,7 @@ Status IndexCatalogEntryImpl::_setMultikeyInMultiDocumentTransaction(
// If the index is not visible within the side transaction, the index may have been created,
// but not committed, in the parent transaction. Therefore, we abandon the side transaction
// and set the multikey flag in the parent transaction.
- if (!_catalogIsPresent(opCtx)) {
+ if (!isPresentInMySnapshot(opCtx)) {
return {ErrorCodes::SnapshotUnavailable, "index not visible in side transaction"};
}
@@ -325,11 +325,11 @@ NamespaceString IndexCatalogEntryImpl::getNSSFromCatalog(OperationContext* opCtx
return DurableCatalog::get(opCtx)->getEntry(_catalogId).nss;
}
-bool IndexCatalogEntryImpl::_catalogIsReady(OperationContext* opCtx) const {
+bool IndexCatalogEntryImpl::isReadyInMySnapshot(OperationContext* opCtx) const {
return DurableCatalog::get(opCtx)->isIndexReady(opCtx, _catalogId, _descriptor->indexName());
}
-bool IndexCatalogEntryImpl::_catalogIsPresent(OperationContext* opCtx) const {
+bool IndexCatalogEntryImpl::isPresentInMySnapshot(OperationContext* opCtx) const {
return DurableCatalog::get(opCtx)->isIndexPresent(opCtx, _catalogId, _descriptor->indexName());
}
diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.h b/src/mongo/db/catalog/index_catalog_entry_impl.h
index f1feb5e0f92..6af6908ef8c 100644
--- a/src/mongo/db/catalog/index_catalog_entry_impl.h
+++ b/src/mongo/db/catalog/index_catalog_entry_impl.h
@@ -159,11 +159,14 @@ public:
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths) final;
- // if this ready is ready for queries
bool isReady(OperationContext* opCtx) const final;
bool isFrozen() const final;
+ bool isPresentInMySnapshot(OperationContext* opCtx) const final;
+
+ bool isReadyInMySnapshot(OperationContext* opCtx) const final;
+
KVPrefix getPrefix() const final {
return _prefix;
}
@@ -191,9 +194,6 @@ private:
const CollectionPtr& collection,
const MultikeyPaths& multikeyPaths);
- bool _catalogIsReady(OperationContext* opCtx) const;
- bool _catalogIsPresent(OperationContext* opCtx) const;
-
/**
* Retrieves the multikey information associated with this index from '_collection',
*