@@ -256,6 +256,13 @@ static int backupOnePage(
256256 int nDestPgsz = sqlite3BtreeGetPageSize (p -> pDest );
257257 const int nCopy = MIN (nSrcPgsz , nDestPgsz );
258258 const i64 iEnd = (i64 )iSrcPg * (i64 )nSrcPgsz ;
259+ #ifdef SQLITE_HAS_CODEC
260+ /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
261+ ** guaranteed that the shared-mutex is held by this thread, handle
262+ ** p->pSrc may not actually be the owner. */
263+ int nSrcReserve = sqlite3BtreeGetReserveNoMutex (p -> pSrc );
264+ int nDestReserve = sqlite3BtreeGetOptimalReserve (p -> pDest );
265+ #endif
259266 int rc = SQLITE_OK ;
260267 i64 iOff ;
261268
@@ -272,6 +279,26 @@ static int backupOnePage(
272279 rc = SQLITE_READONLY ;
273280 }
274281
282+ #ifdef SQLITE_HAS_CODEC
283+ /* Backup is not possible if the page size of the destination is changing
284+ ** and a codec is in use.
285+ */
286+ if ( nSrcPgsz != nDestPgsz && sqlite3PagerGetCodec (pDestPager )!= 0 ){
287+ rc = SQLITE_READONLY ;
288+ }
289+
290+ /* Backup is not possible if the number of bytes of reserve space differ
291+ ** between source and destination. If there is a difference, try to
292+ ** fix the destination to agree with the source. If that is not possible,
293+ ** then the backup cannot proceed.
294+ */
295+ if ( nSrcReserve != nDestReserve ){
296+ u32 newPgsz = nSrcPgsz ;
297+ rc = sqlite3PagerSetPagesize (pDestPager , & newPgsz , nSrcReserve );
298+ if ( rc == SQLITE_OK && newPgsz != (u32 )nSrcPgsz ) rc = SQLITE_READONLY ;
299+ }
300+ #endif
301+
275302 /* This loop runs once for each destination page spanned by the source
276303 ** page. For each iteration, variable iOff is set to the byte offset
277304 ** of the destination page.
@@ -767,6 +794,10 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
767794 b .pDest = pTo ;
768795 b .iNext = 1 ;
769796
797+ #ifdef SQLITE_HAS_CODEC
798+ sqlite3PagerAlignReserve (sqlite3BtreePager (pTo ), sqlite3BtreePager (pFrom ));
799+ #endif
800+
770801 /* 0x7FFFFFFF is the hard limit for the number of pages in a database
771802 ** file. By passing this as the number of pages to copy to
772803 ** sqlite3_backup_step(), we can guarantee that the copy finishes
0 commit comments