1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Added the new FULL option to the SYNCHRONOUS pragma. Still need to test it. (CVS 863)

FossilOrigin-Name: 792a9e157dd066fcaffd4f5b373010151fb4ca61
This commit is contained in:
drh
2003-02-12 14:09:42 +00:00
parent d8d66e8ca0
commit 973b6e333d
11 changed files with 148 additions and 61 deletions

View File

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

View File

@@ -1 +1 @@
6c927dd36c19ebb8bb8222b4d18ed67f4fe733e8
792a9e157dd066fcaffd4f5b373010151fb4ca61

View File

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

View File

@@ -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*);

View File

@@ -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 <ctype.h>
@@ -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; i<sizeof(aKey)/sizeof(aKey[0]); i++){
if( sqliteStrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
}
return 1;
}
/*
** Process a pragma statement.
**
@@ -2257,7 +2290,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
/*
** 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
@@ -2265,33 +2298,35 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
** "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;
@@ -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

View File

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

View File

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

View File

@@ -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*);

View File

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

View File

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

View File

@@ -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 {<html>
<head>
@@ -687,17 +687,18 @@ name change, it works exactly the same.
<h3>4.4 &nbsp; 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>