Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix issues with locking_mode=EXCLUSIVE in WAL. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | wal-incr-ckpt |
Files: | files | file ages | folders |
SHA1: |
8deba0cebd135a18da68530fab9e7d19 |
User & Date: | drh 2010-05-31 20:28:38.000 |
Context
2010-06-01
| ||
00:03 | Fix os_unix.c so that it will compile and build on a Mac. (check-in: bc707c83e5 user: drh tags: wal-incr-ckpt) | |
2010-05-31
| ||
20:28 | Fix issues with locking_mode=EXCLUSIVE in WAL. (check-in: 8deba0cebd user: drh tags: wal-incr-ckpt) | |
18:24 | Add an "isInit" field in the wal-index header that must be non-zero for a valid header. Use this to detect an uninitialized wal-index. (check-in: a16fde1901 user: drh tags: wal-incr-ckpt) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
3395 3396 3397 3398 3399 3400 3401 | p = pDbFd->pShm; if( p==0 ) return SQLITE_OK; pShmNode = p->pShmNode; assert( pShmNode==pDbFd->pInode->pShmNode ); assert( pShmNode->pInode==pDbFd->pInode ); | < < < < | 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 | p = pDbFd->pShm; if( p==0 ) return SQLITE_OK; pShmNode = p->pShmNode; assert( pShmNode==pDbFd->pInode->pShmNode ); assert( pShmNode->pInode==pDbFd->pInode ); /* Remove connection p from the set of connections associated ** with pShmNode */ sqlite3_mutex_enter(pShmNode->mutex); for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} *pp = p->pNext; /* Free the connection p */ |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
1441 1442 1443 1444 1445 1446 1447 | pPager->state = PAGER_SHARED; /* If the connection was in locking_mode=exclusive mode but is no longer, ** drop the EXCLUSIVE lock held on the database file. */ if( rc2==SQLITE_OK && !pPager->exclusiveMode | | < | 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 | pPager->state = PAGER_SHARED; /* If the connection was in locking_mode=exclusive mode but is no longer, ** drop the EXCLUSIVE lock held on the database file. */ if( rc2==SQLITE_OK && !pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, 0) ){ rc2 = osUnlock(pPager->fd, SHARED_LOCK); } }else if( !pPager->exclusiveMode ){ rc2 = osUnlock(pPager->fd, SHARED_LOCK); pPager->state = PAGER_SHARED; pPager->changeCountDone = 0; }else if( pPager->state==PAGER_SYNCED ){ |
︙ | ︙ | |||
2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 | ** other writers or checkpointers. */ static int pagerBeginReadTransaction(Pager *pPager){ int rc; /* Return code */ int changed = 0; /* True if cache must be reset */ assert( pagerUseWal(pPager) ); rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); if( rc==SQLITE_OK ){ int dummy; if( changed ){ pager_reset(pPager); assert( pPager->errCode || pPager->dbSizeValid==0 ); | > > > > > > > | 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 | ** other writers or checkpointers. */ static int pagerBeginReadTransaction(Pager *pPager){ int rc; /* Return code */ int changed = 0; /* True if cache must be reset */ assert( pagerUseWal(pPager) ); /* sqlite3WalEndReadTransaction() was not called for the previous ** transaction in locking_mode=EXCLUSIVE. So call it now. If we ** are in locking_mode=NORMAL and EndRead() was previously called, ** the duplicate call is harmless. */ sqlite3WalEndReadTransaction(pPager->pWal); rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); if( rc==SQLITE_OK ){ int dummy; if( changed ){ pager_reset(pPager); assert( pPager->errCode || pPager->dbSizeValid==0 ); |
︙ | ︙ | |||
4542 4543 4544 4545 4546 4547 4548 | assert( pPager->pInJournal==0 ); assert( !MEMDB && !pPager->tempFile ); if( pagerUseWal(pPager) ){ /* If the pager is configured to use locking_mode=exclusive, and an ** exclusive lock on the database is not already held, obtain it now. */ | | | 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 | assert( pPager->pInJournal==0 ); assert( !MEMDB && !pPager->tempFile ); if( pagerUseWal(pPager) ){ /* If the pager is configured to use locking_mode=exclusive, and an ** exclusive lock on the database is not already held, obtain it now. */ if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK); pPager->state = PAGER_SHARED; if( rc!=SQLITE_OK ){ return rc; } sqlite3WalExclusiveMode(pPager->pWal, 1); } |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
1689 1690 1691 1692 1693 1694 1695 | volatile WalIndexHdr *pHdr; /* Header of the wal-index */ volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ u32 mxReadMark; /* Largest aReadMark[] value */ int mxI; /* Index of largest aReadMark[] value */ int i; /* Loop counter */ int rc; /* Return code */ | | | 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 | volatile WalIndexHdr *pHdr; /* Header of the wal-index */ volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ u32 mxReadMark; /* Largest aReadMark[] value */ int mxI; /* Index of largest aReadMark[] value */ int i; /* Loop counter */ int rc; /* Return code */ assert( pWal->readLock<0 ); /* Not currently locked */ if( !useWal ){ rc = walIndexReadHdr(pWal, pChanged); if( rc==SQLITE_BUSY ){ /* If there is not a recovery running in another thread or process ** then convert BUSY errors to WAL_RETRY. If recovery is known to ** be running, convert BUSY to BUSY_RECOVERY. There is a race here |
︙ | ︙ | |||
2346 2347 2348 2349 2350 2351 2352 | ret = pWal->iCallback; pWal->iCallback = 0; } return (int)ret; } /* | | < < < | < < > > | > | > | | > > > > > > < < > > | | > > | > | > > | > > > > > > > > > > | > > > > > | 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 | ret = pWal->iCallback; pWal->iCallback = 0; } return (int)ret; } /* ** This function is called to change the WAL subsystem into or out ** of locking_mode=EXCLUSIVE. ** ** If op is zero, then attempt to change from locking_mode=EXCLUSIVE ** into locking_mode=NORMAL. This means that we must acquire a lock ** on the pWal->readLock byte. If the WAL is already in locking_mode=NORMAL ** or if the acquisition of the lock fails, then return 0. If the ** transition out of exclusive-mode is successful, return 1. This ** operation must occur while the pager is still holding the exclusive ** lock on the main database file. ** ** If op is one, then change from locking_mode=NORMAL into ** locking_mode=EXCLUSIVE. This means that the pWal->readLock must ** be released. Return 1 if the transition is made and 0 if the ** WAL is already in exclusive-locking mode - meaning that this ** routine is a no-op. The pager must already hold the exclusive lock ** on the main database file before invoking this operation. ** ** If op is negative, then do a dry-run of the op==1 case but do ** not actually change anything. The pager uses this to see if it ** should acquire the database exclusive lock prior to invoking ** the op==1 case. */ int sqlite3WalExclusiveMode(Wal *pWal, int op){ int rc; assert( pWal->writeLock==0 && pWal->readLock>=0 ); if( op==0 ){ if( pWal->exclusiveMode ){ pWal->exclusiveMode = 0; if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){ pWal->exclusiveMode = 1; } rc = pWal->exclusiveMode==0; }else{ /* No changes. Either already in locking_mode=NORMAL or else the ** acquisition of the read-lock failed. The pager must continue to ** hold the database exclusive lock. */ rc = 0; } }else if( op>0 ){ assert( pWal->exclusiveMode==0 ); walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); pWal->exclusiveMode = 1; rc = 1; }else{ rc = pWal->exclusiveMode==0; } return rc; } #endif /* #ifndef SQLITE_OMIT_WAL */ |