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

Fix some problems with multi-file transactions in persistent journal mode. (CVS 5102)

FossilOrigin-Name: e98a7f87f91c62676f94ad5a0c4980ab929ca79d
This commit is contained in:
danielk1977
2008-05-07 19:11:03 +00:00
parent 2ca8bc08dd
commit df2566a33d
5 changed files with 107 additions and 39 deletions

View File

@@ -1,5 +1,5 @@
C Added\stest\scases\sfor\scorrupt\sSerialTypeLen\sheader\svalues,\sand\sadditional\scheck\sto\simprove\sdetection\sof\scorrupt\svalues.\s(CVS\s5101) C Fix\ssome\sproblems\swith\smulti-file\stransactions\sin\spersistent\sjournal\smode.\s(CVS\s5102)
D 2008-05-07T18:59:29 D 2008-05-07T19:11:03
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 8b9b8263852f0217157f9042b8e3dae7427ec739 F Makefile.in 8b9b8263852f0217157f9042b8e3dae7427ec739
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -85,7 +85,7 @@ F src/attach.c 496cc628b2e8c4d8db99d7c136761fcbebd8420b
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
F src/bitvec.c 8ec2212cfb702bc4f402c0b7ae7623d85320c714 F src/bitvec.c 8ec2212cfb702bc4f402c0b7ae7623d85320c714
F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2 F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2
F src/btree.c 556adb8f6905303d6ea00d35a0d1e1fe8a07efe2 F src/btree.c 7401bcbdabd87360351953e5009530c47e4fb305
F src/btree.h 8826591bf54dd35fcf2e67473d5f1bae253861c7 F src/btree.h 8826591bf54dd35fcf2e67473d5f1bae253861c7
F src/btreeInt.h dc04ee33d8eb84714b2acdf81336fbbf6e764530 F src/btreeInt.h dc04ee33d8eb84714b2acdf81336fbbf6e764530
F src/build.c a52d9d51341444a2131e3431608f245db80d9591 F src/build.c a52d9d51341444a2131e3431608f245db80d9591
@@ -121,7 +121,7 @@ F src/os_common.h e8b748b2f2ecc8a498e50bfe5d8721f189c19d2a
F src/os_os2.c 30c378b093d9c17387ebb0ebbf21b7d55a98202b F src/os_os2.c 30c378b093d9c17387ebb0ebbf21b7d55a98202b
F src/os_unix.c a810e2aefdaddacf479407f76f8f4ca381d231b2 F src/os_unix.c a810e2aefdaddacf479407f76f8f4ca381d231b2
F src/os_win.c 3a60bddd07ea6f8adb2314dd5996ac97b988f403 F src/os_win.c 3a60bddd07ea6f8adb2314dd5996ac97b988f403
F src/pager.c 547079d36fb3ca227e77e669268ea910c90774ef F src/pager.c fc173b7ee0b9ee630688466adacd506225417eb7
F src/pager.h 4f051fd856de6fd3c19aef5f82eace54122b9173 F src/pager.h 4f051fd856de6fd3c19aef5f82eace54122b9173
F src/parse.y fc4bd35c6088901f7c8daead26c6fb11c87d22e7 F src/parse.y fc4bd35c6088901f7c8daead26c6fb11c87d22e7
F src/pragma.c 2e4bb2e76e48a32750529fdc4bfe86ac5f54e01b F src/pragma.c 2e4bb2e76e48a32750529fdc4bfe86ac5f54e01b
@@ -351,7 +351,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19 F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
F test/jrnlmode.test 89acaa81503e349a49da73570b1a104f8fd93de7 F test/jrnlmode.test 5b650ba0630fc1089688e18bb7f0c9b8a33417ed
F test/jrnlmode2.test e48ec49320a3f849a5036e3551bf2394112a4aae F test/jrnlmode2.test e48ec49320a3f849a5036e3551bf2394112a4aae
F test/jrnlmode3.test c77f9d4095945f234dddd60ca0f73c24802ed0c1 F test/jrnlmode3.test c77f9d4095945f234dddd60ca0f73c24802ed0c1
F test/jrnlmode4.test 8ee031603fef8ed5deba0de8b012a82be6d5a6a0 F test/jrnlmode4.test 8ee031603fef8ed5deba0de8b012a82be6d5a6a0
@@ -634,7 +634,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P ed728104c8e77a5526a2fcb62fea577940731d90 P 530c6360610f737e85608b23ede2646d69d1bc9a
R 662f2572cbb8e504e1cbbe6b8cab0ff5 R b3765e5e9b24b682270f8e36c5449957
U shane U danielk1977
Z d87bdc7540c0da4b026b69711c54995d Z 58d2f3d9b823776050be08ba53db12b8

View File

