]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Prohibit backup if the destination is using WAL and has a different page
authordrh <drh@noemail.net>
Wed, 5 May 2010 16:23:26 +0000 (16:23 +0000)
committerdrh <drh@noemail.net>
Wed, 5 May 2010 16:23:26 +0000 (16:23 +0000)
size from the source.

FossilOrigin-Name: 7bd44794c482beee16c684712545275e2bf63dfa

manifest
manifest.uuid
src/backup.c
src/sqlite.h.in

index 2e5ada914364c93e0c0d9db23a966565bb6ede49..138bc72434e214595031a994b9f2f1d772d3423b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,8 @@
-C When\sclosing\sa\sWAL\sdatabase,\sif\sthe\sexclusive\slock\son\sthe\sdatabase\sfile\sis\sobtained\sand\sthe\sdatabase\ssuccessfully\scheckpointed,\sdelete\sthe\swal-index\sfile\sfrom\sthe\sfile\ssystem.
-D 2010-05-05T15:33:05
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+C Prohibit\sbackup\sif\sthe\sdestination\sis\susing\sWAL\sand\shas\sa\sdifferent\spage\nsize\sfrom\sthe\ssource.
+D 2010-05-05T16:23:27
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in d83a0ffef3dcbfb08b410a6c6dd6c009ec9167fb
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -106,7 +109,7 @@ F src/alter.c a9ff6f14b3935502537e90194b66c7bc79bed317
 F src/analyze.c 8dfd781ac326496746ecdfc3e099250ed5d79be5
 F src/attach.c 7abe1607c2054585377cdba3c219e8572f84ca5e
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
-F src/backup.c e86634da8c48357a759694c9c7c471125cd8d5a8
+F src/backup.c 5c2dbddbe97f6bc2c01e3fcde4cfd2385b0c7411
 F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
 F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
 F src/btree.c d0414a5f09b0cacb64bd60b91c5a3720585925aa
@@ -166,7 +169,7 @@ F src/resolve.c ac5f1a713cd1ae77f08b83cc69581e11bf5ae6f9
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
 F src/select.c c03d8a0565febcde8c6a12c5d77d065fddae889b
 F src/shell.c c40427c7245535a04a9cb4a417b6cc05c022e6a4
-F src/sqlite.h.in 7afbe9fb794092cb38bd3cfab72c39560ce0def5
+F src/sqlite.h.in ac4c94610542bdbaa9cc94be3059d6830caea8ff
 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
 F src/sqliteInt.h 9819b45610abeca390176243a9a31758c1f0ac7a
 F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
@@ -809,7 +812,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 208e7d5d3a8915433dbf50c6cc6698ec6c8df944
-R 865b9c2886168b2786175a8dffa911ed
-U dan
-Z 1bbd17cb33b9f710875e715283353398
+P 2ac5d96c8e5831b392d83c86491d9ed8bc9c8db7
+R 82b3438b071d9502db3bdd3a22e84c0d
+U drh
+Z de906577ce23bb1b1b5ca675861faf36
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQFL4ZuCoxKgR168RlERAuZbAJ4ikNBaO50mnTJ8j201rDXr+9WYqgCfU42A
+ws1gQpPQnYG7m2yeQMuRCxw=
+=XKt5
+-----END PGP SIGNATURE-----
index cb0a2a9a41c6dd948b1acab54b0e28ede830270f..8fcf35e948f16cc2ce9cd7f9a2103814c2c3ed7a 100644 (file)
@@ -1 +1 @@
-2ac5d96c8e5831b392d83c86491d9ed8bc9c8db7
\ No newline at end of file
+7bd44794c482beee16c684712545275e2bf63dfa
\ No newline at end of file
index c2e00d635bd5eff8e2e0602d82c718642e008b12..fb23577ede44b86ef183e861781c204b5076252c 100644 (file)
@@ -217,7 +217,7 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
   /* Catch the case where the destination is an in-memory database and the
   ** page sizes of the source and destination differ. 
   */
-  if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(sqlite3BtreePager(p->pDest)) ){
+  if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
     rc = SQLITE_READONLY;
   }
 
