From 5eed48c07777dbb71013d94ecde7fef45fc703da Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 23 Apr 2021 13:54:44 -0400 Subject: [PATCH] fix #1622 Allow users to set max MySQL connections and connection lifetime; set a sane default for max connections if it's not present. --- default.yaml | 3 +++ irc/config.go | 7 +++++++ irc/mysql/config.go | 2 ++ irc/mysql/history.go | 8 ++++++++ traditional.yaml | 3 +++ 5 files changed, 23 insertions(+) diff --git a/default.yaml b/default.yaml index 4b6fb9c0..a5978163 100644 --- a/default.yaml +++ b/default.yaml @@ -745,6 +745,9 @@ datastore: password: "hunter2" history-database: "oragono_history" timeout: 3s + max-conns: 4 + # this may be necessary to prevent middleware from closing your connections: + #conn-max-lifetime: 180s # languages config languages: diff --git a/irc/config.go b/irc/config.go index 1e7e8686..368a253f 100644 --- a/irc/config.go +++ b/irc/config.go @@ -18,6 +18,7 @@ import ( "path/filepath" "reflect" "regexp" + "runtime" "strconv" "strings" "time" @@ -1478,6 +1479,12 @@ func LoadConfig(filename string) (config *Config, err error) { config.Datastore.MySQL.ExpireTime = time.Duration(config.History.Restrictions.ExpireTime) config.Datastore.MySQL.TrackAccountMessages = config.History.Retention.EnableAccountIndexing + if config.Datastore.MySQL.MaxConns == 0 { + // #1622: not putting an upper limit on the number of MySQL connections is + // potentially dangerous. as a naive heuristic, assume they're running on the + // same machine: + config.Datastore.MySQL.MaxConns = runtime.NumCPU() + } config.Server.Cloaks.Initialize() if config.Server.Cloaks.Enabled { diff --git a/irc/mysql/config.go b/irc/mysql/config.go index 2c4ff54c..01adb1aa 100644 --- a/irc/mysql/config.go +++ b/irc/mysql/config.go @@ -17,6 +17,8 @@ type Config struct { Password string HistoryDatabase string `yaml:"history-database"` Timeout time.Duration + MaxConns int `yaml:"max-conns"` + ConnMaxLifetime time.Duration `yaml:"conn-max-lifetime"` // XXX these are copied from elsewhere in the config: ExpireTime time.Duration diff --git a/irc/mysql/history.go b/irc/mysql/history.go index c8ec2e5f..e9b284b9 100644 --- a/irc/mysql/history.go +++ b/irc/mysql/history.go @@ -100,6 +100,14 @@ func (m *MySQL) Open() (err error) { return err } + if m.config.MaxConns != 0 { + m.db.SetMaxOpenConns(m.config.MaxConns) + m.db.SetMaxIdleConns(m.config.MaxConns) + } + if m.config.ConnMaxLifetime != 0 { + m.db.SetConnMaxLifetime(m.config.ConnMaxLifetime) + } + err = m.fixSchemas() if err != nil { return err diff --git a/traditional.yaml b/traditional.yaml index 8776dff6..b3220918 100644 --- a/traditional.yaml +++ b/traditional.yaml @@ -718,6 +718,9 @@ datastore: password: "hunter2" history-database: "oragono_history" timeout: 3s + max-conns: 4 + # this may be necessary to prevent middleware from closing your connections: + #conn-max-lifetime: 180s # languages config languages: