From 2c8997b9a599c411080495e21ea7e9563bb21876 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 27 Aug 2005 16:36:48 +0000 Subject: [PATCH] Disable synchronous writes to the master journal when PRAGMA synchronous=OFF for all database files. Ticket #1375. (CVS 2630) FossilOrigin-Name: 644b96aa23de7e828280d35785db840a4fa9413d --- manifest | 21 ++++++------- manifest.uuid | 2 +- src/btree.c | 11 ++++++- src/btree.h | 3 +- src/pager.c | 12 ++++++-- src/pager.h | 3 +- src/vdbeaux.c | 6 +++- test/sync.test | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 122 insertions(+), 17 deletions(-) create mode 100644 test/sync.test diff --git a/manifest b/manifest index 986909bcbd..e4463c5d77 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scomment\sin\svdbeapi.c.\s\sRemove\sunused\sstructure\sdefinition\sfrom\sfunc.c.\s(CVS\s2629) -D 2005-08-27T13:16:33 +C Disable\ssynchronous\swrites\sto\sthe\smaster\sjournal\swhen\sPRAGMA\ssynchronous=OFF\nfor\sall\sdatabase\sfiles.\s\sTicket\s#1375.\s(CVS\s2630) +D 2005-08-27T16:36:49 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -32,8 +32,8 @@ F src/alter.c 26d755f2143719dd3f5b8aaf6cbe3c7f95332528 F src/analyze.c 3ab32927f4d3067ead10e4c4f6fb61b2a93479cc F src/attach.c 4b21689700a72ae281fa85dbaff06b2a62bd49ee F src/auth.c 31e2304bef67f44d635655f44234387ea7d21454 -F src/btree.c 667227e4375d8bf6abd748cf6bad7a2004bf5d87 -F src/btree.h 41a71ce027db9ddee72cb43df2316bbe3a1d92af +F src/btree.c 5b3bc015c49a41c025cfdf8ad36051f3007e2cb0 +F src/btree.h 1ed561263ca0e335bc3e81d761c9d5ff8c22f61e F src/build.c 55e7e915a538bb25b1b7448cfb9189cccba554b2 F src/callback.c 9a1162c8f9dae9fad6d548339669aacb5f6cf76b F src/complete.c 4de937dfdd4c79a501772ab2035b26082f337a79 @@ -56,8 +56,8 @@ F src/os_unix.c 7fae44e25c6137340b786b83ecb29db6ba525a64 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_win.c fe7b99cfcfb61d9bf54493ddf5857885a657fb89 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c 4c6c6a553d6d23ff6a3a50df5fe53f730f3e387f -F src/pager.h 0d9153d6269d60d04af3dd84a0cc0a96253cf4a4 +F src/pager.c cd9896287a8fd33cc267bd0c2b69c421a4808169 +F src/pager.h 17b13225abd93c1e9f470060f40a21b9edb5a164 F src/parse.y d57cdd2adc0923762b40314f08683c836a2e0c90 F src/pragma.c 69413fbdc0c6aaa493a776ea52c1b3e6cf35dfb2 F src/prepare.c 86f0d8e744b8d956eff6bc40e29049efee017610 @@ -84,7 +84,7 @@ F src/vdbe.c 69f33e22c7d0a64b23fbb69e6da95a1bb6869032 F src/vdbe.h 3b29a9af6c7a64ed692bef1fc5f61338f40d2f67 F src/vdbeInt.h 89a7fa5dc35477bd30ea27b0bf38e9e5c2903812 F src/vdbeapi.c f1adebb5e3fe4724ed0e1a82c4a61809d7e15e9e -F src/vdbeaux.c 874624698fad54a59c6a0bcccea9d5aaa8655ab6 +F src/vdbeaux.c ae051fd18bd2fc642910fbc95d6763d730936511 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbemem.c 4732fd4d1a75dc38549493d7f9a81d02bf7c59b5 F src/where.c 485041aa51fb33f43b346e018f7c01422847f364 @@ -207,6 +207,7 @@ F test/select7.test 1bf795b948c133a15a2a5e99d3270e652ec58ce6 F test/sort.test 3b871d6e032f0a6c84d9f3d2d4b226e8fda97de0 F test/subquery.test ed4ecba1afacb586c86fad1cdb92756a48a90302 F test/subselect.test 3f3f7a940dc3195c3139f4d530385cb54665d614 +F test/sync.test d769caaec48456119316775e35e0fdee2fa852d7 F test/table.test d0e05ede3f6e5a8b79f8661ddcc4618cf7e69f8a F test/tableapi.test 6a66d58b37d46dc0f2b3c7d4bd2617d209399bd1 F test/tclsqlite.test a8d9afe680c466881a40252a86ef0fca457ab08c @@ -298,7 +299,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P ecb9604457d5ab6bcd81b582cc4dd85a8f371b86 -R bbe29a50d2da25ad59c230f05a2f2f4d +P 51a381345db45967567dd0a18905d352bf1081e0 +R 4f5f18e550ba91f695166764c512671e U drh -Z 787ff796a6044c29e432aa2a25d2214c +Z d452b4201f127e09042815840df7485c diff --git a/manifest.uuid b/manifest.uuid index a95cd4052a..e63b455474 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -51a381345db45967567dd0a18905d352bf1081e0 \ No newline at end of file +644b96aa23de7e828280d35785db840a4fa9413d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9dad38e7c4..a8978f3315 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.264 2005/08/02 17:13:10 drh Exp $ +** $Id: btree.c,v 1.265 2005/08/27 16:36:49 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -1345,6 +1345,15 @@ int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){ } #endif +/* +** Return TRUE if the given btree is set to safety level 1. In other +** words, return TRUE if no sync() occurs on the disk files. +*/ +int sqlite3BtreeSyncDisabled(Btree *pBt){ + assert( pBt && pBt->pPager ); + return sqlite3pager_nosync(pBt->pPager); +} + #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) /* ** Change the default pages size and the number of reserved bytes per page. diff --git a/src/btree.h b/src/btree.h index 19bb3d8f8d..acc29710f3 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.63 2005/03/21 04:04:03 danielk1977 Exp $ +** @(#) $Id: btree.h,v 1.64 2005/08/27 16:36:49 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -58,6 +58,7 @@ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*); int sqlite3BtreeSetCacheSize(Btree*,int); int sqlite3BtreeSetSafetyLevel(Btree*,int); +int sqlite3BtreeSyncDisabled(Btree*); int sqlite3BtreeSetPageSize(Btree*,int,int); int sqlite3BtreeGetPageSize(Btree*); int sqlite3BtreeGetReserve(Btree*); diff --git a/src/pager.c b/src/pager.c index b3617e6fc0..6cd35d4399 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.209 2005/08/21 16:54:25 drh Exp $ +** @(#) $Id: pager.c,v 1.210 2005/08/27 16:36:49 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -779,7 +779,7 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ if( rc!=SQLITE_OK ) return rc; rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic)); - pPager->needSync = 1; + pPager->needSync = !pPager->noSync; return rc; } @@ -3345,6 +3345,14 @@ const char *sqlite3pager_journalname(Pager *pPager){ return pPager->zJournal; } +/* +** Return true if fsync() calls are disabled for this pager. Return FALSE +** if fsync()s are executed normally. +*/ +int sqlite3pager_nosync(Pager *pPager){ + return pPager->noSync; +} + /* ** Set the codec for this pager */ diff --git a/src/pager.h b/src/pager.h index 512ac52660..f8af87d073 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.44 2005/05/20 20:01:56 drh Exp $ +** @(#) $Id: pager.h,v 1.45 2005/08/27 16:36:49 drh Exp $ */ /* @@ -100,6 +100,7 @@ void sqlite3pager_set_safety_level(Pager*,int); const char *sqlite3pager_filename(Pager*); const char *sqlite3pager_dirname(Pager*); const char *sqlite3pager_journalname(Pager*); +int sqlite3pager_nosync(Pager*); int sqlite3pager_rename(Pager*, const char *zNewName); void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*); int sqlite3pager_movepage(Pager*,void*,Pgno); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 578f9a68d2..d9541a3fee 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1090,6 +1090,7 @@ static int vdbeCommit(sqlite3 *db){ */ #ifndef SQLITE_OMIT_DISKIO else{ + int needSync = 0; char *zMaster = 0; /* File-name for the master journal */ char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); OsFile master; @@ -1125,6 +1126,9 @@ static int vdbeCommit(sqlite3 *db){ if( pBt && sqlite3BtreeIsInTrans(pBt) ){ char const *zFile = sqlite3BtreeGetJournalname(pBt); if( zFile[0]==0 ) continue; /* Ignore :memory: databases */ + if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){ + needSync = 1; + } rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); @@ -1141,7 +1145,7 @@ static int vdbeCommit(sqlite3 *db){ */ zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt); rc = sqlite3OsOpenDirectory(zMainFile, &master); - if( rc!=SQLITE_OK || (rc = sqlite3OsSync(&master))!=SQLITE_OK ){ + if( rc!=SQLITE_OK || (needSync && (rc=sqlite3OsSync(&master))!=SQLITE_OK) ){ sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqliteFree(zMaster); diff --git a/test/sync.test b/test/sync.test new file mode 100644 index 0000000000..54170ae6ed --- /dev/null +++ b/test/sync.test @@ -0,0 +1,81 @@ +# 2005 August 28 +# +# 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. +# +# This file implements tests to verify that fsync is disabled when +# pragma synchronous=off even for multi-database commits. +# +# $Id: sync.test,v 1.1 2005/08/27 16:36:49 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# +# These tests are only applicable on unix when pager pragma are +# enabled. +# +if {$::tcl_platform(platform)!="unix"} { + finish_test +} +ifcapable !pager_pragmas { + finish_test +} + +do_test sync-1.1 { + set sqlite_sync_count 0 + file delete -force test2.db + file delete -force test2.db-journal + execsql { + CREATE TABLE t1(a,b); + ATTACH DATABASE 'test2.db' AS db2; + CREATE TABLE db2.t2(x,y); + } + set sqlite_sync_count +} 8 +do_test sync-1.2 { + set sqlite_sync_count 0 + execsql { + PRAGMA main.synchronous=on; + PRAGMA db2.synchronous=on; + BEGIN; + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(3,4); + COMMIT; + } + set sqlite_sync_count +} 8 +do_test sync-1.3 { + set sqlite_sync_count 0 + execsql { + PRAGMA main.synchronous=full; + PRAGMA db2.synchronous=full; + BEGIN; + INSERT INTO t1 VALUES(3,4); + INSERT INTO t2 VALUES(5,6); + COMMIT; + } + set sqlite_sync_count +} 10 +do_test sync-1.4 { + set sqlite_sync_count 0 + execsql { + PRAGMA main.synchronous=off; + PRAGMA db2.synchronous=off; + BEGIN; + INSERT INTO t1 VALUES(5,6); + INSERT INTO t2 VALUES(7,8); + COMMIT; + } + set sqlite_sync_count +} 0 + + +finish_test