Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5c59f469d0321c6a2e702ca2c61db012 |
User & Date: | danielk1977 2008-06-04 06:45:59.000 |
Context
2008-06-04
| ||
14:20 | Fix a bug in the R-Tree documentation. (CVS 5186) (check-in: bb445a4b1f user: drh tags: trunk) | |
06:45 | 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) (check-in: 5c59f469d0 user: danielk1977 tags: trunk) | |
2008-06-03
| ||
07:34 | Ensure that vacuum3.test closes all opened database connections. Fix for #3157. (CVS 5184) (check-in: 654e3b3de8 user: danielk1977 tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.451 2008/06/04 06:45:59 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include <assert.h> #include <string.h> /* |
︙ | ︙ | |||
402 403 404 405 406 407 408 409 410 411 412 413 414 415 | Pager *pNext; /* Doubly linked list of pagers on which */ Pager *pPrev; /* sqlite3_release_memory() will work */ volatile int iInUseMM; /* Non-zero if unavailable to MM */ volatile int iInUseDB; /* Non-zero if in sqlite3_release_memory() */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ char dbFileVers[16]; /* Changes whenever database file changes */ }; /* ** The following global variables hold counters used for ** testing purposes only. These variables do not exist in ** a non-testing build. These variables are not thread-safe. */ | > | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | Pager *pNext; /* Doubly linked list of pagers on which */ Pager *pPrev; /* sqlite3_release_memory() will work */ volatile int iInUseMM; /* Non-zero if unavailable to MM */ volatile int iInUseDB; /* Non-zero if in sqlite3_release_memory() */ #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 */ }; /* ** The following global variables hold counters used for ** testing purposes only. These variables do not exist in ** a non-testing build. These variables are not thread-safe. */ |
︙ | ︙ | |||
970 971 972 973 974 975 976 977 | ** transaction. */ static int zeroJournalHdr(Pager *pPager, int doTruncate){ int rc = SQLITE_OK; static const char zeroHdr[28]; if( pPager->journalOff ){ IOTRACE(("JZEROHDR %p\n", pPager)) | > > | > > > > > > > > > > > > > > | 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 | ** transaction. */ static int zeroJournalHdr(Pager *pPager, int doTruncate){ int rc = SQLITE_OK; static const char zeroHdr[28]; if( pPager->journalOff ){ i64 iLimit = pPager->journalSizeLimit; IOTRACE(("JZEROHDR %p\n", pPager)) if( doTruncate || iLimit==0 ){ rc = sqlite3OsTruncate(pPager->jfd, 0); }else{ rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); } 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; } /* ** The journal file must be open when this routine is called. A journal ** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the |
︙ | ︙ | |||
2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 | pPager->noSync = pPager->tempFile || !useJournal; pPager->fullSync = (pPager->noSync?0:1); pPager->sync_flags = SQLITE_SYNC_NORMAL; /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ pPager->nExtra = FORCE_ALIGNMENT(nExtra); assert(pPager->fd->pMethods||memDb||tempFile); if( !memDb ){ setSectorSize(pPager); } /* pPager->pBusyHandler = 0; */ /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ *ppPager = pPager; | > | 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 | pPager->noSync = pPager->tempFile || !useJournal; pPager->fullSync = (pPager->noSync?0:1); pPager->sync_flags = SQLITE_SYNC_NORMAL; /* pPager->pFirst = 0; */ /* 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); } /* pPager->pBusyHandler = 0; */ /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ *ppPager = pPager; |
︙ | ︙ | |||
5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 | assert( PAGER_JOURNALMODE_QUERY<0 ); assert( PAGER_JOURNALMODE_DELETE>=0 && PAGER_JOURNALMODE_PERSIST>=0 ); if( eMode>=0 ){ pPager->journalMode = eMode; } return (int)pPager->journalMode; } #ifdef SQLITE_TEST /* ** Print a listing of all referenced pages and their ref count. */ void sqlite3PagerRefdump(Pager *pPager){ PgHdr *pPg; | > > > > > > > > > > | 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 | assert( PAGER_JOURNALMODE_QUERY<0 ); assert( PAGER_JOURNALMODE_DELETE>=0 && PAGER_JOURNALMODE_PERSIST>=0 ); if( eMode>=0 ){ pPager->journalMode = 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. */ void sqlite3PagerRefdump(Pager *pPager){ PgHdr *pPg; |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** | | > > > > > > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** 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.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". */ typedef u32 Pgno; /* |
︙ | ︙ | |||
98 99 100 101 102 103 104 105 106 107 108 109 110 111 | const char *sqlite3PagerJournalname(Pager*); int sqlite3PagerNosync(Pager*); int sqlite3PagerMovepage(Pager*,DbPage*,Pgno); void *sqlite3PagerGetData(DbPage *); void *sqlite3PagerGetExtra(DbPage *); int sqlite3PagerLockingMode(Pager *, int); int sqlite3PagerJournalMode(Pager *, int); void *sqlite3PagerTempSpace(Pager*); int sqlite3PagerSync(Pager *pPager); #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO) int sqlite3PagerReleaseMemory(int); #endif | > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | const char *sqlite3PagerJournalname(Pager*); int sqlite3PagerNosync(Pager*); int sqlite3PagerMovepage(Pager*,DbPage*,Pgno); 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); #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO) int sqlite3PagerReleaseMemory(int); #endif |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.178 2008/06/04 06:45:59 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* Ignore this whole file if pragmas are disabled */ #if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) |
︙ | ︙ | |||
457 458 459 460 461 462 463 | int n = strlen(zRight); eMode = 2; while( eMode>=0 && sqlite3StrNICmp(zRight, azModeName[eMode], n)!=0 ){ eMode--; } } if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){ | | | 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | int n = strlen(zRight); eMode = 2; while( eMode>=0 && sqlite3StrNICmp(zRight, azModeName[eMode], n)!=0 ){ eMode--; } } if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){ /* 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). */ eMode = db->dfltJournalMode; }else{ Pager *pPager; if( pId2->n==0 ){ |
︙ | ︙ | |||
495 496 497 498 499 500 501 502 503 504 505 506 507 508 | || eMode==PAGER_JOURNALMODE_OFF ); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", P4_STATIC); sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, azModeName[eMode], P4_STATIC); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); }else #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ /* ** PRAGMA [database.]auto_vacuum ** PRAGMA [database.]auto_vacuum=N ** ** Get or set the (boolean) value of the database 'auto-vacuum' parameter. | > > > > > > > > > > > > > > > > > > > > > | 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | || eMode==PAGER_JOURNALMODE_OFF ); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", P4_STATIC); sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, 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 */ /* ** PRAGMA [database.]auto_vacuum ** PRAGMA [database.]auto_vacuum=N ** ** Get or set the (boolean) value of the database 'auto-vacuum' parameter. |
︙ | ︙ |
Changes to test/jrnlmode.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2008 April 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus # of these tests is the journal mode pragma. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2008 April 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus # of these tests is the journal mode pragma. # # $Id: jrnlmode.test,v 1.4 2008/06/04 06:46:00 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!pager_pragmas} { finish_test return |
︙ | ︙ | |||
246 247 248 249 250 251 252 253 254 | # is not a problem when journal_mode=off. do_test jrnlmode-4.4 { execsql { DELETE FROM abc } } {} integrity_check jrnlmode-4.5 } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | # is not a problem when journal_mode=off. do_test jrnlmode-4.4 { execsql { DELETE FROM abc } } {} 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 |