mirror of
1
Fork 0

[chore] Use 'immediate' lock for sqlite transactions (#1404)

* [chore] Use 'immediate' lock for sqlite transactions

* allow 1 connection regardless of cpu amount
This commit is contained in:
tobi 2023-01-31 13:46:45 +01:00 committed by GitHub
parent eccb3800d0
commit b80be48fed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 14 deletions

View File

@ -126,7 +126,7 @@ db-tls-ca-cert: ""
# A multiplier of 8 is a sensible default, but you may wish to increase this for instances # A multiplier of 8 is a sensible default, but you may wish to increase this for instances
# running on very performant hardware, or decrease it for instances using v. slow CPUs. # running on very performant hardware, or decrease it for instances using v. slow CPUs.
# #
# If you set this to 0 or less, it will be adjusted to 1. # If you set the multiplier to less than 1, only one open connection will be used regardless of cpu count.
# #
# Examples: [16, 8, 10, 2] # Examples: [16, 8, 10, 2]
# Default: 8 # Default: 8

View File

@ -182,7 +182,7 @@ db-tls-ca-cert: ""
# A multiplier of 8 is a sensible default, but you may wish to increase this for instances # A multiplier of 8 is a sensible default, but you may wish to increase this for instances
# running on very performant hardware, or decrease it for instances using v. slow CPUs. # running on very performant hardware, or decrease it for instances using v. slow CPUs.
# #
# If you set this to 0 or less, it will be adjusted to 1. # If you set the multiplier to less than 1, only one open connection will be used regardless of cpu count.
# #
# Examples: [16, 8, 10, 2] # Examples: [16, 8, 10, 2]
# Default: 8 # Default: 8

View File

@ -256,16 +256,40 @@ func sqliteConn(ctx context.Context) (*DBConn, error) {
} }
// Drop anything fancy from DB address // Drop anything fancy from DB address
address = strings.Split(address, "?")[0] address = strings.Split(address, "?")[0] // drop any provided query strings
address = strings.TrimPrefix(address, "file:") address = strings.TrimPrefix(address, "file:") // we'll prepend this later ourselves
// Append our own SQLite preferences // build our own SQLite preferences
prefs := []string{
// use immediate transaction lock mode to fail quickly if tx can't lock
// see https://pkg.go.dev/modernc.org/sqlite#Driver.Open
"_txlock=immediate",
}
if address == ":memory:" {
log.Warn("using sqlite in-memory mode; all data will be deleted when gts shuts down; this mode should only be used for debugging or running tests")
// Use random name for in-memory instead of ':memory:', so
// multiple in-mem databases can be created without conflict.
address = uuid.NewString()
// in-mem-specific preferences
prefs = append(prefs, []string{
"mode=memory", // indicate in-memory mode using query
"cache=shared", // shared cache so that tests don't fail
}...)
}
// rebuild address string with our derived preferences
address = "file:" + address address = "file:" + address
for i, q := range prefs {
if address == "file::memory:" { var prefix string
address = fmt.Sprintf("file:%s?mode=memory&cache=shared", uuid.NewString()) if i == 0 {
log.Infof("using in-memory database address " + address) prefix = "?"
log.Warn("sqlite in-memory database should only be used for debugging") } else {
prefix = "&"
}
address += prefix + q
} }
// Open new DB instance // Open new DB instance
@ -274,7 +298,7 @@ func sqliteConn(ctx context.Context) (*DBConn, error) {
if errWithCode, ok := err.(*sqlite.Error); ok { if errWithCode, ok := err.(*sqlite.Error); ok {
err = errors.New(sqlite.ErrorCodeString[errWithCode.Code()]) err = errors.New(sqlite.ErrorCodeString[errWithCode.Code()])
} }
return nil, fmt.Errorf("could not open sqlite db: %s", err) return nil, fmt.Errorf("could not open sqlite db with address %s: %w", address, err)
} }
// Tune db connections for sqlite, see: // Tune db connections for sqlite, see:
@ -294,7 +318,7 @@ func sqliteConn(ctx context.Context) (*DBConn, error) {
} }
return nil, fmt.Errorf("sqlite ping: %s", err) return nil, fmt.Errorf("sqlite ping: %s", err)
} }
log.Info("connected to SQLITE database") log.Infof("connected to SQLITE database with address %s", address)
return conn, nil return conn, nil
} }
@ -304,11 +328,11 @@ func sqliteConn(ctx context.Context) (*DBConn, error) {
*/ */
// maxOpenConns returns multiplier * GOMAXPROCS, // maxOpenConns returns multiplier * GOMAXPROCS,
// clamping multiplier to 1 if it was below 1. // returning just 1 instead if multiplier < 1.
func maxOpenConns() int { func maxOpenConns() int {
multiplier := config.GetDbMaxOpenConnsMultiplier() multiplier := config.GetDbMaxOpenConnsMultiplier()
if multiplier < 1 { if multiplier < 1 {
multiplier = 1 return 1
} }
return multiplier * runtime.GOMAXPROCS(0) return multiplier * runtime.GOMAXPROCS(0)
} }