From 99d87e5c3261276ec9892e4a5e0f005497b4118b Mon Sep 17 00:00:00 2001 From: Nick Porter Date: Wed, 25 Jun 2025 14:13:42 +0100 Subject: [PATCH] Move SQLite busy timeout to be a driver option This is a specific kind of timeout - how long to wait for database locks to be released. Due to SQLite's very basic locking, it's easy for multiple update requests to conflict. This provides a more graceful way to handle the locks. --- raddb/mods-config/sql/driver/sqlite | 5 +++++ src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/raddb/mods-config/sql/driver/sqlite b/raddb/mods-config/sql/driver/sqlite index f7c7674460..e4a658c6b2 100644 --- a/raddb/mods-config/sql/driver/sqlite +++ b/raddb/mods-config/sql/driver/sqlite @@ -14,4 +14,9 @@ sqlite { # a new database file will be created, and the SQL statements # contained within the bootstrap file will be executed. # bootstrap = "${modconfdir}/${..:name}/main/sqlite/schema.sql" + + # When a query is run against a locked database, SQLite can + # wait for up to this time for the lock to be released rather + # than failing immediately. + busy_timeout = 0.25s } diff --git a/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c b/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c index 8d1843094a..b7e7609d09 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c @@ -59,10 +59,12 @@ typedef struct { typedef struct { char const *filename; bool bootstrap; + fr_time_delta_t busy_timeout; } rlm_sql_sqlite_t; static const conf_parser_t driver_config[] = { { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_FILE_OUTPUT | CONF_FLAG_REQUIRED, rlm_sql_sqlite_t, filename) }, + { FR_CONF_OFFSET("busy_timeout", rlm_sql_sqlite_t, busy_timeout) }, CONF_PARSER_TERMINATOR }; @@ -367,7 +369,6 @@ static connection_state_t _sql_connection_init(void **h, connection_t *conn, voi rlm_sql_t const *sql = talloc_get_type_abort_const(uctx, rlm_sql_t); rlm_sql_sqlite_t *inst = talloc_get_type_abort(sql->driver_submodule->data, rlm_sql_sqlite_t); rlm_sql_sqlite_conn_t *c; - rlm_sql_config_t const *config = &sql->config; int status; MEM(c = talloc_zero(conn, rlm_sql_sqlite_conn_t)); @@ -400,7 +401,7 @@ static connection_state_t _sql_connection_init(void **h, connection_t *conn, voi talloc_free(c); return CONNECTION_STATE_FAILED; } - status = sqlite3_busy_timeout(c->db, fr_time_delta_to_msec(config->query_timeout)); + status = sqlite3_busy_timeout(c->db, fr_time_delta_to_msec(inst->busy_timeout)); if (sql_check_error(c->db, status) != RLM_SQL_OK) { sql_print_error(c->db, status, "Failed setting busy timeout"); goto error; -- 2.47.3