分类: SQLite/嵌入式数据库
2011-05-04 10:43:23
锁存放在pager 这个结构体中,这个结构体是数据库页在内存中的管理单位。
其中u8 state; 就是表示锁状态的变量
在sqlite1.0.2中 目前只有三种状态
SQLITE_UNLOCK,
READLOCK ,
WRITELOCK
#define SQLITE_UNLOCK 0
#define SQLITE_READLOCK 1
#define SQLITE_WRITELOCK 2
SQLITE_UNLOCK 这个内存页处于初始状态,里面没有数据
SQLITE_READLOCK 这个内存页处于被读取的状态,是不允许修改,但是允许其他进程读取
SQLITE_WRITELOCK 这个内存页正在写入磁盘文件,其他进程不允许读取,也不允许写入
这里应该采用状态机机制来说明,因为公司笔记本没有vision,以后补上。
正常流程
sqlitepager_open 将 pager 初始化为 将 SQLITE_UNLOCK,
sqlitepager_get() 函数将pager 从 SQLITE_UNLOCK变成 SQLITE_READLOCK,
sqlitepager_write() 函数 通过调用 sqlitepager_begin()将 pager从SQLITE_READLOCK变成SQLITE_WRITELOCK,
sqlitepager_commit()函数通过pager_unwritelock()将pager从SQLITE_WRITELOCK变成SQLITE_READLOCK或者是SQLITE_UNLOCK。
sqlitepager_rollback()函数通过pager_unwritelock()将pager从SQLITE_WRITELOCK变成SQLITE_READLOCK或者是SQLITE_UNLOCK。
异常流程锁伴随的结构体如下:
struct Pager {
char *zFilename; /* Name of the database file */
char *zJournal; /* Name of the journal file */
char *zDirectory; /* Directory hold database and journal files */
OsFile fd, jfd; /* File descriptors for database and journal */
OsFile cpfd; /* File descriptor for the checkpoint journal */
int dbSize; /* Number of pages in the file */
int origDbSize; /* dbSize before the current change */
int ckptSize; /* Size of database (in pages) at ckpt_begin() */
off_t ckptJSize; /* Size of journal at ckpt_begin() */
int nRec; /* Number of pages written to the journal */
u32 cksumInit; /* Quasi-random value added to every checksum */
int ckptNRec; /* Number of records in the checkpoint journal */
int nExtra; /* Add this many bytes to each in-memory page */
void (*xDestructor)(void*); /* Call this routine when freeing pages */
int nPage; /* Total number of in-memory pages */
int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */
int mxPage; /* Maximum number of pages to hold in cache */
int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
u8 journalOpen; /* True if journal file descriptors is valid */
u8 journalStarted; /* True if initial magic of journal is synced */
u8 useJournal; /* Do not use a rollback journal on this file */
u8 ckptOpen; /* True if the checkpoint journal is open */
u8 ckptInUse; /* True we are in a checkpoint */
u8 ckptAutoopen; /* Open ckpt journal when main journal is opened*/
u8 noSync; /* Do not sync the journal if true */
u8 fullSync; /* Do extra syncs of the journal for robustness */
u8 state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
u8 errMask; /* One of several kinds of errors */
u8 tempFile; /* zFilename is a temporary file */
u8 readOnly; /* True for a read-only database */
u8 needSync; /* True if an fsync() is needed on the journal */
u8 dirtyFile; /* True if database file has changed in any way */
u8 alwaysRollback; /* Disable dont_rollback() for all pages */
u8 *aInJournal; /* One bit for each page in the database file */
u8 *aInCkpt; /* One bit for each page in the database */
PgHdr *pFirst, *pLast; /* List of free pages */
PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */
PgHdr *pAll; /* List of all pages */
PgHdr *pCkpt; /* List of pages in the checkpoint journal */
PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
}