From fd9c77dfc7b90d447e6bfdb4f0d5b521184aeddb Mon Sep 17 00:00:00 2001
From: Eelco Dolstra <e.dolstra@tudelft.nl>
Date: Wed, 4 Aug 2010 17:35:59 +0000
Subject: [PATCH] * Use SQLite 3.7.0's write-ahead logging (WAL mode).  This is
 a lot   faster than the old mode when fsyncs are enabled, because it only  
 performs an fsync() when doing a checkpoint, rather than at every   commit. 
 Some timings for doing a "nix-instantiate /etc/nixos/nixos   -A system" after
 modifying the stdenv setup script:

    42.5s - SQLite 3.6.23 with truncate mode and fsync
     3.4s - SQLite 3.6.23 with truncate mode and no fsync
    32.1s - SQLite 3.7.0 with truncate mode and fsync
    16.8s - SQLite 3.7.0 with WAL mode and fsync, auto-checkpoint
            every 1000 pages
     8.3s - SQLite 3.7.0 with WAL mode and fsync, auto-checkpoint
            every 8192 pages
     1.7s - SQLite 3.7.0 with WAL mode and no fsync

  The default is now to use WAL mode with fsyncs.  Because WAL doesn't
  work on remote filesystems such as NFS (as it uses shared memory),
  truncate mode can be re-enabled by setting the "use-sqlite-wal"
  option to false.
---
 bootstrap.sh                |  1 +
 configure.ac                |  2 +-
 src/libstore/local-store.cc | 14 ++++++++++++--
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/bootstrap.sh b/bootstrap.sh
index f007c713b..2547f5dc8 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -1,4 +1,5 @@
 #! /bin/sh -e
+rm -f aclocal.m4
 mkdir -p config
 libtoolize --copy
 aclocal
diff --git a/configure.ac b/configure.ac
index 662a65c82..acf5ac7ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -236,7 +236,7 @@ AC_ARG_WITH(sqlite, AC_HELP_STRING([--with-sqlite=PATH],
   [prefix of SQLite]),
   sqlite=$withval, sqlite=)
 AM_CONDITIONAL(HAVE_SQLITE, test -n "$sqlite")
-SQLITE_VERSION=3.6.23
+SQLITE_VERSION=3.7.0
 AC_SUBST(SQLITE_VERSION)
 if test -z "$sqlite"; then
   sqlite_lib='${top_builddir}/externals/sqlite-$(SQLITE_VERSION)/libsqlite3.la'
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 6f3d9efa8..bddcbad12 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -298,10 +298,20 @@ void LocalStore::openDB(bool create)
     if (sqlite3_exec(db, ("pragma synchronous = " + syncMode + ";").c_str(), 0, 0, 0) != SQLITE_OK)
         throw SQLiteError(db, "setting synchronous mode");
 
-    /* Use `truncate' journal mode, which should be a bit faster. */
-    if (sqlite3_exec(db, "pragma main.journal_mode = truncate;", 0, 0, 0) != SQLITE_OK)
+    /* Set the SQLite journal mode.  The default is write-ahead
+       logging since it's the fastest and supports more concurrency.
+       The downside is that it doesn't work over NFS, so allow
+       truncate mode alternatively. */
+    string mode = queryBoolSetting("use-sqlite-wal", true) ? "wal" : "truncate";
+    if (sqlite3_exec(db, ("pragma main.journal_mode = " + mode + ";").c_str(), 0, 0, 0) != SQLITE_OK)
         throw SQLiteError(db, "setting journal mode");
 
+    /* Increase the auto-checkpoint interval to 8192 pages.  This
+       seems enough to ensure that instantiating the NixOS system
+       derivation is done in a single fsync(). */
+    if (sqlite3_exec(db, "pragma wal_autocheckpoint = 8192;", 0, 0, 0) != SQLITE_OK)
+        throw SQLiteError(db, "setting autocheckpoint interval");
+    
     /* Initialise the database schema, if necessary. */
     if (create) {
 #include "schema.sql.hh"
-- 
GitLab