From 9ac042b5cdbc2d7b60d86ee23fa0d63f03733673 Mon Sep 17 00:00:00 2001 From: Jason Wilder Date: Wed, 5 Jul 2017 15:42:21 -0600 Subject: [PATCH] Reduce lock contention when disabling compactions The monitor goroutine calls enable compactions every 10s to spin down (or start up) goroutines for cold shards. This frequent Lock may be causing lock contention for writes and queries which get blocked trying to acquire an RLock. The go RWMutex says that new RLock calls will block if there is a pending Lock call that is blocked. Switching the common path to use an RLock should avoid the Lock and reduce lock contention for writes and queries. --- tsdb/engine/tsm1/engine.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tsdb/engine/tsm1/engine.go b/tsdb/engine/tsm1/engine.go index 457773c2297..d1a9975d906 100644 --- a/tsdb/engine/tsm1/engine.go +++ b/tsdb/engine/tsm1/engine.go @@ -213,6 +213,16 @@ func (e *Engine) SetCompactionsEnabled(enabled bool) { // 'wait' signifies that a corresponding call to disableLevelCompactions(true) was made at some // point, and the associated task that required disabled compactions is now complete func (e *Engine) enableLevelCompactions(wait bool) { + // If we don't need to wait, see if we're already enabled + if !wait { + e.mu.RLock() + if e.done != nil { + e.mu.RUnlock() + return + } + e.mu.RUnlock() + } + e.mu.Lock() if wait { e.levelWorkers -= 1 @@ -263,6 +273,15 @@ func (e *Engine) disableLevelCompactions(wait bool) { } func (e *Engine) enableSnapshotCompactions() { + // Check if already enabled under read lock + e.mu.RLock() + if e.snapDone != nil { + e.mu.RUnlock() + return + } + e.mu.RUnlock() + + // Check again under write lock e.mu.Lock() if e.snapDone != nil { e.mu.Unlock()