Fix a problem where a process in exclusive mode could delete a hot-journal file without rolling it back from within sqlite3_close() or DETACH. This problem was introduced by the previous commit, it is not present in any releases.

FossilOrigin-Name: 51a613950824698687c0db83b7884db33d45f7f5
This commit is contained in:
dan 2010-04-12 17:08:44 +00:00
parent 47f18f7294
commit eada58aa49
3 changed files with 37 additions and 25 deletions

View File

@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Reset\sthe\ssimulated\sdevice\sin\sthe\stest\sharness\sto\sits\sdefault\nconfiguration\swhenever\sit\sis\srestarted.
D 2010-04-12T14:51:10
C Fix\sa\sproblem\swhere\sa\sprocess\sin\sexclusive\smode\scould\sdelete\sa\shot-journal\sfile\swithout\srolling\sit\sback\sfrom\swithin\ssqlite3_close()\sor\sDETACH.\sThis\sproblem\swas\sintroduced\sby\sthe\sprevious\scommit,\sit\sis\snot\spresent\sin\sany\sreleases.
D 2010-04-12T17:08:45
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -155,7 +152,7 @@ F src/os_common.h 240c88b163b02c21a9f21f87d49678a0aa21ff30
F src/os_os2.c 75a8c7b9a00a2cf1a65f9fa4afbc27d46634bb2f
F src/os_unix.c 148d2f625db3727250c0b880481ae7630b6d0eb0
F src/os_win.c 1c7453c2df4dab26d90ff6f91272aea18bcf7053
F src/pager.c bde3cc79424853c5e4b14bff0d465efe8d11d31a
F src/pager.c da5ed17bb729c27a16c45fe38e9531c240a1c6a4
F src/pager.h ef8a2cf10084f60ab45ee2dfded8bf8b0c655ddf
F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf
@ -800,14 +797,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 0906597698b697ab2993a460f257e326cb58e475
R f5bee91a8ab0e92ee4807bc0cf920ec9
U drh
Z d2267b85d8f489a9efc2d0f94542979f
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFLwzNhoxKgR168RlERArhMAJ9Jdcg74XXFdQNQj20xuFFVNZ+ZIACdG1c6
NJ+fuuzqw7g8dHQ7gRK1k0U=
=3V5r
-----END PGP SIGNATURE-----
P 562d20e662da474ea326165730ecfdfcf9b414ee
R 8333162e7f153eb6e6f78b7cbd811ab4
U dan
Z 65fbb5bed20edd048b9a7fedeedd0df1

View File

@ -1 +1 @@
562d20e662da474ea326165730ecfdfcf9b414ee
51a613950824698687c0db83b7884db33d45f7f5

View File

@ -2698,6 +2698,31 @@ void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
assertTruncateConstraint(pPager);
}
/*
** This function is called before attempting a hot-journal rollback. It
** syncs the journal file to disk, then sets pPager->journalHdr to the
** size of the journal file so that the pager_playback() routine knows
** that the entire journal file has been synced.
**
** Syncing a hot-journal to disk before attempting to roll it back ensures
** that if a power-failure occurs during the rollback, the process that
** attempts rollback following system recovery sees the same journal
** content as this process.
**
** If everything goes as planned, SQLITE_OK is returned. Otherwise,
** an SQLite error code.
*/
static int pagerSyncHotJournal(Pager *pPager){
int rc = SQLITE_OK;
if( !pPager->noSync ){
rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL);
}
if( rc==SQLITE_OK ){
rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr);
}
return rc;
}
/*
** Shutdown the page cache. Free all memory and close all files.
**
@ -2727,7 +2752,9 @@ int sqlite3PagerClose(Pager *pPager){
** be played back into the database. If a power failure occurs while
** this is happening, the database may become corrupt.
*/
pPager->journalHdr = -1;
if( isOpen(pPager->jfd) ){
pPager->errCode = pagerSyncHotJournal(pPager);
}
pagerUnlockAndRollback(pPager);
}
sqlite3EndBenignMalloc();
@ -3770,12 +3797,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
** the journal before playing it back.
*/
if( isOpen(pPager->jfd) ){
if( !pPager->noSync ){
rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL);
}
if( rc==SQLITE_OK ){
rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr);
}
rc = pagerSyncHotJournal(pPager);
if( rc==SQLITE_OK ){
rc = pager_playback(pPager, 1);
}