summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDewal Gupta <dewal.gupta@10gen.com>2018-07-23 17:46:33 -0400
committerDewal Gupta <dewal.gupta@10gen.com>2018-08-20 09:38:12 -0400
commit5b5502a6947d12356b1fd3e44ad07e4f2453be41 (patch)
tree3562de6d55c8f6129c63f106bf55252a1157fbaf
parent6c33879eaa545136f8e1c747780ffd3ccb493dce (diff)
downloadmongo-5b5502a6947d12356b1fd3e44ad07e4f2453be41.tar.gz
SERVER-36005 Prevent unsafe IndexCatalogEntryImpl::_catalogIsReady call
(cherry picked from commit dfdffb7e4588d41c99e625ade8e9aa638b0c3fd4)
-rw-r--r--src/mongo/db/catalog/collection_catalog_entry.h2
-rw-r--r--src/mongo/db/catalog/index_catalog_entry_impl.cpp14
-rw-r--r--src/mongo/db/catalog/index_catalog_entry_impl.h1
-rw-r--r--src/mongo/db/storage/bson_collection_catalog_entry.cpp7
-rw-r--r--src/mongo/db/storage/bson_collection_catalog_entry.h2
-rw-r--r--src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp6
-rw-r--r--src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h2
7 files changed, 30 insertions, 4 deletions
diff --git a/src/mongo/db/catalog/collection_catalog_entry.h b/src/mongo/db/catalog/collection_catalog_entry.h
index a55280a6724..f08085d7710 100644
--- a/src/mongo/db/catalog/collection_catalog_entry.h
+++ b/src/mongo/db/catalog/collection_catalog_entry.h
@@ -109,6 +109,8 @@ public:
virtual bool isIndexReady(OperationContext* opCtx, StringData indexName) const = 0;
+ virtual bool isIndexPresent(OperationContext* opCtx, StringData indexName) const = 0;
+
virtual KVPrefix getIndexPrefix(OperationContext* opCtx, StringData indexName) const = 0;
virtual Status removeIndex(OperationContext* opCtx, StringData indexName) = 0;
diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.cpp b/src/mongo/db/catalog/index_catalog_entry_impl.cpp
index f44e5a0f31e..09859e35b4c 100644
--- a/src/mongo/db/catalog/index_catalog_entry_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_entry_impl.cpp
@@ -167,10 +167,12 @@ bool IndexCatalogEntryImpl::isReady(OperationContext* opCtx) const {
// minimumSnapshotVersion on a collection. This means we are unprotected from reading
// 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 (session && session->inMultiDocumentTransaction() && _catalogIsReady(opCtx) != _isReady) {
- uasserted(ErrorCodes::SnapshotUnavailable,
- str::stream() << "Unable to read from a snapshot due to pending collection"
- " catalog changes; please retry the operation.");
+ if (session && session->inMultiDocumentTransaction()) {
+ if (!_catalogIsPresent(opCtx) || _catalogIsReady(opCtx) != _isReady) {
+ uasserted(ErrorCodes::SnapshotUnavailable,
+ str::stream() << "Unable to read from a snapshot due to pending collection"
+ " catalog changes; please retry the operation.");
+ }
}
DEV invariant(_isReady == _catalogIsReady(opCtx));
@@ -360,6 +362,10 @@ RecordId IndexCatalogEntryImpl::_catalogHead(OperationContext* opCtx) const {
return _collection->getIndexHead(opCtx, _descriptor->indexName());
}
+bool IndexCatalogEntryImpl::_catalogIsPresent(OperationContext* opCtx) const {
+ return _collection->isIndexPresent(opCtx, _descriptor->indexName());
+}
+
bool IndexCatalogEntryImpl::_catalogIsMultikey(OperationContext* opCtx,
MultikeyPaths* multikeyPaths) const {
return _collection->isIndexMultikey(opCtx, _descriptor->indexName(), multikeyPaths);
diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.h b/src/mongo/db/catalog/index_catalog_entry_impl.h
index 0564c35d7c0..86fa76c6101 100644
--- a/src/mongo/db/catalog/index_catalog_entry_impl.h
+++ b/src/mongo/db/catalog/index_catalog_entry_impl.h
@@ -170,6 +170,7 @@ private:
class SetHeadChange;
bool _catalogIsReady(OperationContext* opCtx) const;
+ bool _catalogIsPresent(OperationContext* opCtx) const;
RecordId _catalogHead(OperationContext* opCtx) const;
/**
diff --git a/src/mongo/db/storage/bson_collection_catalog_entry.cpp b/src/mongo/db/storage/bson_collection_catalog_entry.cpp
index 21c1530e00d..a518884be93 100644
--- a/src/mongo/db/storage/bson_collection_catalog_entry.cpp
+++ b/src/mongo/db/storage/bson_collection_catalog_entry.cpp
@@ -190,6 +190,13 @@ RecordId BSONCollectionCatalogEntry::getIndexHead(OperationContext* opCtx,
return md.indexes[offset].head;
}
+bool BSONCollectionCatalogEntry::isIndexPresent(OperationContext* opCtx,
+ StringData indexName) const {
+ MetaData md = _getMetaData(opCtx);
+ int offset = md.findIndexOffset(indexName);
+ return offset >= 0;
+}
+
bool BSONCollectionCatalogEntry::isIndexReady(OperationContext* opCtx, StringData indexName) const {
MetaData md = _getMetaData(opCtx);
diff --git a/src/mongo/db/storage/bson_collection_catalog_entry.h b/src/mongo/db/storage/bson_collection_catalog_entry.h
index 4401c554775..ea3261350a2 100644
--- a/src/mongo/db/storage/bson_collection_catalog_entry.h
+++ b/src/mongo/db/storage/bson_collection_catalog_entry.h
@@ -72,6 +72,8 @@ public:
virtual bool isIndexReady(OperationContext* opCtx, StringData indexName) const;
+ virtual bool isIndexPresent(OperationContext* opCtx, StringData indexName) const;
+
virtual KVPrefix getIndexPrefix(OperationContext* opCtx, StringData indexName) const;
// ------ for implementors
diff --git a/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp b/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp
index 865d5fff00f..a2a31433a92 100644
--- a/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp
+++ b/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp
@@ -200,6 +200,12 @@ bool NamespaceDetailsCollectionCatalogEntry::isIndexReady(OperationContext* opCt
return idxNo < getCompletedIndexCount(opCtx);
}
+bool NamespaceDetailsCollectionCatalogEntry::isIndexPresent(OperationContext* opCtx,
+ StringData idxName) const {
+ int idxNo = _findIndexNumber(opCtx, idxName);
+ return idxNo >= 0;
+}
+
KVPrefix NamespaceDetailsCollectionCatalogEntry::getIndexPrefix(OperationContext* opCtx,
StringData indexName) const {
return KVPrefix::kNotPrefixed;
diff --git a/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h b/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h
index 517128ae26d..60cba15378b 100644
--- a/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h
+++ b/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h
@@ -86,6 +86,8 @@ public:
bool isIndexReady(OperationContext* opCtx, StringData indexName) const final;
+ bool isIndexPresent(OperationContext* opCtx, StringData indexName) const final;
+
KVPrefix getIndexPrefix(OperationContext* opCtx, StringData indexName) const final;
Status removeIndex(OperationContext* opCtx, StringData indexName) final;