Modify the hasHotJournal() routine to return a false-positive if it is

unable to open the journal file to check its header due to a race
condition.  Processing downstream of hasHotJournal() already knows how to
deal with false-positives.  Ticket #3883. (CVS 6687)

FossilOrigin-Name: d6b5d8e1ab8e5d3348ace560230702718a2a8af9
This commit is contained in:
drh 2009-05-29 00:30:30 +00:00
parent b74b101766
commit f0039ad815
3 changed files with 35 additions and 10 deletions

View File

@ -1,5 +1,5 @@
C Remove\sreferences\sto\sdeleted\sfunction\ssqlite3ExprRegister().\s\sChanges\sto\nthe\sexpr.c\ssource\smodule\sto\spromote\sbetter\stesting.\s(CVS\s6686)
D 2009-05-28T21:04:38
C Modify\sthe\shasHotJournal()\sroutine\sto\sreturn\sa\sfalse-positive\sif\sit\sis\nunable\sto\sopen\sthe\sjournal\sfile\sto\scheck\sits\sheader\sdue\sto\sa\srace\ncondition.\s\sProcessing\sdownstream\sof\shasHotJournal()\salready\sknows\show\sto\ndeal\swith\sfalse-positives.\s\sTicket\s#3883.\s(CVS\s6687)
D 2009-05-29T00:30:30
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
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 e55d977c516ed880a2f83f0610b019efd9f8bc06
F src/os_win.c 725c38a524d168ce280446ad8761d731bc516405
F src/pager.c 8bf62fefc7afefc065d37611ebfd1fe0e1c2eb39
F src/pager.c 6c0fc1c078fcdeefe969a36a186fb147c459c600
F src/pager.h 73f481a308a873ccd626d97331c081db3b53e2e5
F src/parse.y 07690df997d50b3fdb5e5121e5a27f1a080db13d
F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d
@ -731,7 +731,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 3b46142532934d17aa136c2e56e58e7828df0f54
R 6a3a4185326252490b36e399fe92cbcc
P 6ae4ad6ebee4db88c411df97bb1de574708dd53c
R 3928c5dff5e5480b3ec95781956d3c18
U drh
Z 2830ef720e4e0990284e68ba861f067a
Z a92eea42d5738ee5a30dde1c2bfece9a

View File

@ -1 +1 @@
6ae4ad6ebee4db88c411df97bb1de574708dd53c
d6b5d8e1ab8e5d3348ace560230702718a2a8af9

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.587 2009/05/13 07:52:06 danielk1977 Exp $
** @(#) $Id: pager.c,v 1.588 2009/05/29 00:30:30 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@ -3384,18 +3384,31 @@ static int hasHotJournal(Pager *pPager, int *pExists){
rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
if( rc==SQLITE_OK && exists ){
int locked; /* True if some process holds a RESERVED lock */
/* Race condition here: Another process might have been holding the
** the RESERVED lock and have a journal open at the sqlite3OsAccess()
** call above, but then delete the journal and drop the lock before
** we get to the following sqlite3OsCheckReservedLock() call. If that
** is the case, this routine might think there is a hot journal when
** in fact there is none. This results in a false-positive which will
** be dealt with by the playback routine under. Ticket #3883.
*/
rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
if( rc==SQLITE_OK && !locked ){
int nPage;
/* Check the size of the database file. If it consists of 0 pages,
** then delete the journal file. See the header comment above for
** the reasoning here.
** the reasoning here. Delete the obsolete journal file under
** a RESERVED lock to avoid race conditions.
*/
rc = sqlite3PagerPagecount(pPager, &nPage);
if( rc==SQLITE_OK ){
if( nPage==0 ){
rc = sqlite3OsDelete(pVfs, pPager->zJournal, 0);
if( sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){
sqlite3OsDelete(pVfs, pPager->zJournal, 0);
sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
}
}else{
/* The journal file exists and no other connection has a reserved
** or greater lock on the database file. Now check that there is
@ -3413,6 +3426,18 @@ static int hasHotJournal(Pager *pPager, int *pExists){
}
sqlite3OsClose(pPager->jfd);
*pExists = (first!=0);
}else{
/* If we cannot open the rollback journal file in order to see if
** its has a zero header, that might be due to an I/O error, or
** it might be due to the race condition described above and in
** ticket #3883. Either way, assume that the journal is hot.
** This might be a false positive. But if it is, then the
** automatic journal playback and recovery mechanism will deal
** with it under an EXCLUSIVE lock where we do not need to
** worry so much with race conditions.
*/
*pExists = 1;
rc = SQLITE_OK;
}
}
}