diff --git a/manifest b/manifest index 9854168bf6..e6a447b671 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\sthe\slegacy\sjournal\sformat\swriting\slogic.\s(CVS\s862) -D 2003-02-12T02:10:15 +C Added\sthe\snew\sFULL\soption\sto\sthe\sSYNCHRONOUS\spragma.\s\sStill\sneed\sto\stest\sit.\s(CVS\s863) +D 2003-02-12T14:09:43 F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -19,9 +19,9 @@ F publish.sh ce0bf7e235984bc156dc5d1a0c8092db4c8442f3 F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea F src/auth.c f37bfc9451b8c1fa52f34adff474560018892729 -F src/btree.c 668402ca441592d85da521309625bd1bcc6f010e -F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda -F src/build.c f13728865b6de5eb1ecc61827d334dc881ca1fb5 +F src/btree.c 2a0305ccbe617266ac3524805e0c6ef55a9f9cb7 +F src/btree.h 36a7a26a29382c2b1a519b42bb125880d46d00d4 +F src/build.c 757b1a37436b55b43c8eb41436a23a0ce8cad447 F src/delete.c cbd499f3f9297504c42e328af89bef1a2113d04c F src/encode.c faf03741efe921755ec371cf4a6984536de00042 F src/expr.c bd690b3a6174e97a0f16800e78c8aeae749a4e71 @@ -29,12 +29,12 @@ F src/func.c 90c583f0b91220f7cd411a2407deaf9327245d63 F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 F src/insert.c 13c2ef8984ce0f38701a8af89e4ba7a3c86c0701 -F src/main.c 764a72e6a4f021ae1d3db7e82dab625075f4fedb +F src/main.c f88dfe09ed79588899cb4013836dd940f73a17fa F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 F src/os.c ed27e178e0c4b71f2807da81b8851f0fadc50778 F src/os.h afa3e096213bad86845f8bdca81a9e917505e401 -F src/pager.c 1748a01ed18d7507c4c4dd54985c4aa613583a52 -F src/pager.h ce264d558c8ec289f5a9c50ca4ad499e3522a67e +F src/pager.c f7658e5d07ef66c966443a3f4420510ce640442b +F src/pager.h e5b8e301a732007766dc04880c764d7ee1aa34dd F src/parse.y cdaed5009423d851708848bd279147c268e6022e F src/printf.c f8fd911a8738f9b2eb07aca2870473d34707055d F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe @@ -42,7 +42,7 @@ F src/select.c d12d4c12d6536deccdede90b482d24f0590f5dc8 F src/shell.c 0d260a007e0668fc7dda2b0c89bd597ef2966ec6 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in 6f648803f2ffb9beb35cb1cfa42b323d55519171 -F src/sqliteInt.h 8beea34db78e1452569e22b020934002da5debee +F src/sqliteInt.h 2ae2c24fde8f7bb8040db964223d6e551e979358 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63 F src/tclsqlite.c 8167d40fd34036701e07492d07a6f9e5c4015241 F src/test1.c eb05abd3ec6822f800476c04aed4db112690b144 @@ -60,7 +60,7 @@ F test/all.test 873d30e25a41b3aa48fec5633a7ec1816e107029 F test/auth.test 33e8b9680eb0ce521c54096fff1c9ab506c7dfb8 F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 -F test/btree.test 10e75aec120ecefc0edc4c912a0980a43db1b6c2 +F test/btree.test 1e3463c7838e7e71bbf37c9c6e45beee9c8975ba F test/btree2.test e3b81ec33dc2f89b3e6087436dfe605b870c9080 F test/btree3.test e597fb59be2ac0ea69c62aaa2064e998e528b665 F test/btree4.test fa955a3d7a8bc91d6084b7f494f9e5d1bdfb15b6 @@ -142,7 +142,7 @@ F www/datatypes.tcl 0cb28565580554fa7e03e8fcb303e87ce57757ae F www/download.tcl 0932d7f4f0e8b2adbbd22fac73132f86e43ab4a9 F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c F www/faq.tcl 06276ff6c3e369374bb83034cc9d4a7d3a2a34a1 -F www/fileformat.tcl a4b5c2c6e89b7d42d09f97fd4d7bbd39cbf24936 +F www/fileformat.tcl 5e3009b1451364602916da986501b94d8516bbb4 F www/formatchng.tcl b4449e065d2da38b6563bdf12cf46cfe1d4d765e F www/index.tcl b5265ca54a5124ec40bffb7c7943e072e074d61a F www/lang.tcl 7ad51d873059368a98bcc2afec60d6ba4bb5688a @@ -155,7 +155,7 @@ F www/speed.tcl 4d463e2aea41f688ed320a937f93ff885be918c3 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 8ec5632536eea31197a3b1fd6abc57881a0cf1d7 -R b30735c88387ed3f8675a36136884368 +P 6c927dd36c19ebb8bb8222b4d18ed67f4fe733e8 +R 4c767e05bbbde68a52aa488a93a1a8fd U drh -Z b9a60900a465cbc97d661e720b92ed2b +Z c4a4b24e4cf8bd7a0ea9e8a1c854d6c7 diff --git a/manifest.uuid b/manifest.uuid index 04ad9bd851..5c866f52e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c927dd36c19ebb8bb8222b4d18ed67f4fe733e8 \ No newline at end of file +792a9e157dd066fcaffd4f5b373010151fb4ca61 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 80bf9254fb..9745f6d908 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.82 2003/01/29 22:58:26 drh Exp $ +** $Id: btree.c,v 1.83 2003/02/12 14:09:43 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -745,6 +745,19 @@ int sqliteBtreeSetCacheSize(Btree *pBt, int mxPage){ return SQLITE_OK; } +/* +** Change the way data is synced to disk in order to increase or decrease +** how well the database resists damage due to OS crashes and power +** failures. Level 1 is the same as asynchronous (no syncs() occur and +** there is a high probability of damage) Level 2 is the default. There +** is a very low but non-zero probability of damage. Level 3 reduces the +** probability of damage to near zero but with a write performance reduction. +*/ +int sqliteBtreeSetSafetyLevel(Btree *pBt, int level){ + sqlitepager_set_safety_level(pBt->pPager, level); + return SQLITE_OK; +} + /* ** Get a reference to page1 of the database file. This will ** also acquire a readlock on that file. diff --git a/src/btree.h b/src/btree.h index 72cdc96c3b..b92dce6e28 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,7 +13,7 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.26 2002/12/04 13:40:26 drh Exp $ +** @(#) $Id: btree.h,v 1.27 2003/02/12 14:09:44 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -24,6 +24,7 @@ typedef struct BtCursor BtCursor; int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree); int sqliteBtreeClose(Btree*); int sqliteBtreeSetCacheSize(Btree*, int); +int sqliteBtreeSetSafetyLevel(Btree*, int); int sqliteBtreeBeginTrans(Btree*); int sqliteBtreeCommit(Btree*); @@ -54,7 +55,7 @@ int sqliteBtreeDataSize(BtCursor*, int *pSize); int sqliteBtreeData(BtCursor*, int offset, int amt, char *zBuf); int sqliteBtreeCloseCursor(BtCursor*); -#define SQLITE_N_BTREE_META 4 +#define SQLITE_N_BTREE_META 10 int sqliteBtreeGetMeta(Btree*, int*); int sqliteBtreeUpdateMeta(Btree*, int*); diff --git a/src/build.c b/src/build.c index ade09f24fb..e272376faf 100644 --- a/src/build.c +++ b/src/build.c @@ -25,7 +25,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.128 2003/02/01 13:53:28 drh Exp $ +** $Id: build.c,v 1.129 2003/02/12 14:09:44 drh Exp $ */ #include "sqliteInt.h" #include @@ -2141,6 +2141,39 @@ static int getBoolean(char *z){ return 0; } +/* +** Interpret the given string as a safety level. Return 0 for OFF, +** 1 for ON or NORMAL and 2 for FULL. +** +** Note that the values returned are one less that the values that +** should be passed into sqliteBtreeSetSafetyLevel(). The is done +** to support legacy SQL code. The safety level used to be boolean +** and older scripts may have used numbers 0 for OFF and 1 for ON. +*/ +static int getSafetyLevel(char *z){ + static const struct { + const char *zWord; + int val; + } aKey[] = { + { "no", 0 }, + { "off", 0 }, + { "false", 0 }, + { "yes", 1 }, + { "on", 1 }, + { "true", 1 }, + { "full", 2 }, + }; + int i; + if( z[0]==0 ) return 1; + if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){ + return atoi(z); + } + for(i=0; iz==pLeft->z ){ - sqliteVdbeAddOpList(v, ArraySize(getSync), getSync); + int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync); + sqliteVdbeChangeP2(v, addr+3, addr+10); }else{ int addr; int size = db->cache_size; @@ -2303,20 +2338,24 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ sqliteVdbeAddOp(v, OP_Ne, 0, addr+3); sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0); sqliteVdbeAddOp(v, OP_AbsValue, 0, 0); - if( !getBoolean(zRight) ){ + db->safety_level = getSafetyLevel(zRight)+1; + if( db->safety_level==1 ){ sqliteVdbeAddOp(v, OP_Negative, 0, 0); size = -size; } sqliteVdbeAddOp(v, OP_SetCookie, 0, 2); + sqliteVdbeAddOp(v, OP_Integer, db->safety_level, 0); + sqliteVdbeAddOp(v, OP_SetCookie, 0, 3); sqliteEndWriteOperation(pParse); db->cache_size = size; sqliteBtreeSetCacheSize(db->pBe, db->cache_size); + sqliteBtreeSetSafetyLevel(db->pBe, db->safety_level); } }else /* ** PRAGMA synchronous - ** PRAGMA synchronous=BOOLEAN + ** PRAGMA synchronous=OFF|ON|NORMAL|FULL ** ** Return or set the local value of the synchronous flag. Changing ** the local value does not make changes to the disk file and the @@ -2331,14 +2370,16 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ Vdbe *v = sqliteGetVdbe(pParse); if( v==0 ) return; if( pRight->z==pLeft->z ){ - sqliteVdbeAddOp(v, OP_Integer, db->cache_size>=0, 0); + sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0); sqliteVdbeAddOpList(v, ArraySize(getSync), getSync); }else{ int size = db->cache_size; if( size<0 ) size = -size; - if( !getBoolean(zRight) ) size = -size; + db->safety_level = getSafetyLevel(zRight)+1; + if( db->safety_level==1 ) size = -size; db->cache_size = size; sqliteBtreeSetCacheSize(db->pBe, db->cache_size); + sqliteBtreeSetSafetyLevel(db->pBe, db->safety_level); } }else diff --git a/src/main.c b/src/main.c index 9a4b3f8724..c17c2f100d 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.112 2003/01/29 18:46:53 drh Exp $ +** $Id: main.c,v 1.113 2003/02/12 14:09:44 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -273,6 +273,9 @@ int sqliteInit(sqlite *db, char **pzErrMsg){ if( size==0 ){ size = MAX_PAGES; } db->cache_size = size; sqliteBtreeSetCacheSize(db->pBe, size); + db->safety_level = meta[4]; + if( db->safety_level==0 ) db->safety_level = 2; + sqliteBtreeSetSafetyLevel(db->pBe, db->safety_level); /* ** file_format==1 Version 2.1.0. diff --git a/src/pager.c b/src/pager.c index 533a6bbd0a..0dc83849cb 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.74 2003/02/12 02:10:15 drh Exp $ +** @(#) $Id: pager.c,v 1.75 2003/02/12 14:09:44 drh Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" @@ -101,7 +101,7 @@ struct PgHdr { u8 alwaysRollback; /* Disable dont_rollback() for this page */ PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */ /* SQLITE_PAGE_SIZE bytes of page data follow this header */ - /* Pager.nExtra bytes of local data follow the page data and checksum */ + /* Pager.nExtra bytes of local data follow the page data */ }; /* @@ -470,10 +470,6 @@ static int pager_unwritelock(Pager *pPager){ */ static u32 pager_cksum(Pager *pPager, Pgno pgno, const char *aData){ u32 cksum = pPager->cksumInit + pgno; - /* const u8 *a = (const u8*)aData; - int i; - for(i=0; icksumInit, pgno, cksum); */ return cksum; } @@ -770,6 +766,36 @@ void sqlitepager_set_cachesize(Pager *pPager, int mxPage){ } } +/* +** Adjust the robustness of the database to damage due to OS crashes +** or power failures by changing the number of syncs()s when writing +** the rollback journal. There are three levels: +** +** OFF sqliteOsSync() is never called. This is the default +** for temporary and transient files. +** +** NORMAL The journal is synced once before writes begin on the +** database. This is normally adequate protection, but +** it is theoretically possible, though very unlikely, +** that an inopertune power failure could leave the journal +** in a state which would cause damage to the database +** when it is rolled back. +** +** FULL The journal is synced twice before writes begin on the +** database (with some additional information being written +** in between the two syncs. If we assume that writing a +** single disk sector is atomic, then this mode provides +** assurance that the journal will not be corrupted to the +** point of causing damage to the database during rollback. +** +** Numeric values associated with these states are OFF==1, NORMAL=2, +** and FULL=3. +*/ +void sqlitepager_set_safety_level(Pager *pPager, int level){ + pPager->noSync = level==1 || pPager->tempFile; + pPager->fullSync = level==3 && !pPager->tempFile; +} + /* ** Open a temporary file. Write the name of the file into zName ** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.) Write diff --git a/src/pager.h b/src/pager.h index 64692b6ecd..4735b82d6b 100644 --- a/src/pager.h +++ b/src/pager.h @@ -13,7 +13,7 @@ ** 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.19 2003/02/11 14:55:41 drh Exp $ +** @(#) $Id: pager.h,v 1.20 2003/02/12 14:09:44 drh Exp $ */ /* @@ -70,6 +70,7 @@ int sqlitepager_ckpt_rollback(Pager*); void sqlitepager_dont_rollback(void*); void sqlitepager_dont_write(Pager*, Pgno); int *sqlitepager_stats(Pager*); +void sqlitepager_set_safety_level(Pager*,int); #ifdef SQLITE_TEST void sqlitepager_refdump(Pager*); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5d8ee0a185..e434543263 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.160 2003/02/11 14:55:41 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.161 2003/02/12 14:09:44 drh Exp $ */ #include "config.h" #include "sqlite.h" @@ -207,7 +207,8 @@ struct sqlite { Btree *pBe; /* The B*Tree backend */ Btree *pBeTemp; /* Backend for session temporary tables */ int flags; /* Miscellanous flags. See below */ - int file_format; /* What file format version is this database? */ + u8 file_format; /* What file format version is this database? */ + u8 safety_level; /* How aggressive at synching data to disk */ int schema_cookie; /* Magic number that changes with the schema */ int next_cookie; /* Value of schema_cookie after commit */ int cache_size; /* Number of pages to use in the cache */ diff --git a/test/btree.test b/test/btree.test index 2e107480dd..57a6ee11da 100644 --- a/test/btree.test +++ b/test/btree.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script is btree database backend # -# $Id: btree.test,v 1.13 2002/09/02 12:14:51 drh Exp $ +# $Id: btree.test,v 1.14 2003/02/12 14:09:45 drh Exp $ set testdir [file dirname $argv0] @@ -359,30 +359,30 @@ do_test btree-4.9 { # do_test btree-5.1 { btree_get_meta $::b1 -} {0 0 0 0} +} {0 0 0 0 0 0 0 0 0 0} do_test btree-5.2 { - set rc [catch {btree_update_meta $::b1 1 2 3 4} msg] + set rc [catch {btree_update_meta $::b1 1 2 3 4 5 6 7 8 9 10} msg] lappend rc $msg } {1 SQLITE_ERROR} do_test btree-5.3 { btree_begin_transaction $::b1 - set rc [catch {btree_update_meta $::b1 1 2 3 4} msg] + set rc [catch {btree_update_meta $::b1 1 2 3 4 5 6 7 8 9 10} msg] lappend rc $msg } {0 {}} do_test btree-5.4 { btree_get_meta $::b1 -} {0 2 3 4} +} {0 2 3 4 5 6 7 8 9 10} do_test btree-5.5 { btree_close_cursor $::c1 btree_rollback $::b1 btree_get_meta $::b1 -} {0 0 0 0} +} {0 0 0 0 0 0 0 0 0 0} do_test btree-5.6 { btree_begin_transaction $::b1 - btree_update_meta $::b1 999 10 20 30 + btree_update_meta $::b1 999 10 20 30 40 50 60 70 80 90 btree_commit $::b1 btree_get_meta $::b1 -} {0 10 20 30} +} {0 10 20 30 40 50 60 70 80 90} proc select_all {cursor} { set r {} diff --git a/www/fileformat.tcl b/www/fileformat.tcl index 9f2275ba45..077a128e37 100644 --- a/www/fileformat.tcl +++ b/www/fileformat.tcl @@ -1,7 +1,7 @@ # # Run this script to generated a fileformat.html output file # -set rcsid {$Id: fileformat.tcl,v 1.6 2002/08/18 19:09:24 drh Exp $} +set rcsid {$Id: fileformat.tcl,v 1.7 2003/02/12 14:09:45 drh Exp $} puts { @@ -687,17 +687,18 @@ name change, it works exactly the same.

4.4   Schema Version Numbering And Other Meta-Information

-The four 32-bit integers that are stored beginning at byte offset +The nine 32-bit integers that are stored beginning at byte offset 60 of Page 1 in the b-tree layer are passed up into the schema layer and used for versioning and configuration information. The meaning -of these four integers is as follows: +of the first four integers is shown below. The other five are currently +unused.

  1. The schema version number
  2. The format version number
  3. The recommended pager cache size
  4. -
  5. Unused
  6. +
  7. The safety level