]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid creating a master journal unless two or more databases in the
authordrh <drh@noemail.net>
Mon, 22 Feb 2016 14:57:38 +0000 (14:57 +0000)
committerdrh <drh@noemail.net>
Mon, 22 Feb 2016 14:57:38 +0000 (14:57 +0000)
transaction can actually benefit from that master journal.

FossilOrigin-Name: 3ed1890612bd45bd9c72f670d2cbb0b8fbd35d92

manifest
manifest.uuid
src/vdbeaux.c
test/pager1.test

index 737d2b6c225dc2ad42b19bbf879373d1a277d5c4..82a52654982bdfaf3f0d1b4116db52750ae48d41 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\smagic\snumbers\sassociated\swith\ssynchronous\ssettings\sto\snamed\sconstants.
-D 2016-02-22T13:23:16.525
+C Avoid\screating\sa\smaster\sjournal\sunless\stwo\sor\smore\sdatabases\sin\sthe\ntransaction\scan\sactually\sbenefit\sfrom\sthat\smaster\sjournal.
+D 2016-02-22T14:57:38.065
 F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 28fc4ee02333996d31b3602b39eeb8e609a89ce4
@@ -418,7 +418,7 @@ F src/vdbe.c 822e44c1dd859794f8c414e8bae4d96ac1fa774d
 F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512
 F src/vdbeInt.h 581e5bff9a401fabdb917b816503cda7356ec3e1
 F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009
-F src/vdbeaux.c ec9a4d939a7430b76f53c5ef5cdbca3c8704848a
+F src/vdbeaux.c 51aaf15e5c29512423429cc0e0477e08f7181514
 F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db
 F src/vdbemem.c be8381ed6de54eb9cb9dfa802823cdeb5166d855
 F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062
@@ -932,7 +932,7 @@ F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
 F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
 F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
-F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
+F test/pager1.test f49df1a8b0e38b9ee3a7dd2ab4d427507b7314ce
 F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
 F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
@@ -1429,7 +1429,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh a98af506df552f3b3c0d904f94e4cdc4e1a6d598
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P a48ac4c347813bd2b416b1cb06c3cbf1f4b3781a
-R 5ba950defec5ebb5c806c723cbc4f5b9
+P 9230ba6c01f4a550d92a0cbbf36dbe81af14fbfc
+R 28c7602ad1de5114aacb14204e4f7226
 U drh
-Z 3422238b7807aea6814e5b393b012e9d
+Z aad5fe626dac38bb4fd331764966d6a1
index b896d3d101d71e7a5baab8f3e9f4650fd84e19c1..4ab1f4a5a51da6f99647303188004faaa766da81 100644 (file)
@@ -1 +1 @@
-9230ba6c01f4a550d92a0cbbf36dbe81af14fbfc
\ No newline at end of file
+3ed1890612bd45bd9c72f670d2cbb0b8fbd35d92
\ No newline at end of file
index 9aa05fc868db7aa53a7e8c1153350747813e7817..4f539f0a29d372a34b3758041a804516e5617c7f 100644 (file)
@@ -2155,7 +2155,9 @@ int sqlite3VdbeSetColName(
 */
 static int vdbeCommit(sqlite3 *db, Vdbe *p){
   int i;
-  int nTrans = 0;  /* Number of databases with an active write-transaction */
+  int nTrans = 0;  /* Number of databases with an active write-transaction
+                   ** that are candidates for a two-phase commit using a
+                   ** master-journal */
   int rc = SQLITE_OK;
   int needXcommit = 0;
 
@@ -2183,10 +2185,28 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
   for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
     Btree *pBt = db->aDb[i].pBt;
     if( sqlite3BtreeIsInTrans(pBt) ){
+      /* Whether or not a database might need a master journal depends upon
+      ** its journal mode (among other things).  This matrix determines which
+      ** journal modes use a master journal and which do not */
+      static const u8 aMJNeeded[] = {
+        /* DELETE   */  1,
+        /* PERSIST   */ 1,
+        /* OFF       */ 0,
+        /* TRUNCATE  */ 1,
+        /* MEMORY    */ 0,
+        /* WAL       */ 0
+      };
+      Pager *pPager;   /* Pager associated with pBt */
       needXcommit = 1;
-      if( i!=1 ) nTrans++;
       sqlite3BtreeEnter(pBt);
-      rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
+      pPager = sqlite3BtreePager(pBt);
+      if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
+       && aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
+      ){ 
+        assert( i!=1 );
+        nTrans++;
+      }
+      rc = sqlite3PagerExclusiveLock(pPager);
       sqlite3BtreeLeave(pBt);
     }
   }
index 005b356080dd98271b8aaf306ca8bb021d3dc4ed..bc9ad83fd46541a1bd7214d3c6691b5e8213ab4c 100644 (file)
@@ -529,6 +529,7 @@ set pwd [get_pwd]
 testvfs tv -default 1
 tv script copy_on_mj_delete
 set ::mj_filename_length 0
+set ::mj_delete_cnt 0
 proc copy_on_mj_delete {method filename args} {
   if {[string match *mj* [file tail $filename]]} { 
     #
@@ -542,6 +543,7 @@ proc copy_on_mj_delete {method filename args} {
       set ::mj_filename_length [string length $filename]
     }
     faultsim_save 
+    incr ::mj_delete_cnt
   }
   return SQLITE_OK
 }
