]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add "pragma journal_size_limit", used to limit the space consumed by persistent journ...
authordanielk1977 <danielk1977@noemail.net>
Wed, 4 Jun 2008 06:45:59 +0000 (06:45 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Wed, 4 Jun 2008 06:45:59 +0000 (06:45 +0000)
FossilOrigin-Name: 5c59f469d0321c6a2e702ca2c61db012f63aeecc

manifest
manifest.uuid
src/pager.c
src/pager.h
src/pragma.c
test/jrnlmode.test

index 45c892d057a86f5874c1d7dd8986099ac73565fd..b218fe1100ada7291d0c6aa89a8198cbf305d6a7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Ensure\sthat\svacuum3.test\scloses\sall\sopened\sdatabase\sconnections.\sFix\sfor\s#3157.\s(CVS\s5184)
-D 2008-06-03T07:34:09
+C Add\s"pragma\sjournal_size_limit",\sused\sto\slimit\sthe\sspace\sconsumed\sby\spersistent\sjournal\sfiles\sleft\sin\sthe\sfile-system\safter\sa\stransaction\shas\sconcluded\sin\sexclusive\s(or\sjournal_mode=persist)\smode.\s(CVS\s5185)
+D 2008-06-04T06:45:59
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in ce92ea8dc7adfb743757794f51c10d1b0d9c55e4
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -133,10 +133,10 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
 F src/os_os2.c 1578149e21c4eac42c7f230a6f40500846f8e781
 F src/os_unix.c a6b02934fdd4682db47c006cb03baac8694d8b77
 F src/os_win.c 812f9ba8cd90c8aa54914a56897fb534494576d8
-F src/pager.c d0a77feeaeecaaaec9342a3bb3865ed9a490897a
-F src/pager.h 1ccde54041195311c2b09b6936404d2192db44da
+F src/pager.c d55885a30760028d3fe367df2fe7e2c884d65ff4
+F src/pager.h 71c58cd613174a91b50ed66edad6148639aa064a
 F src/parse.y fc4bd35c6088901f7c8daead26c6fb11c87d22e7
-F src/pragma.c a4919a29a0923e00c6170b0677a50058e352b58c
+F src/pragma.c c6dfbd16fff857aceb2fece8b34891a32d64b19a
 F src/prepare.c cbc9301aba1d0fc3d05fae576f2eb667c189cb36
 F src/printf.c f2d4f6c5b0ec24b643e85fe60258adad8b1f6acc
 F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
@@ -364,7 +364,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
 F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
 F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
-F test/jrnlmode.test 8e8e359e46799cea23d029f28bda6311f0f4c07b
+F test/jrnlmode.test b60a7dae8534ccd2e811deb09258f1172fd6e24f
 F test/jrnlmode2.test e48ec49320a3f849a5036e3551bf2394112a4aae
 F test/jrnlmode3.test c77f9d4095945f234dddd60ca0f73c24802ed0c1
 F test/jrnlmode4.test 8ee031603fef8ed5deba0de8b012a82be6d5a6a0
@@ -591,7 +591,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
 F tool/speedtest8inst1.c c65494ca99d1e09c246dfe37a7ca7a354af9990f
-P 03b5e4581a075179c85e8c16b16fd24c151294d3
-R b2702bf888acb9a4ed6edc79a93f42e2
+P 654e3b3de8ddeba3e31e9677ec4086e9f73c3598
+R 6663a334dd4809e3aa8da9c4ad8955dc
 U danielk1977
-Z 0dbf472f8f6e6a4fc7afad9089837ffd
+Z 785d2e00fd28d9fc7c0eeb4393db61ec
index 5783ff19c50d53a88fd4f3633844842d5757a3be..d6a8b7ac4a71a093fdd8d1d14e88ff60c93ff892 100644 (file)
@@ -1 +1 @@
-654e3b3de8ddeba3e31e9677ec4086e9f73c3598
\ No newline at end of file
+5c59f469d0321c6a2e702ca2c61db012f63aeecc
\ No newline at end of file
index da129dbc7db2372368990989a805687b3ebcd97c..44298cea160d708d2953f2bcede51ad60fb01392 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.450 2008/05/21 15:38:15 drh Exp $
+** @(#) $Id: pager.c,v 1.451 2008/06/04 06:45:59 danielk1977 Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -406,6 +406,7 @@ struct Pager {
 #endif
   char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
   char dbFileVers[16];        /* Changes whenever database file changes */
+  i64 journalSizeLimit;       /* Size limit for persistent journal files */
 };
 
 /*
@@ -974,8 +975,10 @@ static int zeroJournalHdr(Pager *pPager, int doTruncate){
   static const char zeroHdr[28];
 
   if( pPager->journalOff ){
+    i64 iLimit = pPager->journalSizeLimit;
+
     IOTRACE(("JZEROHDR %p\n", pPager))
-    if( doTruncate ){
+    if( doTruncate || iLimit==0 ){
       rc = sqlite3OsTruncate(pPager->jfd, 0);
     }else{
       rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
@@ -983,6 +986,20 @@ static int zeroJournalHdr(Pager *pPager, int doTruncate){
     if( rc==SQLITE_OK ){
       rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->sync_flags);
     }
+
+    /* At this point the transaction is committed but the write lock 
+    ** is still held on the file. If there is a size limit configured for 
+    ** the persistent journal and the journal file currently consumes more
+    ** space than that limit allows for, truncate it now. There is no need
+    ** to sync the file following this operation.
+    */
+    if( rc==SQLITE_OK && iLimit>0 ){
+      i64 sz;
+      rc = sqlite3OsFileSize(pPager->jfd, &sz);
+      if( rc==SQLITE_OK && sz>iLimit ){
+        rc = sqlite3OsTruncate(pPager->jfd, iLimit);
+      }
+    }
   }
   return rc;
 }
