When locking a database file, check if any backup objects need to be restarted even if the page cache is empty. Ticket #3858. (CVS 6632)
FossilOrigin-Name: 90309008c35494c7a075fe76f7eb96b09a01d01b
This commit is contained in:
parent
8b4aff3919
commit
e70f4f6482
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Remove\sdebugging\scomments\sleft\sin\sthe\sprior\scheck-in\sby\smistake.\s(CVS\s6631)
|
||||
D 2009-05-12T18:00:38
|
||||
C When\slocking\sa\sdatabase\sfile,\scheck\sif\sany\sbackup\sobjects\sneed\sto\sbe\srestarted\seven\sif\sthe\spage\scache\sis\sempty.\sTicket\s#3858.\s(CVS\s6632)
|
||||
D 2009-05-13T07:52:06
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -103,7 +103,7 @@ F src/alter.c f0430ee68d8d80711155ddf27876abf218903b03
|
||||
F src/analyze.c e239496cfb5394ac8867f1c112905ddab8d01cd9
|
||||
F src/attach.c 3b99611f04926fc69c35b1145603fc3ddb0ca967
|
||||
F src/auth.c 98db07c2088455797678eb1031f42d4d94d18a71
|
||||
F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d
|
||||
F src/backup.c 91aaf9f065b923f33d8739f44f71ab8d9226a8d1
|
||||
F src/bitvec.c ef370407e03440b0852d05024fb016b14a471d3d
|
||||
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
|
||||
F src/btree.c 7c4b02afea7efb561361f20408414fec68df898c
|
||||
@ -146,7 +146,7 @@ F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc
|
||||
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
|
||||
F src/os_unix.c e55d977c516ed880a2f83f0610b019efd9f8bc06
|
||||
F src/os_win.c 725c38a524d168ce280446ad8761d731bc516405
|
||||
F src/pager.c e7171336ffb0f8adc41e55b63dbb2bc5a616a1ae
|
||||
F src/pager.c 8bf62fefc7afefc065d37611ebfd1fe0e1c2eb39
|
||||
F src/pager.h 73f481a308a873ccd626d97331c081db3b53e2e5
|
||||
F src/parse.y ba2fa210be4b17001e0a16d5e73a8141939b1987
|
||||
F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d
|
||||
@ -237,7 +237,7 @@ F test/autoinc.test ab549b48b389cabd92967b86c379ec8b31fa6c16
|
||||
F test/autovacuum.test 25f891bc343a8bf5d9229e2e9ddab9f31a9ab5ec
|
||||
F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6
|
||||
F test/avtrans.test 1e901d8102706b63534dbd2bdd4d8f16c4082650
|
||||
F test/backup.test 5e487ec8dad73e9d249e9bb9ca5346a03b601b07
|
||||
F test/backup.test 5753622bd0108ac41d8d082afad999232a970b90
|
||||
F test/backup2.test 159419073d9769fdb1780ed7e5b391a046f898d5
|
||||
F test/backup_ioerr.test 1f012e692f42c0442ae652443258f70e9f20fa38
|
||||
F test/backup_malloc.test 1e063c6d75143d0d6e0ae77971dd690070369387
|
||||
@ -729,7 +729,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
P 6fe3750a30ab432ed476c2ae6b58972187abc624
|
||||
R 2cb2b27a2df11b0173b7044701cc4d55
|
||||
U drh
|
||||
Z 5a7b4a2c6dbff0f1170dfdcac92eec35
|
||||
P 8207056036e17b99ab660edd650c5a6de1353299
|
||||
R 78f6a76a6227328fac7487e61a37848c
|
||||
U danielk1977
|
||||
Z 0bcee2bab74917e39d092b4429b3d535
|
||||
|
@ -1 +1 @@
|
||||
8207056036e17b99ab660edd650c5a6de1353299
|
||||
90309008c35494c7a075fe76f7eb96b09a01d01b
|
34
src/backup.c
34
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.13 2009/03/16 13:19:36 danielk1977 Exp $
|
||||
** $Id: backup.c,v 1.14 2009/05/13 07:52:06 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "btreeInt.h"
|
||||
@ -44,6 +44,7 @@ struct sqlite3_backup {
|
||||
Pgno nRemaining; /* Number of pages left to copy */
|
||||
Pgno nPagecount; /* Total number of pages to copy */
|
||||
|
||||
int isAttached; /* True once backup has been registered with pager */
|
||||
sqlite3_backup *pNext; /* Next backup associated with source pager */
|
||||
};
|
||||
|
||||
@ -157,6 +158,7 @@ sqlite3_backup *sqlite3_backup_init(
|
||||
p->pDestDb = pDestDb;
|
||||
p->pSrcDb = pSrcDb;
|
||||
p->iNext = 1;
|
||||
p->isAttached = 0;
|
||||
|
||||
if( 0==p->pSrc || 0==p->pDest ){
|
||||
/* One (or both) of the named databases did not exist. An error has
|
||||
@ -167,18 +169,7 @@ sqlite3_backup *sqlite3_backup_init(
|
||||
p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If everything has gone as planned, attach the backup object to the
|
||||
** source pager. The source pager calls BackupUpdate() and BackupRestart()
|
||||
** to notify this module if the source file is modified mid-backup.
|
||||
*/
|
||||
if( p ){
|
||||
sqlite3_backup **pp; /* Pointer to head of pagers backup list */
|
||||
sqlite3BtreeEnter(p->pSrc);
|
||||
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
|
||||
p->pNext = *pp;
|
||||
*pp = p;
|
||||
sqlite3BtreeLeave(p->pSrc);
|
||||
p->pSrc->nBackup++;
|
||||
}
|
||||
|
||||
@ -271,6 +262,19 @@ static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Register this backup object with the associated source pager for
|
||||
** callbacks when pages are changed or the cache invalidated.
|
||||
*/
|
||||
static void attachBackupObject(sqlite3_backup *p){
|
||||
sqlite3_backup **pp;
|
||||
assert( sqlite3BtreeHoldsMutex(p->pSrc) );
|
||||
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
|
||||
p->pNext = *pp;
|
||||
*pp = p;
|
||||
p->isAttached = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy nPage pages from the source b-tree to the destination.
|
||||
*/
|
||||
@ -340,6 +344,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
p->nRemaining = nSrcPage+1-p->iNext;
|
||||
if( p->iNext>(Pgno)nSrcPage ){
|
||||
rc = SQLITE_DONE;
|
||||
}else if( !p->isAttached ){
|
||||
attachBackupObject(p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -472,12 +478,14 @@ int sqlite3_backup_finish(sqlite3_backup *p){
|
||||
|
||||
/* Detach this backup from the source pager. */
|
||||
if( p->pDestDb ){
|
||||
p->pSrc->nBackup--;
|
||||
}
|
||||
if( p->isAttached ){
|
||||
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
|
||||
while( *pp!=p ){
|
||||
pp = &(*pp)->pNext;
|
||||
}
|
||||
*pp = p->pNext;
|
||||
p->pSrc->nBackup--;
|
||||
}
|
||||
|
||||
/* If a transaction is still open on the Btree, roll it back. */
|
||||
|
@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.586 2009/05/06 18:57:10 shane Exp $
|
||||
** @(#) $Id: pager.c,v 1.587 2009/05/13 07:52:06 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
#include "sqliteInt.h"
|
||||
@ -3622,7 +3622,7 @@ static int pagerSharedLock(Pager *pPager){
|
||||
);
|
||||
}
|
||||
|
||||
if( sqlite3PcachePagecount(pPager->pPCache)>0 ){
|
||||
if( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 ){
|
||||
/* The shared-lock has just been acquired on the database file
|
||||
** and there are already pages in the cache (from a previous
|
||||
** read or write transaction). Check to see if the database
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the sqlite3_backup_XXX API.
|
||||
#
|
||||
# $Id: backup.test,v 1.9 2009/03/16 13:19:36 danielk1977 Exp $
|
||||
# $Id: backup.test,v 1.10 2009/05/13 07:52:08 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -859,5 +859,51 @@ do_test backup-9.2.3 {
|
||||
} {SQLITE_OK}
|
||||
catch {db2 close}
|
||||
|
||||
ifcapable memorymanage {
|
||||
db close
|
||||
file delete -force test.db
|
||||
file delete -force bak.db
|
||||
|
||||
sqlite3 db test.db
|
||||
sqlite3 db2 test.db
|
||||
sqlite3 db3 bak.db
|
||||
|
||||
do_test backup-10.1.1 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, randstr(1000,1000));
|
||||
INSERT INTO t1 VALUES(2, randstr(1000,1000));
|
||||
INSERT INTO t1 VALUES(3, randstr(1000,1000));
|
||||
INSERT INTO t1 VALUES(4, randstr(1000,1000));
|
||||
INSERT INTO t1 VALUES(5, randstr(1000,1000));
|
||||
CREATE INDEX i1 ON t1(a, b);
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
do_test backup-10.1.2 {
|
||||
sqlite3_backup B db3 main db2 main
|
||||
B step 5
|
||||
} {SQLITE_OK}
|
||||
do_test backup-10.1.3 {
|
||||
execsql {
|
||||
UPDATE t1 SET b = randstr(500,500);
|
||||
}
|
||||
} {}
|
||||
sqlite3_release_memory [expr 1024*1024]
|
||||
do_test backup-10.1.3 {
|
||||
B step 50
|
||||
} {SQLITE_DONE}
|
||||
do_test backup-10.1.4 {
|
||||
B finish
|
||||
} {SQLITE_OK}
|
||||
do_test backup-10.1.5 {
|
||||
execsql { PRAGMA integrity_check } db3
|
||||
} {ok}
|
||||
|
||||
db2 close
|
||||
db3 close
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user