mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
ethdb: print a warning log if write delay exceeds threshold
This commit is contained in:
parent
522e0d4424
commit
c3bb251d33
1 changed files with 73 additions and 57 deletions
|
|
@ -34,7 +34,10 @@ import (
|
||||||
gometrics "github.com/rcrowley/go-metrics"
|
gometrics "github.com/rcrowley/go-metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
var OpenFileLimit = 64
|
const (
|
||||||
|
writeDelayNThreshold = 250
|
||||||
|
writeDelayThreshold = 500 * time.Millisecond
|
||||||
|
)
|
||||||
|
|
||||||
type LDBDatabase struct {
|
type LDBDatabase struct {
|
||||||
fn string // filename for reporting
|
fn string // filename for reporting
|
||||||
|
|
@ -178,11 +181,9 @@ func (db *LDBDatabase) LDB() *leveldb.DB {
|
||||||
|
|
||||||
// Meter configures the database metrics collectors and
|
// Meter configures the database metrics collectors and
|
||||||
func (db *LDBDatabase) Meter(prefix string) {
|
func (db *LDBDatabase) Meter(prefix string) {
|
||||||
// Short circuit metering if the metrics system is disabled
|
if metrics.Enabled {
|
||||||
if !metrics.Enabled {
|
// Initialize all database related metrics collector at the requested prefix
|
||||||
return
|
// if metric is enable.
|
||||||
}
|
|
||||||
// Initialize all the metrics collector at the requested prefix
|
|
||||||
db.getTimer = metrics.NewTimer(prefix + "user/gets")
|
db.getTimer = metrics.NewTimer(prefix + "user/gets")
|
||||||
db.putTimer = metrics.NewTimer(prefix + "user/puts")
|
db.putTimer = metrics.NewTimer(prefix + "user/puts")
|
||||||
db.delTimer = metrics.NewTimer(prefix + "user/dels")
|
db.delTimer = metrics.NewTimer(prefix + "user/dels")
|
||||||
|
|
@ -190,11 +191,13 @@ func (db *LDBDatabase) Meter(prefix string) {
|
||||||
db.readMeter = metrics.NewMeter(prefix + "user/reads")
|
db.readMeter = metrics.NewMeter(prefix + "user/reads")
|
||||||
db.writeMeter = metrics.NewMeter(prefix + "user/writes")
|
db.writeMeter = metrics.NewMeter(prefix + "user/writes")
|
||||||
|
|
||||||
db.writeDelayMeter = metrics.NewMeter(prefix + "compact/writedelay/duration")
|
|
||||||
db.writeDelayNMeter = metrics.NewMeter(prefix + "compact/writedelay/counter")
|
|
||||||
db.compTimeMeter = metrics.NewMeter(prefix + "compact/time")
|
db.compTimeMeter = metrics.NewMeter(prefix + "compact/time")
|
||||||
db.compReadMeter = metrics.NewMeter(prefix + "compact/input")
|
db.compReadMeter = metrics.NewMeter(prefix + "compact/input")
|
||||||
db.compWriteMeter = metrics.NewMeter(prefix + "compact/output")
|
db.compWriteMeter = metrics.NewMeter(prefix + "compact/output")
|
||||||
|
}
|
||||||
|
// Initialize essential write delay metrics no matter metric is enable or not.
|
||||||
|
db.writeDelayMeter = metrics.NewMeter(prefix + "compact/writedelay/duration")
|
||||||
|
db.writeDelayNMeter = metrics.NewMeter(prefix + "compact/writedelay/counter")
|
||||||
|
|
||||||
// Create a quit channel for the periodic collector and run it
|
// Create a quit channel for the periodic collector and run it
|
||||||
db.quitLock.Lock()
|
db.quitLock.Lock()
|
||||||
|
|
@ -223,6 +226,7 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
|
||||||
}
|
}
|
||||||
// Iterate ad infinitum and collect the stats
|
// Iterate ad infinitum and collect the stats
|
||||||
for i := 1; ; i++ {
|
for i := 1; ; i++ {
|
||||||
|
if metrics.Enabled {
|
||||||
// Retrieve the database stats
|
// Retrieve the database stats
|
||||||
stats, err := db.db.GetProperty("leveldb.stats")
|
stats, err := db.db.GetProperty("leveldb.stats")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -268,8 +272,9 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
|
||||||
if db.compWriteMeter != nil {
|
if db.compWriteMeter != nil {
|
||||||
db.compWriteMeter.Mark(int64((counters[i%2][2] - counters[(i-1)%2][2]) * 1024 * 1024))
|
db.compWriteMeter.Mark(int64((counters[i%2][2] - counters[(i-1)%2][2]) * 1024 * 1024))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stat write delay.
|
// Gather write delay statistic
|
||||||
writeDelay, err := db.db.GetProperty("leveldb.writedelay")
|
writeDelay, err := db.db.GetProperty("leveldb.writedelay")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
db.log.Error("Failed to read database write delay statistic", "err", err)
|
db.log.Error("Failed to read database write delay statistic", "err", err)
|
||||||
|
|
@ -294,11 +299,22 @@ func (db *LDBDatabase) meter(refresh time.Duration) {
|
||||||
|
|
||||||
if db.writeDelayNMeter != nil {
|
if db.writeDelayNMeter != nil {
|
||||||
db.writeDelayNMeter.Mark(int64((counters[i%2][3] - counters[(i-1)%2][3])))
|
db.writeDelayNMeter.Mark(int64((counters[i%2][3] - counters[(i-1)%2][3])))
|
||||||
|
// If the write delay number been collected in the last minute exceeds the predefined threshold,
|
||||||
|
// print a warning log here.
|
||||||
|
if int(db.writeDelayNMeter.Rate1()) > writeDelayNThreshold {
|
||||||
|
db.log.Warn("Write delay number exceeds the threshold (250) in the last minute")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if db.writeDelayMeter != nil {
|
if db.writeDelayMeter != nil {
|
||||||
db.writeDelayMeter.Mark(int64((counters[i%2][4] - counters[(i-1)%2][4])))
|
db.writeDelayMeter.Mark(int64((counters[i%2][4] - counters[(i-1)%2][4])))
|
||||||
|
// If the write delay duration been collected in the last minute exceeds the predefined threshold,
|
||||||
|
// print a warning log here.
|
||||||
|
if int64(db.writeDelayMeter.Rate1()) > writeDelayThreshold.Nanoseconds() {
|
||||||
|
db.log.Warn("Write delay duration exceeds the threshold (0.5sec) in the last minute")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sleep a bit, then repeat the stats collection
|
// Sleep a bit, then repeat the stats collection
|
||||||
select {
|
select {
|
||||||
case errc := <-db.quitChan:
|
case errc := <-db.quitChan:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue