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

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

@@ -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);
}