Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Speed up xAccess() calls made on an RBU VFS when there are lots of open connections. Cherrypick of [310b4b65]. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | branch-3.22 |
Files: | files | file ages | folders |
SHA3-256: |
fda8fdb0cbc3acf420613f5df4125898 |
User & Date: | dan 2018-10-25 11:55:54.434 |
Original Comment: | Speed up xAccess() calls made on an RBU VFS when there are lots of open connections. |
Context
2018-12-19
| ||
01:30 | Add extra defenses against strategically corrupt databases to fts3/4. (check-in: c255889bd9 user: drh tags: branch-3.22) | |
2018-10-25
| ||
11:55 | Speed up xAccess() calls made on an RBU VFS when there are lots of open connections. Cherrypick of [310b4b65]. (check-in: fda8fdb0cb user: dan tags: branch-3.22) | |
2018-10-01
| ||
17:33 | Speed up xAccess() calls made on an RBU VFS when there are lots of open connections. (check-in: 310b4b65b8 user: dan tags: trunk) | |
2018-03-22
| ||
17:17 | Fix an RBU problem causing errors when updating tables with default collation sequences that require quoting (e.g. COLLATE "ICU_root-u-kn-on"). Cherrypick of [eb4f452e]. (check-in: 5dd61e1cbd user: dan tags: branch-3.22) | |
Changes
Changes to ext/rbu/sqlite3rbu.c.
︙ | ︙ | |||
395 396 397 398 399 400 401 | ** space used by the RBU handle. */ struct rbu_vfs { sqlite3_vfs base; /* rbu VFS shim methods */ sqlite3_vfs *pRealVfs; /* Underlying VFS */ sqlite3_mutex *mutex; /* Mutex to protect pMain */ sqlite3rbu *pRbu; /* Owner RBU object */ | | > | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | ** space used by the RBU handle. */ struct rbu_vfs { sqlite3_vfs base; /* rbu VFS shim methods */ sqlite3_vfs *pRealVfs; /* Underlying VFS */ sqlite3_mutex *mutex; /* Mutex to protect pMain */ sqlite3rbu *pRbu; /* Owner RBU object */ rbu_file *pMain; /* List of main db files */ rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */ }; /* ** Each file opened by an rbu VFS is represented by an instance of ** the following structure. ** ** If this is a temporary file (pRbu!=0 && flags&DELETE_ON_CLOSE), variable |
︙ | ︙ | |||
424 425 426 427 428 429 430 431 432 433 434 435 436 437 | int nShm; /* Number of entries in apShm[] array */ char **apShm; /* Array of mmap'd *-shm regions */ char *zDel; /* Delete this when closing file */ const char *zWal; /* Wal filename for this main db file */ rbu_file *pWalFd; /* Wal file descriptor for this main db */ rbu_file *pMainNext; /* Next MAIN_DB file */ }; /* ** True for an RBU vacuum handle, or false otherwise. */ #define rbuIsVacuum(p) ((p)->zTarget==0) | > | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | int nShm; /* Number of entries in apShm[] array */ char **apShm; /* Array of mmap'd *-shm regions */ char *zDel; /* Delete this when closing file */ const char *zWal; /* Wal filename for this main db file */ rbu_file *pWalFd; /* Wal file descriptor for this main db */ rbu_file *pMainNext; /* Next MAIN_DB file */ rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */ }; /* ** True for an RBU vacuum handle, or false otherwise. */ #define rbuIsVacuum(p) ((p)->zTarget==0) |
︙ | ︙ | |||
4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 | i64 nDiff = nNew - pFd->sz; pRbu->szTemp += nDiff; pFd->sz = nNew; assert( pRbu->szTemp>=0 ); if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL; return SQLITE_OK; } /* ** Close an rbu file. */ static int rbuVfsClose(sqlite3_file *pFile){ rbu_file *p = (rbu_file*)pFile; int rc; int i; /* Free the contents of the apShm[] array. And the array itself. */ for(i=0; i<p->nShm; i++){ sqlite3_free(p->apShm[i]); } sqlite3_free(p->apShm); p->apShm = 0; sqlite3_free(p->zDel); if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < | < > | 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 | i64 nDiff = nNew - pFd->sz; pRbu->szTemp += nDiff; pFd->sz = nNew; assert( pRbu->szTemp>=0 ); if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL; return SQLITE_OK; } /* ** Add an item to the main-db lists, if it is not already present. ** ** There are two main-db lists. One for all file descriptors, and one ** for all file descriptors with rbu_file.pDb!=0. If the argument has ** rbu_file.pDb!=0, then it is assumed to already be present on the ** main list and is only added to the pDb!=0 list. */ static void rbuMainlistAdd(rbu_file *p){ rbu_vfs *pRbuVfs = p->pRbuVfs; rbu_file *pIter; assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) ); sqlite3_mutex_enter(pRbuVfs->mutex); if( p->pRbu==0 ){ for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext); p->pMainNext = pRbuVfs->pMain; pRbuVfs->pMain = p; }else{ for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){} if( pIter==0 ){ p->pMainRbuNext = pRbuVfs->pMainRbu; pRbuVfs->pMainRbu = p; } } sqlite3_mutex_leave(pRbuVfs->mutex); } /* ** Remove an item from the main-db lists. */ static void rbuMainlistRemove(rbu_file *p){ rbu_file **pp; sqlite3_mutex_enter(p->pRbuVfs->mutex); for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){} if( *pp ) *pp = p->pMainNext; p->pMainNext = 0; for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){} if( *pp ) *pp = p->pMainRbuNext; p->pMainRbuNext = 0; sqlite3_mutex_leave(p->pRbuVfs->mutex); } /* ** Given that zWal points to a buffer containing a wal file name passed to ** either the xOpen() or xAccess() VFS method, search the main-db list for ** a file-handle opened by the same database connection on the corresponding ** database file. ** ** If parameter bRbu is true, only search for file-descriptors with ** rbu_file.pDb!=0. */ static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){ rbu_file *pDb; sqlite3_mutex_enter(pRbuVfs->mutex); if( bRbu ){ for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){} }else{ for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){} } sqlite3_mutex_leave(pRbuVfs->mutex); return pDb; } /* ** Close an rbu file. */ static int rbuVfsClose(sqlite3_file *pFile){ rbu_file *p = (rbu_file*)pFile; int rc; int i; /* Free the contents of the apShm[] array. And the array itself. */ for(i=0; i<p->nShm; i++){ sqlite3_free(p->apShm[i]); } sqlite3_free(p->apShm); p->apShm = 0; sqlite3_free(p->zDel); if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ rbuMainlistRemove(p); rbuUnlockShm(p); p->pReal->pMethods->xShmUnmap(p->pReal, 0); } else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ rbuUpdateTempSize(p, 0); } assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p ); /* Close the underlying file handle */ rc = p->pReal->pMethods->xClose(p->pReal); return rc; } |
︙ | ︙ | |||
4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 | rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy); if( rc==SQLITE_OK ){ rc = SQLITE_ERROR; pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error"); }else if( rc==SQLITE_NOTFOUND ){ pRbu->pTargetFd = p; p->pRbu = pRbu; if( p->pWalFd ) p->pWalFd->pRbu = pRbu; rc = SQLITE_OK; } } return rc; } else if( op==SQLITE_FCNTL_RBUCNT ){ | > > > | 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 | rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy); if( rc==SQLITE_OK ){ rc = SQLITE_ERROR; pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error"); }else if( rc==SQLITE_NOTFOUND ){ pRbu->pTargetFd = p; p->pRbu = pRbu; if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ rbuMainlistAdd(p); } if( p->pWalFd ) p->pWalFd->pRbu = pRbu; rc = SQLITE_OK; } } return rc; } else if( op==SQLITE_FCNTL_RBUCNT ){ |
︙ | ︙ | |||
4459 4460 4461 4462 4463 4464 4465 | /* Release the checkpointer and writer locks */ rbuUnlockShm(p); rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag); } return rc; } | < < < < < < < < < < < < < < | 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 | /* Release the checkpointer and writer locks */ rbuUnlockShm(p); rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag); } return rc; } /* ** A main database named zName has just been opened. The following ** function returns a pointer to a buffer owned by SQLite that contains ** the name of the *-wal file this db connection will use. SQLite ** happens to pass a pointer to this buffer when using xAccess() ** or xOpen() to operate on the *-wal file. */ |
︙ | ︙ | |||
4551 4552 4553 4554 4555 4556 4557 | ** (pFd->zWal) to point to a buffer owned by SQLite that contains ** the name of the *-wal file this db connection will use. SQLite ** happens to pass a pointer to this buffer when using xAccess() ** or xOpen() to operate on the *-wal file. */ pFd->zWal = rbuMainToWal(zName, flags); } else if( flags & SQLITE_OPEN_WAL ){ | | | 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 | ** (pFd->zWal) to point to a buffer owned by SQLite that contains ** the name of the *-wal file this db connection will use. SQLite ** happens to pass a pointer to this buffer when using xAccess() ** or xOpen() to operate on the *-wal file. */ pFd->zWal = rbuMainToWal(zName, flags); } else if( flags & SQLITE_OPEN_WAL ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0); if( pDb ){ if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ /* This call is to open a *-wal file. Intead, open the *-oal. This ** code ensures that the string passed to xOpen() is terminated by a ** pair of '\0' bytes in case the VFS attempts to extract a URI ** parameter from it. */ const char *zBase = zName; |
︙ | ︙ | |||
4603 4604 4605 4606 4607 4608 4609 | } if( pFd->pReal->pMethods ){ /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods ** pointer and, if the file is a main database file, link it into the ** mutex protected linked list of all such files. */ pFile->pMethods = &rbuvfs_io_methods; if( flags & SQLITE_OPEN_MAIN_DB ){ | < < | < | 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 | } if( pFd->pReal->pMethods ){ /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods ** pointer and, if the file is a main database file, link it into the ** mutex protected linked list of all such files. */ pFile->pMethods = &rbuvfs_io_methods; if( flags & SQLITE_OPEN_MAIN_DB ){ rbuMainlistAdd(pFd); } }else{ sqlite3_free(pFd->zDel); } return rc; } |
︙ | ︙ | |||
4654 4655 4656 4657 4658 4659 4660 | ** ** b) if the *-wal file does not exist, claim that it does anyway, ** causing SQLite to call xOpen() to open it. This call will also ** be intercepted (see the rbuVfsOpen() function) and the *-oal ** file opened instead. */ if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){ | | | 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 | ** ** b) if the *-wal file does not exist, claim that it does anyway, ** causing SQLite to call xOpen() to open it. This call will also ** be intercepted (see the rbuVfsOpen() function) and the *-oal ** file opened instead. */ if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1); if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ if( *pResOut ){ rc = SQLITE_CANTOPEN; }else{ sqlite3_int64 sz = 0; rc = rbuVfsFileSize(&pDb->base, &sz); *pResOut = (sz>0); |
︙ | ︙ |