1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Prohibit backup if the destination is using WAL and has a different page

size from the source.

FossilOrigin-Name: 7bd44794c482beee16c684712545275e2bf63dfa
This commit is contained in:
drh
2010-05-05 16:23:26 +00:00
parent 1018e90b1e
commit 3289c5efc8
4 changed files with 56 additions and 29 deletions

View File

@@ -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. -----BEGIN PGP SIGNED MESSAGE-----
D 2010-05-05T15:33:05 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.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in d83a0ffef3dcbfb08b410a6c6dd6c009ec9167fb F Makefile.in d83a0ffef3dcbfb08b410a6c6dd6c009ec9167fb
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -106,7 +109,7 @@ F src/alter.c a9ff6f14b3935502537e90194b66c7bc79bed317
F src/analyze.c 8dfd781ac326496746ecdfc3e099250ed5d79be5 F src/analyze.c 8dfd781ac326496746ecdfc3e099250ed5d79be5
F src/attach.c 7abe1607c2054585377cdba3c219e8572f84ca5e F src/attach.c 7abe1607c2054585377cdba3c219e8572f84ca5e
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c e86634da8c48357a759694c9c7c471125cd8d5a8 F src/backup.c 5c2dbddbe97f6bc2c01e3fcde4cfd2385b0c7411
F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0 F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
F src/btree.c d0414a5f09b0cacb64bd60b91c5a3720585925aa F src/btree.c d0414a5f09b0cacb64bd60b91c5a3720585925aa
@@ -166,7 +169,7 @@ F src/resolve.c ac5f1a713cd1ae77f08b83cc69581e11bf5ae6f9
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c c03d8a0565febcde8c6a12c5d77d065fddae889b F src/select.c c03d8a0565febcde8c6a12c5d77d065fddae889b
F src/shell.c c40427c7245535a04a9cb4a417b6cc05c022e6a4 F src/shell.c c40427c7245535a04a9cb4a417b6cc05c022e6a4
F src/sqlite.h.in 7afbe9fb794092cb38bd3cfab72c39560ce0def5 F src/sqlite.h.in ac4c94610542bdbaa9cc94be3059d6830caea8ff
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
F src/sqliteInt.h 9819b45610abeca390176243a9a31758c1f0ac7a F src/sqliteInt.h 9819b45610abeca390176243a9a31758c1f0ac7a
F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3 F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
@@ -809,7 +812,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 208e7d5d3a8915433dbf50c6cc6698ec6c8df944 P 2ac5d96c8e5831b392d83c86491d9ed8bc9c8db7
R 865b9c2886168b2786175a8dffa911ed R 82b3438b071d9502db3bdd3a22e84c0d
U dan U drh
Z 1bbd17cb33b9f710875e715283353398 Z de906577ce23bb1b1b5ca675861faf36
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFL4ZuCoxKgR168RlERAuZbAJ4ikNBaO50mnTJ8j201rDXr+9WYqgCfU42A
ws1gQpPQnYG7m2yeQMuRCxw=
=XKt5
-----END PGP SIGNATURE-----

View File

@@ -1 +1 @@
2ac5d96c8e5831b392d83c86491d9ed8bc9c8db7 7bd44794c482beee16c684712545275e2bf63dfa

View 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 /* Catch the case where the destination is an in-memory database and the
** page sizes of the source and destination differ. ** page sizes of the source and destination differ.
*/ */
if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(sqlite3BtreePager(p->pDest)) ){ if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
rc = SQLITE_READONLY; rc = SQLITE_READONLY;
} }
@@ -287,6 +287,9 @@ static void attachBackupObject(sqlite3_backup *p){
*/ */
int sqlite3_backup_step(sqlite3_backup *p, int nPage){ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
int rc; int rc;
int destMode; /* Destination journal mode */
int pgszSrc; /* Source page size */
int pgszDest; /* Destination page size */
sqlite3_mutex_enter(p->pSrcDb->mutex); sqlite3_mutex_enter(p->pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc); sqlite3BtreeEnter(p->pSrc);
@@ -294,7 +297,17 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
sqlite3_mutex_enter(p->pDestDb->mutex); 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) ){ if( !isFatalError(rc) ){
Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */
Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest 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 if( rc==SQLITE_DONE
&& (rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1))==SQLITE_OK && (rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1))==SQLITE_OK
){ ){
const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc);
const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest);
int nDestTruncate; int nDestTruncate;
if( p->pDestDb ){ if( p->pDestDb ){
@@ -383,18 +394,20 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
** journalled by PagerCommitPhaseOne() before they are destroyed ** journalled by PagerCommitPhaseOne() before they are destroyed
** by the file truncation. ** by the file truncation.
*/ */
if( nSrcPagesize<nDestPagesize ){ assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) );
int ratio = nDestPagesize/nSrcPagesize; assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) );
if( pgszSrc<pgszDest ){
int ratio = pgszDest/pgszSrc;
nDestTruncate = (nSrcPage+ratio-1)/ratio; nDestTruncate = (nSrcPage+ratio-1)/ratio;
if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){ if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
nDestTruncate--; nDestTruncate--;
} }
}else{ }else{
nDestTruncate = nSrcPage * (nSrcPagesize/nDestPagesize); nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
} }
sqlite3PagerTruncateImage(pDestPager, nDestTruncate); sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
if( nSrcPagesize<nDestPagesize ){ if( pgszSrc<pgszDest ){
/* If the source page-size is smaller than the destination page-size, /* If the source page-size is smaller than the destination page-size,
** two extra things may need to happen: ** 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 ** pending-byte page in the source database may need to be
** copied into the destination database. ** 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); sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
assert( pFile ); assert( pFile );
assert( (i64)nDestTruncate*(i64)nDestPagesize >= iSize || ( assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || (
nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) 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)) if( SQLITE_OK==(rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1))
&& SQLITE_OK==(rc = backupTruncateFile(pFile, iSize)) && SQLITE_OK==(rc = backupTruncateFile(pFile, iSize))
&& SQLITE_OK==(rc = sqlite3PagerSync(pDestPager)) && SQLITE_OK==(rc = sqlite3PagerSync(pDestPager))
){ ){
i64 iOff; i64 iOff;
i64 iEnd = MIN(PENDING_BYTE + nDestPagesize, iSize); i64 iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
for( for(
iOff=PENDING_BYTE+nSrcPagesize; iOff=PENDING_BYTE+pgszSrc;
rc==SQLITE_OK && iOff<iEnd; rc==SQLITE_OK && iOff<iEnd;
iOff+=nSrcPagesize iOff+=pgszSrc
){ ){
PgHdr *pSrcPg = 0; PgHdr *pSrcPg = 0;
const Pgno iSrcPg = (Pgno)((iOff/nSrcPagesize)+1); const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg); rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
u8 *zData = sqlite3PagerGetData(pSrcPg); u8 *zData = sqlite3PagerGetData(pSrcPg);
rc = sqlite3OsWrite(pFile, zData, nSrcPagesize, iOff); rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
} }
sqlite3PagerUnref(pSrcPg); sqlite3PagerUnref(pSrcPg);
} }

View File

@@ -5489,10 +5489,14 @@ typedef struct sqlite3_backup sqlite3_backup;
** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an ** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
** **
** ^The sqlite3_backup_step() might return [SQLITE_READONLY] if the destination ** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
** database was opened read-only or if ** <ol>
** the destination is an in-memory database with a different page size ** <li> the destination database was opened read-only, or
** from the source database. ** <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 ** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
** the [sqlite3_busy_handler | busy-handler function] ** the [sqlite3_busy_handler | busy-handler function]