Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Experimental implementation of pessimistic page-level locking based on rollback mode. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | server-edition |
Files: | files | file ages | folders |
SHA3-256: |
64ecf7c7e512827e8a5a42f9f3ad92ff |
User & Date: | dan 2017-04-26 20:45:00.409 |
Context
2017-04-27
| ||
13:05 | If possible, delete the journal file when a database connection is closed. (check-in: d5b5326df2 user: dan tags: server-edition) | |
2017-04-26
| ||
20:45 | Experimental implementation of pessimistic page-level locking based on rollback mode. (check-in: 64ecf7c7e5 user: dan tags: server-edition) | |
17:21 | Add new test file cachespill.test. (check-in: 2d0b64316d user: dan tags: trunk) | |
Changes
Changes to main.mk.
︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | + | icu.o insert.o json1.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_unix.o mutex_w32.o \ notify.o opcodes.o os.o os_unix.o os_win.o \ pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \ random.o resolve.o rowset.o rtree.o select.o sqlite3rbu.o status.o \ server.o \ table.o threads.o tokenize.o treeview.o trigger.o \ update.o userauth.o util.o vacuum.o \ vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ vdbetrace.o wal.o walker.o where.o wherecode.o whereexpr.o \ utf.o vtab.o LIBOBJ += sqlite3session.o |
︙ | |||
140 141 142 143 144 145 146 147 148 149 150 151 152 153 | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | + + | $(TOP)/src/pragma.h \ $(TOP)/src/prepare.c \ $(TOP)/src/printf.c \ $(TOP)/src/random.c \ $(TOP)/src/resolve.c \ $(TOP)/src/rowset.c \ $(TOP)/src/select.c \ $(TOP)/src/server.c \ $(TOP)/src/server.h \ $(TOP)/src/status.c \ $(TOP)/src/shell.c \ $(TOP)/src/sqlite.h.in \ $(TOP)/src/sqlite3ext.h \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/sqliteLimit.h \ $(TOP)/src/table.c \ |
︙ |
Changes to src/pager.c.
︙ | |||
702 703 704 705 706 707 708 709 710 711 712 713 714 715 | 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | + + + | #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ #ifndef SQLITE_OMIT_WAL Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ char *zWal; /* File name for write-ahead log */ #endif #ifdef SQLITE_SERVER_EDITION Server *pServer; #endif }; /* ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS ** or CACHE_WRITE to sqlite3_db_status(). */ |
︙ | |||
831 832 833 834 835 836 837 838 839 840 841 842 843 844 | 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 | + + + + + + | #else # define pagerUseWal(x) 0 # define pagerRollbackWal(x) 0 # define pagerWalFrames(v,w,x,y) 0 # define pagerOpenWalIfPresent(z) SQLITE_OK # define pagerBeginReadTransaction(z) SQLITE_OK #endif #ifdef SQLITE_SERVER_EDITION # define pagerIsServer(x) ((x)->pServer!=0) #else # define pagerIsServer(x) 0 #endif #ifndef NDEBUG /* ** Usage: ** ** assert( assert_pager_state(pPager) ); ** |
︙ | |||
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 | 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 | + | */ static int pagerUnlockDb(Pager *pPager, int eLock){ int rc = SQLITE_OK; assert( !pPager->exclusiveMode || pPager->eLock==eLock ); assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); assert( eLock!=NO_LOCK || pagerIsServer(pPager)==0 ); if( isOpen(pPager->fd) ){ assert( pPager->eLock>=eLock ); rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock); if( pPager->eLock!=UNKNOWN_LOCK ){ pPager->eLock = (u8)eLock; } IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) |
︙ | |||
1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 | 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 | + + + + + + | || pPager->eState==PAGER_ERROR ); sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; releaseAllSavepoints(pPager); #ifdef SQLITE_SERVER_EDITION if( pagerIsServer(pPager) ){ sqlite3ServerEnd(pPager->pServer); pPager->eState = PAGER_OPEN; }else #endif if( pagerUseWal(pPager) ){ assert( !isOpen(pPager->jfd) ); sqlite3WalEndReadTransaction(pPager->pWal); pPager->eState = PAGER_OPEN; }else if( !pPager->exclusiveMode ){ int rc; /* Error code returned by pagerUnlockDb() */ int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; |
︙ | |||
2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 | 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 | + + + + + | } if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; } #ifdef SQLITE_SERVER_EDITION if( pagerIsServer(pPager) ){ rc2 = sqlite3ServerReleaseWriteLocks(pPager->pServer); }else #endif if( !pPager->exclusiveMode && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) ){ rc2 = pagerUnlockDb(pPager, SHARED_LOCK); pPager->changeCountDone = 0; } pPager->eState = PAGER_READER; |
︙ | |||
4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 | 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 | + + + + + + + | pPager->exclusiveMode = 0; #ifndef SQLITE_OMIT_WAL assert( db || pPager->pWal==0 ); sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize, (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp) ); pPager->pWal = 0; #endif #ifdef SQLITE_SERVER_EDITION if( pPager->pServer ){ sqlite3ServerDisconnect(pPager->pServer, pPager->fd); pPager->pServer = 0; sqlite3_free(pPager->zJournal); } #endif pager_reset(pPager); if( MEMDB ){ pager_unlock(pPager); }else{ /* If it is open, sync the journal file before calling UnlockAndRollback. ** If this is not done, then an unsynced portion of the open journal |
︙ | |||
5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 | 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | } } } } return rc; } #ifdef SQLITE_SERVER_EDITION static int pagerServerConnect(Pager *pPager){ int rc = SQLITE_OK; if( pPager->tempFile==0 ){ int iClient = 0; pPager->noLock = 1; pPager->journalMode = PAGER_JOURNALMODE_PERSIST; rc = sqlite3ServerConnect(pPager, &pPager->pServer, &iClient); if( rc==SQLITE_OK ){ pPager->zJournal = sqlite3_mprintf( "%s-journal%d", pPager->zFilename, iClient ); if( pPager->zJournal==0 ){ rc = SQLITE_NOMEM_BKPT; } } } return rc; } int sqlite3PagerRollbackJournal(Pager *pPager, int iClient){ int rc; char *zJrnl = sqlite3_mprintf("%s-journal%d", pPager->zFilename, iClient); if( zJrnl ){ int bExists = 0; sqlite3_file *jfd = 0; sqlite3_vfs * const pVfs = pPager->pVfs; rc = sqlite3OsAccess(pVfs, zJrnl, SQLITE_ACCESS_EXISTS, &bExists); if( rc==SQLITE_OK && bExists ){ int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; rc = sqlite3OsOpenMalloc(pVfs, zJrnl, &jfd, flags, &flags); } assert( rc==SQLITE_OK || jfd==0 ); if( jfd ){ sqlite3_file *saved_jfd = pPager->jfd; u8 saved_eState = pPager->eState; u8 saved_eLock = pPager->eLock; i64 saved_journalOff = pPager->journalOff; i64 saved_journalHdr = pPager->journalHdr; pPager->eLock = EXCLUSIVE_LOCK; pPager->eState = PAGER_WRITER_DBMOD; pPager->jfd = jfd; rc = pagerSyncHotJournal(pPager); if( rc==SQLITE_OK ) rc = pager_playback(pPager, 1); pPager->jfd = saved_jfd; pPager->eState = saved_eState; pPager->eLock = saved_eLock; pPager->journalOff = saved_journalOff; pPager->journalHdr = saved_journalHdr; sqlite3OsCloseFree(jfd); if( rc==SQLITE_OK ){ rc = sqlite3OsDelete(pVfs, zJrnl, 0); } } sqlite3_free(zJrnl); }else{ rc = SQLITE_NOMEM_BKPT; } return rc; } #else # define pagerServerConnect(pPager) SQLITE_OK #endif /* ** This function is called to obtain a shared lock on the database file. ** It is illegal to call sqlite3PagerGet() until after this function ** has been successfully called. If a shared-lock is already held when ** this function is called, it is a no-op. ** |
︙ | |||
5086 5087 5088 5089 5090 5091 5092 | 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 | - + + + | ** be OPEN or READER. READER is only possible if the pager is or was in ** exclusive access mode. */ assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); assert( assert_pager_state(pPager) ); assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); assert( pPager->errCode==SQLITE_OK ); |
︙ | |||
5265 5266 5267 5268 5269 5270 5271 | 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 | - - + + + + + + + + + + + + + | /* If there is a WAL file in the file-system, open this database in WAL ** mode. Otherwise, the following function call is a no-op. */ rc = pagerOpenWalIfPresent(pPager); #ifndef SQLITE_OMIT_WAL assert( pPager->pWal==0 || rc==SQLITE_OK ); #endif |
︙ | |||
5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 | 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 | + + + + + + | */ int sqlite3PagerGet( Pager *pPager, /* The pager open on the database file */ Pgno pgno, /* Page number to fetch */ DbPage **ppPage, /* Write a pointer to the page here */ int flags /* PAGER_GET_XXX flags */ ){ #ifdef SQLITE_SERVER_EDITION if( pagerIsServer(pPager) ){ int rc = sqlite3ServerLock(pPager->pServer, pgno, 0); if( rc!=SQLITE_OK ) return rc; } #endif return pPager->xGet(pPager, pgno, ppPage, flags); } /* ** Acquire a page if it is already in the in-memory cache. Do ** not read the page from disk. Return a pointer to the page, ** or 0 if the page is not in cache. |
︙ | |||
5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 | 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 | + + + + + + + | || pPager->eState==PAGER_WRITER_CACHEMOD || pPager->eState==PAGER_WRITER_DBMOD ); assert( assert_pager_state(pPager) ); assert( pPager->errCode==0 ); assert( pPager->readOnly==0 ); CHECK_PAGE(pPg); #ifdef SQLITE_SERVER_EDITION if( pagerIsServer(pPager) ){ rc = sqlite3ServerLock(pPager->pServer, pPg->pgno, 1); if( rc!=SQLITE_OK ) return rc; } #endif /* The journal file needs to be opened. Higher level routines have already ** obtained the necessary locks to begin the write-transaction, but the ** rollback journal might not yet be open. Open it now if this is the case. ** ** This is done before calling sqlite3PcacheMakeDirty() on the page. ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then |
︙ | |||
6140 6141 6142 6143 6144 6145 6146 | 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 | + + - + + | # define DIRECT_MODE 0 assert( isDirectMode==0 ); UNUSED_PARAMETER(isDirectMode); #else # define DIRECT_MODE isDirectMode #endif if( 0==pagerIsServer(pPager) && !pPager->changeCountDone |
︙ |
Changes to src/pager.h.
︙ | |||
231 232 233 234 235 236 237 238 239 | 231 232 233 234 235 236 237 238 239 240 241 242 243 | + + + + | void sqlite3PagerRefdump(Pager*); void disable_simulated_io_errors(void); void enable_simulated_io_errors(void); #else # define disable_simulated_io_errors() # define enable_simulated_io_errors() #endif #ifdef SQLITE_SERVER_EDITION int sqlite3PagerRollbackJournal(Pager*, int); #endif #endif /* SQLITE_PAGER_H */ |
Added src/server.c.