diff options
author | Geert Bosch <geert@mongodb.com> | 2015-11-05 17:35:59 -0500 |
---|---|---|
committer | Geert Bosch <geert@mongodb.com> | 2015-11-09 16:07:54 -0500 |
commit | ba231028314553f1495e6583d5a59c55919a764c (patch) | |
tree | dc0a3443fc8c337201de8d9f60ba3d2c4202f6f0 /src | |
parent | 1e083524aecb31bb9e2682b6da813f76cf15223c (diff) | |
download | mongo-ba231028314553f1495e6583d5a59c55919a764c.tar.gz |
SERVER-21305: Correctly calculate lock acquisition time for long waits
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/concurrency/lock_state.cpp | 21 | ||||
-rw-r--r-- | src/mongo/db/concurrency/lock_state.h | 4 |
2 files changed, 11 insertions, 14 deletions
diff --git a/src/mongo/db/concurrency/lock_state.cpp b/src/mongo/db/concurrency/lock_state.cpp index da7f5016f19..ea2b9b9c63a 100644 --- a/src/mongo/db/concurrency/lock_state.cpp +++ b/src/mongo/db/concurrency/lock_state.cpp @@ -250,10 +250,7 @@ void CondVarLockGrantNotification::notify(ResourceId resId, LockResult result) { template <bool IsForMMAPV1> LockerImpl<IsForMMAPV1>::LockerImpl() - : _id(idCounter.addAndFetch(1)), - _requestStartTime(0), - _wuowNestingLevel(0), - _batchWriter(false) {} + : _id(idCounter.addAndFetch(1)), _wuowNestingLevel(0), _batchWriter(false) {} template <bool IsForMMAPV1> LockerImpl<IsForMMAPV1>::~LockerImpl() { @@ -648,8 +645,6 @@ LockResult LockerImpl<IsForMMAPV1>::lockBegin(ResourceId resId, LockMode mode) { : globalLockManager.convert(resId, request, mode); if (result == LOCK_WAITING) { - // Start counting the wait time so that lockComplete can update that metric - _requestStartTime = curTimeMicros64(); globalStats.recordWait(_id, resId, mode); _stats.recordWait(resId, mode); } @@ -676,13 +671,19 @@ LockResult LockerImpl<IsForMMAPV1>::lockComplete(ResourceId resId, // Don't go sleeping without bound in order to be able to report long waits or wake up for // deadlock detection. unsigned waitTimeMs = std::min(timeoutMs, DeadlockTimeoutMs); + const uint64_t startOfTotalWaitTime = curTimeMicros64(); + uint64_t startOfCurrentWaitTime = startOfTotalWaitTime; + while (true) { // It is OK if this call wakes up spuriously, because we re-evaluate the remaining // wait time anyways. result = _notify.wait(waitTimeMs); // Account for the time spent waiting on the notification object - const uint64_t elapsedTimeMicros = curTimeMicros64() - _requestStartTime; + const uint64_t curTimeMicros = curTimeMicros64(); + const uint64_t elapsedTimeMicros = curTimeMicros - startOfCurrentWaitTime; + startOfCurrentWaitTime = curTimeMicros; + globalStats.recordWaitTime(_id, resId, mode, elapsedTimeMicros); _stats.recordWaitTime(resId, mode, elapsedTimeMicros); @@ -707,9 +708,9 @@ LockResult LockerImpl<IsForMMAPV1>::lockComplete(ResourceId resId, continue; } - const unsigned elapsedTimeMs = elapsedTimeMicros / 1000; - waitTimeMs = (elapsedTimeMs < timeoutMs) - ? std::min(timeoutMs - elapsedTimeMs, DeadlockTimeoutMs) + const unsigned totalBlockTimeMs = (curTimeMicros - startOfTotalWaitTime) / 1000; + waitTimeMs = (totalBlockTimeMs < timeoutMs) + ? std::min(timeoutMs - totalBlockTimeMs, DeadlockTimeoutMs) : 0; if (waitTimeMs == 0) { diff --git a/src/mongo/db/concurrency/lock_state.h b/src/mongo/db/concurrency/lock_state.h index f8c696b786c..cf634fd3168 100644 --- a/src/mongo/db/concurrency/lock_state.h +++ b/src/mongo/db/concurrency/lock_state.h @@ -205,10 +205,6 @@ private: // and condition variable every time. CondVarLockGrantNotification _notify; - // Timer for measuring duration and timeouts. This value is set when lock acquisition is - // about to wait and is sampled at grant time. - uint64_t _requestStartTime; - // Per-locker locking statistics. Reported in the slow-query log message and through // db.currentOp. Complementary to the per-instance locking statistics. SingleThreadedLockStats _stats; |