Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | If after obtaining an exclusive lock to rollback a hot-journal file it is found that the journal file has been deleted, do not return an SQLITE_BUSY error. Just downgrade the lock and continue with the current operation. This eliminates a spurious SQLITE_BUSY error caused by a race condition. (CVS 6792) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9a0666003764774b0bf861687002f8db |
User & Date: | danielk1977 2009-06-20 11:54:39.000 |
Context
2009-06-20
| ||
18:52 | When recovering from the error-state in pagerSharedLock(), do not search for a hot-journal in the file-system if the pager is configured to use an anonymous temp file as the journal. (CVS 6793) (check-in: 4b46805cbc user: danielk1977 tags: trunk) | |
11:54 | If after obtaining an exclusive lock to rollback a hot-journal file it is found that the journal file has been deleted, do not return an SQLITE_BUSY error. Just downgrade the lock and continue with the current operation. This eliminates a spurious SQLITE_BUSY error caused by a race condition. (CVS 6792) (check-in: 9a06660037 user: danielk1977 tags: trunk) | |
2009-06-19
| ||
22:50 | Improved documentation on the VFS methods. Ticket #3925. (CVS 6791) (check-in: f66fc7713e user: drh tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.599 2009/06/20 11:54:39 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" /* ** Macros for troubleshooting. Normally turned off */ |
︙ | ︙ | |||
3567 3568 3569 3570 3571 3572 3573 | ** IO error occurs while locking the database, checking for a hot-journal ** file or rolling back a journal file, the IO error code is returned. */ static int pagerSharedLock(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ int isErrorReset = 0; /* True if recovering from error state */ | | | | | < | < < | < | 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 | ** IO error occurs while locking the database, checking for a hot-journal ** file or rolling back a journal file, the IO error code is returned. */ static int pagerSharedLock(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ int isErrorReset = 0; /* True if recovering from error state */ /* If this database has no outstanding page references and is in an ** error-state, this is a chance to clear the error. Discard the ** contents of the pager-cache and rollback any hot journal in the ** file-system. */ if( !MEMDB && sqlite3PcacheRefCount(pPager->pPCache)==0 && pPager->errCode ){ isErrorReset = 1; pPager->errCode = SQLITE_OK; pager_reset(pPager); } /* If the pager is still in an error state, do not proceed. The error ** state will be cleared at some point in the future when all page ** references are dropped and the cache can be discarded. |
︙ | ︙ | |||
3658 3659 3660 3661 3662 3663 3664 | rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ rc = SQLITE_CANTOPEN; sqlite3OsClose(pPager->jfd); } }else{ | | | > > > | > | | | | > | 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 | rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ rc = SQLITE_CANTOPEN; sqlite3OsClose(pPager->jfd); } }else{ /* If the journal does not exist, it usually means that some ** other connection managed to get in and roll it back before ** this connection obtained the exclusive lock above. Or, it ** may mean that the pager was in the error-state when this ** function was called and the journal file does not exist. */ rc = pager_end_transaction(pPager, 0); } } } if( rc!=SQLITE_OK ){ goto failed; } /* TODO: Why are these cleared here? Is it necessary? */ pPager->journalStarted = 0; pPager->journalOff = 0; pPager->setMaster = 0; pPager->journalHdr = 0; /* Playback and delete the journal. Drop the database write ** lock and reacquire the read lock. Purge the cache before ** playing back the hot-journal so that we don't end up with ** an inconsistent cache. */ if( isOpen(pPager->jfd) ){ rc = pager_playback(pPager, 1); if( rc!=SQLITE_OK ){ rc = pager_error(pPager, rc); goto failed; } } assert( (pPager->state==PAGER_SHARED) || (pPager->exclusiveMode && pPager->state>PAGER_SHARED) ); } if( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 ){ |
︙ | ︙ |