diff --git a/manifest b/manifest index 21686af482..7a5ca50dcc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sa\sreturn\scode\sbeing\signored\sin\sinsertCell().\s(CVS\s6816) -D 2009-06-25T16:11:05 +C Avoid\swriting\sthe\s8-byte\sjournal-header\smagic\suntil\sthe\sjournal-header\sis\ssynced.\sIn\spersistent\sjournal-mode,\sthis\sprevents\sany\sold\scontent\sthat\sfollows\san\sunsynced\sjournal-header\sfrom\sbeing\sinterpreted\sas\spart\sof\sthe\srollback\sjournal.\s(CVS\s6817) +D 2009-06-26T07:12:07 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 8b8fb7823264331210cddf103831816c286ba446 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -146,7 +146,7 @@ F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5 F src/os_unix.c b64129c296e480c2827606e206ea51bb30904626 F src/os_win.c 725c38a524d168ce280446ad8761d731bc516405 -F src/pager.c 85cb38f0403881f827c30384c51a7a6e54c6d457 +F src/pager.c aff52317d450d0bdb93699f7213c09f51031c7e8 F src/pager.h 5aec418bf99f568b92ae82816a1463400513726d F src/parse.y b6e99f4208a34eb83c62f20dd67f8d9058e86768 F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d @@ -509,7 +509,7 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a F test/rdonly.test bd054831f8a3078e765a0657e247182486f0cb47 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/rollback.test 1f70ab4301d8d105d41438a436cad1fc8897f5e5 +F test/rollback.test 73355ad4492ff9a3a31e61c7e5eb5e01a1de94ca F test/rowhash.test 97f56043ba11f0679920416c0cdbc72e5272267b F test/rowid.test 1c8fc43c60d273e6ea44dfb992db587f3164312c F test/rtree.test 55466a200af3591946c5da77ad5dbfbc1e5e05f9 @@ -626,7 +626,7 @@ F test/tkt3357.test 77c37c6482b526fe89941ce951c22d011f5922ed F test/tkt3419.test 1bbf36d7ea03b638c15804251287c2391f5c1f6b F test/tkt3424.test 61f831bd2b071bd128fa5d00fbda57e656ca5812 F test/tkt3442.test 89d7b41a4ec4d9d9b40ab8575d648579fb13cb4f -F test/tkt3457.test d311ecafbc9aaf876ac8e4a6a58ff2ee01739125 +F test/tkt3457.test edbf54b05cbe5165f00192becbd621038f1615e4 F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19 F test/tkt3472.test 98c7e54b8fef2b1266a552a66c8e5d88a6908d1d F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218 @@ -737,7 +737,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 -P 6e9140a729bd26dd102e603abf6ea16d67e8546e -R 9a284a565af8f19e3d2c682d0105f4bb +P bb5f1c01435dcc1ea056f0d149f750fa7812f652 +R 383a763ea1f6b28e78c47a340c8dfba5 U danielk1977 -Z b70ba767168ad615a996157a1ab667b5 +Z f3d299840c7ab8a7d6b950df9de8e6fa diff --git a/manifest.uuid b/manifest.uuid index 7d2d33aeae..872627d0ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb5f1c01435dcc1ea056f0d149f750fa7812f652 \ No newline at end of file +a5ecffcf025da2fcb241e83c7bebc1095a3b51d6 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index ebf42ef048..608e3b7690 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.601 2009/06/22 05:43:24 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.602 2009/06/26 07:12:07 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -757,7 +757,6 @@ static int writeJournalHdr(Pager *pPager){ } pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); - memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); /* ** Write the nRec Field - the number of page records that follow this @@ -783,8 +782,10 @@ static int writeJournalHdr(Pager *pPager){ if( (pPager->noSync) || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) ){ + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); }else{ + zHeader[0] = '\0'; put32bits(&zHeader[sizeof(aJournalMagic)], 0); } @@ -852,6 +853,7 @@ static int writeJournalHdr(Pager *pPager){ */ static int readJournalHdr( Pager *pPager, /* Pager object */ + int isHot, i64 journalSize, /* Size of the open journal file in bytes */ u32 *pNRec, /* OUT: Value read from the nRec field */ u32 *pDbSize /* OUT: Value of original database size field */ @@ -877,12 +879,14 @@ static int readJournalHdr( ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise, ** proceed. */ - rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); - if( rc ){ - return rc; - } - if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ - return SQLITE_DONE; + if( isHot || iHdrOff!=pPager->journalHdr ){ + rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); + if( rc ){ + return rc; + } + if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ + return SQLITE_DONE; + } } /* Read the first three 32-bit fields of the journal header: The nRec @@ -1977,7 +1981,7 @@ static int pager_playback(Pager *pPager, int isHot){ ** it is corrupted, then a process must of failed while writing it. ** This indicates nothing more needs to be rolled back. */ - rc = readJournalHdr(pPager, szJ, &nRec, &mxPg); + rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg); if( rc!=SQLITE_OK ){ if( rc==SQLITE_DONE ){ rc = SQLITE_OK; @@ -2197,7 +2201,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ u32 ii; /* Loop counter */ u32 nJRec = 0; /* Number of Journal Records */ u32 dummy; - rc = readJournalHdr(pPager, szJ, &nJRec, &dummy); + rc = readJournalHdr(pPager, 0, szJ, &nJRec, &dummy); assert( rc!=SQLITE_DONE ); /* @@ -2764,7 +2768,9 @@ static int syncJournal(Pager *pPager){ ** of the nRec field of the most recently written journal header. ** This field will be updated following the xSync() operation ** on the journal file. */ - i64 iNRecOffset = pPager->journalHdr + sizeof(aJournalMagic); + u8 zHeader[sizeof(aJournalMagic)+4]; + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); /* This block deals with an obscure problem. If the last connection ** that wrote to this database was operating in persistent-journal @@ -2817,7 +2823,9 @@ static int syncJournal(Pager *pPager){ if( rc!=SQLITE_OK ) return rc; } IOTRACE(("JHDR %p %lld %d\n", pPager, iNRecOffset, 4)); - rc = write32bits(pPager->jfd, iNRecOffset, pPager->nRec); + rc = sqlite3OsWrite( + pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr + ); if( rc!=SQLITE_OK ) return rc; } if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ diff --git a/test/rollback.test b/test/rollback.test index b526a62a05..93d12468dc 100644 --- a/test/rollback.test +++ b/test/rollback.test @@ -13,7 +13,7 @@ # caused by an ON CONFLICT ROLLBACK clause aborts any other pending # statements. # -# $Id: rollback.test,v 1.10 2008/10/17 18:51:53 danielk1977 Exp $ +# $Id: rollback.test,v 1.11 2009/06/26 07:12:07 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -114,6 +114,13 @@ if {$tcl_platform(platform) == "unix" fconfigure $fd -encoding binary -translation binary seek $fd $iOffset puts -nonewline $fd $zAppend + + # Also, fix the first journal-header in the journal-file. Because the + # journal file has not yet been synced, the 8-byte magic string at the + # start of the first journal-header has not been written by SQLite. + # So write it now. + seek $fd 0 + puts -nonewline $fd "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" close $fd # Open a handle on testA.db and use it to query the database. At one diff --git a/test/tkt3457.test b/test/tkt3457.test index b173afe2ee..71eb424640 100644 --- a/test/tkt3457.test +++ b/test/tkt3457.test @@ -10,7 +10,7 @@ #*********************************************************************** # This file implements regression tests for SQLite library. # -# $Id: tkt3457.test,v 1.2 2009/06/05 17:09:12 drh Exp $ +# $Id: tkt3457.test,v 1.3 2009/06/26 07:12:07 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -49,6 +49,16 @@ do_test tkt3457-1.1 { file copy -force test.db bak.db file copy -force test.db-journal bak.db-journal + # Fix the first journal-header in the journal-file. Because the + # journal file has not yet been synced, the 8-byte magic string at the + # start of the first journal-header has not been written by SQLite. + # So write it now. + set fd [open bak.db-journal a+] + fconfigure $fd -encoding binary -translation binary + seek $fd 0 + puts -nonewline $fd "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" + close $fd + execsql COMMIT } {}