diff options
author | Spencer T Brody <spencer@mongodb.com> | 2018-07-25 15:04:17 -0400 |
---|---|---|
committer | Spencer T Brody <spencer@mongodb.com> | 2018-08-16 17:57:08 -0400 |
commit | fff8892f9d2420d9ea4d248c4a9f708d03a883f9 (patch) | |
tree | fcefba9385980f452a5951edb7a069787bd011d3 | |
parent | 4d416e3335174373b7fb1ed3f98600d056da8d6e (diff) | |
download | mongo-fff8892f9d2420d9ea4d248c4a9f708d03a883f9.tar.gz |
SERVER-35367 Do not hold locks while calling waitForAllEarlierOplogWritesToBeVisible()
(cherry picked from commit a1b225bcf0e9791b14649df385b3f3f9710a98ab)
3 files changed, 23 insertions, 7 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp index 462e9808355..5ba8cce7585 100644 --- a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp @@ -423,8 +423,6 @@ Status ReplicationCoordinatorExternalStateImpl::initializeReplSetStorage(Operati // retries and they will succeed. Unfortunately, initial sync will // fail if it finds its sync source has an empty oplog. Thus, we // need to wait here until the seed document is visible in our oplog. - AutoGetCollection oplog( - opCtx, NamespaceString::kRsOplogNamespace, MODE_IS); waitForAllEarlierOplogWritesToBeVisible(opCtx); }); @@ -461,8 +459,17 @@ Status ReplicationCoordinatorExternalStateImpl::initializeReplSetStorage(Operati void ReplicationCoordinatorExternalStateImpl::waitForAllEarlierOplogWritesToBeVisible( OperationContext* opCtx) { - AutoGetCollection oplog(opCtx, NamespaceString::kRsOplogNamespace, MODE_IS); - oplog.getCollection()->getRecordStore()->waitForAllEarlierOplogWritesToBeVisible(opCtx); + Collection* oplog; + { + // We don't want to be holding the collection lock while blocking, to avoid deadlocks. + // It is safe to store and access the oplog's Collection object after dropping the lock + // because the oplog is special and cannot be deleted on a running process. + // TODO(spencer): It should be possible to get the pointer to the oplog Collection object + // without ever having to take the collection lock. + AutoGetCollection oplogLock(opCtx, NamespaceString::kRsOplogNamespace, MODE_IS); + oplog = oplogLock.getCollection(); + } + oplog->getRecordStore()->waitForAllEarlierOplogWritesToBeVisible(opCtx); } void ReplicationCoordinatorExternalStateImpl::onDrainComplete(OperationContext* opCtx) { diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp index d271adf849d..927d57b8f61 100644 --- a/src/mongo/db/repl/storage_interface_impl.cpp +++ b/src/mongo/db/repl/storage_interface_impl.cpp @@ -1125,8 +1125,17 @@ Status StorageInterfaceImpl::isAdminDbValid(OperationContext* opCtx) { } void StorageInterfaceImpl::waitForAllEarlierOplogWritesToBeVisible(OperationContext* opCtx) { - AutoGetCollection oplog(opCtx, NamespaceString::kRsOplogNamespace, MODE_IS); - oplog.getCollection()->getRecordStore()->waitForAllEarlierOplogWritesToBeVisible(opCtx); + Collection* oplog; + { + // We don't want to be holding the collection lock while blocking, to avoid deadlocks. + // It is safe to store and access the oplog's Collection object after dropping the lock + // because the oplog is special and cannot be deleted on a running process. + // TODO(spencer): It should be possible to get the pointer to the oplog Collection object + // without ever having to take the collection lock. + AutoGetCollection oplogLock(opCtx, NamespaceString::kRsOplogNamespace, MODE_IS); + oplog = oplogLock.getCollection(); + } + oplog->getRecordStore()->waitForAllEarlierOplogWritesToBeVisible(opCtx); } void StorageInterfaceImpl::oplogDiskLocRegister(OperationContext* opCtx, diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp index 7081f6f38d5..6852a4c60c9 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp @@ -1994,7 +1994,7 @@ void StandardWiredTigerRecordStore::setKey(WT_CURSOR* cursor, RecordId id) const std::unique_ptr<SeekableRecordCursor> StandardWiredTigerRecordStore::getCursor( OperationContext* opCtx, bool forward) const { - dassert(opCtx->lockState()->isReadLocked()); + dassert(opCtx->lockState()->isReadLocked() || _isOplog); if (_isOplog && forward) { WiredTigerRecoveryUnit* wru = WiredTigerRecoveryUnit::get(opCtx); |