@@ -2351,6 +2368,7 @@ int sqlite3PagerOpen(
   /* pPager->pFirstSynced = 0; */
   /* pPager->pLast = 0; */
   pPager->nExtra = FORCE_ALIGNMENT(nExtra);
+  pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
   assert(pPager->fd->pMethods||memDb||tempFile);
   if( !memDb ){
     setSectorSize(pPager);
@@ -5306,6 +5324,16 @@ int sqlite3PagerJournalMode(Pager *pPager, int eMode){
   return (int)pPager->journalMode;
 }
 
+/*
+** Get/set the size-limit used for persistent journal files.
+*/
+i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
+  if( iLimit>=-1 ){
+    pPager->journalSizeLimit = iLimit;
+  }
+  return pPager->journalSizeLimit;
+}
+
 #ifdef SQLITE_TEST
 /*
 ** Print a listing of all referenced pages and their ref count.
index 58e0e18ef47e11b40220e6a1311b98edb4f12077..2fefea8d57c711257f7dc836d709327f8b64c518 100644 (file)
 ** subsystem.  The page cache subsystem reads and writes a file a page
 ** at a time and provides a journal for rollback.
 **
-** @(#) $Id: pager.h,v 1.73 2008/05/27 18:11:45 shane Exp $
+** @(#) $Id: pager.h,v 1.74 2008/06/04 06:45:59 danielk1977 Exp $
 */
 
 #ifndef _PAGER_H_
 #define _PAGER_H_
 
+/*
+** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
+** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
+*/
+#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
+  #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1
+#endif
+
 /*
 ** The type used to represent a page number.  The first page in a file
 ** is called page 1.  0 is used to represent "not a page".
@@ -102,6 +110,7 @@ void *sqlite3PagerGetData(DbPage *);
 void *sqlite3PagerGetExtra(DbPage *); 
 int sqlite3PagerLockingMode(Pager *, int);
 int sqlite3PagerJournalMode(Pager *, int);
+i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
 void *sqlite3PagerTempSpace(Pager*);
 int sqlite3PagerSync(Pager *pPager);
 
index 9a28563e3f730f2f585d6575c8f0b8484040ed3f..863254b11df6c33fdf5f49075e1ad6892f91dc71 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.177 2008/05/15 17:48:20 danielk1977 Exp $
+** $Id: pragma.c,v 1.178 2008/06/04 06:45:59 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -461,7 +461,7 @@ void sqlite3Pragma(
       }
     }
     if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){
-      /* Simple "PRAGMA persistent_journal;" statement. This is a query for
+      /* Simple "PRAGMA journal_mode;" statement. This is a query for
       ** the current default journal mode (which may be different to
       ** the journal-mode of the main database).
       */
@@ -499,6 +499,27 @@ void sqlite3Pragma(
            azModeName[eMode], P4_STATIC);
     sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
   }else
