From: drh Date: Mon, 18 May 2009 17:11:31 +0000 (+0000) Subject: Port the sqlite3_backup fix of check-in (6632), ticket #3858 onto the X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5be782aa86830c05f06277d38dfc4dd5f97ec6a;p=thirdparty%2Fsqlite.git Port the sqlite3_backup fix of check-in (6632), ticket #3858 onto the 3.6.14.1 branch. (CVS 6654) FossilOrigin-Name: 0d3abee273c359b77649e6a08a9eaff09d3bde7b --- diff --git a/manifest b/manifest index e98495a535..062cb973f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sconfigure\sscript\sfor\sthe\s3.6.14.1\srelease.\s(CVS\s6653) -D 2009-05-18T16:22:42 +C Port\sthe\ssqlite3_backup\sfix\sof\scheck-in\s(6632),\sticket\s#3858\sonto\sthe\n3.6.14.1\sbranch.\s(CVS\s6654) +D 2009-05-18T17:11:31 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -103,7 +103,7 @@ F src/alter.c 8ab5824bde0a03dae5829f61557ab7c72757000a F src/analyze.c e239496cfb5394ac8867f1c112905ddab8d01cd9 F src/attach.c 3b99611f04926fc69c35b1145603fc3ddb0ca967 F src/auth.c 98db07c2088455797678eb1031f42d4d94d18a71 -F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d +F src/backup.c 8f985697354e7f3e8cf2a1f11a850d4f1a48da87 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 9ad9f45049a3c9eb0b0713b162ff0d7024ff7259 F src/os_win.c 725c38a524d168ce280446ad8761d731bc516405 -F src/pager.c e7171336ffb0f8adc41e55b63dbb2bc5a616a1ae +F src/pager.c 1379ce5cff06cb850482fa17ba5d7ecc728a166b F src/pager.h 73f481a308a873ccd626d97331c081db3b53e2e5 F src/parse.y a0e8b8e5d646a6352098fccc9d3325b4234a05b9 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 86ae101e91e14fb2bf4214817716b410d53c48e7 F test/backup2.test 159419073d9769fdb1780ed7e5b391a046f898d5 F test/backup_ioerr.test 1f012e692f42c0442ae652443258f70e9f20fa38 F test/backup_malloc.test 1e063c6d75143d0d6e0ae77971dd690070369387 @@ -728,7 +728,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 2a277c55b2f90d53208147423b409bc05e12ebd0 -R 0144b0601cd1455ba6c830cecdd1b041 +P 4ebb85018195d52d8eb0720284f7b2e480c24876 +R c9ff2fe0e5d5bb93f15c93547bbd4db6 U drh -Z a7fc4029e9ddde54f7a2fb207d1382dc +Z 81f489e8f604099cb5ff0ae3a4ddfb47 diff --git a/manifest.uuid b/manifest.uuid index e6c2e31d6d..c321402aa7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4ebb85018195d52d8eb0720284f7b2e480c24876 \ No newline at end of file +0d3abee273c359b77649e6a08a9eaff09d3bde7b \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 781b4b0bca..54588cbaa0 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.13 2009/03/16 13:19:36 danielk1977 Exp $ +** $Id: backup.c,v 1.13.2.1 2009/05/18 17:11:31 drh 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. */ diff --git a/src/pager.c b/src/pager.c index 0edabb3d0e..7ede5bd445 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.586 2009/05/06 18:57:10 shane Exp $ +** @(#) $Id: pager.c,v 1.586.2.1 2009/05/18 17:11:31 drh 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 diff --git a/test/backup.test b/test/backup.test index 24ba6996c8..5f2a3440f8 100644 --- a/test/backup.test +++ b/test/backup.test @@ -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.9.2.1 2009/05/18 17:11:31 drh 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