mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: make database connection pool size configurable (#21403)
Closes https://github.com/coder/coder/issues/21360 A few considerations/notes: - I've kept the number of conns to 10 in all other places, except coderd - which uses the config value - I opted to also make idle conns configurable; the greater the delta between max open and max idle, the more connection churn - Postgres maintains a [_process_ per connection](https://www.postgresql.org/docs/current/connect-estab.html), contrary to what the comment said previously - Operators should be able to tune this, since process churn can negatively affect OS scheduling - I've set the value to `"auto"` by default so it's not another knob one _has to_ twiddle, and sets max idle = max conns / 3 --------- Signed-off-by: Danny Kopping <danny@coder.com>
This commit is contained in:
@@ -442,6 +442,10 @@ var PostgresAuthDrivers = []string{
|
||||
string(PostgresAuthAWSIAMRDS),
|
||||
}
|
||||
|
||||
// PostgresConnMaxIdleAuto is the value for auto-computing max idle connections
|
||||
// based on max open connections.
|
||||
const PostgresConnMaxIdleAuto = "auto"
|
||||
|
||||
// DeploymentValues is the central configuration values the coder server.
|
||||
type DeploymentValues struct {
|
||||
Verbose serpent.Bool `json:"verbose,omitempty"`
|
||||
@@ -462,6 +466,8 @@ type DeploymentValues struct {
|
||||
EphemeralDeployment serpent.Bool `json:"ephemeral_deployment,omitempty" typescript:",notnull"`
|
||||
PostgresURL serpent.String `json:"pg_connection_url,omitempty" typescript:",notnull"`
|
||||
PostgresAuth string `json:"pg_auth,omitempty" typescript:",notnull"`
|
||||
PostgresConnMaxOpen serpent.Int64 `json:"pg_conn_max_open,omitempty" typescript:",notnull"`
|
||||
PostgresConnMaxIdle serpent.String `json:"pg_conn_max_idle,omitempty" typescript:",notnull"`
|
||||
OAuth2 OAuth2Config `json:"oauth2,omitempty" typescript:",notnull"`
|
||||
OIDC OIDCConfig `json:"oidc,omitempty" typescript:",notnull"`
|
||||
Telemetry TelemetryConfig `json:"telemetry,omitempty" typescript:",notnull"`
|
||||
@@ -2623,6 +2629,30 @@ func (c *DeploymentValues) Options() serpent.OptionSet {
|
||||
Value: serpent.EnumOf(&c.PostgresAuth, PostgresAuthDrivers...),
|
||||
YAML: "pgAuth",
|
||||
},
|
||||
{
|
||||
Name: "Postgres Connection Max Open",
|
||||
Description: "Maximum number of open connections to the database. Defaults to 10.",
|
||||
Flag: "postgres-conn-max-open",
|
||||
Env: "CODER_PG_CONN_MAX_OPEN",
|
||||
Default: "10",
|
||||
Value: serpent.Validate(&c.PostgresConnMaxOpen, func(value *serpent.Int64) error {
|
||||
if value.Value() <= 0 {
|
||||
return xerrors.New("must be greater than zero")
|
||||
}
|
||||
return nil
|
||||
}),
|
||||
YAML: "pgConnMaxOpen",
|
||||
},
|
||||
{
|
||||
Name: "Postgres Connection Max Idle",
|
||||
Description: "Maximum number of idle connections to the database. Set to \"auto\" (the default) to use max open / 3. " +
|
||||
"Value must be greater or equal to 0; 0 means explicitly no idle connections.",
|
||||
Flag: "postgres-conn-max-idle",
|
||||
Env: "CODER_PG_CONN_MAX_IDLE",
|
||||
Default: PostgresConnMaxIdleAuto,
|
||||
Value: &c.PostgresConnMaxIdle,
|
||||
YAML: "pgConnMaxIdle",
|
||||
},
|
||||
{
|
||||
Name: "Secure Auth Cookie",
|
||||
Description: "Controls if the 'Secure' property is set on browser session cookies.",
|
||||
@@ -4128,3 +4158,28 @@ func (c CryptoKey) CanVerify(now time.Time) bool {
|
||||
beforeDelete := c.DeletesAt.IsZero() || now.Before(c.DeletesAt)
|
||||
return hasSecret && beforeDelete
|
||||
}
|
||||
|
||||
// ComputeMaxIdleConns calculates the effective maxIdleConns value. If
|
||||
// configuredIdle is "auto", it returns maxOpen/3 with a minimum of 1. If
|
||||
// configuredIdle exceeds maxOpen, it returns an error.
|
||||
func ComputeMaxIdleConns(maxOpen int, configuredIdle string) (int, error) {
|
||||
configuredIdle = strings.TrimSpace(configuredIdle)
|
||||
if configuredIdle == PostgresConnMaxIdleAuto {
|
||||
computed := maxOpen / 3
|
||||
if computed < 1 {
|
||||
return 1, nil
|
||||
}
|
||||
return computed, nil
|
||||
}
|
||||
idle, err := strconv.Atoi(configuredIdle)
|
||||
if err != nil {
|
||||
return 0, xerrors.Errorf("invalid max idle connections %q: must be %q or >= 0", configuredIdle, PostgresConnMaxIdleAuto)
|
||||
}
|
||||
if idle < 0 {
|
||||
return 0, xerrors.Errorf("max idle connections must be %q or >= 0", PostgresConnMaxIdleAuto)
|
||||
}
|
||||
if idle > maxOpen {
|
||||
return 0, xerrors.Errorf("max idle connections (%d) cannot exceed max open connections (%d)", idle, maxOpen)
|
||||
}
|
||||
return idle, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user