OLD | NEW |
1 /* | 1 /* |
2 ** 2001 September 15 | 2 ** 2001 September 15 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 Pgno nOrig; /* Original number of pages in file */ | 449 Pgno nOrig; /* Original number of pages in file */ |
450 Pgno iSubRec; /* Index of first record in sub-journal */ | 450 Pgno iSubRec; /* Index of first record in sub-journal */ |
451 #ifndef SQLITE_OMIT_WAL | 451 #ifndef SQLITE_OMIT_WAL |
452 u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ | 452 u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ |
453 #endif | 453 #endif |
454 }; | 454 }; |
455 | 455 |
456 /* | 456 /* |
457 ** Bits of the Pager.doNotSpill flag. See further description below. | 457 ** Bits of the Pager.doNotSpill flag. See further description below. |
458 */ | 458 */ |
459 #define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */ | 459 #define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */ |
460 #define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill
*/ | 460 #define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */ |
461 #define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ | 461 #define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ |
462 | 462 |
463 /* | 463 /* |
464 ** An open page cache is an instance of struct Pager. A description of | 464 ** An open page cache is an instance of struct Pager. A description of |
465 ** some of the more important member variables follows: | 465 ** some of the more important member variables follows: |
466 ** | 466 ** |
467 ** eState | 467 ** eState |
468 ** | 468 ** |
469 ** The current 'state' of the pager object. See the comment and state | 469 ** The current 'state' of the pager object. See the comment and state |
470 ** diagram above for a description of the pager state. | 470 ** diagram above for a description of the pager state. |
471 ** | 471 ** |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 ** to the file-system in order to free up memory). | 533 ** to the file-system in order to free up memory). |
534 ** | 534 ** |
535 ** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, | 535 ** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, |
536 ** writing to the database from pagerStress() is disabled altogether. | 536 ** writing to the database from pagerStress() is disabled altogether. |
537 ** The SPILLFLAG_ROLLBACK case is done in a very obscure case that | 537 ** The SPILLFLAG_ROLLBACK case is done in a very obscure case that |
538 ** comes up during savepoint rollback that requires the pcache module | 538 ** comes up during savepoint rollback that requires the pcache module |
539 ** to allocate a new page to prevent the journal file from being written | 539 ** to allocate a new page to prevent the journal file from being written |
540 ** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF | 540 ** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF |
541 ** case is a user preference. | 541 ** case is a user preference. |
542 ** | 542 ** |
543 ** If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStres
s() | 543 ** If the SPILLFLAG_NOSYNC bit is set, writing to the database from |
544 ** is permitted, but syncing the journal file is not. This flag is set | 544 ** pagerStress() is permitted, but syncing the journal file is not. |
545 ** by sqlite3PagerWrite() when the file-system sector-size is larger than | 545 ** This flag is set by sqlite3PagerWrite() when the file-system sector-size |
546 ** the database page-size in order to prevent a journal sync from happening | 546 ** is larger than the database page-size in order to prevent a journal sync |
547 ** in between the journalling of two pages on the same sector. | 547 ** from happening in between the journalling of two pages on the same sector. |
548 ** | 548 ** |
549 ** subjInMemory | 549 ** subjInMemory |
550 ** | 550 ** |
551 ** This is a boolean variable. If true, then any required sub-journal | 551 ** This is a boolean variable. If true, then any required sub-journal |
552 ** is opened as an in-memory journal file. If false, then in-memory | 552 ** is opened as an in-memory journal file. If false, then in-memory |
553 ** sub-journals are only used for in-memory pager files. | 553 ** sub-journals are only used for in-memory pager files. |
554 ** | 554 ** |
555 ** This variable is updated by the upper layer each time a new | 555 ** This variable is updated by the upper layer each time a new |
556 ** write-transaction is opened. | 556 ** write-transaction is opened. |
557 ** | 557 ** |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 ** or the journal_mode). From another view, these class members describe | 639 ** or the journal_mode). From another view, these class members describe |
640 ** the "state" of the pager, while other class members describe the | 640 ** the "state" of the pager, while other class members describe the |
641 ** "configuration" of the pager. | 641 ** "configuration" of the pager. |
642 */ | 642 */ |
643 u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ | 643 u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ |
644 u8 eLock; /* Current lock held on database file */ | 644 u8 eLock; /* Current lock held on database file */ |
645 u8 changeCountDone; /* Set after incrementing the change-counter */ | 645 u8 changeCountDone; /* Set after incrementing the change-counter */ |
646 u8 setMaster; /* True if a m-j name has been written to jrnl */ | 646 u8 setMaster; /* True if a m-j name has been written to jrnl */ |
647 u8 doNotSpill; /* Do not spill the cache when non-zero */ | 647 u8 doNotSpill; /* Do not spill the cache when non-zero */ |
648 u8 subjInMemory; /* True to use in-memory sub-journals */ | 648 u8 subjInMemory; /* True to use in-memory sub-journals */ |
| 649 u8 bUseFetch; /* True to use xFetch() */ |
| 650 u8 hasHeldSharedLock; /* True if a shared lock has ever been held */ |
649 Pgno dbSize; /* Number of pages in the database */ | 651 Pgno dbSize; /* Number of pages in the database */ |
650 Pgno dbOrigSize; /* dbSize before the current transaction */ | 652 Pgno dbOrigSize; /* dbSize before the current transaction */ |
651 Pgno dbFileSize; /* Number of pages in the database file */ | 653 Pgno dbFileSize; /* Number of pages in the database file */ |
652 Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ | 654 Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ |
653 int errCode; /* One of several kinds of errors */ | 655 int errCode; /* One of several kinds of errors */ |
654 int nRec; /* Pages journalled since last j-header written */ | 656 int nRec; /* Pages journalled since last j-header written */ |
655 u32 cksumInit; /* Quasi-random value added to every checksum */ | 657 u32 cksumInit; /* Quasi-random value added to every checksum */ |
656 u32 nSubRec; /* Number of records written to sub-journal */ | 658 u32 nSubRec; /* Number of records written to sub-journal */ |
657 Bitvec *pInJournal; /* One bit for each page in the database file */ | 659 Bitvec *pInJournal; /* One bit for each page in the database file */ |
658 sqlite3_file *fd; /* File descriptor for database */ | 660 sqlite3_file *fd; /* File descriptor for database */ |
659 sqlite3_file *jfd; /* File descriptor for main journal */ | 661 sqlite3_file *jfd; /* File descriptor for main journal */ |
660 sqlite3_file *sjfd; /* File descriptor for sub-journal */ | 662 sqlite3_file *sjfd; /* File descriptor for sub-journal */ |
661 i64 journalOff; /* Current write offset in the journal file */ | 663 i64 journalOff; /* Current write offset in the journal file */ |
662 i64 journalHdr; /* Byte offset to previous journal header */ | 664 i64 journalHdr; /* Byte offset to previous journal header */ |
663 sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ | 665 sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ |
664 PagerSavepoint *aSavepoint; /* Array of active savepoints */ | 666 PagerSavepoint *aSavepoint; /* Array of active savepoints */ |
665 int nSavepoint; /* Number of elements in aSavepoint[] */ | 667 int nSavepoint; /* Number of elements in aSavepoint[] */ |
| 668 u32 iDataVersion; /* Changes whenever database content changes */ |
666 char dbFileVers[16]; /* Changes whenever database file changes */ | 669 char dbFileVers[16]; /* Changes whenever database file changes */ |
667 | 670 |
668 u8 bUseFetch; /* True to use xFetch() */ | |
669 int nMmapOut; /* Number of mmap pages currently outstanding */ | 671 int nMmapOut; /* Number of mmap pages currently outstanding */ |
670 sqlite3_int64 szMmap; /* Desired maximum mmap size */ | 672 sqlite3_int64 szMmap; /* Desired maximum mmap size */ |
671 PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ | 673 PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ |
672 /* | 674 /* |
673 ** End of the routinely-changing class members | 675 ** End of the routinely-changing class members |
674 ***************************************************************************/ | 676 ***************************************************************************/ |
675 | 677 |
676 u16 nExtra; /* Add this many bytes to each in-memory page */ | 678 u16 nExtra; /* Add this many bytes to each in-memory page */ |
677 i16 nReserve; /* Number of unused bytes at end of each page */ | 679 i16 nReserve; /* Number of unused bytes at end of each page */ |
678 u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ | 680 u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 ** Return 0 if it is not open, or non-zero (but not 1) if it is. | 801 ** Return 0 if it is not open, or non-zero (but not 1) if it is. |
800 ** | 802 ** |
801 ** This is so that expressions can be written as: | 803 ** This is so that expressions can be written as: |
802 ** | 804 ** |
803 ** if( isOpen(pPager->jfd) ){ ... | 805 ** if( isOpen(pPager->jfd) ){ ... |
804 ** | 806 ** |
805 ** instead of | 807 ** instead of |
806 ** | 808 ** |
807 ** if( pPager->jfd->pMethods ){ ... | 809 ** if( pPager->jfd->pMethods ){ ... |
808 */ | 810 */ |
809 #define isOpen(pFd) ((pFd)->pMethods) | 811 #define isOpen(pFd) ((pFd)->pMethods!=0) |
810 | 812 |
811 /* | 813 /* |
812 ** Return true if this pager uses a write-ahead log instead of the usual | 814 ** Return true if this pager uses a write-ahead log instead of the usual |
813 ** rollback journal. Otherwise false. | 815 ** rollback journal. Otherwise false. |
814 */ | 816 */ |
815 #ifndef SQLITE_OMIT_WAL | 817 #ifndef SQLITE_OMIT_WAL |
816 static int pagerUseWal(Pager *pPager){ | 818 static int pagerUseWal(Pager *pPager){ |
817 return (pPager->pWal!=0); | 819 return (pPager->pWal!=0); |
818 } | 820 } |
819 #else | 821 #else |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 ** * The bit corresponding to the page-number is not set in | 1024 ** * The bit corresponding to the page-number is not set in |
1023 ** PagerSavepoint.pInSavepoint. | 1025 ** PagerSavepoint.pInSavepoint. |
1024 */ | 1026 */ |
1025 static int subjRequiresPage(PgHdr *pPg){ | 1027 static int subjRequiresPage(PgHdr *pPg){ |
1026 Pager *pPager = pPg->pPager; | 1028 Pager *pPager = pPg->pPager; |
1027 PagerSavepoint *p; | 1029 PagerSavepoint *p; |
1028 Pgno pgno = pPg->pgno; | 1030 Pgno pgno = pPg->pgno; |
1029 int i; | 1031 int i; |
1030 for(i=0; i<pPager->nSavepoint; i++){ | 1032 for(i=0; i<pPager->nSavepoint; i++){ |
1031 p = &pPager->aSavepoint[i]; | 1033 p = &pPager->aSavepoint[i]; |
1032 if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){ | 1034 if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ |
1033 return 1; | 1035 return 1; |
1034 } | 1036 } |
1035 } | 1037 } |
1036 return 0; | 1038 return 0; |
1037 } | 1039 } |
1038 | 1040 |
| 1041 #ifdef SQLITE_DEBUG |
1039 /* | 1042 /* |
1040 ** Return true if the page is already in the journal file. | 1043 ** Return true if the page is already in the journal file. |
1041 */ | 1044 */ |
1042 static int pageInJournal(Pager *pPager, PgHdr *pPg){ | 1045 static int pageInJournal(Pager *pPager, PgHdr *pPg){ |
1043 return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno); | 1046 return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno); |
1044 } | 1047 } |
| 1048 #endif |
1045 | 1049 |
1046 /* | 1050 /* |
1047 ** Read a 32-bit integer from the given file descriptor. Store the integer | 1051 ** Read a 32-bit integer from the given file descriptor. Store the integer |
1048 ** that is read in *pRes. Return SQLITE_OK if everything worked, or an | 1052 ** that is read in *pRes. Return SQLITE_OK if everything worked, or an |
1049 ** error code is something goes wrong. | 1053 ** error code is something goes wrong. |
1050 ** | 1054 ** |
1051 ** All values are stored on disk as big-endian. | 1055 ** All values are stored on disk as big-endian. |
1052 */ | 1056 */ |
1053 static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){ | 1057 static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){ |
1054 unsigned char ac[4]; | 1058 unsigned char ac[4]; |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1646 } | 1650 } |
1647 iHdrOff = pPager->journalOff; | 1651 iHdrOff = pPager->journalOff; |
1648 | 1652 |
1649 /* Write the master journal data to the end of the journal file. If | 1653 /* Write the master journal data to the end of the journal file. If |
1650 ** an error occurs, return the error code to the caller. | 1654 ** an error occurs, return the error code to the caller. |
1651 */ | 1655 */ |
1652 if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager)))) | 1656 if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager)))) |
1653 || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4))) | 1657 || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4))) |
1654 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster))) | 1658 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster))) |
1655 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum))) | 1659 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum))) |
1656 || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaste
r+8))) | 1660 || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, |
| 1661 iHdrOff+4+nMaster+8))) |
1657 ){ | 1662 ){ |
1658 return rc; | 1663 return rc; |
1659 } | 1664 } |
1660 pPager->journalOff += (nMaster+20); | 1665 pPager->journalOff += (nMaster+20); |
1661 | 1666 |
1662 /* If the pager is in peristent-journal mode, then the physical | 1667 /* If the pager is in peristent-journal mode, then the physical |
1663 ** journal-file may extend past the end of the master-journal name | 1668 ** journal-file may extend past the end of the master-journal name |
1664 ** and 8 bytes of magic data just written to the file. This is | 1669 ** and 8 bytes of magic data just written to the file. This is |
1665 ** dangerous because the code to rollback a hot-journal file | 1670 ** dangerous because the code to rollback a hot-journal file |
1666 ** will not be able to find the master-journal name to determine | 1671 ** will not be able to find the master-journal name to determine |
1667 ** whether or not the journal is hot. | 1672 ** whether or not the journal is hot. |
1668 ** | 1673 ** |
1669 ** Easiest thing to do in this scenario is to truncate the journal | 1674 ** Easiest thing to do in this scenario is to truncate the journal |
1670 ** file to the required size. | 1675 ** file to the required size. |
1671 */ | 1676 */ |
1672 if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) | 1677 if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) |
1673 && jrnlSize>pPager->journalOff | 1678 && jrnlSize>pPager->journalOff |
1674 ){ | 1679 ){ |
1675 rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff); | 1680 rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff); |
1676 } | 1681 } |
1677 return rc; | 1682 return rc; |
1678 } | 1683 } |
1679 | 1684 |
1680 /* | 1685 /* |
1681 ** Discard the entire contents of the in-memory page-cache. | 1686 ** Discard the entire contents of the in-memory page-cache. |
1682 */ | 1687 */ |
1683 static void pager_reset(Pager *pPager){ | 1688 static void pager_reset(Pager *pPager){ |
| 1689 pPager->iDataVersion++; |
1684 sqlite3BackupRestart(pPager->pBackup); | 1690 sqlite3BackupRestart(pPager->pBackup); |
1685 sqlite3PcacheClear(pPager->pPCache); | 1691 sqlite3PcacheClear(pPager->pPCache); |
1686 } | 1692 } |
1687 | 1693 |
1688 /* | 1694 /* |
| 1695 ** Return the pPager->iDataVersion value |
| 1696 */ |
| 1697 u32 sqlite3PagerDataVersion(Pager *pPager){ |
| 1698 assert( pPager->eState>PAGER_OPEN ); |
| 1699 return pPager->iDataVersion; |
| 1700 } |
| 1701 |
| 1702 /* |
1689 ** Free all structures in the Pager.aSavepoint[] array and set both | 1703 ** Free all structures in the Pager.aSavepoint[] array and set both |
1690 ** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal | 1704 ** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal |
1691 ** if it is open and the pager is not in exclusive mode. | 1705 ** if it is open and the pager is not in exclusive mode. |
1692 */ | 1706 */ |
1693 static void releaseAllSavepoints(Pager *pPager){ | 1707 static void releaseAllSavepoints(Pager *pPager){ |
1694 int ii; /* Iterator for looping through Pager.aSavepoint */ | 1708 int ii; /* Iterator for looping through Pager.aSavepoint */ |
1695 for(ii=0; ii<pPager->nSavepoint; ii++){ | 1709 for(ii=0; ii<pPager->nSavepoint; ii++){ |
1696 sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); | 1710 sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); |
1697 } | 1711 } |
1698 if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){ | 1712 if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){ |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2095 static void pagerReportSize(Pager *pPager){ | 2109 static void pagerReportSize(Pager *pPager){ |
2096 if( pPager->xCodecSizeChng ){ | 2110 if( pPager->xCodecSizeChng ){ |
2097 pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, | 2111 pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, |
2098 (int)pPager->nReserve); | 2112 (int)pPager->nReserve); |
2099 } | 2113 } |
2100 } | 2114 } |
2101 #else | 2115 #else |
2102 # define pagerReportSize(X) /* No-op if we do not support a codec */ | 2116 # define pagerReportSize(X) /* No-op if we do not support a codec */ |
2103 #endif | 2117 #endif |
2104 | 2118 |
| 2119 #ifdef SQLITE_HAS_CODEC |
| 2120 /* |
| 2121 ** Make sure the number of reserved bits is the same in the destination |
| 2122 ** pager as it is in the source. This comes up when a VACUUM changes the |
| 2123 ** number of reserved bits to the "optimal" amount. |
| 2124 */ |
| 2125 void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){ |
| 2126 if( pDest->nReserve!=pSrc->nReserve ){ |
| 2127 pDest->nReserve = pSrc->nReserve; |
| 2128 pagerReportSize(pDest); |
| 2129 } |
| 2130 } |
| 2131 #endif |
| 2132 |
2105 /* | 2133 /* |
2106 ** Read a single page from either the journal file (if isMainJrnl==1) or | 2134 ** Read a single page from either the journal file (if isMainJrnl==1) or |
2107 ** from the sub-journal (if isMainJrnl==0) and playback that page. | 2135 ** from the sub-journal (if isMainJrnl==0) and playback that page. |
2108 ** The page begins at offset *pOffset into the file. The *pOffset | 2136 ** The page begins at offset *pOffset into the file. The *pOffset |
2109 ** value is increased to the start of the next page in the journal. | 2137 ** value is increased to the start of the next page in the journal. |
2110 ** | 2138 ** |
2111 ** The main rollback journal uses checksums - the statement journal does | 2139 ** The main rollback journal uses checksums - the statement journal does |
2112 ** not. | 2140 ** not. |
2113 ** | 2141 ** |
2114 ** If the page number of the page record read from the (sub-)journal file | 2142 ** If the page number of the page record read from the (sub-)journal file |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2197 return SQLITE_OK; | 2225 return SQLITE_OK; |
2198 } | 2226 } |
2199 if( isMainJrnl ){ | 2227 if( isMainJrnl ){ |
2200 rc = read32bits(jfd, (*pOffset)-4, &cksum); | 2228 rc = read32bits(jfd, (*pOffset)-4, &cksum); |
2201 if( rc ) return rc; | 2229 if( rc ) return rc; |
2202 if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ | 2230 if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ |
2203 return SQLITE_DONE; | 2231 return SQLITE_DONE; |
2204 } | 2232 } |
2205 } | 2233 } |
2206 | 2234 |
2207 /* If this page has already been played by before during the current | 2235 /* If this page has already been played back before during the current |
2208 ** rollback, then don't bother to play it back again. | 2236 ** rollback, then don't bother to play it back again. |
2209 */ | 2237 */ |
2210 if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ | 2238 if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ |
2211 return rc; | 2239 return rc; |
2212 } | 2240 } |
2213 | 2241 |
2214 /* When playing back page 1, restore the nReserve setting | 2242 /* When playing back page 1, restore the nReserve setting |
2215 */ | 2243 */ |
2216 if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ | 2244 if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ |
2217 pPager->nReserve = ((u8*)aData)[20]; | 2245 pPager->nReserve = ((u8*)aData)[20]; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2298 ** populated, then moved using sqlite3PagerMovepage(). | 2326 ** populated, then moved using sqlite3PagerMovepage(). |
2299 ** | 2327 ** |
2300 ** The solution is to add an in-memory page to the cache containing | 2328 ** The solution is to add an in-memory page to the cache containing |
2301 ** the data just read from the sub-journal. Mark the page as dirty | 2329 ** the data just read from the sub-journal. Mark the page as dirty |
2302 ** and if the pager requires a journal-sync, then mark the page as | 2330 ** and if the pager requires a journal-sync, then mark the page as |
2303 ** requiring a journal-sync before it is written. | 2331 ** requiring a journal-sync before it is written. |
2304 */ | 2332 */ |
2305 assert( isSavepnt ); | 2333 assert( isSavepnt ); |
2306 assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 ); | 2334 assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 ); |
2307 pPager->doNotSpill |= SPILLFLAG_ROLLBACK; | 2335 pPager->doNotSpill |= SPILLFLAG_ROLLBACK; |
2308 rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1); | 2336 rc = sqlite3PagerGet(pPager, pgno, &pPg, 1); |
2309 assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); | 2337 assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); |
2310 pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; | 2338 pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; |
2311 if( rc!=SQLITE_OK ) return rc; | 2339 if( rc!=SQLITE_OK ) return rc; |
2312 pPg->flags &= ~PGHDR_NEED_READ; | 2340 pPg->flags &= ~PGHDR_NEED_READ; |
2313 sqlite3PcacheMakeDirty(pPg); | 2341 sqlite3PcacheMakeDirty(pPg); |
2314 } | 2342 } |
2315 if( pPg ){ | 2343 if( pPg ){ |
2316 /* No page should ever be explicitly rolled back that is in use, except | 2344 /* No page should ever be explicitly rolled back that is in use, except |
2317 ** for page 1 which is held in use in order to keep the lock on the | 2345 ** for page 1 which is held in use in order to keep the lock on the |
2318 ** database active. However such a page may be rolled back as a result | 2346 ** database active. However such a page may be rolled back as a result |
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2892 if( rc ){ | 2920 if( rc ){ |
2893 /* If the read is unsuccessful, set the dbFileVers[] to something | 2921 /* If the read is unsuccessful, set the dbFileVers[] to something |
2894 ** that will never be a valid file version. dbFileVers[] is a copy | 2922 ** that will never be a valid file version. dbFileVers[] is a copy |
2895 ** of bytes 24..39 of the database. Bytes 28..31 should always be | 2923 ** of bytes 24..39 of the database. Bytes 28..31 should always be |
2896 ** zero or the size of the database in page. Bytes 32..35 and 35..39 | 2924 ** zero or the size of the database in page. Bytes 32..35 and 35..39 |
2897 ** should be page numbers which are never 0xffffffff. So filling | 2925 ** should be page numbers which are never 0xffffffff. So filling |
2898 ** pPager->dbFileVers[] with all 0xff bytes should suffice. | 2926 ** pPager->dbFileVers[] with all 0xff bytes should suffice. |
2899 ** | 2927 ** |
2900 ** For an encrypted database, the situation is more complex: bytes | 2928 ** For an encrypted database, the situation is more complex: bytes |
2901 ** 24..39 of the database are white noise. But the probability of | 2929 ** 24..39 of the database are white noise. But the probability of |
2902 ** white noising equaling 16 bytes of 0xff is vanishingly small so | 2930 ** white noise equaling 16 bytes of 0xff is vanishingly small so |
2903 ** we should still be ok. | 2931 ** we should still be ok. |
2904 */ | 2932 */ |
2905 memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); | 2933 memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); |
2906 }else{ | 2934 }else{ |
2907 u8 *dbFileVers = &((u8*)pPg->pData)[24]; | 2935 u8 *dbFileVers = &((u8*)pPg->pData)[24]; |
2908 memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); | 2936 memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); |
2909 } | 2937 } |
2910 } | 2938 } |
2911 CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM); | 2939 CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM); |
2912 | 2940 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3026 ** Hence, if page 1 appears anywhere on the list, it will be the first page. | 3054 ** Hence, if page 1 appears anywhere on the list, it will be the first page. |
3027 */ | 3055 */ |
3028 static int pagerWalFrames( | 3056 static int pagerWalFrames( |
3029 Pager *pPager, /* Pager object */ | 3057 Pager *pPager, /* Pager object */ |
3030 PgHdr *pList, /* List of frames to log */ | 3058 PgHdr *pList, /* List of frames to log */ |
3031 Pgno nTruncate, /* Database size after this commit */ | 3059 Pgno nTruncate, /* Database size after this commit */ |
3032 int isCommit /* True if this is a commit */ | 3060 int isCommit /* True if this is a commit */ |
3033 ){ | 3061 ){ |
3034 int rc; /* Return code */ | 3062 int rc; /* Return code */ |
3035 int nList; /* Number of pages in pList */ | 3063 int nList; /* Number of pages in pList */ |
3036 #if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES) | |
3037 PgHdr *p; /* For looping over pages */ | 3064 PgHdr *p; /* For looping over pages */ |
3038 #endif | |
3039 | 3065 |
3040 assert( pPager->pWal ); | 3066 assert( pPager->pWal ); |
3041 assert( pList ); | 3067 assert( pList ); |
3042 #ifdef SQLITE_DEBUG | 3068 #ifdef SQLITE_DEBUG |
3043 /* Verify that the page list is in accending order */ | 3069 /* Verify that the page list is in accending order */ |
3044 for(p=pList; p && p->pDirty; p=p->pDirty){ | 3070 for(p=pList; p && p->pDirty; p=p->pDirty){ |
3045 assert( p->pgno < p->pDirty->pgno ); | 3071 assert( p->pgno < p->pDirty->pgno ); |
3046 } | 3072 } |
3047 #endif | 3073 #endif |
3048 | 3074 |
3049 assert( pList->pDirty==0 || isCommit ); | 3075 assert( pList->pDirty==0 || isCommit ); |
3050 if( isCommit ){ | 3076 if( isCommit ){ |
3051 /* If a WAL transaction is being committed, there is no point in writing | 3077 /* If a WAL transaction is being committed, there is no point in writing |
3052 ** any pages with page numbers greater than nTruncate into the WAL file. | 3078 ** any pages with page numbers greater than nTruncate into the WAL file. |
3053 ** They will never be read by any client. So remove them from the pDirty | 3079 ** They will never be read by any client. So remove them from the pDirty |
3054 ** list here. */ | 3080 ** list here. */ |
3055 PgHdr *p; | |
3056 PgHdr **ppNext = &pList; | 3081 PgHdr **ppNext = &pList; |
3057 nList = 0; | 3082 nList = 0; |
3058 for(p=pList; (*ppNext = p)!=0; p=p->pDirty){ | 3083 for(p=pList; (*ppNext = p)!=0; p=p->pDirty){ |
3059 if( p->pgno<=nTruncate ){ | 3084 if( p->pgno<=nTruncate ){ |
3060 ppNext = &p->pDirty; | 3085 ppNext = &p->pDirty; |
3061 nList++; | 3086 nList++; |
3062 } | 3087 } |
3063 } | 3088 } |
3064 assert( pList ); | 3089 assert( pList ); |
3065 }else{ | 3090 }else{ |
3066 nList = 1; | 3091 nList = 1; |
3067 } | 3092 } |
3068 pPager->aStat[PAGER_STAT_WRITE] += nList; | 3093 pPager->aStat[PAGER_STAT_WRITE] += nList; |
3069 | 3094 |
3070 if( pList->pgno==1 ) pager_write_changecounter(pList); | 3095 if( pList->pgno==1 ) pager_write_changecounter(pList); |
3071 rc = sqlite3WalFrames(pPager->pWal, | 3096 rc = sqlite3WalFrames(pPager->pWal, |
3072 pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags | 3097 pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags |
3073 ); | 3098 ); |
3074 if( rc==SQLITE_OK && pPager->pBackup ){ | 3099 if( rc==SQLITE_OK && pPager->pBackup ){ |
3075 PgHdr *p; | |
3076 for(p=pList; p; p=p->pDirty){ | 3100 for(p=pList; p; p=p->pDirty){ |
3077 sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); | 3101 sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); |
3078 } | 3102 } |
3079 } | 3103 } |
3080 | 3104 |
3081 #ifdef SQLITE_CHECK_PAGES | 3105 #ifdef SQLITE_CHECK_PAGES |
3082 pList = sqlite3PcacheDirtyList(pPager->pPCache); | 3106 pList = sqlite3PcacheDirtyList(pPager->pPCache); |
3083 for(p=pList; p; p=p->pDirty){ | 3107 for(p=pList; p; p=p->pDirty){ |
3084 pager_set_pagehash(p); | 3108 pager_set_pagehash(p); |
3085 } | 3109 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3135 /* Query the WAL sub-system for the database size. The WalDbsize() | 3159 /* Query the WAL sub-system for the database size. The WalDbsize() |
3136 ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or | 3160 ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or |
3137 ** if the database size is not available. The database size is not | 3161 ** if the database size is not available. The database size is not |
3138 ** available from the WAL sub-system if the log file is empty or | 3162 ** available from the WAL sub-system if the log file is empty or |
3139 ** contains no valid committed transactions. | 3163 ** contains no valid committed transactions. |
3140 */ | 3164 */ |
3141 assert( pPager->eState==PAGER_OPEN ); | 3165 assert( pPager->eState==PAGER_OPEN ); |
3142 assert( pPager->eLock>=SHARED_LOCK ); | 3166 assert( pPager->eLock>=SHARED_LOCK ); |
3143 nPage = sqlite3WalDbsize(pPager->pWal); | 3167 nPage = sqlite3WalDbsize(pPager->pWal); |
3144 | 3168 |
3145 /* If the database size was not available from the WAL sub-system, | 3169 /* If the number of pages in the database is not available from the |
3146 ** determine it based on the size of the database file. If the size | 3170 ** WAL sub-system, determine the page counte based on the size of |
3147 ** of the database file is not an integer multiple of the page-size, | 3171 ** the database file. If the size of the database file is not an |
3148 ** round down to the nearest page. Except, any file larger than 0 | 3172 ** integer multiple of the page-size, round up the result. |
3149 ** bytes in size is considered to contain at least one page. | |
3150 */ | 3173 */ |
3151 if( nPage==0 ){ | 3174 if( nPage==0 ){ |
3152 i64 n = 0; /* Size of db file in bytes */ | 3175 i64 n = 0; /* Size of db file in bytes */ |
3153 assert( isOpen(pPager->fd) || pPager->tempFile ); | 3176 assert( isOpen(pPager->fd) || pPager->tempFile ); |
3154 if( isOpen(pPager->fd) ){ | 3177 if( isOpen(pPager->fd) ){ |
3155 int rc = sqlite3OsFileSize(pPager->fd, &n); | 3178 int rc = sqlite3OsFileSize(pPager->fd, &n); |
3156 if( rc!=SQLITE_OK ){ | 3179 if( rc!=SQLITE_OK ){ |
3157 return rc; | 3180 return rc; |
3158 } | 3181 } |
3159 } | 3182 } |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3362 | 3385 |
3363 sqlite3BitvecDestroy(pDone); | 3386 sqlite3BitvecDestroy(pDone); |
3364 if( rc==SQLITE_OK ){ | 3387 if( rc==SQLITE_OK ){ |
3365 pPager->journalOff = szJ; | 3388 pPager->journalOff = szJ; |
3366 } | 3389 } |
3367 | 3390 |
3368 return rc; | 3391 return rc; |
3369 } | 3392 } |
3370 | 3393 |
3371 /* | 3394 /* |
3372 ** Change the maximum number of in-memory pages that are allowed. | 3395 ** Change the maximum number of in-memory pages that are allowed |
| 3396 ** before attempting to recycle clean and unused pages. |
3373 */ | 3397 */ |
3374 void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ | 3398 void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ |
3375 sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); | 3399 sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); |
3376 } | 3400 } |
3377 | 3401 |
3378 /* | 3402 /* |
| 3403 ** Change the maximum number of in-memory pages that are allowed |
| 3404 ** before attempting to spill pages to journal. |
| 3405 */ |
| 3406 int sqlite3PagerSetSpillsize(Pager *pPager, int mxPage){ |
| 3407 return sqlite3PcacheSetSpillsize(pPager->pPCache, mxPage); |
| 3408 } |
| 3409 |
| 3410 /* |
3379 ** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap. | 3411 ** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap. |
3380 */ | 3412 */ |
3381 static void pagerFixMaplimit(Pager *pPager){ | 3413 static void pagerFixMaplimit(Pager *pPager){ |
3382 #if SQLITE_MAX_MMAP_SIZE>0 | 3414 #if SQLITE_MAX_MMAP_SIZE>0 |
3383 sqlite3_file *fd = pPager->fd; | 3415 sqlite3_file *fd = pPager->fd; |
3384 if( isOpen(fd) && fd->pMethods->iVersion>=3 ){ | 3416 if( isOpen(fd) && fd->pMethods->iVersion>=3 ){ |
3385 sqlite3_int64 sz; | 3417 sqlite3_int64 sz; |
3386 sz = pPager->szMmap; | 3418 sz = pPager->szMmap; |
3387 pPager->bUseFetch = (sz>0); | 3419 pPager->bUseFetch = (sz>0); |
3388 sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); | 3420 sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3880 ** Page references obtained by calling this function should be released | 3912 ** Page references obtained by calling this function should be released |
3881 ** by calling pagerReleaseMapPage(). | 3913 ** by calling pagerReleaseMapPage(). |
3882 */ | 3914 */ |
3883 static int pagerAcquireMapPage( | 3915 static int pagerAcquireMapPage( |
3884 Pager *pPager, /* Pager object */ | 3916 Pager *pPager, /* Pager object */ |
3885 Pgno pgno, /* Page number */ | 3917 Pgno pgno, /* Page number */ |
3886 void *pData, /* xFetch()'d data for this page */ | 3918 void *pData, /* xFetch()'d data for this page */ |
3887 PgHdr **ppPage /* OUT: Acquired page object */ | 3919 PgHdr **ppPage /* OUT: Acquired page object */ |
3888 ){ | 3920 ){ |
3889 PgHdr *p; /* Memory mapped page to return */ | 3921 PgHdr *p; /* Memory mapped page to return */ |
3890 | 3922 |
3891 if( pPager->pMmapFreelist ){ | 3923 if( pPager->pMmapFreelist ){ |
3892 *ppPage = p = pPager->pMmapFreelist; | 3924 *ppPage = p = pPager->pMmapFreelist; |
3893 pPager->pMmapFreelist = p->pDirty; | 3925 pPager->pMmapFreelist = p->pDirty; |
3894 p->pDirty = 0; | 3926 p->pDirty = 0; |
3895 memset(p->pExtra, 0, pPager->nExtra); | 3927 memset(p->pExtra, 0, pPager->nExtra); |
3896 }else{ | 3928 }else{ |
3897 *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); | 3929 *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); |
3898 if( p==0 ){ | 3930 if( p==0 ){ |
3899 sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); | 3931 sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); |
3900 return SQLITE_NOMEM; | 3932 return SQLITE_NOMEM; |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4304 sqlite3MemJournalOpen(pPager->sjfd); | 4336 sqlite3MemJournalOpen(pPager->sjfd); |
4305 }else{ | 4337 }else{ |
4306 rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL); | 4338 rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL); |
4307 } | 4339 } |
4308 } | 4340 } |
4309 return rc; | 4341 return rc; |
4310 } | 4342 } |
4311 | 4343 |
4312 /* | 4344 /* |
4313 ** Append a record of the current state of page pPg to the sub-journal. | 4345 ** Append a record of the current state of page pPg to the sub-journal. |
4314 ** It is the callers responsibility to use subjRequiresPage() to check | |
4315 ** that it is really required before calling this function. | |
4316 ** | 4346 ** |
4317 ** If successful, set the bit corresponding to pPg->pgno in the bitvecs | 4347 ** If successful, set the bit corresponding to pPg->pgno in the bitvecs |
4318 ** for all open savepoints before returning. | 4348 ** for all open savepoints before returning. |
4319 ** | 4349 ** |
4320 ** This function returns SQLITE_OK if everything is successful, an IO | 4350 ** This function returns SQLITE_OK if everything is successful, an IO |
4321 ** error code if the attempt to write to the sub-journal fails, or | 4351 ** error code if the attempt to write to the sub-journal fails, or |
4322 ** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint | 4352 ** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint |
4323 ** bitvec. | 4353 ** bitvec. |
4324 */ | 4354 */ |
4325 static int subjournalPage(PgHdr *pPg){ | 4355 static int subjournalPage(PgHdr *pPg){ |
(...skipping 26 matching lines...) Expand all Loading... |
4352 } | 4382 } |
4353 } | 4383 } |
4354 } | 4384 } |
4355 if( rc==SQLITE_OK ){ | 4385 if( rc==SQLITE_OK ){ |
4356 pPager->nSubRec++; | 4386 pPager->nSubRec++; |
4357 assert( pPager->nSavepoint>0 ); | 4387 assert( pPager->nSavepoint>0 ); |
4358 rc = addToSavepointBitvecs(pPager, pPg->pgno); | 4388 rc = addToSavepointBitvecs(pPager, pPg->pgno); |
4359 } | 4389 } |
4360 return rc; | 4390 return rc; |
4361 } | 4391 } |
| 4392 static int subjournalPageIfRequired(PgHdr *pPg){ |
| 4393 if( subjRequiresPage(pPg) ){ |
| 4394 return subjournalPage(pPg); |
| 4395 }else{ |
| 4396 return SQLITE_OK; |
| 4397 } |
| 4398 } |
4362 | 4399 |
4363 /* | 4400 /* |
4364 ** This function is called by the pcache layer when it has reached some | 4401 ** This function is called by the pcache layer when it has reached some |
4365 ** soft memory limit. The first argument is a pointer to a Pager object | 4402 ** soft memory limit. The first argument is a pointer to a Pager object |
4366 ** (cast as a void*). The pager is always 'purgeable' (not an in-memory | 4403 ** (cast as a void*). The pager is always 'purgeable' (not an in-memory |
4367 ** database). The second argument is a reference to a page that is | 4404 ** database). The second argument is a reference to a page that is |
4368 ** currently dirty but has no outstanding references. The page | 4405 ** currently dirty but has no outstanding references. The page |
4369 ** is always associated with the Pager object passed as the first | 4406 ** is always associated with the Pager object passed as the first |
4370 ** argument. | 4407 ** argument. |
4371 ** | 4408 ** |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4409 if( pPager->doNotSpill | 4446 if( pPager->doNotSpill |
4410 && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0 | 4447 && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0 |
4411 || (pPg->flags & PGHDR_NEED_SYNC)!=0) | 4448 || (pPg->flags & PGHDR_NEED_SYNC)!=0) |
4412 ){ | 4449 ){ |
4413 return SQLITE_OK; | 4450 return SQLITE_OK; |
4414 } | 4451 } |
4415 | 4452 |
4416 pPg->pDirty = 0; | 4453 pPg->pDirty = 0; |
4417 if( pagerUseWal(pPager) ){ | 4454 if( pagerUseWal(pPager) ){ |
4418 /* Write a single frame for this page to the log. */ | 4455 /* Write a single frame for this page to the log. */ |
4419 if( subjRequiresPage(pPg) ){ | 4456 rc = subjournalPageIfRequired(pPg); |
4420 rc = subjournalPage(pPg); | |
4421 } | |
4422 if( rc==SQLITE_OK ){ | 4457 if( rc==SQLITE_OK ){ |
4423 rc = pagerWalFrames(pPager, pPg, 0, 0); | 4458 rc = pagerWalFrames(pPager, pPg, 0, 0); |
4424 } | 4459 } |
4425 }else{ | 4460 }else{ |
4426 | 4461 |
4427 /* Sync the journal file if required. */ | 4462 /* Sync the journal file if required. */ |
4428 if( pPg->flags&PGHDR_NEED_SYNC | 4463 if( pPg->flags&PGHDR_NEED_SYNC |
4429 || pPager->eState==PAGER_WRITER_CACHEMOD | 4464 || pPager->eState==PAGER_WRITER_CACHEMOD |
4430 ){ | 4465 ){ |
4431 rc = syncJournal(pPager, 1); | 4466 rc = syncJournal(pPager, 1); |
4432 } | 4467 } |
4433 | 4468 |
4434 /* If the page number of this page is larger than the current size of | |
4435 ** the database image, it may need to be written to the sub-journal. | |
4436 ** This is because the call to pager_write_pagelist() below will not | |
4437 ** actually write data to the file in this case. | |
4438 ** | |
4439 ** Consider the following sequence of events: | |
4440 ** | |
4441 ** BEGIN; | |
4442 ** <journal page X> | |
4443 ** <modify page X> | |
4444 ** SAVEPOINT sp; | |
4445 ** <shrink database file to Y pages> | |
4446 ** pagerStress(page X) | |
4447 ** ROLLBACK TO sp; | |
4448 ** | |
4449 ** If (X>Y), then when pagerStress is called page X will not be written | |
4450 ** out to the database file, but will be dropped from the cache. Then, | |
4451 ** following the "ROLLBACK TO sp" statement, reading page X will read | |
4452 ** data from the database file. This will be the copy of page X as it | |
4453 ** was when the transaction started, not as it was when "SAVEPOINT sp" | |
4454 ** was executed. | |
4455 ** | |
4456 ** The solution is to write the current data for page X into the | |
4457 ** sub-journal file now (if it is not already there), so that it will | |
4458 ** be restored to its current value when the "ROLLBACK TO sp" is | |
4459 ** executed. | |
4460 */ | |
4461 if( NEVER( | |
4462 rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) | |
4463 ) ){ | |
4464 rc = subjournalPage(pPg); | |
4465 } | |
4466 | |
4467 /* Write the contents of the page out to the database file. */ | 4469 /* Write the contents of the page out to the database file. */ |
4468 if( rc==SQLITE_OK ){ | 4470 if( rc==SQLITE_OK ){ |
4469 assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); | 4471 assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); |
4470 rc = pager_write_pagelist(pPager, pPg); | 4472 rc = pager_write_pagelist(pPager, pPg); |
4471 } | 4473 } |
4472 } | 4474 } |
4473 | 4475 |
4474 /* Mark the page as clean. */ | 4476 /* Mark the page as clean. */ |
4475 if( rc==SQLITE_OK ){ | 4477 if( rc==SQLITE_OK ){ |
4476 PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); | 4478 PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); |
4477 sqlite3PcacheMakeClean(pPg); | 4479 sqlite3PcacheMakeClean(pPg); |
4478 } | 4480 } |
4479 | 4481 |
4480 return pager_error(pPager, rc); | 4482 return pager_error(pPager, rc); |
4481 } | 4483 } |
4482 | 4484 |
| 4485 /* |
| 4486 ** Flush all unreferenced dirty pages to disk. |
| 4487 */ |
| 4488 int sqlite3PagerFlush(Pager *pPager){ |
| 4489 int rc = pPager->errCode; |
| 4490 if( !MEMDB ){ |
| 4491 PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); |
| 4492 assert( assert_pager_state(pPager) ); |
| 4493 while( rc==SQLITE_OK && pList ){ |
| 4494 PgHdr *pNext = pList->pDirty; |
| 4495 if( pList->nRef==0 ){ |
| 4496 rc = pagerStress((void*)pPager, pList); |
| 4497 } |
| 4498 pList = pNext; |
| 4499 } |
| 4500 } |
| 4501 |
| 4502 return rc; |
| 4503 } |
4483 | 4504 |
4484 /* | 4505 /* |
4485 ** Allocate and initialize a new Pager object and put a pointer to it | 4506 ** Allocate and initialize a new Pager object and put a pointer to it |
4486 ** in *ppPager. The pager should eventually be freed by passing it | 4507 ** in *ppPager. The pager should eventually be freed by passing it |
4487 ** to sqlite3PagerClose(). | 4508 ** to sqlite3PagerClose(). |
4488 ** | 4509 ** |
4489 ** The zFilename argument is the path to the database file to open. | 4510 ** The zFilename argument is the path to the database file to open. |
4490 ** If zFilename is NULL then a randomly-named temporary file is created | 4511 ** If zFilename is NULL then a randomly-named temporary file is created |
4491 ** and used as the file to be cached. Temporary files are be deleted | 4512 ** and used as the file to be cached. Temporary files are be deleted |
4492 ** automatically when they are closed. If zFilename is ":memory:" then | 4513 ** automatically when they are closed. If zFilename is ":memory:" then |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4712 ** | 4733 ** |
4713 ** This branch is also run for an in-memory database. An in-memory | 4734 ** This branch is also run for an in-memory database. An in-memory |
4714 ** database is the same as a temp-file that is never written out to | 4735 ** database is the same as a temp-file that is never written out to |
4715 ** disk and uses an in-memory rollback journal. | 4736 ** disk and uses an in-memory rollback journal. |
4716 ** | 4737 ** |
4717 ** This branch also runs for files marked as immutable. | 4738 ** This branch also runs for files marked as immutable. |
4718 */ | 4739 */ |
4719 act_like_temp_file: | 4740 act_like_temp_file: |
4720 tempFile = 1; | 4741 tempFile = 1; |
4721 pPager->eState = PAGER_READER; /* Pretend we already have a lock */ | 4742 pPager->eState = PAGER_READER; /* Pretend we already have a lock */ |
4722 pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE locking mo
de */ | 4743 pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */ |
4723 pPager->noLock = 1; /* Do no locking */ | 4744 pPager->noLock = 1; /* Do no locking */ |
4724 readOnly = (vfsFlags&SQLITE_OPEN_READONLY); | 4745 readOnly = (vfsFlags&SQLITE_OPEN_READONLY); |
4725 } | 4746 } |
4726 | 4747 |
4727 /* The following call to PagerSetPagesize() serves to set the value of | 4748 /* The following call to PagerSetPagesize() serves to set the value of |
4728 ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. | 4749 ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. |
4729 */ | 4750 */ |
4730 if( rc==SQLITE_OK ){ | 4751 if( rc==SQLITE_OK ){ |
4731 assert( pPager->memDb==0 ); | 4752 assert( pPager->memDb==0 ); |
4732 rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); | 4753 rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); |
4733 testcase( rc!=SQLITE_OK ); | 4754 testcase( rc!=SQLITE_OK ); |
4734 } | 4755 } |
4735 | 4756 |
4736 /* Initialize the PCache object. */ | 4757 /* Initialize the PCache object. */ |
4737 if( rc==SQLITE_OK ){ | 4758 if( rc==SQLITE_OK ){ |
4738 assert( nExtra<1000 ); | 4759 assert( nExtra<1000 ); |
4739 nExtra = ROUND8(nExtra); | 4760 nExtra = ROUND8(nExtra); |
4740 rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, | 4761 rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, |
4741 !memDb?pagerStress:0, (void *)pPager, pPager->pPCache
); | 4762 !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); |
4742 } | 4763 } |
4743 | 4764 |
4744 /* If an error occurred above, free the Pager structure and close the file. | 4765 /* If an error occurred above, free the Pager structure and close the file. |
4745 */ | 4766 */ |
4746 if( rc!=SQLITE_OK ){ | 4767 if( rc!=SQLITE_OK ){ |
4747 sqlite3OsClose(pPager->fd); | 4768 sqlite3OsClose(pPager->fd); |
4748 sqlite3PageFree(pPager->pTmpSpace); | 4769 sqlite3PageFree(pPager->pTmpSpace); |
4749 sqlite3_free(pPager); | 4770 sqlite3_free(pPager); |
4750 return rc; | 4771 return rc; |
4751 } | 4772 } |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4950 } | 4971 } |
4951 } | 4972 } |
4952 } | 4973 } |
4953 } | 4974 } |
4954 | 4975 |
4955 return rc; | 4976 return rc; |
4956 } | 4977 } |
4957 | 4978 |
4958 /* | 4979 /* |
4959 ** This function is called to obtain a shared lock on the database file. | 4980 ** This function is called to obtain a shared lock on the database file. |
4960 ** It is illegal to call sqlite3PagerAcquire() until after this function | 4981 ** It is illegal to call sqlite3PagerGet() until after this function |
4961 ** has been successfully called. If a shared-lock is already held when | 4982 ** has been successfully called. If a shared-lock is already held when |
4962 ** this function is called, it is a no-op. | 4983 ** this function is called, it is a no-op. |
4963 ** | 4984 ** |
4964 ** The following operations are also performed by this function. | 4985 ** The following operations are also performed by this function. |
4965 ** | 4986 ** |
4966 ** 1) If the pager is currently in PAGER_OPEN state (no lock held | 4987 ** 1) If the pager is currently in PAGER_OPEN state (no lock held |
4967 ** on the database file), then an attempt is made to obtain a | 4988 ** on the database file), then an attempt is made to obtain a |
4968 ** SHARED lock on the database file. Immediately after obtaining | 4989 ** SHARED lock on the database file. Immediately after obtaining |
4969 ** the SHARED lock, the file-system is checked for a hot-journal, | 4990 ** the SHARED lock, the file-system is checked for a hot-journal, |
4970 ** which is played back if present. Following any hot-journal | 4991 ** which is played back if present. Following any hot-journal |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5111 pager_error(pPager, rc); | 5132 pager_error(pPager, rc); |
5112 goto failed; | 5133 goto failed; |
5113 } | 5134 } |
5114 | 5135 |
5115 assert( pPager->eState==PAGER_OPEN ); | 5136 assert( pPager->eState==PAGER_OPEN ); |
5116 assert( (pPager->eLock==SHARED_LOCK) | 5137 assert( (pPager->eLock==SHARED_LOCK) |
5117 || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) | 5138 || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) |
5118 ); | 5139 ); |
5119 } | 5140 } |
5120 | 5141 |
5121 if( !pPager->tempFile && ( | 5142 if( !pPager->tempFile && pPager->hasHeldSharedLock ){ |
5122 pPager->pBackup | 5143 /* The shared-lock has just been acquired then check to |
5123 || sqlite3PcachePagecount(pPager->pPCache)>0 | 5144 ** see if the database has been modified. If the database has changed, |
5124 || USEFETCH(pPager) | 5145 ** flush the cache. The hasHeldSharedLock flag prevents this from |
5125 )){ | 5146 ** occurring on the very first access to a file, in order to save a |
5126 /* The shared-lock has just been acquired on the database file | 5147 ** single unnecessary sqlite3OsRead() call at the start-up. |
5127 ** and there are already pages in the cache (from a previous | |
5128 ** read or write transaction). Check to see if the database | |
5129 ** has been modified. If the database has changed, flush the | |
5130 ** cache. | |
5131 ** | 5148 ** |
5132 ** Database changes is detected by looking at 15 bytes beginning | 5149 ** Database changes are detected by looking at 15 bytes beginning |
5133 ** at offset 24 into the file. The first 4 of these 16 bytes are | 5150 ** at offset 24 into the file. The first 4 of these 16 bytes are |
5134 ** a 32-bit counter that is incremented with each change. The | 5151 ** a 32-bit counter that is incremented with each change. The |
5135 ** other bytes change randomly with each file change when | 5152 ** other bytes change randomly with each file change when |
5136 ** a codec is in use. | 5153 ** a codec is in use. |
5137 ** | 5154 ** |
5138 ** There is a vanishingly small chance that a change will not be | 5155 ** There is a vanishingly small chance that a change will not be |
5139 ** detected. The chance of an undetected change is so small that | 5156 ** detected. The chance of an undetected change is so small that |
5140 ** it can be neglected. | 5157 ** it can be neglected. |
5141 */ | 5158 */ |
5142 Pgno nPage = 0; | 5159 Pgno nPage = 0; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5188 rc = pagerPagecount(pPager, &pPager->dbSize); | 5205 rc = pagerPagecount(pPager, &pPager->dbSize); |
5189 } | 5206 } |
5190 | 5207 |
5191 failed: | 5208 failed: |
5192 if( rc!=SQLITE_OK ){ | 5209 if( rc!=SQLITE_OK ){ |
5193 assert( !MEMDB ); | 5210 assert( !MEMDB ); |
5194 pager_unlock(pPager); | 5211 pager_unlock(pPager); |
5195 assert( pPager->eState==PAGER_OPEN ); | 5212 assert( pPager->eState==PAGER_OPEN ); |
5196 }else{ | 5213 }else{ |
5197 pPager->eState = PAGER_READER; | 5214 pPager->eState = PAGER_READER; |
| 5215 pPager->hasHeldSharedLock = 1; |
5198 } | 5216 } |
5199 return rc; | 5217 return rc; |
5200 } | 5218 } |
5201 | 5219 |
5202 /* | 5220 /* |
5203 ** If the reference count has reached zero, rollback any active | 5221 ** If the reference count has reached zero, rollback any active |
5204 ** transaction and unlock the pager. | 5222 ** transaction and unlock the pager. |
5205 ** | 5223 ** |
5206 ** Except, in locking_mode=EXCLUSIVE when there is nothing to in | 5224 ** Except, in locking_mode=EXCLUSIVE when there is nothing to in |
5207 ** the rollback journal, the unlock is not performed and there is | 5225 ** the rollback journal, the unlock is not performed and there is |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5256 ** an appropriate error code is returned and *ppPage is set to NULL. | 5274 ** an appropriate error code is returned and *ppPage is set to NULL. |
5257 ** | 5275 ** |
5258 ** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt | 5276 ** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt |
5259 ** to find a page in the in-memory cache first. If the page is not already | 5277 ** to find a page in the in-memory cache first. If the page is not already |
5260 ** in memory, this routine goes to disk to read it in whereas Lookup() | 5278 ** in memory, this routine goes to disk to read it in whereas Lookup() |
5261 ** just returns 0. This routine acquires a read-lock the first time it | 5279 ** just returns 0. This routine acquires a read-lock the first time it |
5262 ** has to go to disk, and could also playback an old journal if necessary. | 5280 ** has to go to disk, and could also playback an old journal if necessary. |
5263 ** Since Lookup() never goes to disk, it never has to deal with locks | 5281 ** Since Lookup() never goes to disk, it never has to deal with locks |
5264 ** or journal files. | 5282 ** or journal files. |
5265 */ | 5283 */ |
5266 int sqlite3PagerAcquire( | 5284 int sqlite3PagerGet( |
5267 Pager *pPager, /* The pager open on the database file */ | 5285 Pager *pPager, /* The pager open on the database file */ |
5268 Pgno pgno, /* Page number to fetch */ | 5286 Pgno pgno, /* Page number to fetch */ |
5269 DbPage **ppPage, /* Write a pointer to the page here */ | 5287 DbPage **ppPage, /* Write a pointer to the page here */ |
5270 int flags /* PAGER_GET_XXX flags */ | 5288 int flags /* PAGER_GET_XXX flags */ |
5271 ){ | 5289 ){ |
5272 int rc = SQLITE_OK; | 5290 int rc = SQLITE_OK; |
5273 PgHdr *pPg = 0; | 5291 PgHdr *pPg = 0; |
5274 u32 iFrame = 0; /* Frame to read from WAL file */ | 5292 u32 iFrame = 0; /* Frame to read from WAL file */ |
5275 const int noContent = (flags & PAGER_GET_NOCONTENT); | 5293 const int noContent = (flags & PAGER_GET_NOCONTENT); |
5276 | 5294 |
5277 /* It is acceptable to use a read-only (mmap) page for any page except | 5295 /* It is acceptable to use a read-only (mmap) page for any page except |
5278 ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY | 5296 ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY |
5279 ** flag was specified by the caller. And so long as the db is not a | 5297 ** flag was specified by the caller. And so long as the db is not a |
5280 ** temporary or in-memory database. */ | 5298 ** temporary or in-memory database. */ |
5281 const int bMmapOk = (pgno!=1 && USEFETCH(pPager) | 5299 const int bMmapOk = (pgno>1 && USEFETCH(pPager) |
5282 && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) | 5300 && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) |
5283 #ifdef SQLITE_HAS_CODEC | 5301 #ifdef SQLITE_HAS_CODEC |
5284 && pPager->xCodec==0 | 5302 && pPager->xCodec==0 |
5285 #endif | 5303 #endif |
5286 ); | 5304 ); |
5287 | 5305 |
| 5306 /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here |
| 5307 ** allows the compiler optimizer to reuse the results of the "pgno>1" |
| 5308 ** test in the previous statement, and avoid testing pgno==0 in the |
| 5309 ** common case where pgno is large. */ |
| 5310 if( pgno<=1 && pgno==0 ){ |
| 5311 return SQLITE_CORRUPT_BKPT; |
| 5312 } |
5288 assert( pPager->eState>=PAGER_READER ); | 5313 assert( pPager->eState>=PAGER_READER ); |
5289 assert( assert_pager_state(pPager) ); | 5314 assert( assert_pager_state(pPager) ); |
5290 assert( noContent==0 || bMmapOk==0 ); | 5315 assert( noContent==0 || bMmapOk==0 ); |
5291 | 5316 |
5292 if( pgno==0 ){ | 5317 assert( pPager->hasHeldSharedLock==1 ); |
5293 return SQLITE_CORRUPT_BKPT; | |
5294 } | |
5295 | 5318 |
5296 /* If the pager is in the error state, return an error immediately. | 5319 /* If the pager is in the error state, return an error immediately. |
5297 ** Otherwise, request the page from the PCache layer. */ | 5320 ** Otherwise, request the page from the PCache layer. */ |
5298 if( pPager->errCode!=SQLITE_OK ){ | 5321 if( pPager->errCode!=SQLITE_OK ){ |
5299 rc = pPager->errCode; | 5322 rc = pPager->errCode; |
5300 }else{ | 5323 }else{ |
5301 if( bMmapOk && pagerUseWal(pPager) ){ | 5324 if( bMmapOk && pagerUseWal(pPager) ){ |
5302 rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); | 5325 rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); |
5303 if( rc!=SQLITE_OK ) goto pager_acquire_err; | 5326 if( rc!=SQLITE_OK ) goto pager_acquire_err; |
5304 } | 5327 } |
(...skipping 24 matching lines...) Expand all Loading... |
5329 goto pager_acquire_err; | 5352 goto pager_acquire_err; |
5330 } | 5353 } |
5331 } | 5354 } |
5332 | 5355 |
5333 { | 5356 { |
5334 sqlite3_pcache_page *pBase; | 5357 sqlite3_pcache_page *pBase; |
5335 pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); | 5358 pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); |
5336 if( pBase==0 ){ | 5359 if( pBase==0 ){ |
5337 rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); | 5360 rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); |
5338 if( rc!=SQLITE_OK ) goto pager_acquire_err; | 5361 if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 5362 if( pBase==0 ){ |
| 5363 pPg = *ppPage = 0; |
| 5364 rc = SQLITE_NOMEM; |
| 5365 goto pager_acquire_err; |
| 5366 } |
5339 } | 5367 } |
5340 pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); | 5368 pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); |
5341 if( pPg==0 ) rc = SQLITE_NOMEM; | 5369 assert( pPg!=0 ); |
5342 } | 5370 } |
5343 } | 5371 } |
5344 | 5372 |
5345 if( rc!=SQLITE_OK ){ | 5373 if( rc!=SQLITE_OK ){ |
5346 /* Either the call to sqlite3PcacheFetch() returned an error or the | 5374 /* Either the call to sqlite3PcacheFetch() returned an error or the |
5347 ** pager was already in the error-state when this function was called. | 5375 ** pager was already in the error-state when this function was called. |
5348 ** Set pPg to 0 and jump to the exception handler. */ | 5376 ** Set pPg to 0 and jump to the exception handler. */ |
5349 pPg = 0; | 5377 pPg = 0; |
5350 goto pager_acquire_err; | 5378 goto pager_acquire_err; |
5351 } | 5379 } |
5352 assert( (*ppPage)->pgno==pgno ); | 5380 assert( pPg==(*ppPage) ); |
5353 assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 ); | 5381 assert( pPg->pgno==pgno ); |
| 5382 assert( pPg->pPager==pPager || pPg->pPager==0 ); |
5354 | 5383 |
5355 if( (*ppPage)->pPager && !noContent ){ | 5384 if( pPg->pPager && !noContent ){ |
5356 /* In this case the pcache already contains an initialized copy of | 5385 /* In this case the pcache already contains an initialized copy of |
5357 ** the page. Return without further ado. */ | 5386 ** the page. Return without further ado. */ |
5358 assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); | 5387 assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); |
5359 pPager->aStat[PAGER_STAT_HIT]++; | 5388 pPager->aStat[PAGER_STAT_HIT]++; |
5360 return SQLITE_OK; | 5389 return SQLITE_OK; |
5361 | 5390 |
5362 }else{ | 5391 }else{ |
5363 /* The pager cache has created a new page. Its content needs to | 5392 /* The pager cache has created a new page. Its content needs to |
5364 ** be initialized. */ | 5393 ** be initialized. */ |
5365 | 5394 |
5366 pPg = *ppPage; | |
5367 pPg->pPager = pPager; | 5395 pPg->pPager = pPager; |
5368 | 5396 |
5369 /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page | 5397 /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page |
5370 ** number greater than this, or the unused locking-page, is requested. */ | 5398 ** number greater than this, or the unused locking-page, is requested. */ |
5371 if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ | 5399 if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ |
5372 rc = SQLITE_CORRUPT_BKPT; | 5400 rc = SQLITE_CORRUPT_BKPT; |
5373 goto pager_acquire_err; | 5401 goto pager_acquire_err; |
5374 } | 5402 } |
5375 | 5403 |
5376 if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){ | 5404 if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){ |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5434 ** in the page if the page is not already in cache. This routine | 5462 ** in the page if the page is not already in cache. This routine |
5435 ** returns NULL if the page is not in cache or if a disk I/O error | 5463 ** returns NULL if the page is not in cache or if a disk I/O error |
5436 ** has ever happened. | 5464 ** has ever happened. |
5437 */ | 5465 */ |
5438 DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ | 5466 DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ |
5439 sqlite3_pcache_page *pPage; | 5467 sqlite3_pcache_page *pPage; |
5440 assert( pPager!=0 ); | 5468 assert( pPager!=0 ); |
5441 assert( pgno!=0 ); | 5469 assert( pgno!=0 ); |
5442 assert( pPager->pPCache!=0 ); | 5470 assert( pPager->pPCache!=0 ); |
5443 pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0); | 5471 pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0); |
| 5472 assert( pPage==0 || pPager->hasHeldSharedLock ); |
| 5473 if( pPage==0 ) return 0; |
5444 return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); | 5474 return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); |
5445 } | 5475 } |
5446 | 5476 |
5447 /* | 5477 /* |
5448 ** Release a page reference. | 5478 ** Release a page reference. |
5449 ** | 5479 ** |
5450 ** If the number of references to the page drop to zero, then the | 5480 ** If the number of references to the page drop to zero, then the |
5451 ** page is added to the LRU list. When all references to all pages | 5481 ** page is added to the LRU list. When all references to all pages |
5452 ** are released, a rollback occurs and the lock on the database is | 5482 ** are released, a rollback occurs and the lock on the database is |
5453 ** removed. | 5483 ** removed. |
5454 */ | 5484 */ |
5455 void sqlite3PagerUnrefNotNull(DbPage *pPg){ | 5485 void sqlite3PagerUnrefNotNull(DbPage *pPg){ |
5456 Pager *pPager; | 5486 Pager *pPager; |
5457 assert( pPg!=0 ); | 5487 assert( pPg!=0 ); |
5458 pPager = pPg->pPager; | 5488 pPager = pPg->pPager; |
5459 if( pPg->flags & PGHDR_MMAP ){ | 5489 if( pPg->flags & PGHDR_MMAP ){ |
5460 pagerReleaseMapPage(pPg); | 5490 pagerReleaseMapPage(pPg); |
5461 }else{ | 5491 }else{ |
5462 sqlite3PcacheRelease(pPg); | 5492 sqlite3PcacheRelease(pPg); |
5463 } | 5493 } |
5464 pagerUnlockIfUnused(pPager); | 5494 pagerUnlockIfUnused(pPager); |
5465 } | 5495 } |
5466 void sqlite3PagerUnref(DbPage *pPg){ | 5496 void sqlite3PagerUnref(DbPage *pPg){ |
5467 if( pPg ) sqlite3PagerUnrefNotNull(pPg); | 5497 if( pPg ) sqlite3PagerUnrefNotNull(pPg); |
5468 } | 5498 } |
5469 | 5499 |
5470 #if defined(__APPLE__) | |
5471 /* | |
5472 ** Create and return a CFURLRef given a cstring containing the path to a file. | |
5473 */ | |
5474 static CFURLRef create_cfurl_from_cstring(const char* filePath){ | |
5475 CFStringRef urlString = CFStringCreateWithFileSystemRepresentation( | |
5476 kCFAllocatorDefault, filePath); | |
5477 CFURLRef urlRef = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, | |
5478 urlString, kCFURLPOSIXPathStyle, FALSE); | |
5479 CFRelease(urlString); | |
5480 return urlRef; | |
5481 } | |
5482 #endif | |
5483 | |
5484 /* | 5500 /* |
5485 ** This function is called at the start of every write transaction. | 5501 ** This function is called at the start of every write transaction. |
5486 ** There must already be a RESERVED or EXCLUSIVE lock on the database | 5502 ** There must already be a RESERVED or EXCLUSIVE lock on the database |
5487 ** file when this routine is called. | 5503 ** file when this routine is called. |
5488 ** | 5504 ** |
5489 ** Open the journal file for pager pPager and write a journal header | 5505 ** Open the journal file for pager pPager and write a journal header |
5490 ** to the start of it. If there are active savepoints, open the sub-journal | 5506 ** to the start of it. If there are active savepoints, open the sub-journal |
5491 ** as well. This function is only used when the journal file is being | 5507 ** as well. This function is only used when the journal file is being |
5492 ** opened to write a rollback log for a transaction. It is not used | 5508 ** opened to write a rollback log for a transaction. It is not used |
5493 ** when opening a hot journal file to roll it back. | 5509 ** when opening a hot journal file to roll it back. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5538 ** it was originally opened. */ | 5554 ** it was originally opened. */ |
5539 rc = databaseIsUnmoved(pPager); | 5555 rc = databaseIsUnmoved(pPager); |
5540 if( rc==SQLITE_OK ){ | 5556 if( rc==SQLITE_OK ){ |
5541 #ifdef SQLITE_ENABLE_ATOMIC_WRITE | 5557 #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
5542 rc = sqlite3JournalOpen( | 5558 rc = sqlite3JournalOpen( |
5543 pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) | 5559 pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) |
5544 ); | 5560 ); |
5545 #else | 5561 #else |
5546 rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); | 5562 rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); |
5547 #endif | 5563 #endif |
5548 #if defined(__APPLE__) | |
5549 /* Set the TimeMachine exclusion metadata for the journal if it has | |
5550 ** been set for the database. Only do this for unix-type vfs | |
5551 ** implementations. */ | |
5552 if( rc==SQLITE_OK && pPager->zFilename!=NULL | |
5553 && strlen(pPager->zFilename)>0 | |
5554 && strncmp(pVfs->zName, "unix", 4)==0 | |
5555 && ( pVfs->zName[4]=='-' || pVfs->zName[4]=='\0' ) ){ | |
5556 CFURLRef database = create_cfurl_from_cstring(pPager->zFilename); | |
5557 if( CSBackupIsItemExcluded(database, NULL) ){ | |
5558 CFURLRef journal = create_cfurl_from_cstring(pPager->zJournal); | |
5559 /* Ignore errors from the following exclusion call. */ | |
5560 CSBackupSetItemExcluded(journal, TRUE, FALSE); | |
5561 CFRelease(journal); | |
5562 } | |
5563 CFRelease(database); | |
5564 } | |
5565 #endif | |
5566 } | 5564 } |
5567 } | 5565 } |
5568 assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); | 5566 assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); |
5569 } | 5567 } |
5570 | 5568 |
5571 | 5569 |
5572 /* Write the first journal header to the journal file and open | 5570 /* Write the first journal header to the journal file and open |
5573 ** the sub-journal if necessary. | 5571 ** the sub-journal if necessary. |
5574 */ | 5572 */ |
5575 if( rc==SQLITE_OK ){ | 5573 if( rc==SQLITE_OK ){ |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5622 | 5620 |
5623 if( pagerUseWal(pPager) ){ | 5621 if( pagerUseWal(pPager) ){ |
5624 /* If the pager is configured to use locking_mode=exclusive, and an | 5622 /* If the pager is configured to use locking_mode=exclusive, and an |
5625 ** exclusive lock on the database is not already held, obtain it now. | 5623 ** exclusive lock on the database is not already held, obtain it now. |
5626 */ | 5624 */ |
5627 if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ | 5625 if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ |
5628 rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); | 5626 rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); |
5629 if( rc!=SQLITE_OK ){ | 5627 if( rc!=SQLITE_OK ){ |
5630 return rc; | 5628 return rc; |
5631 } | 5629 } |
5632 sqlite3WalExclusiveMode(pPager->pWal, 1); | 5630 (void)sqlite3WalExclusiveMode(pPager->pWal, 1); |
5633 } | 5631 } |
5634 | 5632 |
5635 /* Grab the write lock on the log file. If successful, upgrade to | 5633 /* Grab the write lock on the log file. If successful, upgrade to |
5636 ** PAGER_RESERVED state. Otherwise, return an error code to the caller. | 5634 ** PAGER_RESERVED state. Otherwise, return an error code to the caller. |
5637 ** The busy-handler is not invoked if another connection already | 5635 ** The busy-handler is not invoked if another connection already |
5638 ** holds the write-lock. If possible, the upper layer will call it. | 5636 ** holds the write-lock. If possible, the upper layer will call it. |
5639 */ | 5637 */ |
5640 rc = sqlite3WalBeginWriteTransaction(pPager->pWal); | 5638 rc = sqlite3WalBeginWriteTransaction(pPager->pWal); |
5641 }else{ | 5639 }else{ |
5642 /* Obtain a RESERVED lock on the database file. If the exFlag parameter | 5640 /* Obtain a RESERVED lock on the database file. If the exFlag parameter |
(...skipping 27 matching lines...) Expand all Loading... |
5670 assert( rc==SQLITE_OK || pPager->eState==PAGER_READER ); | 5668 assert( rc==SQLITE_OK || pPager->eState==PAGER_READER ); |
5671 assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED ); | 5669 assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED ); |
5672 assert( assert_pager_state(pPager) ); | 5670 assert( assert_pager_state(pPager) ); |
5673 } | 5671 } |
5674 | 5672 |
5675 PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); | 5673 PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); |
5676 return rc; | 5674 return rc; |
5677 } | 5675 } |
5678 | 5676 |
5679 /* | 5677 /* |
| 5678 ** Write page pPg onto the end of the rollback journal. |
| 5679 */ |
| 5680 static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){ |
| 5681 Pager *pPager = pPg->pPager; |
| 5682 int rc; |
| 5683 u32 cksum; |
| 5684 char *pData2; |
| 5685 i64 iOff = pPager->journalOff; |
| 5686 |
| 5687 /* We should never write to the journal file the page that |
| 5688 ** contains the database locks. The following assert verifies |
| 5689 ** that we do not. */ |
| 5690 assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) ); |
| 5691 |
| 5692 assert( pPager->journalHdr<=pPager->journalOff ); |
| 5693 CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); |
| 5694 cksum = pager_cksum(pPager, (u8*)pData2); |
| 5695 |
| 5696 /* Even if an IO or diskfull error occurs while journalling the |
| 5697 ** page in the block above, set the need-sync flag for the page. |
| 5698 ** Otherwise, when the transaction is rolled back, the logic in |
| 5699 ** playback_one_page() will think that the page needs to be restored |
| 5700 ** in the database file. And if an IO error occurs while doing so, |
| 5701 ** then corruption may follow. |
| 5702 */ |
| 5703 pPg->flags |= PGHDR_NEED_SYNC; |
| 5704 |
| 5705 rc = write32bits(pPager->jfd, iOff, pPg->pgno); |
| 5706 if( rc!=SQLITE_OK ) return rc; |
| 5707 rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); |
| 5708 if( rc!=SQLITE_OK ) return rc; |
| 5709 rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); |
| 5710 if( rc!=SQLITE_OK ) return rc; |
| 5711 |
| 5712 IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, |
| 5713 pPager->journalOff, pPager->pageSize)); |
| 5714 PAGER_INCR(sqlite3_pager_writej_count); |
| 5715 PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", |
| 5716 PAGERID(pPager), pPg->pgno, |
| 5717 ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); |
| 5718 |
| 5719 pPager->journalOff += 8 + pPager->pageSize; |
| 5720 pPager->nRec++; |
| 5721 assert( pPager->pInJournal!=0 ); |
| 5722 rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); |
| 5723 testcase( rc==SQLITE_NOMEM ); |
| 5724 assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); |
| 5725 rc |= addToSavepointBitvecs(pPager, pPg->pgno); |
| 5726 assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); |
| 5727 return rc; |
| 5728 } |
| 5729 |
| 5730 /* |
5680 ** Mark a single data page as writeable. The page is written into the | 5731 ** Mark a single data page as writeable. The page is written into the |
5681 ** main journal or sub-journal as required. If the page is written into | 5732 ** main journal or sub-journal as required. If the page is written into |
5682 ** one of the journals, the corresponding bit is set in the | 5733 ** one of the journals, the corresponding bit is set in the |
5683 ** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs | 5734 ** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs |
5684 ** of any open savepoints as appropriate. | 5735 ** of any open savepoints as appropriate. |
5685 */ | 5736 */ |
5686 static int pager_write(PgHdr *pPg){ | 5737 static int pager_write(PgHdr *pPg){ |
5687 Pager *pPager = pPg->pPager; | 5738 Pager *pPager = pPg->pPager; |
5688 int rc = SQLITE_OK; | 5739 int rc = SQLITE_OK; |
5689 int inJournal; | |
5690 | 5740 |
5691 /* This routine is not called unless a write-transaction has already | 5741 /* This routine is not called unless a write-transaction has already |
5692 ** been started. The journal file may or may not be open at this point. | 5742 ** been started. The journal file may or may not be open at this point. |
5693 ** It is never called in the ERROR state. | 5743 ** It is never called in the ERROR state. |
5694 */ | 5744 */ |
5695 assert( pPager->eState==PAGER_WRITER_LOCKED | 5745 assert( pPager->eState==PAGER_WRITER_LOCKED |
5696 || pPager->eState==PAGER_WRITER_CACHEMOD | 5746 || pPager->eState==PAGER_WRITER_CACHEMOD |
5697 || pPager->eState==PAGER_WRITER_DBMOD | 5747 || pPager->eState==PAGER_WRITER_DBMOD |
5698 ); | 5748 ); |
5699 assert( assert_pager_state(pPager) ); | 5749 assert( assert_pager_state(pPager) ); |
5700 assert( pPager->errCode==0 ); | 5750 assert( pPager->errCode==0 ); |
5701 assert( pPager->readOnly==0 ); | 5751 assert( pPager->readOnly==0 ); |
5702 | |
5703 CHECK_PAGE(pPg); | 5752 CHECK_PAGE(pPg); |
5704 | 5753 |
5705 /* The journal file needs to be opened. Higher level routines have already | 5754 /* The journal file needs to be opened. Higher level routines have already |
5706 ** obtained the necessary locks to begin the write-transaction, but the | 5755 ** obtained the necessary locks to begin the write-transaction, but the |
5707 ** rollback journal might not yet be open. Open it now if this is the case. | 5756 ** rollback journal might not yet be open. Open it now if this is the case. |
5708 ** | 5757 ** |
5709 ** This is done before calling sqlite3PcacheMakeDirty() on the page. | 5758 ** This is done before calling sqlite3PcacheMakeDirty() on the page. |
5710 ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then | 5759 ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then |
5711 ** an error might occur and the pager would end up in WRITER_LOCKED state | 5760 ** an error might occur and the pager would end up in WRITER_LOCKED state |
5712 ** with pages marked as dirty in the cache. | 5761 ** with pages marked as dirty in the cache. |
5713 */ | 5762 */ |
5714 if( pPager->eState==PAGER_WRITER_LOCKED ){ | 5763 if( pPager->eState==PAGER_WRITER_LOCKED ){ |
5715 rc = pager_open_journal(pPager); | 5764 rc = pager_open_journal(pPager); |
5716 if( rc!=SQLITE_OK ) return rc; | 5765 if( rc!=SQLITE_OK ) return rc; |
5717 } | 5766 } |
5718 assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); | 5767 assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); |
5719 assert( assert_pager_state(pPager) ); | 5768 assert( assert_pager_state(pPager) ); |
5720 | 5769 |
5721 /* Mark the page as dirty. If the page has already been written | 5770 /* Mark the page that is about to be modified as dirty. */ |
5722 ** to the journal then we can return right away. | 5771 sqlite3PcacheMakeDirty(pPg); |
| 5772 |
| 5773 /* If a rollback journal is in use, them make sure the page that is about |
| 5774 ** to change is in the rollback journal, or if the page is a new page off |
| 5775 ** then end of the file, make sure it is marked as PGHDR_NEED_SYNC. |
5723 */ | 5776 */ |
5724 sqlite3PcacheMakeDirty(pPg); | 5777 assert( (pPager->pInJournal!=0) == isOpen(pPager->jfd) ); |
5725 inJournal = pageInJournal(pPager, pPg); | 5778 if( pPager->pInJournal!=0 |
5726 if( inJournal && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){ | 5779 && sqlite3BitvecTestNotNull(pPager->pInJournal, pPg->pgno)==0 |
5727 assert( !pagerUseWal(pPager) ); | 5780 ){ |
5728 }else{ | 5781 assert( pagerUseWal(pPager)==0 ); |
5729 | 5782 if( pPg->pgno<=pPager->dbOrigSize ){ |
5730 /* The transaction journal now exists and we have a RESERVED or an | 5783 rc = pagerAddPageToRollbackJournal(pPg); |
5731 ** EXCLUSIVE lock on the main database file. Write the current page to | 5784 if( rc!=SQLITE_OK ){ |
5732 ** the transaction journal if it is not there already. | 5785 return rc; |
5733 */ | 5786 } |
5734 if( !inJournal && !pagerUseWal(pPager) ){ | 5787 }else{ |
5735 assert( pagerUseWal(pPager)==0 ); | 5788 if( pPager->eState!=PAGER_WRITER_DBMOD ){ |
5736 if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){ | |
5737 u32 cksum; | |
5738 char *pData2; | |
5739 i64 iOff = pPager->journalOff; | |
5740 | |
5741 /* We should never write to the journal file the page that | |
5742 ** contains the database locks. The following assert verifies | |
5743 ** that we do not. */ | |
5744 assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) ); | |
5745 | |
5746 assert( pPager->journalHdr<=pPager->journalOff ); | |
5747 CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); | |
5748 cksum = pager_cksum(pPager, (u8*)pData2); | |
5749 | |
5750 /* Even if an IO or diskfull error occurs while journalling the | |
5751 ** page in the block above, set the need-sync flag for the page. | |
5752 ** Otherwise, when the transaction is rolled back, the logic in | |
5753 ** playback_one_page() will think that the page needs to be restored | |
5754 ** in the database file. And if an IO error occurs while doing so, | |
5755 ** then corruption may follow. | |
5756 */ | |
5757 pPg->flags |= PGHDR_NEED_SYNC; | 5789 pPg->flags |= PGHDR_NEED_SYNC; |
5758 | |
5759 rc = write32bits(pPager->jfd, iOff, pPg->pgno); | |
5760 if( rc!=SQLITE_OK ) return rc; | |
5761 rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); | |
5762 if( rc!=SQLITE_OK ) return rc; | |
5763 rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); | |
5764 if( rc!=SQLITE_OK ) return rc; | |
5765 | |
5766 IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, | |
5767 pPager->journalOff, pPager->pageSize)); | |
5768 PAGER_INCR(sqlite3_pager_writej_count); | |
5769 PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", | |
5770 PAGERID(pPager), pPg->pgno, | |
5771 ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); | |
5772 | |
5773 pPager->journalOff += 8 + pPager->pageSize; | |
5774 pPager->nRec++; | |
5775 assert( pPager->pInJournal!=0 ); | |
5776 rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); | |
5777 testcase( rc==SQLITE_NOMEM ); | |
5778 assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); | |
5779 rc |= addToSavepointBitvecs(pPager, pPg->pgno); | |
5780 if( rc!=SQLITE_OK ){ | |
5781 assert( rc==SQLITE_NOMEM ); | |
5782 return rc; | |
5783 } | |
5784 }else{ | |
5785 if( pPager->eState!=PAGER_WRITER_DBMOD ){ | |
5786 pPg->flags |= PGHDR_NEED_SYNC; | |
5787 } | |
5788 PAGERTRACE(("APPEND %d page %d needSync=%d\n", | |
5789 PAGERID(pPager), pPg->pgno, | |
5790 ((pPg->flags&PGHDR_NEED_SYNC)?1:0))); | |
5791 } | 5790 } |
5792 } | 5791 PAGERTRACE(("APPEND %d page %d needSync=%d\n", |
5793 | 5792 PAGERID(pPager), pPg->pgno, |
5794 /* If the statement journal is open and the page is not in it, | 5793 ((pPg->flags&PGHDR_NEED_SYNC)?1:0))); |
5795 ** then write the current page to the statement journal. Note that | |
5796 ** the statement journal format differs from the standard journal format | |
5797 ** in that it omits the checksums and the header. | |
5798 */ | |
5799 if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){ | |
5800 rc = subjournalPage(pPg); | |
5801 } | 5794 } |
5802 } | 5795 } |
5803 | 5796 |
5804 /* Update the database size and return. | 5797 /* The PGHDR_DIRTY bit is set above when the page was added to the dirty-list |
| 5798 ** and before writing the page into the rollback journal. Wait until now, |
| 5799 ** after the page has been successfully journalled, before setting the |
| 5800 ** PGHDR_WRITEABLE bit that indicates that the page can be safely modified. |
5805 */ | 5801 */ |
| 5802 pPg->flags |= PGHDR_WRITEABLE; |
| 5803 |
| 5804 /* If the statement journal is open and the page is not in it, |
| 5805 ** then write the page into the statement journal. |
| 5806 */ |
| 5807 if( pPager->nSavepoint>0 ){ |
| 5808 rc = subjournalPageIfRequired(pPg); |
| 5809 } |
| 5810 |
| 5811 /* Update the database size and return. */ |
5806 if( pPager->dbSize<pPg->pgno ){ | 5812 if( pPager->dbSize<pPg->pgno ){ |
5807 pPager->dbSize = pPg->pgno; | 5813 pPager->dbSize = pPg->pgno; |
5808 } | 5814 } |
5809 return rc; | 5815 return rc; |
5810 } | 5816 } |
5811 | 5817 |
5812 /* | 5818 /* |
5813 ** This is a variant of sqlite3PagerWrite() that runs when the sector size | 5819 ** This is a variant of sqlite3PagerWrite() that runs when the sector size |
5814 ** is larger than the page size. SQLite makes the (reasonable) assumption that | 5820 ** is larger than the page size. SQLite makes the (reasonable) assumption that |
5815 ** all bytes of a sector are written together by hardware. Hence, all bytes of | 5821 ** all bytes of a sector are written together by hardware. Hence, all bytes of |
5816 ** a sector need to be journalled in case of a power loss in the middle of | 5822 ** a sector need to be journalled in case of a power loss in the middle of |
5817 ** a write. | 5823 ** a write. |
5818 ** | 5824 ** |
5819 ** Usually, the sector size is less than or equal to the page size, in which | 5825 ** Usually, the sector size is less than or equal to the page size, in which |
5820 ** case pages can be individually written. This routine only runs in the except
ional | 5826 ** case pages can be individually written. This routine only runs in the |
5821 ** case where the page size is smaller than the sector size. | 5827 ** exceptional case where the page size is smaller than the sector size. |
5822 */ | 5828 */ |
5823 static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ | 5829 static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ |
5824 int rc = SQLITE_OK; /* Return code */ | 5830 int rc = SQLITE_OK; /* Return code */ |
5825 Pgno nPageCount; /* Total number of pages in database file */ | 5831 Pgno nPageCount; /* Total number of pages in database file */ |
5826 Pgno pg1; /* First page of the sector pPg is located on.
*/ | 5832 Pgno pg1; /* First page of the sector pPg is located on. */ |
5827 int nPage = 0; /* Number of pages starting at pg1 to journal *
/ | 5833 int nPage = 0; /* Number of pages starting at pg1 to journal */ |
5828 int ii; /* Loop counter */ | 5834 int ii; /* Loop counter */ |
5829 int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ | 5835 int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ |
5830 Pager *pPager = pPg->pPager; /* The pager that owns pPg */ | 5836 Pager *pPager = pPg->pPager; /* The pager that owns pPg */ |
5831 Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); | 5837 Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); |
5832 | 5838 |
5833 /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow | 5839 /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow |
5834 ** a journal header to be written between the pages journaled by | 5840 ** a journal header to be written between the pages journaled by |
5835 ** this function. | 5841 ** this function. |
5836 */ | 5842 */ |
5837 assert( !MEMDB ); | 5843 assert( !MEMDB ); |
5838 assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); | 5844 assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); |
5839 pPager->doNotSpill |= SPILLFLAG_NOSYNC; | 5845 pPager->doNotSpill |= SPILLFLAG_NOSYNC; |
5840 | 5846 |
(...skipping 13 matching lines...) Expand all Loading... |
5854 } | 5860 } |
5855 assert(nPage>0); | 5861 assert(nPage>0); |
5856 assert(pg1<=pPg->pgno); | 5862 assert(pg1<=pPg->pgno); |
5857 assert((pg1+nPage)>pPg->pgno); | 5863 assert((pg1+nPage)>pPg->pgno); |
5858 | 5864 |
5859 for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){ | 5865 for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){ |
5860 Pgno pg = pg1+ii; | 5866 Pgno pg = pg1+ii; |
5861 PgHdr *pPage; | 5867 PgHdr *pPage; |
5862 if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ | 5868 if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ |
5863 if( pg!=PAGER_MJ_PGNO(pPager) ){ | 5869 if( pg!=PAGER_MJ_PGNO(pPager) ){ |
5864 rc = sqlite3PagerGet(pPager, pg, &pPage); | 5870 rc = sqlite3PagerGet(pPager, pg, &pPage, 0); |
5865 if( rc==SQLITE_OK ){ | 5871 if( rc==SQLITE_OK ){ |
5866 rc = pager_write(pPage); | 5872 rc = pager_write(pPage); |
5867 if( pPage->flags&PGHDR_NEED_SYNC ){ | 5873 if( pPage->flags&PGHDR_NEED_SYNC ){ |
5868 needSync = 1; | 5874 needSync = 1; |
5869 } | 5875 } |
5870 sqlite3PagerUnrefNotNull(pPage); | 5876 sqlite3PagerUnrefNotNull(pPage); |
5871 } | 5877 } |
5872 } | 5878 } |
5873 }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){ | 5879 }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){ |
5874 if( pPage->flags&PGHDR_NEED_SYNC ){ | 5880 if( pPage->flags&PGHDR_NEED_SYNC ){ |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5908 ** | 5914 ** |
5909 ** The difference between this function and pager_write() is that this | 5915 ** The difference between this function and pager_write() is that this |
5910 ** function also deals with the special case where 2 or more pages | 5916 ** function also deals with the special case where 2 or more pages |
5911 ** fit on a single disk sector. In this case all co-resident pages | 5917 ** fit on a single disk sector. In this case all co-resident pages |
5912 ** must have been written to the journal file before returning. | 5918 ** must have been written to the journal file before returning. |
5913 ** | 5919 ** |
5914 ** If an error occurs, SQLITE_NOMEM or an IO error code is returned | 5920 ** If an error occurs, SQLITE_NOMEM or an IO error code is returned |
5915 ** as appropriate. Otherwise, SQLITE_OK. | 5921 ** as appropriate. Otherwise, SQLITE_OK. |
5916 */ | 5922 */ |
5917 int sqlite3PagerWrite(PgHdr *pPg){ | 5923 int sqlite3PagerWrite(PgHdr *pPg){ |
| 5924 Pager *pPager = pPg->pPager; |
5918 assert( (pPg->flags & PGHDR_MMAP)==0 ); | 5925 assert( (pPg->flags & PGHDR_MMAP)==0 ); |
5919 assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED ); | 5926 assert( pPager->eState>=PAGER_WRITER_LOCKED ); |
5920 assert( pPg->pPager->eState!=PAGER_ERROR ); | 5927 assert( assert_pager_state(pPager) ); |
5921 assert( assert_pager_state(pPg->pPager) ); | 5928 if( pPager->errCode ){ |
5922 if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){ | 5929 return pPager->errCode; |
| 5930 }else if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ |
| 5931 if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg); |
| 5932 return SQLITE_OK; |
| 5933 }else if( pPager->sectorSize > (u32)pPager->pageSize ){ |
5923 return pagerWriteLargeSector(pPg); | 5934 return pagerWriteLargeSector(pPg); |
5924 }else{ | 5935 }else{ |
5925 return pager_write(pPg); | 5936 return pager_write(pPg); |
5926 } | 5937 } |
5927 } | 5938 } |
5928 | 5939 |
5929 /* | 5940 /* |
5930 ** Return TRUE if the page given in the argument was previously passed | 5941 ** Return TRUE if the page given in the argument was previously passed |
5931 ** to sqlite3PagerWrite(). In other words, return TRUE if it is ok | 5942 ** to sqlite3PagerWrite(). In other words, return TRUE if it is ok |
5932 ** to change the content of the page. | 5943 ** to change the content of the page. |
5933 */ | 5944 */ |
5934 #ifndef NDEBUG | 5945 #ifndef NDEBUG |
5935 int sqlite3PagerIswriteable(DbPage *pPg){ | 5946 int sqlite3PagerIswriteable(DbPage *pPg){ |
5936 return pPg->flags&PGHDR_DIRTY; | 5947 return pPg->flags & PGHDR_WRITEABLE; |
5937 } | 5948 } |
5938 #endif | 5949 #endif |
5939 | 5950 |
5940 /* | 5951 /* |
5941 ** A call to this routine tells the pager that it is not necessary to | 5952 ** A call to this routine tells the pager that it is not necessary to |
5942 ** write the information on page pPg back to the disk, even though | 5953 ** write the information on page pPg back to the disk, even though |
5943 ** that page might be marked as dirty. This happens, for example, when | 5954 ** that page might be marked as dirty. This happens, for example, when |
5944 ** the page has been added as a leaf of the freelist and so its | 5955 ** the page has been added as a leaf of the freelist and so its |
5945 ** content no longer matters. | 5956 ** content no longer matters. |
5946 ** | 5957 ** |
5947 ** The overlying software layer calls this routine when all of the data | 5958 ** The overlying software layer calls this routine when all of the data |
5948 ** on the given page is unused. The pager marks the page as clean so | 5959 ** on the given page is unused. The pager marks the page as clean so |
5949 ** that it does not get written to disk. | 5960 ** that it does not get written to disk. |
5950 ** | 5961 ** |
5951 ** Tests show that this optimization can quadruple the speed of large | 5962 ** Tests show that this optimization can quadruple the speed of large |
5952 ** DELETE operations. | 5963 ** DELETE operations. |
5953 */ | 5964 */ |
5954 void sqlite3PagerDontWrite(PgHdr *pPg){ | 5965 void sqlite3PagerDontWrite(PgHdr *pPg){ |
5955 Pager *pPager = pPg->pPager; | 5966 Pager *pPager = pPg->pPager; |
5956 if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ | 5967 if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ |
5957 PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); | 5968 PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); |
5958 IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) | 5969 IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) |
5959 pPg->flags |= PGHDR_DONT_WRITE; | 5970 pPg->flags |= PGHDR_DONT_WRITE; |
| 5971 pPg->flags &= ~PGHDR_WRITEABLE; |
5960 pager_set_pagehash(pPg); | 5972 pager_set_pagehash(pPg); |
5961 } | 5973 } |
5962 } | 5974 } |
5963 | 5975 |
5964 /* | 5976 /* |
5965 ** This routine is called to increment the value of the database file | 5977 ** This routine is called to increment the value of the database file |
5966 ** change-counter, stored as a 4-byte big-endian integer starting at | 5978 ** change-counter, stored as a 4-byte big-endian integer starting at |
5967 ** byte offset 24 of the pager file. The secondary change counter at | 5979 ** byte offset 24 of the pager file. The secondary change counter at |
5968 ** 92 is also updated, as is the SQLite version number at offset 96. | 5980 ** 92 is also updated, as is the SQLite version number at offset 96. |
5969 ** | 5981 ** |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6008 #else | 6020 #else |
6009 # define DIRECT_MODE isDirectMode | 6021 # define DIRECT_MODE isDirectMode |
6010 #endif | 6022 #endif |
6011 | 6023 |
6012 if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){ | 6024 if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){ |
6013 PgHdr *pPgHdr; /* Reference to page 1 */ | 6025 PgHdr *pPgHdr; /* Reference to page 1 */ |
6014 | 6026 |
6015 assert( !pPager->tempFile && isOpen(pPager->fd) ); | 6027 assert( !pPager->tempFile && isOpen(pPager->fd) ); |
6016 | 6028 |
6017 /* Open page 1 of the file for writing. */ | 6029 /* Open page 1 of the file for writing. */ |
6018 rc = sqlite3PagerGet(pPager, 1, &pPgHdr); | 6030 rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0); |
6019 assert( pPgHdr==0 || rc==SQLITE_OK ); | 6031 assert( pPgHdr==0 || rc==SQLITE_OK ); |
6020 | 6032 |
6021 /* If page one was fetched successfully, and this function is not | 6033 /* If page one was fetched successfully, and this function is not |
6022 ** operating in direct-mode, make page 1 writable. When not in | 6034 ** operating in direct-mode, make page 1 writable. When not in |
6023 ** direct mode, page 1 is always held in cache and hence the PagerGet() | 6035 ** direct mode, page 1 is always held in cache and hence the PagerGet() |
6024 ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. | 6036 ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. |
6025 */ | 6037 */ |
6026 if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){ | 6038 if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){ |
6027 rc = sqlite3PagerWrite(pPgHdr); | 6039 rc = sqlite3PagerWrite(pPgHdr); |
6028 } | 6040 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6086 ** rollback. If the connection is in WAL mode, this call is a no-op. | 6098 ** rollback. If the connection is in WAL mode, this call is a no-op. |
6087 ** Otherwise, if the connection does not already have an EXCLUSIVE lock on | 6099 ** Otherwise, if the connection does not already have an EXCLUSIVE lock on |
6088 ** the database file, an attempt is made to obtain one. | 6100 ** the database file, an attempt is made to obtain one. |
6089 ** | 6101 ** |
6090 ** If the EXCLUSIVE lock is already held or the attempt to obtain it is | 6102 ** If the EXCLUSIVE lock is already held or the attempt to obtain it is |
6091 ** successful, or the connection is in WAL mode, SQLITE_OK is returned. | 6103 ** successful, or the connection is in WAL mode, SQLITE_OK is returned. |
6092 ** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is | 6104 ** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is |
6093 ** returned. | 6105 ** returned. |
6094 */ | 6106 */ |
6095 int sqlite3PagerExclusiveLock(Pager *pPager){ | 6107 int sqlite3PagerExclusiveLock(Pager *pPager){ |
6096 int rc = SQLITE_OK; | 6108 int rc = pPager->errCode; |
6097 assert( pPager->eState==PAGER_WRITER_CACHEMOD | |
6098 || pPager->eState==PAGER_WRITER_DBMOD | |
6099 || pPager->eState==PAGER_WRITER_LOCKED | |
6100 ); | |
6101 assert( assert_pager_state(pPager) ); | 6109 assert( assert_pager_state(pPager) ); |
6102 if( 0==pagerUseWal(pPager) ){ | 6110 if( rc==SQLITE_OK ){ |
6103 rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); | 6111 assert( pPager->eState==PAGER_WRITER_CACHEMOD |
| 6112 || pPager->eState==PAGER_WRITER_DBMOD |
| 6113 || pPager->eState==PAGER_WRITER_LOCKED |
| 6114 ); |
| 6115 assert( assert_pager_state(pPager) ); |
| 6116 if( 0==pagerUseWal(pPager) ){ |
| 6117 rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); |
| 6118 } |
6104 } | 6119 } |
6105 return rc; | 6120 return rc; |
6106 } | 6121 } |
6107 | 6122 |
6108 /* | 6123 /* |
6109 ** Sync the database file for the pager pPager. zMaster points to the name | 6124 ** Sync the database file for the pager pPager. zMaster points to the name |
6110 ** of a master journal file that should be written into the individual | 6125 ** of a master journal file that should be written into the individual |
6111 ** journal file. zMaster may be NULL, which is interpreted as no master | 6126 ** journal file. zMaster may be NULL, which is interpreted as no master |
6112 ** journal (a single database transaction). | 6127 ** journal (a single database transaction). |
6113 ** | 6128 ** |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6160 ** backup in progress needs to be restarted. | 6175 ** backup in progress needs to be restarted. |
6161 */ | 6176 */ |
6162 sqlite3BackupRestart(pPager->pBackup); | 6177 sqlite3BackupRestart(pPager->pBackup); |
6163 }else{ | 6178 }else{ |
6164 if( pagerUseWal(pPager) ){ | 6179 if( pagerUseWal(pPager) ){ |
6165 PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); | 6180 PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); |
6166 PgHdr *pPageOne = 0; | 6181 PgHdr *pPageOne = 0; |
6167 if( pList==0 ){ | 6182 if( pList==0 ){ |
6168 /* Must have at least one page for the WAL commit flag. | 6183 /* Must have at least one page for the WAL commit flag. |
6169 ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ | 6184 ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ |
6170 rc = sqlite3PagerGet(pPager, 1, &pPageOne); | 6185 rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0); |
6171 pList = pPageOne; | 6186 pList = pPageOne; |
6172 pList->pDirty = 0; | 6187 pList->pDirty = 0; |
6173 } | 6188 } |
6174 assert( rc==SQLITE_OK ); | 6189 assert( rc==SQLITE_OK ); |
6175 if( ALWAYS(pList) ){ | 6190 if( ALWAYS(pList) ){ |
6176 rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); | 6191 rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); |
6177 } | 6192 } |
6178 sqlite3PagerUnref(pPageOne); | 6193 sqlite3PagerUnref(pPageOne); |
6179 if( rc==SQLITE_OK ){ | 6194 if( rc==SQLITE_OK ){ |
6180 sqlite3PcacheCleanAll(pPager->pPCache); | 6195 sqlite3PcacheCleanAll(pPager->pPCache); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6332 if( pPager->eState==PAGER_WRITER_LOCKED | 6347 if( pPager->eState==PAGER_WRITER_LOCKED |
6333 && pPager->exclusiveMode | 6348 && pPager->exclusiveMode |
6334 && pPager->journalMode==PAGER_JOURNALMODE_PERSIST | 6349 && pPager->journalMode==PAGER_JOURNALMODE_PERSIST |
6335 ){ | 6350 ){ |
6336 assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); | 6351 assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); |
6337 pPager->eState = PAGER_READER; | 6352 pPager->eState = PAGER_READER; |
6338 return SQLITE_OK; | 6353 return SQLITE_OK; |
6339 } | 6354 } |
6340 | 6355 |
6341 PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); | 6356 PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); |
| 6357 pPager->iDataVersion++; |
6342 rc = pager_end_transaction(pPager, pPager->setMaster, 1); | 6358 rc = pager_end_transaction(pPager, pPager->setMaster, 1); |
6343 return pager_error(pPager, rc); | 6359 return pager_error(pPager, rc); |
6344 } | 6360 } |
6345 | 6361 |
6346 /* | 6362 /* |
6347 ** If a write transaction is open, then all changes made within the | 6363 ** If a write transaction is open, then all changes made within the |
6348 ** transaction are reverted and the current write-transaction is closed. | 6364 ** transaction are reverted and the current write-transaction is closed. |
6349 ** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR | 6365 ** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR |
6350 ** state if an error occurs. | 6366 ** state if an error occurs. |
6351 ** | 6367 ** |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6415 } | 6431 } |
6416 | 6432 |
6417 /* | 6433 /* |
6418 ** Return TRUE if the database file is opened read-only. Return FALSE | 6434 ** Return TRUE if the database file is opened read-only. Return FALSE |
6419 ** if the database is (in theory) writable. | 6435 ** if the database is (in theory) writable. |
6420 */ | 6436 */ |
6421 u8 sqlite3PagerIsreadonly(Pager *pPager){ | 6437 u8 sqlite3PagerIsreadonly(Pager *pPager){ |
6422 return pPager->readOnly; | 6438 return pPager->readOnly; |
6423 } | 6439 } |
6424 | 6440 |
| 6441 #ifdef SQLITE_DEBUG |
6425 /* | 6442 /* |
6426 ** Return the number of references to the pager. | 6443 ** Return the sum of the reference counts for all pages held by pPager. |
6427 */ | 6444 */ |
6428 int sqlite3PagerRefcount(Pager *pPager){ | 6445 int sqlite3PagerRefcount(Pager *pPager){ |
6429 return sqlite3PcacheRefCount(pPager->pPCache); | 6446 return sqlite3PcacheRefCount(pPager->pPCache); |
6430 } | 6447 } |
| 6448 #endif |
6431 | 6449 |
6432 /* | 6450 /* |
6433 ** Return the approximate number of bytes of memory currently | 6451 ** Return the approximate number of bytes of memory currently |
6434 ** used by the pager and its associated cache. | 6452 ** used by the pager and its associated cache. |
6435 */ | 6453 */ |
6436 int sqlite3PagerMemUsed(Pager *pPager){ | 6454 int sqlite3PagerMemUsed(Pager *pPager){ |
6437 int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr) | 6455 int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr) |
6438 + 5*sizeof(void*); | 6456 + 5*sizeof(void*); |
6439 return perPageSize*sqlite3PcachePagecount(pPager->pPCache) | 6457 return perPageSize*sqlite3PcachePagecount(pPager->pPCache) |
6440 + sqlite3MallocSize(pPager) | 6458 + sqlite3MallocSize(pPager) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6503 /* | 6521 /* |
6504 ** Check that there are at least nSavepoint savepoints open. If there are | 6522 ** Check that there are at least nSavepoint savepoints open. If there are |
6505 ** currently less than nSavepoints open, then open one or more savepoints | 6523 ** currently less than nSavepoints open, then open one or more savepoints |
6506 ** to make up the difference. If the number of savepoints is already | 6524 ** to make up the difference. If the number of savepoints is already |
6507 ** equal to nSavepoint, then this function is a no-op. | 6525 ** equal to nSavepoint, then this function is a no-op. |
6508 ** | 6526 ** |
6509 ** If a memory allocation fails, SQLITE_NOMEM is returned. If an error | 6527 ** If a memory allocation fails, SQLITE_NOMEM is returned. If an error |
6510 ** occurs while opening the sub-journal file, then an IO error code is | 6528 ** occurs while opening the sub-journal file, then an IO error code is |
6511 ** returned. Otherwise, SQLITE_OK. | 6529 ** returned. Otherwise, SQLITE_OK. |
6512 */ | 6530 */ |
6513 int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ | 6531 static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ |
6514 int rc = SQLITE_OK; /* Return code */ | 6532 int rc = SQLITE_OK; /* Return code */ |
6515 int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ | 6533 int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ |
| 6534 int ii; /* Iterator variable */ |
| 6535 PagerSavepoint *aNew; /* New Pager.aSavepoint array */ |
6516 | 6536 |
6517 assert( pPager->eState>=PAGER_WRITER_LOCKED ); | 6537 assert( pPager->eState>=PAGER_WRITER_LOCKED ); |
6518 assert( assert_pager_state(pPager) ); | 6538 assert( assert_pager_state(pPager) ); |
| 6539 assert( nSavepoint>nCurrent && pPager->useJournal ); |
6519 | 6540 |
6520 if( nSavepoint>nCurrent && pPager->useJournal ){ | 6541 /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM |
6521 int ii; /* Iterator variable */ | 6542 ** if the allocation fails. Otherwise, zero the new portion in case a |
6522 PagerSavepoint *aNew; /* New Pager.aSavepoint array */ | 6543 ** malloc failure occurs while populating it in the for(...) loop below. |
| 6544 */ |
| 6545 aNew = (PagerSavepoint *)sqlite3Realloc( |
| 6546 pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint |
| 6547 ); |
| 6548 if( !aNew ){ |
| 6549 return SQLITE_NOMEM; |
| 6550 } |
| 6551 memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint)); |
| 6552 pPager->aSavepoint = aNew; |
6523 | 6553 |
6524 /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM | 6554 /* Populate the PagerSavepoint structures just allocated. */ |
6525 ** if the allocation fails. Otherwise, zero the new portion in case a | 6555 for(ii=nCurrent; ii<nSavepoint; ii++){ |
6526 ** malloc failure occurs while populating it in the for(...) loop below. | 6556 aNew[ii].nOrig = pPager->dbSize; |
6527 */ | 6557 if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ |
6528 aNew = (PagerSavepoint *)sqlite3Realloc( | 6558 aNew[ii].iOffset = pPager->journalOff; |
6529 pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint | 6559 }else{ |
6530 ); | 6560 aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); |
6531 if( !aNew ){ | 6561 } |
| 6562 aNew[ii].iSubRec = pPager->nSubRec; |
| 6563 aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); |
| 6564 if( !aNew[ii].pInSavepoint ){ |
6532 return SQLITE_NOMEM; | 6565 return SQLITE_NOMEM; |
6533 } | 6566 } |
6534 memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint)); | 6567 if( pagerUseWal(pPager) ){ |
6535 pPager->aSavepoint = aNew; | 6568 sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); |
6536 | |
6537 /* Populate the PagerSavepoint structures just allocated. */ | |
6538 for(ii=nCurrent; ii<nSavepoint; ii++){ | |
6539 aNew[ii].nOrig = pPager->dbSize; | |
6540 if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ | |
6541 aNew[ii].iOffset = pPager->journalOff; | |
6542 }else{ | |
6543 aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); | |
6544 } | |
6545 aNew[ii].iSubRec = pPager->nSubRec; | |
6546 aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); | |
6547 if( !aNew[ii].pInSavepoint ){ | |
6548 return SQLITE_NOMEM; | |
6549 } | |
6550 if( pagerUseWal(pPager) ){ | |
6551 sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); | |
6552 } | |
6553 pPager->nSavepoint = ii+1; | |
6554 } | 6569 } |
6555 assert( pPager->nSavepoint==nSavepoint ); | 6570 pPager->nSavepoint = ii+1; |
6556 assertTruncateConstraint(pPager); | |
6557 } | 6571 } |
6558 | 6572 assert( pPager->nSavepoint==nSavepoint ); |
| 6573 assertTruncateConstraint(pPager); |
6559 return rc; | 6574 return rc; |
6560 } | 6575 } |
| 6576 int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ |
| 6577 assert( pPager->eState>=PAGER_WRITER_LOCKED ); |
| 6578 assert( assert_pager_state(pPager) ); |
| 6579 |
| 6580 if( nSavepoint>pPager->nSavepoint && pPager->useJournal ){ |
| 6581 return pagerOpenSavepoint(pPager, nSavepoint); |
| 6582 }else{ |
| 6583 return SQLITE_OK; |
| 6584 } |
| 6585 } |
| 6586 |
6561 | 6587 |
6562 /* | 6588 /* |
6563 ** This function is called to rollback or release (commit) a savepoint. | 6589 ** This function is called to rollback or release (commit) a savepoint. |
6564 ** The savepoint to release or rollback need not be the most recently | 6590 ** The savepoint to release or rollback need not be the most recently |
6565 ** created savepoint. | 6591 ** created savepoint. |
6566 ** | 6592 ** |
6567 ** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. | 6593 ** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. |
6568 ** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with | 6594 ** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with |
6569 ** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes | 6595 ** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes |
6570 ** that have occurred since the specified savepoint was created. | 6596 ** that have occurred since the specified savepoint was created. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6646 ** shared cache, it uses nullIfMemDb==0 so that in-memory databases can | 6672 ** shared cache, it uses nullIfMemDb==0 so that in-memory databases can |
6647 ** participate in shared-cache. | 6673 ** participate in shared-cache. |
6648 */ | 6674 */ |
6649 const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){ | 6675 const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){ |
6650 return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename; | 6676 return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename; |
6651 } | 6677 } |
6652 | 6678 |
6653 /* | 6679 /* |
6654 ** Return the VFS structure for the pager. | 6680 ** Return the VFS structure for the pager. |
6655 */ | 6681 */ |
6656 const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ | 6682 sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ |
6657 return pPager->pVfs; | 6683 return pPager->pVfs; |
6658 } | 6684 } |
6659 | 6685 |
6660 /* | 6686 /* |
6661 ** Return the file handle for the database file associated | 6687 ** Return the file handle for the database file associated |
6662 ** with the pager. This might return NULL if the file has | 6688 ** with the pager. This might return NULL if the file has |
6663 ** not yet been opened. | 6689 ** not yet been opened. |
6664 */ | 6690 */ |
6665 sqlite3_file *sqlite3PagerFile(Pager *pPager){ | 6691 sqlite3_file *sqlite3PagerFile(Pager *pPager){ |
6666 return pPager->fd; | 6692 return pPager->fd; |
6667 } | 6693 } |
6668 | 6694 |
6669 /* | 6695 /* |
| 6696 ** Return the file handle for the journal file (if it exists). |
| 6697 ** This will be either the rollback journal or the WAL file. |
| 6698 */ |
| 6699 sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ |
| 6700 #if SQLITE_OMIT_WAL |
| 6701 return pPager->jfd; |
| 6702 #else |
| 6703 return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; |
| 6704 #endif |
| 6705 } |
| 6706 |
| 6707 /* |
6670 ** Return the full pathname of the journal file. | 6708 ** Return the full pathname of the journal file. |
6671 */ | 6709 */ |
6672 const char *sqlite3PagerJournalname(Pager *pPager){ | 6710 const char *sqlite3PagerJournalname(Pager *pPager){ |
6673 return pPager->zJournal; | 6711 return pPager->zJournal; |
6674 } | 6712 } |
6675 | 6713 |
6676 /* | 6714 /* |
6677 ** Return true if fsync() calls are disabled for this pager. Return FALSE | 6715 ** Return true if fsync() calls are disabled for this pager. Return FALSE |
6678 ** if fsync()s are executed normally. | 6716 ** if fsync()s are executed normally. |
6679 */ | 6717 */ |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6781 ** ROLLBACK TO one; | 6819 ** ROLLBACK TO one; |
6782 ** | 6820 ** |
6783 ** If page X were not written to the sub-journal here, it would not | 6821 ** If page X were not written to the sub-journal here, it would not |
6784 ** be possible to restore its contents when the "ROLLBACK TO one" | 6822 ** be possible to restore its contents when the "ROLLBACK TO one" |
6785 ** statement were is processed. | 6823 ** statement were is processed. |
6786 ** | 6824 ** |
6787 ** subjournalPage() may need to allocate space to store pPg->pgno into | 6825 ** subjournalPage() may need to allocate space to store pPg->pgno into |
6788 ** one or more savepoint bitvecs. This is the reason this function | 6826 ** one or more savepoint bitvecs. This is the reason this function |
6789 ** may return SQLITE_NOMEM. | 6827 ** may return SQLITE_NOMEM. |
6790 */ | 6828 */ |
6791 if( pPg->flags&PGHDR_DIRTY | 6829 if( (pPg->flags & PGHDR_DIRTY)!=0 |
6792 && subjRequiresPage(pPg) | 6830 && SQLITE_OK!=(rc = subjournalPageIfRequired(pPg)) |
6793 && SQLITE_OK!=(rc = subjournalPage(pPg)) | |
6794 ){ | 6831 ){ |
6795 return rc; | 6832 return rc; |
6796 } | 6833 } |
6797 | 6834 |
6798 PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", | 6835 PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", |
6799 PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); | 6836 PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); |
6800 IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) | 6837 IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) |
6801 | 6838 |
6802 /* If the journal needs to be sync()ed before page pPg->pgno can | 6839 /* If the journal needs to be sync()ed before page pPg->pgno can |
6803 ** be written to, store pPg->pgno in local variable needSyncPgno. | 6840 ** be written to, store pPg->pgno in local variable needSyncPgno. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6855 ** flag. | 6892 ** flag. |
6856 ** | 6893 ** |
6857 ** If the attempt to load the page into the page-cache fails, (due | 6894 ** If the attempt to load the page into the page-cache fails, (due |
6858 ** to a malloc() or IO failure), clear the bit in the pInJournal[] | 6895 ** to a malloc() or IO failure), clear the bit in the pInJournal[] |
6859 ** array. Otherwise, if the page is loaded and written again in | 6896 ** array. Otherwise, if the page is loaded and written again in |
6860 ** this transaction, it may be written to the database file before | 6897 ** this transaction, it may be written to the database file before |
6861 ** it is synced into the journal file. This way, it may end up in | 6898 ** it is synced into the journal file. This way, it may end up in |
6862 ** the journal file twice, but that is not a problem. | 6899 ** the journal file twice, but that is not a problem. |
6863 */ | 6900 */ |
6864 PgHdr *pPgHdr; | 6901 PgHdr *pPgHdr; |
6865 rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr); | 6902 rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0); |
6866 if( rc!=SQLITE_OK ){ | 6903 if( rc!=SQLITE_OK ){ |
6867 if( needSyncPgno<=pPager->dbOrigSize ){ | 6904 if( needSyncPgno<=pPager->dbOrigSize ){ |
6868 assert( pPager->pTmpSpace!=0 ); | 6905 assert( pPager->pTmpSpace!=0 ); |
6869 sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); | 6906 sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); |
6870 } | 6907 } |
6871 return rc; | 6908 return rc; |
6872 } | 6909 } |
6873 pPgHdr->flags |= PGHDR_NEED_SYNC; | 6910 pPgHdr->flags |= PGHDR_NEED_SYNC; |
6874 sqlite3PcacheMakeDirty(pPgHdr); | 6911 sqlite3PcacheMakeDirty(pPgHdr); |
6875 sqlite3PagerUnrefNotNull(pPgHdr); | 6912 sqlite3PagerUnrefNotNull(pPgHdr); |
6876 } | 6913 } |
6877 | 6914 |
6878 return SQLITE_OK; | 6915 return SQLITE_OK; |
6879 } | 6916 } |
6880 #endif | 6917 #endif |
6881 | 6918 |
6882 /* | 6919 /* |
| 6920 ** The page handle passed as the first argument refers to a dirty page |
| 6921 ** with a page number other than iNew. This function changes the page's |
| 6922 ** page number to iNew and sets the value of the PgHdr.flags field to |
| 6923 ** the value passed as the third parameter. |
| 6924 */ |
| 6925 void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){ |
| 6926 assert( pPg->pgno!=iNew ); |
| 6927 pPg->flags = flags; |
| 6928 sqlite3PcacheMove(pPg, iNew); |
| 6929 } |
| 6930 |
| 6931 /* |
6883 ** Return a pointer to the data for the specified page. | 6932 ** Return a pointer to the data for the specified page. |
6884 */ | 6933 */ |
6885 void *sqlite3PagerGetData(DbPage *pPg){ | 6934 void *sqlite3PagerGetData(DbPage *pPg){ |
6886 assert( pPg->nRef>0 || pPg->pPager->memDb ); | 6935 assert( pPg->nRef>0 || pPg->pPager->memDb ); |
6887 return pPg->pData; | 6936 return pPg->pData; |
6888 } | 6937 } |
6889 | 6938 |
6890 /* | 6939 /* |
6891 ** Return a pointer to the Pager.nExtra bytes of "extra" space | 6940 ** Return a pointer to the Pager.nExtra bytes of "extra" space |
6892 ** allocated along with the specified page. | 6941 ** allocated along with the specified page. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7017 if( rc==SQLITE_OK ){ | 7066 if( rc==SQLITE_OK ){ |
7018 sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); | 7067 sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); |
7019 } | 7068 } |
7020 if( rc==SQLITE_OK && state==PAGER_READER ){ | 7069 if( rc==SQLITE_OK && state==PAGER_READER ){ |
7021 pagerUnlockDb(pPager, SHARED_LOCK); | 7070 pagerUnlockDb(pPager, SHARED_LOCK); |
7022 }else if( state==PAGER_OPEN ){ | 7071 }else if( state==PAGER_OPEN ){ |
7023 pager_unlock(pPager); | 7072 pager_unlock(pPager); |
7024 } | 7073 } |
7025 assert( state==pPager->eState ); | 7074 assert( state==pPager->eState ); |
7026 } | 7075 } |
| 7076 }else if( eMode==PAGER_JOURNALMODE_OFF ){ |
| 7077 sqlite3OsClose(pPager->jfd); |
7027 } | 7078 } |
7028 } | 7079 } |
7029 | 7080 |
7030 /* Return the new journal mode */ | 7081 /* Return the new journal mode */ |
7031 return (int)pPager->journalMode; | 7082 return (int)pPager->journalMode; |
7032 } | 7083 } |
7033 | 7084 |
7034 /* | 7085 /* |
7035 ** Return the current journal mode. | 7086 ** Return the current journal mode. |
7036 */ | 7087 */ |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7088 ** This function is called when the user invokes "PRAGMA wal_checkpoint", | 7139 ** This function is called when the user invokes "PRAGMA wal_checkpoint", |
7089 ** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint() | 7140 ** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint() |
7090 ** or wal_blocking_checkpoint() API functions. | 7141 ** or wal_blocking_checkpoint() API functions. |
7091 ** | 7142 ** |
7092 ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. | 7143 ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. |
7093 */ | 7144 */ |
7094 int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ | 7145 int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ |
7095 int rc = SQLITE_OK; | 7146 int rc = SQLITE_OK; |
7096 if( pPager->pWal ){ | 7147 if( pPager->pWal ){ |
7097 rc = sqlite3WalCheckpoint(pPager->pWal, eMode, | 7148 rc = sqlite3WalCheckpoint(pPager->pWal, eMode, |
7098 pPager->xBusyHandler, pPager->pBusyHandlerArg, | 7149 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), |
| 7150 pPager->pBusyHandlerArg, |
7099 pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, | 7151 pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, |
7100 pnLog, pnCkpt | 7152 pnLog, pnCkpt |
7101 ); | 7153 ); |
7102 } | 7154 } |
7103 return rc; | 7155 return rc; |
7104 } | 7156 } |
7105 | 7157 |
7106 int sqlite3PagerWalCallback(Pager *pPager){ | 7158 int sqlite3PagerWalCallback(Pager *pPager){ |
7107 return sqlite3WalCallback(pPager->pWal); | 7159 return sqlite3WalCallback(pPager->pWal); |
7108 } | 7160 } |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7254 if( rc==SQLITE_OK ){ | 7306 if( rc==SQLITE_OK ){ |
7255 rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, | 7307 rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, |
7256 pPager->pageSize, (u8*)pPager->pTmpSpace); | 7308 pPager->pageSize, (u8*)pPager->pTmpSpace); |
7257 pPager->pWal = 0; | 7309 pPager->pWal = 0; |
7258 pagerFixMaplimit(pPager); | 7310 pagerFixMaplimit(pPager); |
7259 } | 7311 } |
7260 } | 7312 } |
7261 return rc; | 7313 return rc; |
7262 } | 7314 } |
7263 | 7315 |
| 7316 #ifdef SQLITE_ENABLE_SNAPSHOT |
| 7317 /* |
| 7318 ** If this is a WAL database, obtain a snapshot handle for the snapshot |
| 7319 ** currently open. Otherwise, return an error. |
| 7320 */ |
| 7321 int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){ |
| 7322 int rc = SQLITE_ERROR; |
| 7323 if( pPager->pWal ){ |
| 7324 rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot); |
| 7325 } |
| 7326 return rc; |
| 7327 } |
| 7328 |
| 7329 /* |
| 7330 ** If this is a WAL database, store a pointer to pSnapshot. Next time a |
| 7331 ** read transaction is opened, attempt to read from the snapshot it |
| 7332 ** identifies. If this is not a WAL database, return an error. |
| 7333 */ |
| 7334 int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){ |
| 7335 int rc = SQLITE_OK; |
| 7336 if( pPager->pWal ){ |
| 7337 sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot); |
| 7338 }else{ |
| 7339 rc = SQLITE_ERROR; |
| 7340 } |
| 7341 return rc; |
| 7342 } |
| 7343 #endif /* SQLITE_ENABLE_SNAPSHOT */ |
7264 #endif /* !SQLITE_OMIT_WAL */ | 7344 #endif /* !SQLITE_OMIT_WAL */ |
7265 | 7345 |
7266 #ifdef SQLITE_ENABLE_ZIPVFS | 7346 #ifdef SQLITE_ENABLE_ZIPVFS |
7267 /* | 7347 /* |
7268 ** A read-lock must be held on the pager when this function is called. If | 7348 ** A read-lock must be held on the pager when this function is called. If |
7269 ** the pager is in WAL mode and the WAL file currently contains one or more | 7349 ** the pager is in WAL mode and the WAL file currently contains one or more |
7270 ** frames, return the size in bytes of the page images stored within the | 7350 ** frames, return the size in bytes of the page images stored within the |
7271 ** WAL frames. Otherwise, if this is not a WAL database or the WAL file | 7351 ** WAL frames. Otherwise, if this is not a WAL database or the WAL file |
7272 ** is empty, return 0. | 7352 ** is empty, return 0. |
7273 */ | 7353 */ |
7274 int sqlite3PagerWalFramesize(Pager *pPager){ | 7354 int sqlite3PagerWalFramesize(Pager *pPager){ |
7275 assert( pPager->eState>=PAGER_READER ); | 7355 assert( pPager->eState>=PAGER_READER ); |
7276 return sqlite3WalFramesize(pPager->pWal); | 7356 return sqlite3WalFramesize(pPager->pWal); |
7277 } | 7357 } |
7278 #endif | 7358 #endif |
7279 | 7359 |
| 7360 |
7280 #endif /* SQLITE_OMIT_DISKIO */ | 7361 #endif /* SQLITE_OMIT_DISKIO */ |
OLD | NEW |