@@ -579,29 +581,68 @@ foreach {tn1 tcl} {
   }
 } {
   eval $tcl
-  foreach {tn2 sql} {
+  foreach {tn2 sql usesMJ} {
     o { 
       PRAGMA main.synchronous=OFF;
       PRAGMA aux.synchronous=OFF;
       PRAGMA journal_mode = DELETE;
-    }
+    } 0
     o512 { 
       PRAGMA main.synchronous=OFF;
       PRAGMA aux.synchronous=OFF;
       PRAGMA main.page_size = 512;
       PRAGMA aux.page_size = 512;
       PRAGMA journal_mode = DELETE;
-    }
+    } 0
     n { 
       PRAGMA main.synchronous=NORMAL;
       PRAGMA aux.synchronous=NORMAL;
       PRAGMA journal_mode = DELETE;
-    }
+    } 1
     f { 
       PRAGMA main.synchronous=FULL;
       PRAGMA aux.synchronous=FULL;
       PRAGMA journal_mode = DELETE;
-    }
+    } 1
+    w1 { 
+      PRAGMA main.synchronous=NORMAL;
+      PRAGMA aux.synchronous=NORMAL;
+      PRAGMA journal_mode = WAL;
+    } 0
+    w2 { 
+      PRAGMA main.synchronous=NORMAL;
+      PRAGMA aux.synchronous=NORMAL;
+      PRAGMA main.journal_mode=DELETE;
+      PRAGMA aux.journal_mode=WAL;
+    } 0
+    o1a { 
+      PRAGMA main.synchronous=FULL;
+      PRAGMA aux.synchronous=OFF;
+      PRAGMA journal_mode=DELETE;
+    } 0
+    o1b { 
+      PRAGMA main.synchronous=OFF;
+      PRAGMA aux.synchronous=NORMAL;
+      PRAGMA journal_mode=DELETE;
+    } 0
+    m1 { 
+      PRAGMA main.synchronous=NORMAL;
+      PRAGMA aux.synchronous=NORMAL;
+      PRAGMA main.journal_mode=DELETE;
+      PRAGMA aux.journal_mode = MEMORY;
+    } 0
+    t1 { 
+      PRAGMA main.synchronous=NORMAL;
+      PRAGMA aux.synchronous=NORMAL;
+      PRAGMA main.journal_mode=DELETE;
+      PRAGMA aux.journal_mode = TRUNCATE;
+    } 1
+    p1 { 
+      PRAGMA main.synchronous=NORMAL;
+      PRAGMA aux.synchronous=NORMAL;
+      PRAGMA main.journal_mode=DELETE;
+      PRAGMA aux.journal_mode = PERSIST;
+    } 1
   } {
 
     set tn "${tn1}.${tn2}"
@@ -613,6 +654,7 @@ foreach {tn1 tcl} {
     #
     tv filter xDelete
     do_test pager1-4.4.$tn.1 {
+      set ::mj_delete_cnt 0
       faultsim_delete_and_reopen $prefix
       execsql "
         ATTACH '${prefix}2' AS aux;
@@ -634,6 +676,13 @@ foreach {tn1 tcl} {
       }
     } {}
     tv filter {}
+
+    # Verify that a master journal was deleted only for those cases where
+    # master journals really ought to be used
+    #
+    do_test pager1-4.4.$tn.1b {
+      set ::mj_delete_cnt
+    } $usesMJ
     
     # Check that the transaction was committed successfully.
     #
@@ -644,25 +693,33 @@ foreach {tn1 tcl} {
       SELECT * FROM b
     } {won too free double-you why zed}
     
-    # Restore the file-system and reopen the databases. Check that it now
-    # appears that the transaction was not committed (because the file-system
-    # was restored to the state where it had not been).
-    #
-    do_test pager1-4.4.$tn.4 {
-      faultsim_restore_and_reopen $prefix
-      execsql "ATTACH '${prefix}2' AS aux"
-    } {}
-    do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed}
-    do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free}
+    if {$usesMJ} {
+      # Restore the file-system and reopen the databases. Check that it now
+      # appears that the transaction was not committed (because the file-system
+      # was restored to the state where it had not been).
+      #
+      do_test pager1-4.4.$tn.4 {
+        faultsim_restore_and_reopen $prefix
+        execsql "ATTACH '${prefix}2' AS aux"
+      } {}
+      do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed}
+      do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free}
+    }
     
     # Restore the file-system again. This time, before reopening the databases,
     # delete the master-journal file from the file-system. It now appears that
     # the transaction was committed (no master-journal file == no rollback).
     #
     do_test pager1-4.4.$tn.7 {
-      faultsim_restore_and_reopen $prefix
-      foreach f [glob ${prefix}-mj*] { forcedelete $f }
+      if {$::mj_delete_cnt>0} {
+        faultsim_restore_and_reopen $prefix
+        foreach f [glob ${prefix}-mj*] { forcedelete $f }
+      } else {
+        db close
+        sqlite3 db $prefix
+      }
       execsql "ATTACH '${prefix}2' AS aux"
+      glob -nocomplain ${prefix}-mj*
     } {}
     do_execsql_test pager1-4.4.$tn.8 {
       SELECT * FROM a
@@ -678,7 +735,6 @@ db close
 tv delete
 forcedelete $dirname
 
-
 # Set up a VFS to make a copy of the file-system just before deleting a
 # journal file to commit a transaction. The transaction modifies exactly
 # two database pages (and page 1 - the change counter).