Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the names of the log.c and log.h source files to wal.c and wal.h. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | wal |
Files: | files | file ages | folders |
SHA1: |
56fe5d7624f840417152bcc63efbe21a |
User & Date: | drh 2010-04-26 00:19:45.000 |
Context
2010-04-26
| ||
10:40 | Add mutexes to fix a race condition in wal.c. This isn't a very good fix. (check-in: 3d159939cc user: dan tags: wal) | |
00:19 | Change the names of the log.c and log.h source files to wal.c and wal.h. (check-in: 56fe5d7624 user: drh tags: wal) | |
00:04 | Begin moving WAL-specific I/O into the VFS. This checkin contains VFS infrastructure but it is untested and is not yet hooked up to the WAL. The version number is bumped to 3.7.0 because of the VFS extension. (check-in: f5e615c28c user: drh tags: wal) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
272 273 274 275 276 277 278 279 280 281 282 283 284 285 | $(TOP)/src/vdbeapi.c \ $(TOP)/src/vdbeaux.c \ $(TOP)/src/vdbeblob.c \ $(TOP)/src/vdbemem.c \ $(TOP)/src/vdbetrace.c \ $(TOP)/src/vdbeInt.h \ $(TOP)/src/vtab.c \ $(TOP)/src/walker.c \ $(TOP)/src/where.c # Generated source code files # SRC += \ keywordhash.h \ | > > | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | $(TOP)/src/vdbeapi.c \ $(TOP)/src/vdbeaux.c \ $(TOP)/src/vdbeblob.c \ $(TOP)/src/vdbemem.c \ $(TOP)/src/vdbetrace.c \ $(TOP)/src/vdbeInt.h \ $(TOP)/src/vtab.c \ $(TOP)/src/wal.c \ $(TOP)/src/wal.h \ $(TOP)/src/walker.c \ $(TOP)/src/where.c # Generated source code files # SRC += \ keywordhash.h \ |
︙ | ︙ | |||
738 739 740 741 742 743 744 745 746 747 748 749 750 751 | vdbetrace.lo: $(TOP)/src/vdbetrace.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c vtab.lo: $(TOP)/src/vtab.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c walker.lo: $(TOP)/src/walker.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c where.lo: $(TOP)/src/where.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR) | > > > | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 | vdbetrace.lo: $(TOP)/src/vdbetrace.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c vtab.lo: $(TOP)/src/vtab.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c wal.lo: $(TOP)/src/wal.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c walker.lo: $(TOP)/src/walker.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c where.lo: $(TOP)/src/where.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR) |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
52 53 54 55 56 57 58 | # LIBOBJ+= alter.o analyze.o attach.o auth.o \ backup.o bitvec.o btmutex.o btree.o build.o \ callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \ fts3.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \ fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o fts3_write.o \ func.o global.o hash.o \ | | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | # LIBOBJ+= alter.o analyze.o attach.o auth.o \ backup.o bitvec.o btmutex.o btree.o build.o \ callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \ fts3.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \ fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o fts3_write.o \ func.o global.o hash.o \ icu.o insert.o journal.o legacy.o loadext.o \ main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \ memjournal.o \ mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \ notify.o opcodes.o os.o os_os2.o os_unix.o os_win.o \ pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \ random.o resolve.o rowset.o rtree.o select.o status.o \ table.o tokenize.o trigger.o \ update.o util.o vacuum.o \ vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbetrace.o \ wal.o walker.o where.o utf.o vtab.o # All of the source code files. # SRC = \ $(TOP)/src/alter.c \ |
︙ | ︙ | |||
97 98 99 100 101 102 103 | $(TOP)/src/hash.c \ $(TOP)/src/hash.h \ $(TOP)/src/hwtime.h \ $(TOP)/src/insert.c \ $(TOP)/src/journal.c \ $(TOP)/src/legacy.c \ $(TOP)/src/loadext.c \ | < < | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | $(TOP)/src/hash.c \ $(TOP)/src/hash.h \ $(TOP)/src/hwtime.h \ $(TOP)/src/insert.c \ $(TOP)/src/journal.c \ $(TOP)/src/legacy.c \ $(TOP)/src/loadext.c \ $(TOP)/src/main.c \ $(TOP)/src/malloc.c \ $(TOP)/src/mem0.c \ $(TOP)/src/mem1.c \ $(TOP)/src/mem2.c \ $(TOP)/src/mem3.c \ $(TOP)/src/mem5.c \ |
︙ | ︙ | |||
156 157 158 159 160 161 162 163 164 165 166 167 168 169 | $(TOP)/src/vdbeapi.c \ $(TOP)/src/vdbeaux.c \ $(TOP)/src/vdbeblob.c \ $(TOP)/src/vdbemem.c \ $(TOP)/src/vdbetrace.c \ $(TOP)/src/vdbeInt.h \ $(TOP)/src/vtab.c \ $(TOP)/src/walker.c \ $(TOP)/src/where.c # Source code for extensions # SRC += \ $(TOP)/ext/fts1/fts1.c \ | > > | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | $(TOP)/src/vdbeapi.c \ $(TOP)/src/vdbeaux.c \ $(TOP)/src/vdbeblob.c \ $(TOP)/src/vdbemem.c \ $(TOP)/src/vdbetrace.c \ $(TOP)/src/vdbeInt.h \ $(TOP)/src/vtab.c \ $(TOP)/src/wal.c \ $(TOP)/src/wal.h \ $(TOP)/src/walker.c \ $(TOP)/src/where.c # Source code for extensions # SRC += \ $(TOP)/ext/fts1/fts1.c \ |
︙ | ︙ | |||
253 254 255 256 257 258 259 | #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c TESTSRC2 = \ $(TOP)/src/attach.c $(TOP)/src/backup.c $(TOP)/src/btree.c \ $(TOP)/src/build.c $(TOP)/src/date.c \ | | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c TESTSRC2 = \ $(TOP)/src/attach.c $(TOP)/src/backup.c $(TOP)/src/btree.c \ $(TOP)/src/build.c $(TOP)/src/date.c \ $(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/wal.c \ $(TOP)/src/mem5.c $(TOP)/src/os.c \ $(TOP)/src/os_os2.c $(TOP)/src/os_unix.c $(TOP)/src/os_win.c \ $(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c \ $(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c \ $(TOP)/src/pcache1.c $(TOP)/src/select.c $(TOP)/src/tokenize.c \ $(TOP)/src/utf.c $(TOP)/src/util.c $(TOP)/src/vdbeapi.c $(TOP)/src/vdbeaux.c \ $(TOP)/src/vdbe.c $(TOP)/src/vdbemem.c $(TOP)/src/where.c parse.c \ |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
16 17 18 19 20 21 22 | ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "wal.h" /* ******************** NOTES ON THE DESIGN OF THE PAGER ************************ ** ** Within this comment block, a page is deemed to have been synced ** automatically as soon as it is written when PRAGMA synchronous=OFF. ** Otherwise, the page is not synced until the xSync method of the VFS |
︙ | ︙ | |||
1223 1224 1225 1226 1227 1228 1229 | ** this happens. One can argue that this doesn't need to be cleared ** until the change-counter check fails in PagerSharedLock(). ** Clearing the page size cache here is being conservative. */ pPager->dbSizeValid = 0; if( pagerUseLog(pPager) ){ | | | 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 | ** this happens. One can argue that this doesn't need to be cleared ** until the change-counter check fails in PagerSharedLock(). ** Clearing the page size cache here is being conservative. */ pPager->dbSizeValid = 0; if( pagerUseLog(pPager) ){ sqlite3WalCloseSnapshot(pPager->pLog); }else{ rc = osUnlock(pPager->fd, NO_LOCK); } if( rc ){ pPager->errCode = rc; } IOTRACE(("UNLOCK %p\n", pPager)) |
︙ | ︙ | |||
1422 1423 1424 1425 1426 1427 1428 | } sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; sqlite3PcacheCleanAll(pPager->pPCache); if( pagerUseLog(pPager) ){ | | | 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 | } sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; sqlite3PcacheCleanAll(pPager->pPCache); if( pagerUseLog(pPager) ){ rc2 = sqlite3WalWriteLock(pPager->pLog, 0); pPager->state = PAGER_SHARED; }else if( !pPager->exclusiveMode ){ rc2 = osUnlock(pPager->fd, SHARED_LOCK); pPager->state = PAGER_SHARED; pPager->changeCountDone = 0; }else if( pPager->state==PAGER_SYNCED ){ pPager->state = PAGER_EXCLUSIVE; |
︙ | ︙ | |||
2189 2190 2191 2192 2193 2194 2195 | assert( pPager->tempFile ); memset(pPg->pData, 0, pPager->pageSize); return SQLITE_OK; } if( pagerUseLog(pPager) ){ /* Try to pull the page from the write-ahead log. */ | | | 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 | assert( pPager->tempFile ); memset(pPg->pData, 0, pPager->pageSize); return SQLITE_OK; } if( pagerUseLog(pPager) ){ /* Try to pull the page from the write-ahead log. */ rc = sqlite3WalRead(pPager->pLog, pgno, &isInLog, pPg->pData); } if( rc==SQLITE_OK && !isInLog ){ iOffset = (pgno-1)*(i64)pPager->pageSize; rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } |
︙ | ︙ | |||
2278 2279 2280 2281 2282 2283 2284 | ** updated as data is copied out of the rollback journal and into the ** database. This is not generally possible with a WAL database, as ** rollback involves simply truncating the log file. Therefore, if one ** or more frames have already been written to the log (and therefore ** also copied into the backup databases) as part of this transaction, ** the backups must be restarted. */ | | | | 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 | ** updated as data is copied out of the rollback journal and into the ** database. This is not generally possible with a WAL database, as ** rollback involves simply truncating the log file. Therefore, if one ** or more frames have already been written to the log (and therefore ** also copied into the backup databases) as part of this transaction, ** the backups must be restarted. */ if( sqlite3WalDirty(pPager->pLog) ){ sqlite3BackupRestart(pPager->pBackup); } /* For all pages in the cache that are currently dirty or have already ** been written (but not committed) to the log file, do one of the ** following: ** ** + Discard the cached page (if refcount==0), or ** + Reload page content from the database (if refcount>0). */ pPager->dbSize = pPager->dbOrigSize; rc = sqlite3WalUndo(pPager->pLog, pagerUndoCallback, (void *)pPager); pList = sqlite3PcacheDirtyList(pPager->pPCache); while( pList && rc==SQLITE_OK ){ PgHdr *pNext = pList->pDirty; rc = pagerUndoCallback((void *)pPager, pList->pgno); pList = pNext; } |
︙ | ︙ | |||
2734 2735 2736 2737 2738 2739 2740 | if( pPager->dbSizeValid ){ nPage = pPager->dbSize; }else{ int rc; /* Error returned by OsFileSize() */ i64 n = 0; /* File size in bytes returned by OsFileSize() */ if( pagerUseLog(pPager) ){ | | | 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 | if( pPager->dbSizeValid ){ nPage = pPager->dbSize; }else{ int rc; /* Error returned by OsFileSize() */ i64 n = 0; /* File size in bytes returned by OsFileSize() */ if( pagerUseLog(pPager) ){ sqlite3WalDbsize(pPager->pLog, &nPage); } if( nPage==0 ){ assert( isOpen(pPager->fd) || pPager->tempFile ); if( isOpen(pPager->fd) ){ if( SQLITE_OK!=(rc = sqlite3OsFileSize(pPager->fd, &n)) ){ pager_error(pPager, rc); |
︙ | ︙ | |||
2919 2920 2921 2922 2923 2924 2925 | int sqlite3PagerClose(Pager *pPager){ u8 *pTmp = (u8 *)pPager->pTmpSpace; disable_simulated_io_errors(); sqlite3BeginBenignMalloc(); pPager->errCode = 0; pPager->exclusiveMode = 0; | | | 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 | int sqlite3PagerClose(Pager *pPager){ u8 *pTmp = (u8 *)pPager->pTmpSpace; disable_simulated_io_errors(); sqlite3BeginBenignMalloc(); pPager->errCode = 0; pPager->exclusiveMode = 0; sqlite3WalClose(pPager->pLog, pPager->fd, (pPager->noSync ? 0 : pPager->sync_flags), pTmp ); pPager->pLog = 0; pager_reset(pPager); if( MEMDB ){ pager_unlock(pPager); }else{ |
︙ | ︙ | |||
3266 3267 3268 3269 3270 3271 3272 | assert( pPager->nSavepoint>0 ); rc = addToSavepointBitvecs(pPager, pPg->pgno); } return rc; } /* | | | | 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 | assert( pPager->nSavepoint>0 ); rc = addToSavepointBitvecs(pPager, pPg->pgno); } return rc; } /* ** This function is a wrapper around sqlite3WalFrames(). As well as logging ** the contents of the list of pages headed by pList (connected by pDirty), ** this function notifies any active backup processes that the pages have ** changed. */ static int pagerLogFrames( Pager *pPager, /* Pager object */ PgHdr *pList, /* List of frames to log */ Pgno nTruncate, /* Database size after this commit */ int isCommit, /* True if this is a commit */ int sync_flags /* Flags to pass to OsSync() (or 0) */ ){ int rc; /* Return code */ assert( pPager->pLog ); rc = sqlite3WalFrames(pPager->pLog, pPager->pageSize, pList, nTruncate, isCommit, sync_flags ); if( rc==SQLITE_OK && pPager->pBackup ){ PgHdr *p; for(p=pList; p; p=p->pDirty){ sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); } |
︙ | ︙ | |||
3834 3835 3836 3837 3838 3839 3840 | static int pagerOpenSnapshot(Pager *pPager){ int rc; /* Return code */ int changed = 0; /* True if cache must be reset */ assert( pagerUseLog(pPager) ); | | | 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 | static int pagerOpenSnapshot(Pager *pPager){ int rc; /* Return code */ int changed = 0; /* True if cache must be reset */ assert( pagerUseLog(pPager) ); rc = sqlite3WalOpenSnapshot(pPager->pLog, &changed); if( rc==SQLITE_OK ){ int dummy; if( changed ){ pager_reset(pPager); assert( pPager->errCode || pPager->dbSizeValid==0 ); } rc = sqlite3PagerPagecount(pPager, &dummy); |
︙ | ︙ | |||
4452 4453 4454 4455 4456 4457 4458 | if( pagerUseLog(pPager) ){ /* Grab the write lock on the log file. If successful, upgrade to ** PAGER_EXCLUSIVE state. Otherwise, return an error code to the caller. ** The busy-handler is not invoked if another connection already ** holds the write-lock. If possible, the upper layer will call it. */ | | | 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 | if( pagerUseLog(pPager) ){ /* Grab the write lock on the log file. If successful, upgrade to ** PAGER_EXCLUSIVE state. Otherwise, return an error code to the caller. ** The busy-handler is not invoked if another connection already ** holds the write-lock. If possible, the upper layer will call it. */ rc = sqlite3WalWriteLock(pPager->pLog, 1); if( rc==SQLITE_OK ){ pPager->dbOrigSize = pPager->dbSize; pPager->state = PAGER_RESERVED; pPager->journalOff = 0; } }else{ /* Obtain a RESERVED lock on the database file. If the exFlag parameter |
︙ | ︙ | |||
5773 5774 5775 5776 5777 5778 5779 | /* ** This function is called when the user invokes "PRAGMA checkpoint". */ int sqlite3PagerCheckpoint(Pager *pPager){ int rc = SQLITE_OK; if( pPager->pLog ){ u8 *zBuf = (u8 *)pPager->pTmpSpace; | | | | | 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 | /* ** This function is called when the user invokes "PRAGMA checkpoint". */ int sqlite3PagerCheckpoint(Pager *pPager){ int rc = SQLITE_OK; if( pPager->pLog ){ u8 *zBuf = (u8 *)pPager->pTmpSpace; rc = sqlite3WalCheckpoint(pPager->pLog, pPager->fd, (pPager->noSync ? 0 : pPager->sync_flags), zBuf, pPager->xBusyHandler, pPager->pBusyHandlerArg ); } return rc; } int sqlite3PagerLogCallback(Pager *pPager){ return sqlite3WalCallback(pPager->pLog); } /* ** Open a connection to the write-ahead log file for pager pPager. If ** the log connection is already open, this function is a no-op. ** ** The caller must be holding a SHARED lock on the database file to call ** this function. */ int sqlite3PagerOpenLog(Pager *pPager, int *pisOpen){ int rc = SQLITE_OK; /* Return code */ assert( pPager->state>=PAGER_SHARED ); if( !pPager->pLog ){ /* Open the connection to the log file. If this operation fails, ** (e.g. due to malloc() failure), unlock the database file and ** return an error code. */ rc = sqlite3WalOpen(pPager->pVfs, pPager->zFilename, &pPager->pLog); if( rc==SQLITE_OK ){ pPager->journalMode = PAGER_JOURNALMODE_WAL; } }else{ *pisOpen = 1; } |
︙ | ︙ | |||
5839 5840 5841 5842 5843 5844 5845 | if( !pPager->pLog ){ int logexists = 0; rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED); if( rc==SQLITE_OK ){ rc = pagerHasWAL(pPager, &logexists); } if( rc==SQLITE_OK && logexists ){ | | | | 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 | if( !pPager->pLog ){ int logexists = 0; rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED); if( rc==SQLITE_OK ){ rc = pagerHasWAL(pPager, &logexists); } if( rc==SQLITE_OK && logexists ){ rc = sqlite3WalOpen(pPager->pVfs, pPager->zFilename, &pPager->pLog); } } /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on ** the database file, the log and log-summary files will be deleted. */ if( rc==SQLITE_OK && pPager->pLog ){ rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_EXCLUSIVE); if( rc==SQLITE_OK ){ rc = sqlite3WalClose(pPager->pLog, pPager->fd, (pPager->noSync ? 0 : pPager->sync_flags), (u8*)pPager->pTmpSpace ); pPager->pLog = 0; } } return rc; } #endif /* SQLITE_OMIT_DISKIO */ |
Name change from src/log.c to src/wal.c.
︙ | ︙ | |||
53 54 55 56 57 58 59 | ** The fields in the log-summary file header are described in the comment ** directly above the definition of struct LogSummaryHdr (see below). ** Immediately following the fields in the LogSummaryHdr structure is ** an 8 byte checksum based on the contents of the header. This field is ** not the same as the iCheck1 and iCheck2 fields of the LogSummaryHdr. */ | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | ** The fields in the log-summary file header are described in the comment ** directly above the definition of struct LogSummaryHdr (see below). ** Immediately following the fields in the LogSummaryHdr structure is ** an 8 byte checksum based on the contents of the header. This field is ** not the same as the iCheck1 and iCheck2 fields of the LogSummaryHdr. */ #include "wal.h" #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> typedef struct LogSummaryHdr LogSummaryHdr; typedef struct LogSummary LogSummary; |
︙ | ︙ | |||
1002 1003 1004 1005 1006 1007 1008 | ** ** A SHARED lock should be held on the database file when this function ** is called. The purpose of this SHARED lock is to prevent any other ** client from unlinking the log or log-summary file. If another process ** were to do this just after this client opened one of these files, the ** system would be badly broken. */ | | | 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 | ** ** A SHARED lock should be held on the database file when this function ** is called. The purpose of this SHARED lock is to prevent any other ** client from unlinking the log or log-summary file. If another process ** were to do this just after this client opened one of these files, the ** system would be badly broken. */ int sqlite3WalOpen( sqlite3_vfs *pVfs, /* vfs module to open log file with */ const char *zDb, /* Name of database file */ Log **ppLog /* OUT: Allocated Log handle */ ){ int rc = SQLITE_OK; /* Return Code */ Log *pRet; /* Object to allocate and return */ LogSummary *pSummary = 0; /* Summary object */ |
︙ | ︙ | |||
1260 1261 1262 1263 1264 1265 1266 | logIteratorFree(pIter); return rc; } /* ** Close a connection to a log file. */ | | | 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 | logIteratorFree(pIter); return rc; } /* ** Close a connection to a log file. */ int sqlite3WalClose( Log *pLog, /* Log to close */ sqlite3_file *pFd, /* Database file */ int sync_flags, /* Flags to pass to OsSync() (or 0) */ u8 *zBuf /* Buffer of at least page-size bytes */ ){ int rc = SQLITE_OK; if( pLog ){ |
︙ | ︙ | |||
1440 1441 1442 1443 1444 1445 1446 | ** ** If this call obtains a new read-lock and the database contents have been ** modified since the most recent call to LogCloseSnapshot() on this Log ** connection, then *pChanged is set to 1 before returning. Otherwise, it ** is left unmodified. This is used by the pager layer to determine whether ** or not any cached pages may be safely reused. */ | | | 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 | ** ** If this call obtains a new read-lock and the database contents have been ** modified since the most recent call to LogCloseSnapshot() on this Log ** connection, then *pChanged is set to 1 before returning. Otherwise, it ** is left unmodified. This is used by the pager layer to determine whether ** or not any cached pages may be safely reused. */ int sqlite3WalOpenSnapshot(Log *pLog, int *pChanged){ int rc = SQLITE_OK; if( pLog->isLocked==0 ){ int nAttempt; /* Obtain a snapshot-lock on the log-summary file. The procedure ** for obtaining the snapshot log is: ** |
︙ | ︙ | |||
1476 1477 1478 1479 1480 1481 1482 | if( rc!=SQLITE_OK ){ return rc; } rc = logSummaryReadHdr(pLog, pChanged); if( rc!=SQLITE_OK ){ /* An error occured while attempting log recovery. */ | | | | | 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 | if( rc!=SQLITE_OK ){ return rc; } rc = logSummaryReadHdr(pLog, pChanged); if( rc!=SQLITE_OK ){ /* An error occured while attempting log recovery. */ sqlite3WalCloseSnapshot(pLog); } } return rc; } /* ** Unlock the current snapshot. */ void sqlite3WalCloseSnapshot(Log *pLog){ if( pLog->isLocked ){ assert( pLog->isLocked==LOG_REGION_A || pLog->isLocked==LOG_REGION_D ); logLockRegion(pLog, pLog->isLocked, LOG_UNLOCK); } pLog->isLocked = 0; } /* ** Read a page from the log, if it is present. */ int sqlite3WalRead(Log *pLog, Pgno pgno, int *pInLog, u8 *pOut){ u32 iRead = 0; u32 *aData = pLog->pSummary->aData; int iFrame = (pLog->hdr.iLastPg & 0xFFFFFF00); assert( pLog->isLocked ); /* Do a linear search of the unindexed block of page-numbers (if any) |
︙ | ︙ | |||
1562 1563 1564 1565 1566 1567 1568 | return SQLITE_OK; } /* ** Set *pPgno to the size of the database file (or zero, if unknown). */ | | | | 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 | return SQLITE_OK; } /* ** Set *pPgno to the size of the database file (or zero, if unknown). */ void sqlite3WalDbsize(Log *pLog, Pgno *pPgno){ assert( pLog->isLocked ); *pPgno = pLog->hdr.nPage; } /* ** This function returns SQLITE_OK if the caller may write to the database. ** Otherwise, if the caller is operating on a snapshot that has already ** been overwritten by another writer, SQLITE_BUSY is returned. */ int sqlite3WalWriteLock(Log *pLog, int op){ assert( pLog->isLocked ); if( op ){ /* Obtain the writer lock */ int rc = logLockRegion(pLog, LOG_REGION_C|LOG_REGION_D, LOG_WRLOCK); if( rc!=SQLITE_OK ){ return rc; |
︙ | ︙ | |||
1632 1633 1634 1635 1636 1637 1638 | ** to the log since the start of the transaction. If the callback returns ** other than SQLITE_OK, it is not invoked again and the error code is ** returned to the caller. ** ** Otherwise, if the callback function does not return an error, this ** function returns SQLITE_OK. */ | | | | | 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 | ** to the log since the start of the transaction. If the callback returns ** other than SQLITE_OK, it is not invoked again and the error code is ** returned to the caller. ** ** Otherwise, if the callback function does not return an error, this ** function returns SQLITE_OK. */ int sqlite3WalUndo(Log *pLog, int (*xUndo)(void *, Pgno), void *pUndoCtx){ int rc = SQLITE_OK; Pgno iMax = pLog->hdr.iLastPg; Pgno iFrame; assert( pLog->isWriteLocked ); logSummaryReadHdr(pLog, 0); for(iFrame=pLog->hdr.iLastPg+1; iFrame<=iMax && rc==SQLITE_OK; iFrame++){ rc = xUndo(pUndoCtx, pLog->pSummary->aData[logSummaryEntry(iFrame)]); } return rc; } /* ** Return true if data has been written but not committed to the log file. */ int sqlite3WalDirty(Log *pLog){ assert( pLog->isWriteLocked ); return( pLog->hdr.iLastPg!=((LogSummaryHdr*)pLog->pSummary->aData)->iLastPg ); } /* ** Write a set of frames to the log. The caller must hold at least a ** RESERVED lock on the database file. */ int sqlite3WalFrames( Log *pLog, /* Log handle to write to */ int nPgsz, /* Database page-size in bytes */ PgHdr *pList, /* List of dirty pages to write */ Pgno nTruncate, /* Database size after this commit */ int isCommit, /* True if this is a commit */ int sync_flags /* Flags to pass to OsSync() (or 0) */ ){ |
︙ | ︙ | |||
1797 1798 1799 1800 1801 1802 1803 | ** ** 1. Wait for an EXCLUSIVE lock on regions B and C. ** 2. Wait for an EXCLUSIVE lock on region A. ** 3. Copy the contents of the log into the database file. ** 4. Zero the log-summary header (so new readers will ignore the log). ** 5. Drop the locks obtained in steps 1 and 2. */ | | | 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 | ** ** 1. Wait for an EXCLUSIVE lock on regions B and C. ** 2. Wait for an EXCLUSIVE lock on region A. ** 3. Copy the contents of the log into the database file. ** 4. Zero the log-summary header (so new readers will ignore the log). ** 5. Drop the locks obtained in steps 1 and 2. */ int sqlite3WalCheckpoint( Log *pLog, /* Log connection */ sqlite3_file *pFd, /* File descriptor open on db file */ int sync_flags, /* Flags to sync db file with (or 0) */ u8 *zBuf, /* Temporary buffer to use */ int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ ){ |
︙ | ︙ | |||
1835 1836 1837 1838 1839 1840 1841 | } /* Release the locks. */ logLockRegion(pLog, LOG_REGION_A|LOG_REGION_B|LOG_REGION_C, LOG_UNLOCK); return rc; } | | < | 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 | } /* Release the locks. */ logLockRegion(pLog, LOG_REGION_A|LOG_REGION_B|LOG_REGION_C, LOG_UNLOCK); return rc; } int sqlite3WalCallback(Log *pLog){ u32 ret = 0; if( pLog ){ ret = pLog->iCallback; pLog->iCallback = 0; } return (int)ret; } |
Name change from src/log.h to src/wal.h.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This header file defines the interface to the write-ahead logging ** system. Refer to the comments below and the header comment attached to ** the implementation of each function in log.c for further details. */ | | | | | | | | | | | | | | | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | ** ************************************************************************* ** This header file defines the interface to the write-ahead logging ** system. Refer to the comments below and the header comment attached to ** the implementation of each function in log.c for further details. */ #ifndef _WAL_H_ #define _WAL_H_ #include "sqliteInt.h" /* Connection to a log file. There is one object of this type for each pager. */ typedef struct Log Log; /* Open and close a connection to a log file. */ int sqlite3WalOpen(sqlite3_vfs*, const char *zDb, Log **ppLog); int sqlite3WalClose(Log *pLog, sqlite3_file *pFd, int sync_flags, u8 *zBuf); /* Used by readers to open (lock) and close (unlock) a snapshot. */ int sqlite3WalOpenSnapshot(Log *pLog, int *); void sqlite3WalCloseSnapshot(Log *pLog); /* Read a page from the log, if it is present. */ int sqlite3WalRead(Log *pLog, Pgno pgno, int *pInLog, u8 *pOut); void sqlite3WalDbsize(Log *pLog, Pgno *pPgno); /* Obtain or release the WRITER lock. */ int sqlite3WalWriteLock(Log *pLog, int op); /* Undo any frames written (but not committed) to the log */ int sqlite3WalUndo(Log *pLog, int (*xUndo)(void *, Pgno), void *pUndoCtx); /* Return true if data has been written but not committed to the log file. */ int sqlite3WalDirty(Log *pLog); /* Write a frame or frames to the log. */ int sqlite3WalFrames(Log *pLog, int, PgHdr *, Pgno, int, int); /* Copy pages from the log to the database file */ int sqlite3WalCheckpoint( Log *pLog, /* Log connection */ sqlite3_file *pFd, /* File descriptor open on db file */ int sync_flags, /* Flags to sync db file with (or 0) */ u8 *zBuf, /* Temporary buffer to use */ int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ ); /* Return the value to pass to a log callback. Or 0 for no callback. */ int sqlite3WalCallback(Log *pLog); #endif /* _WAL_H_ */ |
Changes to tool/mksqlite3c.tcl.
︙ | ︙ | |||
89 90 91 92 93 94 95 | fts3.h fts3Int.h fts3_hash.h fts3_tokenizer.h hash.h hwtime.h keywordhash.h | < > | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | fts3.h fts3Int.h fts3_hash.h fts3_tokenizer.h hash.h hwtime.h keywordhash.h mutex.h opcodes.h os_common.h os.h os_os2.h pager.h parse.h pcache.h rtree.h sqlite3ext.h sqlite3.h sqliteicu.h sqliteInt.h sqliteLimit.h vdbe.h vdbeInt.h wal.h } { set available_hdr($hdr) 1 } set available_hdr(sqliteInt.h) 0 # 78 stars used for comment formatting. set s78 \ |
︙ | ︙ | |||
240 241 242 243 244 245 246 | os_unix.c os_win.c bitvec.c pcache.c pcache1.c rowset.c | | | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | os_unix.c os_win.c bitvec.c pcache.c pcache1.c rowset.c wal.c pager.c btmutex.c btree.c backup.c vdbemem.c |
︙ | ︙ |