Make write-ahead-log default and configurable for sqlite (#1985)

* correctly enable WAL log for sqlite

this commit makes headscale correctly enable write-ahead-log for
sqlite and adds an option to turn it on and off.

WAL is enabled by default and should make sqlite perform a lot better,
even further eliminating the need to use postgres.

It also adds a couple of other useful defaults.

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>

* update changelog

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>

---------

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
Kristoffer Dalby 2024-06-23 22:06:59 +02:00 committed by GitHub
parent 8f8f469c0a
commit 4a34cfc4a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 28 additions and 3 deletions

View file

@ -59,6 +59,7 @@ after improving the test harness as part of adopting [#1460](https://github.com/
- Add `autogroup:internet` to Policy [#1917](https://github.com/juanfont/headscale/pull/1917) - Add `autogroup:internet` to Policy [#1917](https://github.com/juanfont/headscale/pull/1917)
- Restore foreign keys and add constraints [#1562](https://github.com/juanfont/headscale/pull/1562) - Restore foreign keys and add constraints [#1562](https://github.com/juanfont/headscale/pull/1562)
- Make registration page easier to use on mobile devices - Make registration page easier to use on mobile devices
- Make write-ahead-log default on and configurable for SQLite [#1985](https://github.com/juanfont/headscale/pull/1985)
## 0.22.3 (2023-05-12) ## 0.22.3 (2023-05-12)

View file

@ -144,6 +144,10 @@ database:
sqlite: sqlite:
path: /var/lib/headscale/db.sqlite path: /var/lib/headscale/db.sqlite
# Enable WAL mode for SQLite. This is recommended for production environments.
# https://www.sqlite.org/wal.html
write_ahead_log: true
# # Postgres config # # Postgres config
# postgres: # postgres:
# # If using a Unix socket to connect to Postgres, set the socket path in the 'host' field and leave 'port' blank. # # If using a Unix socket to connect to Postgres, set the socket path in the 'host' field and leave 'port' blank.

View file

@ -434,13 +434,29 @@ func openDB(cfg types.DatabaseConfig) (*gorm.DB, error) {
Msg("Opening database") Msg("Opening database")
db, err := gorm.Open( db, err := gorm.Open(
sqlite.Open(cfg.Sqlite.Path+"?_synchronous=1&_journal_mode=WAL"), sqlite.Open(cfg.Sqlite.Path),
&gorm.Config{ &gorm.Config{
Logger: dbLogger, Logger: dbLogger,
}, },
) )
db.Exec("PRAGMA foreign_keys=ON") if err := db.Exec(`
PRAGMA foreign_keys=ON;
PRAGMA busy_timeout=10000;
PRAGMA auto_vacuum=INCREMENTAL;
PRAGMA synchronous=NORMAL;
`).Error; err != nil {
return nil, fmt.Errorf("enabling foreign keys: %w", err)
}
if cfg.Sqlite.WriteAheadLog {
if err := db.Exec(`
PRAGMA journal_mode=WAL;
PRAGMA wal_autocheckpoint=0;
`).Error; err != nil {
return nil, fmt.Errorf("setting WAL mode: %w", err)
}
}
// The pure Go SQLite library does not handle locking in // The pure Go SQLite library does not handle locking in
// the same way as the C based one and we cant use the gorm // the same way as the C based one and we cant use the gorm

View file

@ -82,6 +82,7 @@ type Config struct {
type SqliteConfig struct { type SqliteConfig struct {
Path string Path string
WriteAheadLog bool
} }
type PostgresConfig struct { type PostgresConfig struct {
@ -222,6 +223,8 @@ func LoadConfig(path string, isFile bool) error {
viper.SetDefault("database.postgres.max_idle_conns", 10) viper.SetDefault("database.postgres.max_idle_conns", 10)
viper.SetDefault("database.postgres.conn_max_idle_time_secs", 3600) viper.SetDefault("database.postgres.conn_max_idle_time_secs", 3600)
viper.SetDefault("database.sqlite.write_ahead_log", true)
viper.SetDefault("oidc.scope", []string{oidc.ScopeOpenID, "profile", "email"}) viper.SetDefault("oidc.scope", []string{oidc.ScopeOpenID, "profile", "email"})
viper.SetDefault("oidc.strip_email_domain", true) viper.SetDefault("oidc.strip_email_domain", true)
viper.SetDefault("oidc.only_start_if_oidc_is_available", true) viper.SetDefault("oidc.only_start_if_oidc_is_available", true)
@ -443,6 +446,7 @@ func GetDatabaseConfig() DatabaseConfig {
Path: util.AbsolutePathFromConfigPath( Path: util.AbsolutePathFromConfigPath(
viper.GetString("database.sqlite.path"), viper.GetString("database.sqlite.path"),
), ),
WriteAheadLog: viper.GetBool("database.sqlite.write_ahead_log"),
}, },
Postgres: PostgresConfig{ Postgres: PostgresConfig{
Host: viper.GetString("database.postgres.host"), Host: viper.GetString("database.postgres.host"),