forked from mirrors/gotosocial
[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:
parent
eccb3800d0
commit
b80be48fed
3 changed files with 38 additions and 14 deletions
|
@ -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
|
||||
# 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]
|
||||
# Default: 8
|
||||
|
|
|
@ -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
|
||||
# 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]
|
||||
# Default: 8
|
||||
|
|
|
@ -256,16 +256,40 @@ func sqliteConn(ctx context.Context) (*DBConn, error) {
|
|||
}
|
||||
|
||||
// Drop anything fancy from DB address
|
||||
address = strings.Split(address, "?")[0]
|
||||
address = strings.TrimPrefix(address, "file:")
|
||||
address = strings.Split(address, "?")[0] // drop any provided query strings
|
||||
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
|
||||
|
||||
if address == "file::memory:" {
|
||||
address = fmt.Sprintf("file:%s?mode=memory&cache=shared", uuid.NewString())
|
||||
log.Infof("using in-memory database address " + address)
|
||||
log.Warn("sqlite in-memory database should only be used for debugging")
|
||||
for i, q := range prefs {
|
||||
var prefix string
|
||||
if i == 0 {
|
||||
prefix = "?"
|
||||
} else {
|
||||
prefix = "&"
|
||||
}
|
||||
address += prefix + q
|
||||
}
|
||||
|
||||
// Open new DB instance
|
||||
|
@ -274,7 +298,7 @@ func sqliteConn(ctx context.Context) (*DBConn, error) {
|
|||
if errWithCode, ok := err.(*sqlite.Error); ok {
|
||||
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:
|
||||
|
@ -294,7 +318,7 @@ func sqliteConn(ctx context.Context) (*DBConn, error) {
|
|||
}
|
||||
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
|
||||
}
|
||||
|
@ -304,11 +328,11 @@ func sqliteConn(ctx context.Context) (*DBConn, error) {
|
|||
*/
|
||||
|
||||
// maxOpenConns returns multiplier * GOMAXPROCS,
|
||||
// clamping multiplier to 1 if it was below 1.
|
||||
// returning just 1 instead if multiplier < 1.
|
||||
func maxOpenConns() int {
|
||||
multiplier := config.GetDbMaxOpenConnsMultiplier()
|
||||
if multiplier < 1 {
|
||||
multiplier = 1
|
||||
return 1
|
||||
}
|
||||
return multiplier * runtime.GOMAXPROCS(0)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue