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
This commit is contained in:
drh 2009-02-03 22:51:06 +00:00
parent 6231286dfe
commit d3a5c50ec7
4 changed files with 38 additions and 16 deletions

View File

@ -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

View File

@ -1 +1 @@
76f23a4394574e31f237e55c641bc70534f44d97
7f827ba9d7af2dfe44aed386b4407716c85daf5e

View File

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

View File

@ -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; u<nRec; u++){
if( needPagerReset ){
pager_reset(pPager);
needPagerReset = 0;
}
rc = pager_playback_one_page(pPager, 1, &pPager->journalOff, 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);