mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Have the pager change to at least WRITER_CACHEMOD state before marking any pages as dirty (instead of immediately after). Otherwise, if an error occurs, the pager may be left in WRITER_LOCKED state with dirty pages in the cache.
FossilOrigin-Name: 471a4efbb7e5e32b144b2e2128337a6af950b8f5
This commit is contained in:
32
src/pager.c
32
src/pager.c
@@ -5205,29 +5205,29 @@ static int pager_write(PgHdr *pPg){
|
||||
|
||||
CHECK_PAGE(pPg);
|
||||
|
||||
/* The journal file needs to be opened. Higher level routines have already
|
||||
** obtained the necessary locks to begin the write-transaction, but the
|
||||
** rollback journal might not yet be open. Open it now if this is the case.
|
||||
**
|
||||
** This is done before calling sqlite3PcacheMakeDirty() on the page.
|
||||
** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then
|
||||
** an error might occur and the pager would end up in WRITER_LOCKED state
|
||||
** with pages marked as dirty in the cache.
|
||||
*/
|
||||
if( pPager->eState==PAGER_WRITER_LOCKED ){
|
||||
rc = pager_open_journal(pPager);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
|
||||
assert( assert_pager_state(pPager) );
|
||||
|
||||
/* Mark the page as dirty. If the page has already been written
|
||||
** to the journal then we can return right away.
|
||||
*/
|
||||
sqlite3PcacheMakeDirty(pPg);
|
||||
if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){
|
||||
assert( !pagerUseWal(pPager) );
|
||||
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
|
||||
}else{
|
||||
|
||||
/* If we get this far, it means that the page needs to be
|
||||
** written to the transaction journal or the checkpoint journal
|
||||
** or both.
|
||||
**
|
||||
** Higher level routines have already obtained the necessary locks
|
||||
** to begin the write-transaction, but the rollback journal might not
|
||||
** yet be open. Open it now if this is the case.
|
||||
*/
|
||||
if( pPager->eState==PAGER_WRITER_LOCKED ){
|
||||
rc = pager_open_journal(pPager);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
|
||||
assert( assert_pager_state(pPager) );
|
||||
|
||||
/* The transaction journal now exists and we have a RESERVED or an
|
||||
** EXCLUSIVE lock on the main database file. Write the current page to
|
||||
|
Reference in New Issue
Block a user