Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add WALTRACE() macros to help with debugging and analysis. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | wal-incr-ckpt |
Files: | files | file ages | folders |
SHA1: |
765c33181a7b9d99b452ce750d69f217 |
User & Date: | drh 2010-05-31 12:15:19.000 |
Context
2010-05-31
| ||
12:30 | Do not fail a checkpoint just because active readers prevent backfill. (check-in: 9aa4243e0c user: drh tags: wal-incr-ckpt) | |
12:15 | Add WALTRACE() macros to help with debugging and analysis. (check-in: 765c33181a user: drh tags: wal-incr-ckpt) | |
12:02 | Another minor fix to checkpoint on the WAL branch. (check-in: 853f1e3f77 user: dan tags: wal-incr-ckpt) | |
Changes
Changes to src/test1.c.
︙ | ︙ | |||
5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 | #if SQLITE_OS_WIN extern int sqlite3_os_type; #endif #ifdef SQLITE_DEBUG extern int sqlite3WhereTrace; extern int sqlite3OSTrace; extern int sqlite3VdbeAddopTrace; #endif #ifdef SQLITE_TEST extern char sqlite3_query_plan[]; static char *query_plan = sqlite3_query_plan; #ifdef SQLITE_ENABLE_FTS3 extern int sqlite3_fts3_enable_parentheses; #endif | > | 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 | #if SQLITE_OS_WIN extern int sqlite3_os_type; #endif #ifdef SQLITE_DEBUG extern int sqlite3WhereTrace; extern int sqlite3OSTrace; extern int sqlite3VdbeAddopTrace; extern int sqlite3WalTrace; #endif #ifdef SQLITE_TEST extern char sqlite3_query_plan[]; static char *query_plan = sqlite3_query_plan; #ifdef SQLITE_ENABLE_FTS3 extern int sqlite3_fts3_enable_parentheses; #endif |
︙ | ︙ | |||
5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 | #ifdef SQLITE_DEBUG Tcl_LinkVar(interp, "sqlite_addop_trace", (char*)&sqlite3VdbeAddopTrace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_where_trace", (char*)&sqlite3WhereTrace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_os_trace", (char*)&sqlite3OSTrace, TCL_LINK_INT); #endif #ifndef SQLITE_OMIT_DISKIO Tcl_LinkVar(interp, "sqlite_opentemp_count", (char*)&sqlite3_opentemp_count, TCL_LINK_INT); #endif Tcl_LinkVar(interp, "sqlite_static_bind_value", (char*)&sqlite_static_bind_value, TCL_LINK_STRING); | > > | 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 | #ifdef SQLITE_DEBUG Tcl_LinkVar(interp, "sqlite_addop_trace", (char*)&sqlite3VdbeAddopTrace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_where_trace", (char*)&sqlite3WhereTrace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_os_trace", (char*)&sqlite3OSTrace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_wal_trace", (char*)&sqlite3WalTrace, TCL_LINK_INT); #endif #ifndef SQLITE_OMIT_DISKIO Tcl_LinkVar(interp, "sqlite_opentemp_count", (char*)&sqlite3_opentemp_count, TCL_LINK_INT); #endif Tcl_LinkVar(interp, "sqlite_static_bind_value", (char*)&sqlite_static_bind_value, TCL_LINK_STRING); |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
218 219 220 221 222 223 224 225 226 227 228 229 230 231 | ** When a rollback occurs, the value of K is decreased. Hash table entries ** that correspond to frames greater than the new K value are removed ** from the hash table at this point. */ #ifndef SQLITE_OMIT_WAL #include "wal.h" /* ** Indices of various locking bytes. WAL_NREADER is the number ** of available reader locks and should be at least 3. */ #define WAL_WRITE_LOCK 0 #define WAL_ALL_BUT_WRITE 1 | > > > > > > > > > > > > > | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | ** When a rollback occurs, the value of K is decreased. Hash table entries ** that correspond to frames greater than the new K value are removed ** from the hash table at this point. */ #ifndef SQLITE_OMIT_WAL #include "wal.h" /* ** Trace output macros */ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) int sqlite3WalTrace = 0; #endif #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) # define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X #else # define WALTRACE(X) #endif /* ** Indices of various locking bytes. WAL_NREADER is the number ** of available reader locks and should be at least 3. */ #define WAL_WRITE_LOCK 0 #define WAL_ALL_BUT_WRITE 1 |
︙ | ︙ | |||
576 577 578 579 580 581 582 583 584 585 586 587 588 589 | */ #define HASHTABLE_NPAGE 4096 /* Must be power of 2 and multiple of 256 */ #define HASHTABLE_DATATYPE u16 #define HASHTABLE_HASH_1 383 /* Should be prime */ #define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */ #define HASHTABLE_NBYTE (sizeof(HASHTABLE_DATATYPE)*HASHTABLE_NSLOT) /* ** Set or release locks. ** ** In locking_mode=EXCLUSIVE, all of these routines become no-ops. */ static int walLockShared(Wal *pWal, int lockIdx){ if( pWal->exclusiveMode ) return SQLITE_OK; | > > > > > > > > > > > > > > > > > > > > > > | | > > > > > | | > > > > > | 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 | */ #define HASHTABLE_NPAGE 4096 /* Must be power of 2 and multiple of 256 */ #define HASHTABLE_DATATYPE u16 #define HASHTABLE_HASH_1 383 /* Should be prime */ #define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */ #define HASHTABLE_NBYTE (sizeof(HASHTABLE_DATATYPE)*HASHTABLE_NSLOT) #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) /* ** Names of locks. */ static const char *walLockName(int lockIdx){ if( lockIdx==WAL_WRITE_LOCK ){ return "WRITE-LOCK"; }else if( lockIdx==WAL_CKPT_LOCK ){ return "CKPT-LOCK"; }else if( lockIdx==WAL_RECOVER_LOCK ){ return "RECOVER-LOCK"; }else{ static char zName[15]; sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]", lockIdx-WAL_READ_LOCK(0)); return zName; } } #endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ /* ** Set or release locks. ** ** In locking_mode=EXCLUSIVE, all of these routines become no-ops. */ static int walLockShared(Wal *pWal, int lockIdx){ int rc; if( pWal->exclusiveMode ) return SQLITE_OK; rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, walLockName(lockIdx), rc ? "failed" : "ok")); return rc; } static void walUnlockShared(Wal *pWal, int lockIdx){ if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); } static int walLockExclusive(Wal *pWal, int lockIdx, int n){ int rc; if( pWal->exclusiveMode ) return SQLITE_OK; rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, walLockName(lockIdx), n, rc ? "failed" : "ok")); return rc; } static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal, walLockName(lockIdx), n)); } /* ** Return the index in the Wal.pWiData array that corresponds to ** frame iFrame. ** ** Wal.pWiData is an array of u32 elements that is the wal-index. |
︙ | ︙ | |||
909 910 911 912 913 914 915 916 917 918 919 920 921 922 | i64 nSize; /* Size of log file */ u32 aFrameCksum[2] = {0, 0}; rc = walLockExclusive(pWal, WAL_ALL_BUT_WRITE, SQLITE_SHM_NLOCK-1); if( rc ){ return rc; } memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); rc = sqlite3OsFileSize(pWal->pWalFd, &nSize); if( rc!=SQLITE_OK ){ goto recovery_error; } | > | 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 | i64 nSize; /* Size of log file */ u32 aFrameCksum[2] = {0, 0}; rc = walLockExclusive(pWal, WAL_ALL_BUT_WRITE, SQLITE_SHM_NLOCK-1); if( rc ){ return rc; } WALTRACE(("WAL%p: recovery begin...\n", pWal)); memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); rc = sqlite3OsFileSize(pWal->pWalFd, &nSize); if( rc!=SQLITE_OK ){ goto recovery_error; } |
︙ | ︙ | |||
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 | if( rc==SQLITE_OK ){ pWal->hdr.aFrameCksum[0] = aFrameCksum[0]; pWal->hdr.aFrameCksum[1] = aFrameCksum[1]; walIndexWriteHdr(pWal); } recovery_error: walUnlockExclusive(pWal, WAL_ALL_BUT_WRITE, SQLITE_SHM_NLOCK-1); return rc; } /* ** Close an open wal-index. */ | > | 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | if( rc==SQLITE_OK ){ pWal->hdr.aFrameCksum[0] = aFrameCksum[0]; pWal->hdr.aFrameCksum[1] = aFrameCksum[1]; walIndexWriteHdr(pWal); } recovery_error: WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); walUnlockExclusive(pWal, WAL_ALL_BUT_WRITE, SQLITE_SHM_NLOCK-1); return rc; } /* ** Close an open wal-index. */ |
︙ | ︙ | |||
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 | if( rc!=SQLITE_OK ){ walIndexClose(pRet, 0); sqlite3OsClose(pRet->pWalFd); sqlite3_free(pRet); }else{ *ppWal = pRet; } return rc; } /* ** Find the smallest page number out of all pages held in the WAL that ** has not been returned by any prior invocation of this method on the | > | 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 | if( rc!=SQLITE_OK ){ walIndexClose(pRet, 0); sqlite3OsClose(pRet->pWalFd); sqlite3_free(pRet); }else{ *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } return rc; } /* ** Find the smallest page number out of all pages held in the WAL that ** has not been returned by any prior invocation of this method on the |
︙ | ︙ | |||
1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 | } walIndexClose(pWal, isDelete); sqlite3OsClose(pWal->pWalFd); if( isDelete ){ sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); } sqlite3_free(pWal); } return rc; } /* ** Try to read the wal-index header. Return 0 on success and 1 if | > | 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 | } walIndexClose(pWal, isDelete); sqlite3OsClose(pWal->pWalFd); if( isDelete ){ sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); } WALTRACE(("WAL%p: closed\n", pWal)); sqlite3_free(pWal); } return rc; } /* ** Try to read the wal-index header. Return 0 on success and 1 if |
︙ | ︙ | |||
2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 | PgHdr *p; /* Iterator to run through pList with. */ PgHdr *pLast = 0; /* Last frame in list */ int nLast = 0; /* Number of extra copies of last page */ assert( pList ); assert( pWal->writeLock ); assert( pWal->pWiData==0 ); /* If this is the first frame written into the log, write the WAL ** header to the start of the WAL file. See comments at the top of ** this source file for a description of the WAL header format. */ iFrame = pWal->hdr.mxFrame; if( iFrame==0 ){ u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assembly wal-header in */ sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); sqlite3Put4byte(&aWalHdr[4], 3007000); sqlite3Put4byte(&aWalHdr[8], szPage); pWal->szPage = szPage; pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); if( rc!=SQLITE_OK ){ return rc; } walChecksumBytes(1, aWalHdr, sizeof(aWalHdr), 0, pWal->hdr.aFrameCksum); } assert( pWal->szPage==szPage ); | > > > > > > > > | 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 | PgHdr *p; /* Iterator to run through pList with. */ PgHdr *pLast = 0; /* Last frame in list */ int nLast = 0; /* Number of extra copies of last page */ assert( pList ); assert( pWal->writeLock ); assert( pWal->pWiData==0 ); #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill")); } #endif /* If this is the first frame written into the log, write the WAL ** header to the start of the WAL file. See comments at the top of ** this source file for a description of the WAL header format. */ iFrame = pWal->hdr.mxFrame; if( iFrame==0 ){ u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assembly wal-header in */ sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); sqlite3Put4byte(&aWalHdr[4], 3007000); sqlite3Put4byte(&aWalHdr[8], szPage); pWal->szPage = szPage; pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok")); if( rc!=SQLITE_OK ){ return rc; } walChecksumBytes(1, aWalHdr, sizeof(aWalHdr), 0, pWal->hdr.aFrameCksum); } assert( pWal->szPage==szPage ); |
︙ | ︙ | |||
2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 | if( isCommit ){ walIndexWriteHdr(pWal); pWal->iCallback = iFrame; } } walIndexUnmap(pWal); return rc; } /* ** This routine is called to implement sqlite3_wal_checkpoint() and ** related interfaces. ** | > | 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 | if( isCommit ){ walIndexWriteHdr(pWal); pWal->iCallback = iFrame; } } walIndexUnmap(pWal); WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok")); return rc; } /* ** This routine is called to implement sqlite3_wal_checkpoint() and ** related interfaces. ** |
︙ | ︙ | |||
2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 | ){ int rc; /* Return code */ int isChanged = 0; /* True if a new wal-index header is loaded */ assert( pWal->pWiData==0 ); assert( pWal->ckptLock==0 ); rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc ){ /* Usually this is SQLITE_BUSY meaning that another thread or process ** is already running a checkpoint, or maybe a recovery. But it might ** also be SQLITE_IOERR. */ return rc; } | > | 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 | ){ int rc; /* Return code */ int isChanged = 0; /* True if a new wal-index header is loaded */ assert( pWal->pWiData==0 ); assert( pWal->ckptLock==0 ); WALTRACE(("WAL%p: checkpoint begins\n", pWal)); rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc ){ /* Usually this is SQLITE_BUSY meaning that another thread or process ** is already running a checkpoint, or maybe a recovery. But it might ** also be SQLITE_IOERR. */ return rc; } |
︙ | ︙ | |||
2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 | memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); } /* Release the locks. */ walIndexUnmap(pWal); walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); pWal->ckptLock = 0; return rc; } /* Return the value to pass to a sqlite3_wal_hook callback, the ** number of frames in the WAL at the point of the last commit since ** sqlite3WalCallback() was called. If no commits have occurred since ** the last call, then return 0. | > | 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 | memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); } /* Release the locks. */ walIndexUnmap(pWal); walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); pWal->ckptLock = 0; WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok")); return rc; } /* Return the value to pass to a sqlite3_wal_hook callback, the ** number of frames in the WAL at the point of the last commit since ** sqlite3WalCallback() was called. If no commits have occurred since ** the last call, then return 0. |
︙ | ︙ |