Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Avoid running recovery while there is another read/write client. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | server-edition |
Files: | files | file ages | folders |
SHA3-256: |
a38858a24c6edaa05966b7e158e603bc |
User & Date: | dan 2017-05-13 19:07:10.813 |
Context
2017-05-15
| ||
19:32 | Avoid writer starvation by adding a RESERVED state to page locks. (check-in: 9b7f80246f user: dan tags: server-edition) | |
2017-05-13
| ||
19:07 | Avoid running recovery while there is another read/write client. (check-in: a38858a24c user: dan tags: server-edition) | |
2017-05-12
| ||
18:52 | Require exclusive access to the db to wrap the wal file. Have "PRAGMA wal_checkpoint = restart" block for this. (check-in: cbf44ed975 user: dan tags: server-edition) | |
Changes
Changes to src/server.c.
︙ | ︙ | |||
508 509 510 511 512 513 514 515 516 | v = *pSlot; } } server_lock_out: return rc; } #endif /* ifdef SQLITE_SERVER_EDITION */ | > > > > > > > > | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | v = *pSlot; } } server_lock_out: return rc; } int sqlite3ServerHasLock(Server *p, Pgno pgno, int bWrite){ u32 v = *serverPageLockSlot(p, pgno); if( bWrite ){ return (v>>HMA_CLIENT_SLOTS)==(p->iClient+1); } return (v & (1 << p->iClient))!=0; } #endif /* ifdef SQLITE_SERVER_EDITION */ |
Changes to src/server.h.
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 | void sqlite3ServerDisconnect(Server *p, sqlite3_file *dbfd); int sqlite3ServerBegin(Server *p); int sqlite3ServerEnd(Server *p); int sqlite3ServerReleaseWriteLocks(Server *p); int sqlite3ServerLock(Server *p, Pgno pgno, int bWrite, int bBlock); #endif /* SQLITE_SERVER_H */ #endif /* SQLITE_SERVER_EDITION */ | > > | 24 25 26 27 28 29 30 31 32 33 34 35 36 | void sqlite3ServerDisconnect(Server *p, sqlite3_file *dbfd); int sqlite3ServerBegin(Server *p); int sqlite3ServerEnd(Server *p); int sqlite3ServerReleaseWriteLocks(Server *p); int sqlite3ServerLock(Server *p, Pgno pgno, int bWrite, int bBlock); int sqlite3ServerHasLock(Server *p, Pgno pgno, int bWrite); #endif /* SQLITE_SERVER_H */ #endif /* SQLITE_SERVER_EDITION */ |
Changes to src/wal.c.
︙ | ︙ | |||
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 | testcase( pWal->szPage<=32768 ); testcase( pWal->szPage>=65536 ); } /* The header was successfully read. Return zero. */ return 0; } /* ** Read the wal-index header from the wal-index and into pWal->hdr. ** If the wal-header appears to be corrupt, try to reconstruct the ** wal-index from the WAL before returning. ** ** Set *pChanged to 1 if the wal-index header value in pWal->hdr is | > > > > > > > > | 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 | testcase( pWal->szPage<=32768 ); testcase( pWal->szPage>=65536 ); } /* The header was successfully read. Return zero. */ return 0; } static int walIndexWriteLock(Wal *pWal){ if( walIsServer(pWal) ){ return sqlite3ServerLock(pWal->pServer, 0, 1, 0); }else{ return walLockExclusive(pWal, WAL_WRITE_LOCK, 1); } } /* ** Read the wal-index header from the wal-index and into pWal->hdr. ** If the wal-header appears to be corrupt, try to reconstruct the ** wal-index from the WAL before returning. ** ** Set *pChanged to 1 if the wal-index header value in pWal->hdr is |
︙ | ︙ | |||
2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 | /* If the first attempt failed, it might have been due to a race ** with a writer. So get a WRITE lock and try again. */ assert( badHdr==0 || pWal->writeLock==0 ); if( badHdr ){ if( pWal->readOnly & WAL_SHM_RDONLY ){ if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ walUnlockShared(pWal, WAL_WRITE_LOCK); rc = SQLITE_READONLY_RECOVERY; } | > | > | > | 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 | /* If the first attempt failed, it might have been due to a race ** with a writer. So get a WRITE lock and try again. */ assert( badHdr==0 || pWal->writeLock==0 ); if( badHdr ){ if( pWal->readOnly & WAL_SHM_RDONLY ){ assert( walIsServer(pWal)==0 ); if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ walUnlockShared(pWal, WAL_WRITE_LOCK); rc = SQLITE_READONLY_RECOVERY; } }else if( SQLITE_OK==(rc = walIndexWriteLock(pWal)) ){ pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); if( badHdr ){ /* If the wal-index header is still malformed even while holding ** a WRITE lock, it can only mean that the header is corrupted and ** needs to be reconstructed. So run recovery to do exactly that. */ rc = walIndexRecover(pWal); *pChanged = 1; } } pWal->writeLock = 0; if( walIsServer(pWal)==0 ){ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); } } } /* If the header is read successfully, check the version number to make ** sure the wal-index was not constructed with some future format that ** this version of SQLite cannot understand. */ |
︙ | ︙ | |||
2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 | u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ int iHash; /* Used to loop through N hash tables */ int iMinHash; /* This routine is only be called from within a read transaction. */ assert( walIsServer(pWal) || pWal->readLock>=0 || pWal->lockError ); if( walIsServer(pWal) && pWal->writeLock==0 ){ /* A server mode connection must read from the most recent snapshot. */ iLast = walIndexHdr(pWal)->mxFrame; } /* If the "last page" field of the wal-index header snapshot is 0, then ** no data will be read from the wal under any circumstances. Return early | > > > | 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 | u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ int iHash; /* Used to loop through N hash tables */ int iMinHash; /* This routine is only be called from within a read transaction. */ assert( walIsServer(pWal) || pWal->readLock>=0 || pWal->lockError ); assert( walIsServer(pWal)==0 || pWal->writeLock==0 || sqlite3ServerHasLock(pWal->pServer, 0, 1) ); if( walIsServer(pWal) && pWal->writeLock==0 ){ /* A server mode connection must read from the most recent snapshot. */ iLast = walIndexHdr(pWal)->mxFrame; } /* If the "last page" field of the wal-index header snapshot is 0, then ** no data will be read from the wal under any circumstances. Return early |
︙ | ︙ | |||
3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 | pWal->writeLock = 1; rc = walIndexTryHdr(pWal, &bDummy); } if( rc!=SQLITE_OK ){ return rc; } } /* If this frame set completes a transaction, then nTruncate>0. If ** nTruncate==0 then this frame set does not complete the transaction. */ assert( (isCommit!=0)==(nTruncate!=0) ); #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} | > | 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 | pWal->writeLock = 1; rc = walIndexTryHdr(pWal, &bDummy); } if( rc!=SQLITE_OK ){ return rc; } } assert( walIsServer(pWal)==0 || sqlite3ServerHasLock(pWal->pServer, 0, 1) ); /* If this frame set completes a transaction, then nTruncate>0. If ** nTruncate==0 then this frame set does not complete the transaction. */ assert( (isCommit!=0)==(nTruncate!=0) ); #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} |
︙ | ︙ |