Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix some edge cases with backing up databases that are exactly PENDING_BYTE bytes in size, or just slightly larger. (CVS 6288) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2fc450e8e60248d6111d0b0d2b8f2344 |
User & Date: | danielk1977 2009-02-12 17:01:50.000 |
Context
2009-02-12
| ||
17:06 | Update thread tests to clear the sqlite_open_file_count counter at the end. This counter is not threadsafe and can end up with an invalid value at the end of the thread tests. (CVS 6289) (check-in: 8c4d71a169 user: drh tags: trunk) | |
17:01 | Fix some edge cases with backing up databases that are exactly PENDING_BYTE bytes in size, or just slightly larger. (CVS 6288) (check-in: 2fc450e8e6 user: danielk1977 tags: trunk) | |
09:36 | Modify lock.test to account for "PRAGMA lock_status" returning "unknown" for in-memory databases. (CVS 6287) (check-in: 9a6e558ba6 user: danielk1977 tags: trunk) | |
Changes
Changes to src/backup.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. ** ** $Id: backup.c,v 1.10 2009/02/12 17:01:50 danielk1977 Exp $ */ #include "sqliteInt.h" #include "btreeInt.h" /* Macro to find the minimum of two numeric values. */ #ifndef MIN |
︙ | ︙ | |||
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | ** destination file that lie beyond the nDestTruncate page mark are ** journalled by PagerCommitPhaseOne() before they are destroyed ** by the file truncation. */ if( nSrcPagesize<nDestPagesize ){ int ratio = nDestPagesize/nSrcPagesize; nDestTruncate = (nSrcPage+ratio-1)/ratio; }else{ nDestTruncate = nSrcPage * (nSrcPagesize/nDestPagesize); } sqlite3PagerTruncateImage(pDestPager, nDestTruncate); if( nSrcPagesize<nDestPagesize ){ /* If the source page-size is smaller than the destination page-size, ** two extra things may need to happen: ** ** * The destination may need to be truncated, and ** ** * Data stored on the pages immediately following the ** pending-byte page in the source database may need to be ** copied into the destination database. */ const i64 iSize = (i64)nSrcPagesize * (i64)nSrcPage; sqlite3_file * const pFile = sqlite3PagerFile(pDestPager); assert( pFile ); | > > > | > > > | 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | ** destination file that lie beyond the nDestTruncate page mark are ** journalled by PagerCommitPhaseOne() before they are destroyed ** by the file truncation. */ if( nSrcPagesize<nDestPagesize ){ int ratio = nDestPagesize/nSrcPagesize; nDestTruncate = (nSrcPage+ratio-1)/ratio; if( nDestTruncate==PENDING_BYTE_PAGE(p->pDest->pBt) ){ nDestTruncate--; } }else{ nDestTruncate = nSrcPage * (nSrcPagesize/nDestPagesize); } sqlite3PagerTruncateImage(pDestPager, nDestTruncate); if( nSrcPagesize<nDestPagesize ){ /* If the source page-size is smaller than the destination page-size, ** two extra things may need to happen: ** ** * The destination may need to be truncated, and ** ** * Data stored on the pages immediately following the ** pending-byte page in the source database may need to be ** copied into the destination database. */ const i64 iSize = (i64)nSrcPagesize * (i64)nSrcPage; sqlite3_file * const pFile = sqlite3PagerFile(pDestPager); assert( pFile ); assert( (i64)nDestTruncate*(i64)nDestPagesize >= iSize || ( nDestTruncate==(PENDING_BYTE_PAGE(p->pDest->pBt)-1) && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+nDestPagesize )); 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); for( |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.568 2009/02/12 17:01:50 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" /* ** Macros for troubleshooting. Normally turned off */ |
︙ | ︙ | |||
4172 4173 4174 4175 4176 4177 4178 | } /* Update the database size and return. */ assert( pPager->state>=PAGER_SHARED ); if( pPager->dbSize<pPg->pgno ){ pPager->dbSize = pPg->pgno; | < < < | 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 | } /* Update the database size and return. */ assert( pPager->state>=PAGER_SHARED ); if( pPager->dbSize<pPg->pgno ){ pPager->dbSize = pPg->pgno; } return rc; } /* ** Mark a data page as writeable. This routine must be called before ** making changes to a page. The caller must check the return value |
︙ | ︙ |
Changes to test/backup.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2009 January 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the sqlite3_backup_XXX API. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2009 January 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # 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.8 2009/02/12 17:01:50 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl #--------------------------------------------------------------------- # Test organization: # |
︙ | ︙ | |||
316 317 318 319 320 321 322 323 324 325 326 327 328 329 | db close db2 close incr iTest } } } # # End of backup-3.* tests. #--------------------------------------------------------------------- #--------------------------------------------------------------------- # The following tests, backup-4.*, test various error conditions: | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | db close db2 close incr iTest } } } #-------------------------------------------------------------------- do_test backup-3.$iTest.1 { catch { file delete -force test.db } catch { file delete -force test2.db } sqlite3 db test.db set iTab 1 db eval { PRAGMA page_size = 512 } while {[file size test.db] <= $::sqlite_pending_byte} { db eval "CREATE TABLE t${iTab}(a, b, c)" incr iTab } sqlite3 db2 test2.db db2 eval { PRAGMA page_size = 4096 } while {[file size test2.db] < $::sqlite_pending_byte} { db2 eval "CREATE TABLE t${iTab}(a, b, c)" incr iTab } sqlite3_backup B db2 main db main B step -1 } {SQLITE_DONE} do_test backup-3.$iTest.2 { B finish } {SQLITE_OK} # # End of backup-3.* tests. #--------------------------------------------------------------------- #--------------------------------------------------------------------- # The following tests, backup-4.*, test various error conditions: |
︙ | ︙ |