Skip to content

Commit

Permalink
ethdb/pebble: print warning log if pebble performance degrades (ether…
Browse files Browse the repository at this point in the history
  • Loading branch information
rjl493456442 authored and zzzckck committed May 14, 2024
1 parent 2c87200 commit bf16a39
Showing 1 changed file with 30 additions and 13 deletions.
43 changes: 30 additions & 13 deletions ethdb/pebble/pebble.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ const (

// numLevels is the level number of pebble sst files
numLevels = 7
// degradationWarnInterval specifies how often warning should be printed if the
// leveldb database cannot keep up with requested writes.
degradationWarnInterval = time.Minute
)

// Database is a persistent key-value store based on the pebble storage engine.
Expand Down Expand Up @@ -79,14 +82,16 @@ type Database struct {

log log.Logger // Contextual logger tracking the database path

activeComp int // Current number of active compactions
compStartTime time.Time // The start time of the earliest currently-active compaction
compTime atomic.Int64 // Total time spent in compaction in ns
level0Comp atomic.Uint32 // Total number of level-zero compactions
nonLevel0Comp atomic.Uint32 // Total number of non level-zero compactions
writeDelayStartTime time.Time // The start time of the latest write stall
writeDelayCount atomic.Int64 // Total number of write stall counts
writeDelayTime atomic.Int64 // Total time spent in write stalls
activeComp int // Current number of active compactions
compStartTime time.Time // The start time of the earliest currently-active compaction
compTime atomic.Int64 // Total time spent in compaction in ns
level0Comp atomic.Uint32 // Total number of level-zero compactions
nonLevel0Comp atomic.Uint32 // Total number of non level-zero compactions

writeStalled atomic.Bool // Flag whether the write is stalled
writeDelayStartTime time.Time // The start time of the latest write stall
writeDelayCount atomic.Int64 // Total number of write stall counts
writeDelayTime atomic.Int64 // Total time spent in write stalls

writeOptions *pebble.WriteOptions
}
Expand Down Expand Up @@ -115,10 +120,13 @@ func (d *Database) onCompactionEnd(info pebble.CompactionInfo) {

func (d *Database) onWriteStallBegin(b pebble.WriteStallBeginInfo) {
d.writeDelayStartTime = time.Now()
d.writeDelayCount.Add(1)
d.writeStalled.Store(true)
}

func (d *Database) onWriteStallEnd() {
d.writeDelayTime.Add(int64(time.Since(d.writeDelayStartTime)))
d.writeStalled.Store(false)
}

// panicLogger is just a noop logger to disable Pebble's internal logger.
Expand Down Expand Up @@ -461,13 +469,15 @@ func (d *Database) meter(refresh time.Duration, namespace string) {

// Create storage and warning log tracer for write delay.
var (
compTimes [2]int64
writeDelayTimes [2]int64
writeDelayCounts [2]int64
compWrites [2]int64
compReads [2]int64
compTimes [2]int64
compWrites [2]int64
compReads [2]int64

nWrites [2]int64

writeDelayTimes [2]int64
writeDelayCounts [2]int64
lastWriteStallReport time.Time
)

// Iterate ad infinitum and collect the stats
Expand Down Expand Up @@ -507,6 +517,13 @@ func (d *Database) meter(refresh time.Duration, namespace string) {
if d.writeDelayMeter != nil {
d.writeDelayMeter.Mark(writeDelayTimes[i%2] - writeDelayTimes[(i-1)%2])
}
// Print a warning log if writing has been stalled for a while. The log will
// be printed per minute to avoid overwhelming users.
if d.writeStalled.Load() && writeDelayCounts[i%2] == writeDelayCounts[(i-1)%2] &&
time.Now().After(lastWriteStallReport.Add(degradationWarnInterval)) {
d.log.Warn("Database compacting, degraded performance")
lastWriteStallReport = time.Now()
}
if d.compTimeMeter != nil {
d.compTimeMeter.Mark(compTimes[i%2] - compTimes[(i-1)%2])
}
Expand Down

0 comments on commit bf16a39

Please sign in to comment.