+
+  /*
+  **  PRAGMA [database.]journal_size_limit
+  **  PRAGMA [database.]journal_size_limit=N
+  **
+  ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.
+  */
+  if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
+    Pager *pPager = sqlite3BtreePager(pDb->pBt);
+    i64 iLimit = -2;
+    if( zRight ){
+      int iLimit32 = atoi(zRight);
+      if( iLimit32<-1 ){
+        iLimit32 = -1;
+      }
+      iLimit = iLimit32;
+    }
+    iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
+    returnSingleInt(pParse, "journal_size_limit", (int)iLimit);
+  }else
+
 #endif /* SQLITE_OMIT_PAGER_PRAGMAS */
 
   /*
index 4cc7e1f6ccefea62864dc94bc8f55f9bfbda99d3..cb6c3eb52aa8c165bb46ee0435cafd234a157a4c 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library. The focus
 # of these tests is the journal mode pragma.
 #
-# $Id: jrnlmode.test,v 1.3 2008/05/20 07:05:09 danielk1977 Exp $
+# $Id: jrnlmode.test,v 1.4 2008/06/04 06:46:00 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -251,4 +251,135 @@ ifcapable autovacuum&&pragma {
   integrity_check jrnlmode-4.5
 }
 
+#------------------------------------------------------------------------
+# The following test caes, jrnlmode-5.*, test the journal_size_limit
+# pragma.
+ifcapable pragma {
+  db close
+  file delete -force test.db test2.db test3.db
+  sqlite3 db test.db
+
+  do_test jrnlmode-5.1 {
+    execsql {pragma page_size=1024}
+    execsql {pragma journal_mode=persist}
+  } {persist}
+
+  do_test jrnlmode-5.2 {
+    execsql { PRAGMA journal_size_limit }
+  } {-1}
+  do_test jrnlmode-5.3 {
+    execsql { 
+      ATTACH 'test2.db' AS aux;
+      PRAGMA aux.journal_size_limit;
+    }
+  } {-1}
+  do_test jrnlmode-5.4 {
+    execsql { PRAGMA aux.journal_size_limit = 10240 }
+  } {10240}
+  do_test jrnlmode-5.5 {
+    execsql { PRAGMA main.journal_size_limit = 20480 }
+  } {20480}
+  do_test jrnlmode-5.6 {
+    execsql { PRAGMA journal_size_limit }
+  } {20480}
+  do_test jrnlmode-5.7 {
+    execsql { PRAGMA aux.journal_size_limit }
+  } {10240}
+
+  do_test jrnlmode-5.8 {
+    execsql { ATTACH 'test3.db' AS aux2 }
+  } {}
+
+  do_test jrnlmode-5.9 {
+    execsql {
+      CREATE TABLE main.t1(a, b, c);
+      CREATE TABLE aux.t2(a, b, c);
+      CREATE TABLE aux2.t3(a, b, c);
+    }
+  } {}
+  do_test jrnlmode-5.10 {
+    list \
+      [file exists test.db-journal]  \
+      [file exists test2.db-journal] \
+      [file exists test3.db-journal]
+  } {1 1 1}
+  do_test jrnlmode-5.11 {
+    execsql {
+      BEGIN;
+      INSERT INTO t3 VALUES(randomblob(1000),randomblob(1000),randomblob(1000));
+      INSERT INTO t3 
+          SELECT randomblob(1000),randomblob(1000),randomblob(1000) FROM t3;
+      INSERT INTO t3 
+          SELECT randomblob(1000),randomblob(1000),randomblob(1000) FROM t3;
+      INSERT INTO t3 
+          SELECT randomblob(1000),randomblob(1000),randomblob(1000) FROM t3;
+      INSERT INTO t3 
+          SELECT randomblob(1000),randomblob(1000),randomblob(1000) FROM t3;
+      INSERT INTO t3 
+          SELECT randomblob(1000),randomblob(1000),randomblob(1000) FROM t3;
+      INSERT INTO t2 SELECT * FROM t3;
+      INSERT INTO t1 SELECT * FROM t2;
+      COMMIT;
+    }
+    list \
+      [file exists test.db-journal]  \
+      [file exists test2.db-journal] \
+      [file exists test3.db-journal] \
+      [file size test.db-journal]    \
+      [file size test2.db-journal]   \
+      [file size test3.db-journal]
+  } {1 1 1 0 0 0}
+
+  do_test jrnlmode-5.12 {
+    execsql {
+      BEGIN;
+      UPDATE t1 SET a = randomblob(1000);
+    }
+    expr {[file size test.db-journal]>30000}
+  } {1}
+  do_test jrnlmode-5.13 {
+    execsql COMMIT
+    file size test.db-journal
+  } {20480}
+
+  do_test jrnlmode-5.14 {
+    execsql {
+      BEGIN;
+      UPDATE t2 SET a = randomblob(1000);
+    }
+    expr {[file size test2.db-journal]>30000}
+  } {1}
+  do_test jrnlmode-5.15 {
+    execsql COMMIT
+    file size test2.db-journal
+  } {10240}
+
+  do_test jrnlmode-5.16 {
+    execsql {
+      BEGIN;
+      UPDATE t3 SET a = randomblob(1000);
+    }
+    set journalsize [file size test3.db-journal]
+    expr {$journalsize>30000}
+  } {1}
+  do_test jrnlmode-5.17 {
+    execsql COMMIT
+    file size test3.db-journal
+  } $journalsize
+
+  do_test jrnlmode-5.18 {
+    execsql {
+      PRAGMA journal_size_limit = -4;
+      BEGIN;
+      UPDATE t1 SET a = randomblob(1000);
+    }
+    set journalsize [file size test.db-journal]
+    expr {$journalsize>30000}
+  } {1}
+  do_test jrnlmode-5.19 {
+    execsql COMMIT
+    file size test.db-journal
+  } $journalsize
+}
+
 finish_test