@@ -1 +1 @@
530c6360610f737e85608b23ede2646d69d1bc9a e98a7f87f91c62676f94ad5a0c4980ab929ca79d

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give. ** May you share freely, never taking more than you give.
** **
************************************************************************* *************************************************************************
** $Id: btree.c,v 1.456 2008/05/07 07:13:16 danielk1977 Exp $ ** $Id: btree.c,v 1.457 2008/05/07 19:11:03 danielk1977 Exp $
** **
** This file implements a external (disk-based) database using BTrees. ** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information. ** See the header comment on "btreeInt.h" for additional information.
@@ -6839,7 +6839,6 @@ static int btreeCopyFile(Btree *pTo, Btree *pFrom){
rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage); rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pDbPage); rc = sqlite3PagerWrite(pDbPage);
}
if( rc==SQLITE_OK && i>nFromPage ){ if( rc==SQLITE_OK && i>nFromPage ){
/* Yeah. It seems wierd to call DontWrite() right after Write(). But /* Yeah. It seems wierd to call DontWrite() right after Write(). But
** that is because the names of those procedures do not exactly ** that is because the names of those procedures do not exactly
@@ -6854,6 +6853,7 @@ static int btreeCopyFile(Btree *pTo, Btree *pFrom){
} }
sqlite3PagerUnref(pDbPage); sqlite3PagerUnref(pDbPage);
} }
}
/* Overwrite the data in page i of the target database */ /* Overwrite the data in page i of the target database */
if( rc==SQLITE_OK && i!=iSkip && i<=nNewPage ){ if( rc==SQLITE_OK && i!=iSkip && i<=nNewPage ){

View File

@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while ** file simultaneously, or one process from reading the database while
** another is writing. ** another is writing.
** **
** @(#) $Id: pager.c,v 1.442 2008/05/07 12:45:41 drh Exp $ ** @(#) $Id: pager.c,v 1.443 2008/05/07 19:11:03 danielk1977 Exp $
*/ */
#ifndef SQLITE_OMIT_DISKIO #ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -968,15 +968,21 @@ static void seekJournalHdr(Pager *pPager){
** effect of invalidating the journal file and committing the ** effect of invalidating the journal file and committing the
** transaction. ** transaction.
*/ */
static int zeroJournalHdr(Pager *pPager){ static int zeroJournalHdr(Pager *pPager, int doTruncate){
int rc; int rc = SQLITE_OK;
static const char zeroHdr[28]; static const char zeroHdr[28];
if( pPager->journalOff ){
IOTRACE(("JZEROHDR %p\n", pPager)) IOTRACE(("JZEROHDR %p\n", pPager))
if( doTruncate ){
rc = sqlite3OsTruncate(pPager->jfd, 0);
}else{
rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
}
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->sync_flags); rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->sync_flags);
} }
}
return rc; return rc;
} }
@@ -1163,6 +1169,7 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
int len; int len;
int i; int i;
i64 jrnlOff; i64 jrnlOff;
i64 jrnlSize;
u32 cksum = 0; u32 cksum = 0;
char zBuf[sizeof(aJournalMagic)+2*4]; char zBuf[sizeof(aJournalMagic)+2*4];
@@ -1196,7 +1203,25 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
put32bits(&zBuf[4], cksum); put32bits(&zBuf[4], cksum);
memcpy(&zBuf[8], aJournalMagic, sizeof(aJournalMagic)); memcpy(&zBuf[8], aJournalMagic, sizeof(aJournalMagic));
rc = sqlite3OsWrite(pPager->jfd, zBuf, 8+sizeof(aJournalMagic), jrnlOff); rc = sqlite3OsWrite(pPager->jfd, zBuf, 8+sizeof(aJournalMagic), jrnlOff);
jrnlOff += 8+sizeof(aJournalMagic);
pPager->needSync = !pPager->noSync; pPager->needSync = !pPager->noSync;
/* If the pager is in peristent-journal mode, then the physical
** journal-file may extend past the end of the master-journal name
** and 8 bytes of magic data just written to the file. This is
** dangerous because the code to rollback a hot-journal file
** will not be able to find the master-journal name to determine
** whether or not the journal is hot.
**
** Easiest thing to do in this scenario is to truncate the journal
** file to the required size.
*/
if( (rc==SQLITE_OK)
&& (rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))==SQLITE_OK
&& jrnlSize>jrnlOff
){
rc = sqlite3OsTruncate(pPager->jfd, jrnlOff);
}
return rc; return rc;
} }
@@ -1358,7 +1383,7 @@ static void pagerUnlockAndRollback(Pager *p){
** This might give a performance improvement on windows where opening ** This might give a performance improvement on windows where opening
** a file is an expensive operation. ** a file is an expensive operation.
*/ */
static int pager_end_transaction(Pager *pPager){ static int pager_end_transaction(Pager *pPager, int hasMaster){
PgHdr *pPg; PgHdr *pPg;
int rc = SQLITE_OK; int rc = SQLITE_OK;
int rc2 = SQLITE_OK; int rc2 = SQLITE_OK;
@@ -1374,7 +1399,7 @@ static int pager_end_transaction(Pager *pPager){
if( pPager->journalOpen ){ if( pPager->journalOpen ){
if( (pPager->exclusiveMode || if( (pPager->exclusiveMode ||
pPager->journalMode==PAGER_JOURNALMODE_PERSIST) pPager->journalMode==PAGER_JOURNALMODE_PERSIST)
&& (rc = zeroJournalHdr(pPager))==SQLITE_OK ){ && (rc = zeroJournalHdr(pPager, hasMaster))==SQLITE_OK ){
pPager->journalOff = 0; pPager->journalOff = 0;
pPager->journalStarted = 0; pPager->journalStarted = 0;
}else{ }else{
@@ -1908,7 +1933,7 @@ end_playback:
rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
} }
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = pager_end_transaction(pPager); rc = pager_end_transaction(pPager, zMaster[0]!='\0');
} }
if( rc==SQLITE_OK && zMaster[0] ){ if( rc==SQLITE_OK && zMaster[0] ){
/* If there was a master journal and this routine will return success, /* If there was a master journal and this routine will return success,
@@ -3960,7 +3985,7 @@ static int pager_open_journal(Pager *pPager){
rc = sqlite3PagerStmtBegin(pPager); rc = sqlite3PagerStmtBegin(pPager);
} }
if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && rc!=SQLITE_IOERR_NOMEM ){ if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && rc!=SQLITE_IOERR_NOMEM ){
rc = pager_end_transaction(pPager); rc = pager_end_transaction(pPager, 0);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = SQLITE_FULL; rc = SQLITE_FULL;
} }
@@ -4759,7 +4784,7 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager){
return SQLITE_OK; return SQLITE_OK;
} }
assert( pPager->state==PAGER_SYNCED || !pPager->dirtyCache ); assert( pPager->state==PAGER_SYNCED || !pPager->dirtyCache );
rc = pager_end_transaction(pPager); rc = pager_end_transaction(pPager, pPager->setMaster);
rc = pager_error(pPager, rc); rc = pager_error(pPager, rc);
pagerLeave(pPager); pagerLeave(pPager);
return rc; return rc;
@@ -4818,7 +4843,7 @@ int sqlite3PagerRollback(Pager *pPager){
pagerEnter(pPager); pagerEnter(pPager);
if( !pPager->dirtyCache || !pPager->journalOpen ){ if( !pPager->dirtyCache || !pPager->journalOpen ){
rc = pager_end_transaction(pPager); rc = pager_end_transaction(pPager, pPager->setMaster);
pagerLeave(pPager); pagerLeave(pPager);
return rc; return rc;
} }
@@ -4833,7 +4858,7 @@ int sqlite3PagerRollback(Pager *pPager){
if( pPager->state==PAGER_RESERVED ){ if( pPager->state==PAGER_RESERVED ){
int rc2; int rc2;
rc = pager_playback(pPager, 0); rc = pager_playback(pPager, 0);
rc2 = pager_end_transaction(pPager); rc2 = pager_end_transaction(pPager, pPager->setMaster);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = rc2; rc = rc2;
} }

View File

@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The focus # This file implements regression tests for SQLite library. The focus
# of these tests is the journal mode pragma. # of these tests is the journal mode pragma.
# #
# $Id: jrnlmode.test,v 1.1 2008/04/19 20:34:19 drh Exp $ # $Id: jrnlmode.test,v 1.2 2008/05/07 19:11:03 danielk1977 Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -152,5 +152,48 @@ ifcapable attach {
} {} } {}
} }
ifcapable attach {
file delete -force test2.db
do_test jrnlmode-2.1 {
execsql {
ATTACH 'test2.db' AS aux;
PRAGMA main.journal_mode = persist;
PRAGMA aux.journal_mode = persist;
CREATE TABLE abc(a, b, c);
CREATE TABLE aux.def(d, e, f);
}
execsql {
BEGIN;
INSERT INTO abc VALUES(1, 2, 3);
INSERT INTO def VALUES(4, 5, 6);
COMMIT;
}
list [file exists test.db-journal] [file exists test2.db-journal]
} {1 1}
do_test jrnlmode-2.2 {
file size test.db-journal
} {0}
do_test jrnlmode-2.3 {
execsql {
SELECT * FROM abc;
}
} {1 2 3}
do_test jrnlmode-2.4 {
file size test.db-journal
} {0}
do_test jrnlmode-2.5 {
execsql {
SELECT * FROM def;
}
} {4 5 6}
}
finish_test finish_test