-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
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
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
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
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
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
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
-6c927dd36c19ebb8bb8222b4d18ed67f4fe733e8
\ No newline at end of file
+792a9e157dd066fcaffd4f5b373010151fb4ca61
\ No newline at end of file
** 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
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.
** 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_
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*);
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*);
** 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 <ctype.h>
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; i<sizeof(aKey)/sizeof(aKey[0]); i++){
+ if( sqliteStrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
+ }
+ return 1;
+}
+
/*
** Process a pragma statement.
**
/*
** PRAGMA default_synchronous
- ** PRAGMA default_synchronous=BOOLEAN
+ ** PRAGMA default_synchronous=ON|OFF|NORMAL|FULL
**
** The first form returns the persistent value of the "synchronous" setting
** that is stored in the database. This is the synchronous setting that
** "synchronous" pragma. The second form changes the persistent and the
** local synchronous setting to the value given.
**
- ** If synchronous is on, SQLite will do an fsync() system call at strategic
- ** points to insure that all previously written data has actually been
- ** written onto the disk surface before continuing. This mode insures that
- ** the database will always be in a consistent state event if the operating
- ** system crashes or power to the computer is interrupted unexpectedly.
- ** When synchronous is off, SQLite will not wait for changes to actually
- ** be written to the disk before continuing. As soon as it hands changes
- ** to the operating system, it assumes that the changes are permanent and
- ** it continues going. The database cannot be corrupted by a program crash
- ** even with synchronous off, but an operating system crash or power loss
- ** could potentially corrupt data. On the other hand, synchronous off is
- ** faster than synchronous on.
+ ** If synchronous is OFF, SQLite does not attempt any fsync() systems calls
+ ** to make sure data is committed to disk. Write operations are very fast,
+ ** but a power failure can leave the database in an inconsistent state.
+ ** If synchronous is ON or NORMAL, SQLite will do an fsync() system call to
+ ** make sure data is being written to disk. The risk of corruption due to
+ ** a power loss in this mode is negligible but non-zero. If synchronous
+ ** is FULL, extra fsync()s occur to reduce the risk of corruption to near
+ ** zero, but with a write performance penalty. The default mode is NORMAL.
*/
if( sqliteStrICmp(zLeft,"default_synchronous")==0 ){
static VdbeOp getSync[] = {
- { OP_Integer, 0, 0, 0},
+ { OP_ColumnName, 0, 0, "synchronous"},
+ { OP_ReadCookie, 0, 3, 0},
+ { OP_Dup, 0, 0, 0},
+ { OP_If, 0, 0, 0}, /* 3 */
{ OP_ReadCookie, 0, 2, 0},
{ OP_Integer, 0, 0, 0},
{ OP_Lt, 0, 5, 0},
{ OP_AddImm, 1, 0, 0},
- { OP_ColumnName, 0, 0, "synchronous"},
{ OP_Callback, 1, 0, 0},
+ { OP_Halt, 0, 0, 0},
+ { OP_AddImm, -1, 0, 0}, /* 10 */
+ { OP_Callback, 1, 0, 0}
};
Vdbe *v = sqliteGetVdbe(pParse);
if( v==0 ) return;
if( pRight->z==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;
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
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
** 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"
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.
** 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"
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 */
};
/*
*/
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; i<SQLITE_PAGE_SIZE; i++){ cksum += a[i]; } */
- /* fprintf(stderr,"CKSUM for %p(%08x) page %d: %08x\n", pPager, pPager->cksumInit, pgno, cksum); */
return cksum;
}
}
}
+/*
+** 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
** 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 $
*/
/*
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*);
*************************************************************************
** 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"
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 */
# 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]
#
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 {}
#
# 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 {<html>
<head>
<h3>4.4 Schema Version Numbering And Other Meta-Information</h3>
<p>
-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.
</p>
<ol>
<li>The schema version number</li>
<li>The format version number</li>
<li>The recommended pager cache size</li>
-<li>Unused</li>
+<li>The safety level</li>
</ol>
<p>