@@ -287,6 +287,9 @@ static void attachBackupObject(sqlite3_backup *p){
 */
 int sqlite3_backup_step(sqlite3_backup *p, int nPage){
   int rc;
+  int destMode;       /* Destination journal mode */
+  int pgszSrc;        /* Source page size */
+  int pgszDest;       /* Destination page size */
 
   sqlite3_mutex_enter(p->pSrcDb->mutex);
   sqlite3BtreeEnter(p->pSrc);
@@ -294,7 +297,17 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
     sqlite3_mutex_enter(p->pDestDb->mutex);
   }
 
-  rc = p->rc;
+  /* Do not allow backup if the destination database is in WAL mode */
+  destMode = sqlite3PagerJournalMode(sqlite3BtreePager(p->pDest),
+                                     PAGER_JOURNALMODE_QUERY);
+  pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
+  pgszDest = sqlite3BtreeGetPageSize(p->pDest);
+  if( destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){
+    rc = SQLITE_READONLY;
+  }else{
+    rc = p->rc;
+  }
+
   if( !isFatalError(rc) ){
     Pager * const pSrcPager = sqlite3BtreePager(p->pSrc);     /* Source pager */
     Pager * const pDestPager = sqlite3BtreePager(p->pDest);   /* Dest pager */
@@ -363,8 +376,6 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
     if( rc==SQLITE_DONE 
      && (rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1))==SQLITE_OK
     ){
-      const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc);
-      const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest);
       int nDestTruncate;
   
       if( p->pDestDb ){
@@ -383,18 +394,20 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
       ** journalled by PagerCommitPhaseOne() before they are destroyed
       ** by the file truncation.
       */
-      if( nSrcPagesize<nDestPagesize ){
-        int ratio = nDestPagesize/nSrcPagesize;
+      assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) );
+      assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) );
+      if( pgszSrc<pgszDest ){
+        int ratio = pgszDest/pgszSrc;
         nDestTruncate = (nSrcPage+ratio-1)/ratio;
         if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
           nDestTruncate--;
         }
       }else{
-        nDestTruncate = nSrcPage * (nSrcPagesize/nDestPagesize);
+        nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
       }
       sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
 
-      if( nSrcPagesize<nDestPagesize ){
+      if( pgszSrc<pgszDest ){
         /* If the source page-size is smaller than the destination page-size,
         ** two extra things may need to happen:
         **
@@ -404,31 +417,31 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
         **     pending-byte page in the source database may need to be
         **     copied into the destination database.
         */
-        const i64 iSize = (i64)nSrcPagesize * (i64)nSrcPage;
+        const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
         sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
 
         assert( pFile );
-        assert( (i64)nDestTruncate*(i64)nDestPagesize >= iSize || (
+        assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || (
               nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
-           && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+nDestPagesize
+           && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
         ));
         if( SQLITE_OK==(rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1))
          && SQLITE_OK==(rc = backupTruncateFile(pFile, iSize))
          && SQLITE_OK==(rc = sqlite3PagerSync(pDestPager))
         ){
           i64 iOff;
-          i64 iEnd = MIN(PENDING_BYTE + nDestPagesize, iSize);
+          i64 iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
           for(
-            iOff=PENDING_BYTE+nSrcPagesize
+            iOff=PENDING_BYTE+pgszSrc
             rc==SQLITE_OK && iOff<iEnd; 
-            iOff+=nSrcPagesize
+            iOff+=pgszSrc
           ){
             PgHdr *pSrcPg = 0;
-            const Pgno iSrcPg = (Pgno)((iOff/nSrcPagesize)+1);
+            const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
             rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
             if( rc==SQLITE_OK ){
               u8 *zData = sqlite3PagerGetData(pSrcPg);
-              rc = sqlite3OsWrite(pFile, zData, nSrcPagesize, iOff);
+              rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
             }
             sqlite3PagerUnref(pSrcPg);
           }
index 00e83365860ae473e22057dc6808c92d53e52115..f7d462f01791e19c876cab27d5363d946b115d9d 100644 (file)
@@ -5489,10 +5489,14 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
 ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
 **
-** ^The sqlite3_backup_step() might return [SQLITE_READONLY] if the destination
-** database was opened read-only or if
-** the destination is an in-memory database with a different page size
-** from the source database.
+** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
+** <ol>
+** <li> the destination database was opened read-only, or
+** <li> the destination database is using write-ahead-log journaling
+** and the destination and source page sizes differ, or
+** <li> The destination database is an in-memory database and the
+** destination and source page sizes differ.
+** </ol>)^
 **
 ** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
 ** the [sqlite3_busy_handler | busy-handler function]