Imagine this sequence of events:
- I run a background index build (or any background job, really) on the namespace "test.coll".
- Someone issues a restartCatalog command.
- We close all of the open databases via DBHolder::closeAll(). This simply loops through each database and attempts to close it. Suppose the order of databases is "local", then "test".
- Database "local" is closed. The cached oplog collection pointer is cleared.
- We attempt to close database "test" but then throw because a background operation is in progress.
- A later operation causes us to write to the oplog, and we dereference our bad oplog pointer because logOp() does not call acquireOplogCollectionForLogging().
One solution would be to add a ScopeGuard to restartCatalog that calls repl::acquireOplogCollectionForLogging() if the call to catalog::closeCatalog() fails for any reason.