From d3a5c50ec758b4b410b2d0217b431cdf890cf9fd Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Feb 2009 22:51:06 +0000 Subject: [PATCH] Correction to check-ins (6246) and (6247): The backup object might not hold a valid destination connection pointer. Also, do not reset the page cache when establishing a read-lock while there is a persistent or truncated journal, only if there is a journal that really needs to rollback. Otherwise backups always reset whenever the source database file is read. (CVS 6248) FossilOrigin-Name: 7f827ba9d7af2dfe44aed386b4407716c85daf5e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/backup.c | 22 ++++++++++++++++------ src/pager.c | 16 ++++++++++++++-- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index e5ef658893..ebe65090fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\sbackup\smust\sclear\sthe\sinternal\sschema\sof\sthe\sdestination\sdatabase\sso\nthat\sthe\sschema\swill\sbe\sreloaded\sfor\sthe\snext\ssqlite3_prepare()\s(CVS\s6247) -D 2009-02-03T22:17:42 +C Correction\sto\scheck-ins\s(6246)\sand\s(6247):\s\sThe\sbackup\sobject\smight\snot\nhold\sa\svalid\sdestination\sconnection\spointer.\s\sAlso,\sdo\snot\sreset\sthe\npage\scache\swhen\sestablishing\sa\sread-lock\swhile\sthere\sis\sa\spersistent\nor\struncated\sjournal,\sonly\sif\sthere\sis\sa\sjournal\sthat\sreally\sneeds\sto\nrollback.\s\sOtherwise\sbackups\salways\sreset\swhenever\sthe\ssource\sdatabase\nfile\sis\sread.\s(CVS\s6248) +D 2009-02-03T22:51:06 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in c7a5a30fb6852bd7839b1024e1661da8549878ee F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -101,7 +101,7 @@ F src/alter.c 0ec29744c36c6e976596ce38c16289ebc5dc94db F src/analyze.c c86fd6a1425b22b3a46ce72ad403e4280026364f F src/attach.c 81d37d1948f409146a7b22b96998fd90649d1fd3 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 -F src/backup.c 0491573a4ce3bb8cfb5c6da32f0d42d04b79407a +F src/backup.c ddae8526793b0e2fab7d9e686b63c766218dfabe F src/bitvec.c 44f7059ac1f874d364b34af31b9617e52223ba75 F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a F src/btree.c 800a065686c49a0cdefc933779a750a7c3c0509f @@ -143,7 +143,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60 F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5 F src/os_unix.c f0fce3042011d462b8ae633564a5668260bd3636 F src/os_win.c ec133f2a3c0da786995ea09ba67056af8f18cc2e -F src/pager.c 9e7c6db1635be2caf31ff3d407ecb2e145f89a8a +F src/pager.c b8f4ae64cb179618da4bc08989c7bd5a50a5e12a F src/pager.h 0c9f3520c00d8a3b8e792ca56c9a11b6b02b4b0f F src/parse.y 4f4d16aee0d11f69fec2adb77dac88878043ed8d F src/pcache.c fcf7738c83c4d3e9d45836b2334c8a368cc41274 @@ -700,7 +700,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 5f6c06b974f26532264467ace603b6f1f830fba9 -R 56f7689073a568269b1239d4961d1fb6 +P 76f23a4394574e31f237e55c641bc70534f44d97 +R 5bdad9729a46d9221b6bdee25bf60220 U drh -Z b3307c22d24e3af571a952d745c2e4d1 +Z a3b0a3e20a12c71211622ecafa1dae99 diff --git a/manifest.uuid b/manifest.uuid index 110ee77b88..a879c689c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -76f23a4394574e31f237e55c641bc70534f44d97 \ No newline at end of file +7f827ba9d7af2dfe44aed386b4407716c85daf5e \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 8ca360bef4..340c93504e 100644 --- a/src/backup.c +++ b/src/backup.c @@ -12,7 +12,7 @@ ** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. ** -** $Id: backup.c,v 1.3 2009/02/03 22:17:42 drh Exp $ +** $Id: backup.c,v 1.4 2009/02/03 22:51:06 drh Exp $ */ #include "sqliteInt.h" #include "btreeInt.h" @@ -251,7 +251,9 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ sqlite3_mutex_enter(p->pSrcDb->mutex); sqlite3BtreeEnter(p->pSrc); - sqlite3_mutex_enter(p->pDestDb->mutex); + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } rc = p->rc; if( rc==SQLITE_OK ){ @@ -324,7 +326,9 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ ** same schema version. */ sqlite3BtreeUpdateMeta(p->pDest, 1, p->iDestSchema+1); - sqlite3ResetInternalSchema(p->pDestDb, 0); + if( p->pDestDb ){ + sqlite3ResetInternalSchema(p->pDestDb, 0); + } /* Set nDestTruncate to the final number of pages in the destination ** database. The complication here is that the destination page @@ -408,7 +412,9 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ p->rc = rc; } } - sqlite3_mutex_leave(p->pDestDb->mutex); + if( p->pDestDb ){ + sqlite3_mutex_leave(p->pDestDb->mutex); + } sqlite3BtreeLeave(p->pSrc); sqlite3_mutex_leave(p->pSrcDb->mutex); return rc; @@ -426,7 +432,9 @@ int sqlite3_backup_finish(sqlite3_backup *p){ sqlite3_mutex_enter(p->pSrcDb->mutex); sqlite3BtreeEnter(p->pSrc); mutex = p->pSrcDb->mutex; - sqlite3_mutex_enter(p->pDestDb->mutex); + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } /* Detach this backup from the source pager. */ if( p->pDestDb ){ @@ -446,7 +454,9 @@ int sqlite3_backup_finish(sqlite3_backup *p){ sqlite3Error(p->pDestDb, rc, 0); /* Exit the mutexes and free the backup context structure. */ - sqlite3_mutex_leave(p->pDestDb->mutex); + if( p->pDestDb ){ + sqlite3_mutex_leave(p->pDestDb->mutex); + } sqlite3BtreeLeave(p->pSrc); if( p->pDestDb ){ sqlite3_free(p); diff --git a/src/pager.c b/src/pager.c index 10c09e7499..302a036ad2 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.562 2009/02/03 16:51:25 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.563 2009/02/03 22:51:06 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1895,6 +1895,13 @@ static void setSectorSize(Pager *pPager){ ** ** If an I/O or malloc() error occurs, the journal-file is not deleted ** and an error code is returned. +** +** The isHot parameter indicates that we are trying to rollback a journal +** that might be a hot journal. Or, it could be that the journal is +** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE. +** If the journal really is hot, reset the pager cache prior rolling +** back any content. If the journal is merely persistent, no reset is +** needed. */ static int pager_playback(Pager *pPager, int isHot){ sqlite3_vfs *pVfs = pPager->pVfs; @@ -1905,6 +1912,7 @@ static int pager_playback(Pager *pPager, int isHot){ int rc; /* Result code of a subroutine */ int res = 1; /* Value returned by sqlite3OsAccess() */ char *zMaster = 0; /* Name of master journal file if any */ + int needPagerReset; /* True to reset page prior to first page rollback */ /* Figure out how many records are in the journal. Abort early if ** the journal is empty. @@ -1936,6 +1944,7 @@ static int pager_playback(Pager *pPager, int isHot){ goto end_playback; } pPager->journalOff = 0; + needPagerReset = isHot; /* This loop terminates either when a readJournalHdr() or ** pager_playback_one_page() call returns SQLITE_DONE or an IO error @@ -2005,6 +2014,10 @@ static int pager_playback(Pager *pPager, int isHot){ ** database file and/or page cache. */ for(u=0; ujournalOff, 0, 0); if( rc!=SQLITE_OK ){ if( rc==SQLITE_DONE ){ @@ -3557,7 +3570,6 @@ static int pagerSharedLock(Pager *pPager){ ** playing back the hot-journal so that we don't end up with ** an inconsistent cache. */ - pager_reset(pPager); rc = pager_playback(pPager, 1); if( rc!=SQLITE_OK ){ rc = pager_error(pPager, rc);