From: Teemu Toivola Date: Mon, 13 May 2019 17:25:11 +0000 (+0300) Subject: expose SQLite synchronous flag as DatabaseSynchronous in configuration with default... X-Git-Tag: v2.3~27 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c300f8ea92477d8412de1e8cdbfd84f907e2ce44;p=vnstat expose SQLite synchronous flag as DatabaseSynchronous in configuration with default value depending on the setting of WriteAheadLoggingDatabase --- diff --git a/CHANGES b/CHANGES index 82d7e73..4e47643 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,9 @@ Write-Ahead Logging mode which may provide some disk i/o benefits, see https://www.sqlite.org/wal.html for more details and note that SQLite 3.22.0 or later is required to support read-only operations + - Add configuration option DatabaseSynchronous for changing the SQLite + setting of the "synchronous" flag, see + https://www.sqlite.org/pragma.html#pragma_synchronous for more details - Show warning in log if writing cached data to database is slow - Try database query for up to 5 seconds when database is busy or locked instead of giving up immediately diff --git a/UPGRADE.md b/UPGRADE.md index 9147a7e..c4448db 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,7 +1,7 @@ # New configuration settings - * 2.3: WriteAheadLoggingDatabase + * 2.3: WriteAheadLoggingDatabase, DatabaseSynchronous * 2.2: 64bitInterfaceCounters diff --git a/cfg/vnstat.conf b/cfg/vnstat.conf index ad178e3..72bd8bc 100644 --- a/cfg/vnstat.conf +++ b/cfg/vnstat.conf @@ -151,6 +151,10 @@ PidFile "/var/run/vnstat/vnstat.pid" # use SQLite Write-Ahead Logging mode (1 = enabled, 0 = disabled) WriteAheadLoggingDatabase 0 +# change the setting of the SQLite "synchronous" flag +# (-1 = auto, 0 = off, 1, = normal, 2 = full, 3 = extra) +DatabaseSynchronous -1 + # vnstati ## diff --git a/man/vnstat.conf.5 b/man/vnstat.conf.5 index 01584f7..50f5ec4 100644 --- a/man/vnstat.conf.5 +++ b/man/vnstat.conf.5 @@ -212,6 +212,18 @@ defines for how many past days entries will be stored. Set to -1 for unlimited entries or to 0 to disable the data collection of this resolution. +.TP +.B DatabaseSynchronous +Change the setting of the SQLite "synchronous" flag which controls how much +care is taken to ensure disk writes have fully completed when writing data to +the database before continuing other actions. Higher values take extra steps +to ensure data safety at the cost of slower performance. A value of 0 will +result in all handling being left to the filesystem itself. Set to -1 to +select the default value according to database mode controlled by +.B WriteAheadLoggingDatabase +setting. See SQLite documentation for more details regarding values from 1 +to 3. Value range: -1..3 + .TP .B HourlyDays Data retention duration for the one hour resolution entries. The configuration diff --git a/src/cfg.c b/src/cfg.c index 6917737..9a4d161 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -65,6 +65,7 @@ int loadcfg(const char *cfgfile) {"PidFile", cfg.pidfile, 0, 512, 0}, {"64bitInterfaceCounters", 0, &cfg.is64bit, 0, 0}, {"WriteAheadLoggingDatabase", 0, &cfg.waldb, 0, 0}, + {"DatabaseSynchronous", 0, &cfg.dbsynchronous, 0, 0}, {"HeaderFormat", cfg.hformat, 0, 64, 0}, {"HourlyRate", 0, &cfg.hourlyrate, 0, 0}, {"SummaryRate", 0, &cfg.summaryrate, 0, 0}, @@ -192,6 +193,7 @@ void validatecfg(void) validateint("UpdateFileOwner", &cfg.updatefileowner, UPDATEFILEOWNER, 0, 2); validateint("64bitInterfaceCounters", &cfg.is64bit, IS64BIT, -2, 1); validatebool("WriteAheadLoggingDatabase", &cfg.waldb, WALDB); + validateint("DatabaseSynchronous", &cfg.dbsynchronous, DBSYNCHRONOUS, -1, 3); validatebool("TransparentBg", &cfg.transbg, TRANSBG); validatebool("HourlyRate", &cfg.hourlyrate, HOURLYRATE); validatebool("SummaryRate", &cfg.summaryrate, SUMMARYRATE); @@ -342,6 +344,7 @@ void defaultcfg(void) strncpy_nt(cfg.pidfile, PIDFILE, 512); cfg.is64bit = IS64BIT; cfg.waldb = WALDB; + cfg.dbsynchronous = DBSYNCHRONOUS; cfg.transbg = TRANSBG; strncpy_nt(cfg.cbg, CBACKGROUND, 8); diff --git a/src/cfgoutput.c b/src/cfgoutput.c index c24a52d..e6dce2a 100644 --- a/src/cfgoutput.c +++ b/src/cfgoutput.c @@ -166,6 +166,10 @@ void printcfgfile(void) printf("# use SQLite Write-Ahead Logging mode (1 = enabled, 0 = disabled)\n"); printf("WriteAheadLoggingDatabase %d\n\n", cfg.waldb); + printf("# change the setting of the SQLite \"synchronous\" flag\n"); + printf("# (-1 = auto, 0 = off, 1, = normal, 2 = full, 3 = extra)\n"); + printf("DatabaseSynchronous %d\n\n", cfg.dbsynchronous); + printf("\n"); /* vnstati section */ diff --git a/src/common.h b/src/common.h index 296fa48..15abcc8 100644 --- a/src/common.h +++ b/src/common.h @@ -234,6 +234,7 @@ and most can be changed later from the config file. #define WALDB 0 #define WALDBCHECKPOINTINTERVALMINS 240 #define SLOWDBFLUSHWARNLIMIT 3.0 +#define DBSYNCHRONOUS -1 /* database read timeout */ #define DBREADTIMEOUTSECS 5 @@ -269,7 +270,7 @@ typedef struct { char cline[8], clinel[8], cvnstat[8], crx[8], crxd[8], ctx[8], ctxd[8]; int32_t unitmode, rateunitmode, rateunit, bvar, qmode, sampletime, hourlyrate, summaryrate; int32_t monthrotate, monthrotateyears, maxbw, spacecheck, trafficlessentries, transbg, ostyle; - int32_t defaultdecimals, hourlydecimals, hourlystyle, is64bit, waldb; + int32_t defaultdecimals, hourlydecimals, hourlystyle, is64bit, waldb, dbsynchronous; char cfgfile[512], logfile[512], pidfile[512]; char daemonuser[33], daemongroup[33]; int32_t timesyncwait, updateinterval, pollinterval, saveinterval, offsaveinterval, savestatus; diff --git a/src/dbsql.c b/src/dbsql.c index 73babe8..584ccf0 100644 --- a/src/dbsql.c +++ b/src/dbsql.c @@ -165,6 +165,7 @@ int db_validate(const int readonly) int db_setpragmas(void) { int rc; + char sql[25]; sqlite3_stmt *sqlstmt; /* enable use of foreign keys */ @@ -204,18 +205,36 @@ int db_setpragmas(void) if (!db_exec("PRAGMA journal_mode = WAL")) { return 0; } - if (!db_exec("PRAGMA synchronous = 1")) { - return 0; - } } else { if (!db_exec("PRAGMA journal_mode = DELETE")) { return 0; } + } +#endif + + /* set synchronous */ + if (cfg.dbsynchronous == -1) { +#if HAVE_DECL_SQLITE_CHECKPOINT_RESTART + if (cfg.waldb) { + if (!db_exec("PRAGMA synchronous = 1")) { + return 0; + } + } else { + if (!db_exec("PRAGMA synchronous = 2")) { + return 0; + } + } +#else if (!db_exec("PRAGMA synchronous = 2")) { return 0; } - } #endif + } else { + snprintf(sql, 25, "PRAGMA synchronous = %d", cfg.dbsynchronous); + if (!db_exec(sql)) { + return 0; + } + } return 1; }