diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2014-11-24 17:11:14 -0500 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2014-11-24 17:11:14 -0500 |
commit | 0ad070c47135f205c638b47e217d46d7da9fd329 (patch) | |
tree | 3eebf17de5947754adda5acf013489697484844b | |
parent | 02077a6e7d7215af65cfd88beda865672d45a442 (diff) | |
download | mongo-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.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_entry.cpp | 41 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_entry.h | 4 |
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 { |