0
0
mirror of https://github.com/sqlite/sqlite.git synced 2024-12-01 17:23:42 +01:00

Add "pragma journal_size_limit", used to limit the space consumed by persistent journal files left in the file-system after a transaction has concluded in exclusive (or journal_mode=persist) mode. (CVS 5185)

FossilOrigin-Name: 5c59f469d0321c6a2e702ca2c61db012f63aeecc
This commit is contained in:
danielk1977 2008-06-04 06:45:59 +00:00
parent 53a4ddf7c4
commit b53e496095
6 changed files with 205 additions and 16 deletions

View File

@ -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

View File

@ -1 +1 @@
654e3b3de8ddeba3e31e9677ec4086e9f73c3598
5c59f469d0321c6a2e702ca2c61db012f63aeecc

View 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.

View File

@ -13,12 +13,20 @@
** 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);

View 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 */
/*

View 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