From 3289c5efc89f8b4e567f6f8d5336f6e126108960 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 May 2010 16:23:26 +0000 Subject: [PATCH] Prohibit backup if the destination is using WAL and has a different page size from the source. FossilOrigin-Name: 7bd44794c482beee16c684712545275e2bf63dfa --- manifest | 26 ++++++++++++++++++-------- manifest.uuid | 2 +- src/backup.c | 45 +++++++++++++++++++++++++++++---------------- src/sqlite.h.in | 12 ++++++++---- 4 files changed, 56 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 2e5ada9143..138bc72434 100644 --- 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----- diff --git a/manifest.uuid b/manifest.uuid index cb0a2a9a41..8fcf35e948 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ac5d96c8e5831b392d83c86491d9ed8bc9c8db7 \ No newline at end of file +7bd44794c482beee16c684712545275e2bf63dfa \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index c2e00d635b..fb23577ede 100644 --- a/src/backup.c +++ b/src/backup.c @@ -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( nSrcPagesizepSrc) ); + assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) ); + if( pgszSrcpDest->pBt) ){ nDestTruncate--; } }else{ - nDestTruncate = nSrcPage * (nSrcPagesize/nDestPagesize); + nDestTruncate = nSrcPage * (pgszSrc/pgszDest); } sqlite3PagerTruncateImage(pDestPager, nDestTruncate); - if( nSrcPagesize= 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 +**
  • the destination database was opened read-only, or +**
  • the destination database is using write-ahead-log journaling +** and the destination and source page sizes differ, or +**
  • The destination database is an in-memory database and the +** destination and source page sizes differ. +** )^ ** ** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then ** the [sqlite3_busy_handler | busy-handler function]