From d02427e41a464c1478d6579b1c343dd0553d2a71 Mon Sep 17 00:00:00 2001 From: JT Olio Date: Tue, 4 Jun 2019 15:30:21 -0600 Subject: [PATCH] db: set max open conns, conn max lifetime, add db stat monitoring (#2117) --- internal/dbutil/defaults.go | 31 +++++++++++++++++++-- internal/dbutil/pgutil/db.go | 7 ++++- satellite/satellitedb/database.go | 2 +- scripts/testdata/satellite-config.yaml.lock | 9 ++++++ storage/postgreskv/client.go | 7 ++++- storagenode/storagenodedb/infodb.go | 12 ++++---- 6 files changed, 57 insertions(+), 11 deletions(-) diff --git a/internal/dbutil/defaults.go b/internal/dbutil/defaults.go index eaa7d0cf6..488ac433e 100644 --- a/internal/dbutil/defaults.go +++ b/internal/dbutil/defaults.go @@ -3,5 +3,32 @@ package dbutil -// DefaultMaxIdleConns default value for database connections -const DefaultMaxIdleConns = 100 +import ( + "database/sql" + "flag" + + monkit "gopkg.in/spacemonkeygo/monkit.v2" +) + +var ( + maxIdleConns = flag.Int("db.max_idle_conns", 50, "default value for database connections, -1 means the stdlib default") + maxOpenConns = flag.Int("db.max_open_conns", 100, "default value for database connections, -1 means the stdlib default") + connMaxLifetime = flag.Duration("db.conn_max_lifetime", -1, "default value for database connections, -1 means the stdlib default") +) + +// Configure Sets Connection Boundaries and adds db_stats monitoring to monkit +func Configure(db *sql.DB, mon *monkit.Scope) { + if *maxIdleConns >= 0 { + db.SetMaxIdleConns(*maxIdleConns) + } + if *maxOpenConns >= 0 { + db.SetMaxOpenConns(*maxOpenConns) + } + if *connMaxLifetime >= 0 { + db.SetConnMaxLifetime(*connMaxLifetime) + } + mon.Chain("db_stats", monkit.StatSourceFunc( + func(cb func(name string, val float64)) { + monkit.StatSourceFromStruct(db.Stats()).Stats(cb) + })) +} diff --git a/internal/dbutil/pgutil/db.go b/internal/dbutil/pgutil/db.go index 6cdbb566d..4828beaa6 100644 --- a/internal/dbutil/pgutil/db.go +++ b/internal/dbutil/pgutil/db.go @@ -9,6 +9,7 @@ import ( "github.com/lib/pq" "github.com/zeebo/errs" + monkit "gopkg.in/spacemonkeygo/monkit.v2" "storj.io/storj/internal/dbutil" "storj.io/storj/internal/dbutil/dbschema" @@ -21,6 +22,10 @@ type DB struct { Schema string } +var ( + mon = monkit.Package() +) + // Open opens a postgres database with a schema func Open(connstr string, schemaPrefix string) (*DB, error) { schemaName := schemaPrefix + "-" + CreateRandomTestingSchemaName(8) @@ -30,7 +35,7 @@ func Open(connstr string, schemaPrefix string) (*DB, error) { return nil, err } - db.SetMaxIdleConns(dbutil.DefaultMaxIdleConns) + dbutil.Configure(db, mon) err = CreateSchema(db, schemaName) if err != nil { diff --git a/satellite/satellitedb/database.go b/satellite/satellitedb/database.go index b0d43a26b..b7960c2de 100644 --- a/satellite/satellitedb/database.go +++ b/satellite/satellitedb/database.go @@ -54,7 +54,7 @@ func New(log *zap.Logger, databaseURL string) (satellite.DB, error) { } log.Debug("Connected to:", zap.String("db source", source)) - db.SetMaxIdleConns(dbutil.DefaultMaxIdleConns) + dbutil.Configure(db.DB, mon) core := &DB{log: log, db: db, driver: driver, source: source} if driver == "sqlite3" { diff --git a/scripts/testdata/satellite-config.yaml.lock b/scripts/testdata/satellite-config.yaml.lock index ec09b9e4f..c9f48322e 100644 --- a/scripts/testdata/satellite-config.yaml.lock +++ b/scripts/testdata/satellite-config.yaml.lock @@ -40,6 +40,15 @@ # satellite database connection string # database: "postgres://" +# default value for database connections, -1 means the stdlib default +# db.conn_max_lifetime: -1ns + +# default value for database connections, -1 means the stdlib default +# db.max_idle_conns: 50 + +# default value for database connections, -1 means the stdlib default +# db.max_open_conns: 100 + # address to listen on for debug endpoints # debug.addr: "127.0.0.1:0" diff --git a/storage/postgreskv/client.go b/storage/postgreskv/client.go index 47a0750ae..9f3f70962 100644 --- a/storage/postgreskv/client.go +++ b/storage/postgreskv/client.go @@ -9,6 +9,7 @@ import ( "github.com/lib/pq" "github.com/zeebo/errs" + monkit "gopkg.in/spacemonkeygo/monkit.v2" "storj.io/storj/internal/dbutil" "storj.io/storj/storage" @@ -20,6 +21,10 @@ const ( defaultBucket = "" ) +var ( + mon = monkit.Package() +) + // Client is the entrypoint into a postgreskv data store type Client struct { URL string @@ -33,7 +38,7 @@ func New(dbURL string) (*Client, error) { return nil, err } - pgConn.SetMaxIdleConns(dbutil.DefaultMaxIdleConns) + dbutil.Configure(pgConn, mon) err = schema.PrepareDB(pgConn, dbURL) if err != nil { diff --git a/storagenode/storagenodedb/infodb.go b/storagenode/storagenodedb/infodb.go index caee53c18..b6361bec3 100644 --- a/storagenode/storagenodedb/infodb.go +++ b/storagenode/storagenodedb/infodb.go @@ -36,7 +36,7 @@ func newInfo(path string) (*InfoDB, error) { return nil, ErrInfo.Wrap(err) } - db.SetMaxIdleConns(dbutil.DefaultMaxIdleConns) + dbutil.Configure(db, mon) return &InfoDB{db: db}, nil } @@ -48,7 +48,7 @@ func NewInfoInMemory() (*InfoDB, error) { return nil, ErrInfo.Wrap(err) } - db.SetMaxIdleConns(dbutil.DefaultMaxIdleConns) + dbutil.Configure(db, mon) return &InfoDB{db: db}, nil } @@ -153,15 +153,15 @@ func (db *InfoDB) Migration() *migrate.Migration { `CREATE TABLE order_archive ( satellite_id BLOB NOT NULL, serial_number BLOB NOT NULL, - + order_limit_serialized BLOB NOT NULL, -- serialized pb.OrderLimit order_serialized BLOB NOT NULL, -- serialized pb.Order - + uplink_cert_id INTEGER NOT NULL, - + status INTEGER NOT NULL, -- accepted, rejected, confirmed archived_at TIMESTAMP NOT NULL, -- when was it rejected - + FOREIGN KEY(uplink_cert_id) REFERENCES certificate(cert_id) )`, `CREATE INDEX idx_order_archive_satellite ON order_archive(satellite_id)`,