Consider two concurrent time-series inserts: one which inserts into an existing bucket, and one which expires an idle bucket in order to allocate a new one.
The former acquires BucketCatalog::_statesMutex inside of BucketCatalog::BucketAccess::_confirmStateForAcquiredBucket and then later acquires BucketCatalog::_idleMutex inside of BucketCatalog::_markBucketNotIdle.
The latter acquires BucketCatalog::_idleMutex inside of BucketCatalog::_expireIdleBuckets and then later acquires BucketCatalog::_statesMutex inside of BucketCatalog::_removeBucket.
Deadlock.
The full BucketCatalog stack traces to reach this deadlock are:
mongo::BucketCatalog::insert mongo::BucketCatalog::BucketAccess::BucketAccess mongo::BucketCatalog::BucketAccess::_findOpenBucketThenLock mongo::BucketCatalog::BucketAccess::_confirmStateForAcquiredBucket mongo::BucketCatalog::_markBucketNotIdle
and
mongo::BucketCatalog::insert mongo::BucketCatalog::BucketAccess::BucketAccess mongo::BucketCatalog::BucketAccess::_findOrCreateOpenBucketThenLock mongo::BucketCatalog::BucketAccess::_create mongo::BucketCatalog::_allocateBucket mongo::BucketCatalog::_expireIdleBuckets mongo::BucketCatalog::_removeBucket
Attached is a patch which reproduces the deadlock.
- is related to
-
SERVER-59925 Stress test and fix deadlock in expiring idle buckets
- Closed