summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-11-24 17:11:14 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-11-24 17:11:14 -0500
commit0ad070c47135f205c638b47e217d46d7da9fd329 (patch)
tree3eebf17de5947754adda5acf013489697484844b
parent02077a6e7d7215af65cfd88beda865672d45a442 (diff)
downloadmongo-0ad070c47135f205c638b47e217d46d7da9fd329.tar.gz
Revert "SERVER-16133 Use RESOURCE_METADATA X lock to set the multiKey index value"
This reverts commit 58e49b2726807b7e7c2f0309607ffa454befbff6.
-rw-r--r--src/mongo/db/catalog/index_catalog.cpp4
-rw-r--r--src/mongo/db/catalog/index_catalog_entry.cpp41
-rw-r--r--src/mongo/db/catalog/index_catalog_entry.h4
3 files changed, 29 insertions, 20 deletions
diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp
index 0bd3810db97..3087523fe97 100644
--- a/src/mongo/db/catalog/index_catalog.cpp
+++ b/src/mongo/db/catalog/index_catalog.cpp
@@ -497,6 +497,10 @@ namespace {
IndexCatalogEntry* entry = _catalog->_entries.find( desc );
fassert( 17331, entry && entry == _entry );
+ if ( entry->wantToSetIsMultikey() ) {
+ entry->setMultikey(_txn);
+ }
+
entry->setIsReady( true );
}
diff --git a/src/mongo/db/catalog/index_catalog_entry.cpp b/src/mongo/db/catalog/index_catalog_entry.cpp
index 2d403072dd6..28fb57d5de2 100644
--- a/src/mongo/db/catalog/index_catalog_entry.cpp
+++ b/src/mongo/db/catalog/index_catalog_entry.cpp
@@ -75,8 +75,8 @@ namespace mongo {
_accessMethod( NULL ),
_headManager(new HeadManagerImpl(this)),
_ordering( Ordering::make( descriptor->keyPattern() ) ),
- _isReady( false ) {
-
+ _isReady( false ),
+ _wantToSetIsMultikey( false ) {
_descriptor->_cachedEntry = this;
}
@@ -146,30 +146,32 @@ namespace mongo {
invariant(!_ice->_isMultikey);
}
- virtual void commit() { _ice->_isMultikey = true; }
- virtual void rollback() { }
+ virtual void commit() {}
+ virtual void rollback() { _ice->_isMultikey = false; }
- private:
- IndexCatalogEntry* const _ice;
+ IndexCatalogEntry* _ice;
};
- void IndexCatalogEntry::setMultikey(OperationContext* txn) {
- if (isMultikey(txn)) {
+ void IndexCatalogEntry::setMultikey( OperationContext* txn ) {
+ if ( isMultikey( txn ) )
return;
- }
-
- // Only one thread should set the multi-key value per collection, because the metadata for
- // a collection is one large document.
- Lock::ResourceLock collMDLock(txn->lockState(),
- ResourceId(RESOURCE_METADATA, _collection->ns()),
- MODE_X);
- // Check again in case we blocked on the MD lock and another thread beat us to setting the
- // multiKey metadata for this index.
- if (isMultikey(txn)) {
+ if ( !_isReady && txn->lockState() &&
+ !txn->lockState()->isCollectionLockedForMode( _ns, MODE_X ) ) {
+ // We don't have an exclusive lock, so can't set is multi key.
+ // But, we're building it in an IX lock, so we keep track and will set it later
+ _wantToSetIsMultikey = true;
return;
}
+ const ResourceId collRes = ResourceId(RESOURCE_COLLECTION, _ns);
+ LockResult res = txn->lockState()->lock(collRes, MODE_X, UINT_MAX, true);
+ if (res == LOCK_DEADLOCK) throw WriteConflictException();
+ invariant(res == LOCK_OK);
+
+ // Lock will be held until end of WUOW to ensure rollback safety.
+ ON_BLOCK_EXIT(&Locker::unlock, txn->lockState(), collRes);
+
if ( _collection->setIndexIsMultikey( txn,
_descriptor->indexName(),
true ) ) {
@@ -180,9 +182,8 @@ namespace mongo {
}
}
- // We should only enable the multi-key value after the transaction has committed and the
- // multi-key property has been persisted.
txn->recoveryUnit()->registerChange(new SetMultikeyChange(this));
+ _isMultikey = true;
}
// ----
diff --git a/src/mongo/db/catalog/index_catalog_entry.h b/src/mongo/db/catalog/index_catalog_entry.h
index cc086b73ec9..b40904d42da 100644
--- a/src/mongo/db/catalog/index_catalog_entry.h
+++ b/src/mongo/db/catalog/index_catalog_entry.h
@@ -87,6 +87,8 @@ namespace mongo {
// if this ready is ready for queries
bool isReady( OperationContext* txn ) const;
+ bool wantToSetIsMultikey() const { return _wantToSetIsMultikey; }
+
private:
class SetMultikeyChange;
@@ -117,6 +119,8 @@ namespace mongo {
bool _isReady; // cache of NamespaceDetails info
DiskLoc _head; // cache of IndexDetails
bool _isMultikey; // cache of NamespaceDetails info
+
+ bool _wantToSetIsMultikey; // see ::setMultikey
};
class IndexCatalogEntryContainer {