SQLite3數(shù)據(jù)庫中的文件鎖和同步機(jī)制
SQLite3 提供了一個(gè)新的鎖和同步機(jī)制來提高并發(fā),減少死鎖。
SQLite3的鎖和同步有PagerModule(pager.c)負(fù)責(zé)處理。PagerModue負(fù)責(zé)SQLite事務(wù)的ACID,也提供緩存功能。PagerModue不需要知道BTree,字符編碼, 索引的結(jié)構(gòu), Pager Module用來管理Page, 一個(gè)Page對應(yīng)一個(gè)DiskBlock, 大小一般是1024Byte。
1. SQLite3 數(shù)據(jù)庫的鎖狀態(tài)
UNLOCKED
SHARED
RESERVED 保留鎖, 表示數(shù)據(jù)庫將被寫, 一個(gè)數(shù)據(jù)庫只能有一個(gè)保留鎖, 保留鎖可以和共享鎖共存,與PENDING鎖的不同之處在于還能獲得新的共享鎖,PENDING鎖被激活時(shí), 不能再獲得共享鎖。
PENDING
EXCLUSIVE
2. 回滾日志文件
如果有更新數(shù)據(jù)庫操作, SQLite就會(huì)生成回滾日志文件, 以"-journal"的文件名結(jié)尾, 與數(shù)據(jù)庫文件存放在同一目錄下。如果多個(gè)數(shù)據(jù)庫同時(shí)工作, 每個(gè)數(shù)據(jù)庫都有自己的回滾日志文件, 并且還有一個(gè)master journal日志文件。master journal沒有數(shù)據(jù), 只包含各個(gè)回滾日志文件名。每個(gè)數(shù)據(jù)庫的回滾日志文件也會(huì)包含masterjournal文件名。
當(dāng)訪問數(shù)據(jù)庫時(shí)發(fā)現(xiàn)有"hot journal"時(shí), SQLite就會(huì)進(jìn)行回滾工作, 回滾結(jié)束就刪除回滾日志文件。
處理"hot journal"
(1) 嘗試獲得SHAREDLOCK, 如果失敗, 立即結(jié)束, 返回SQLITE_BUSY
(2) 檢查是否有"hotjournal", 如果沒有立即返回, 否則繼續(xù)執(zhí)行以下步驟
(3) 嘗試獲得PENDINGLOCK, 然后EXCLUSIVELOCK, 如果失敗, 表示其他進(jìn)程正在做回滾, 釋放所有鎖, 關(guān)閉數(shù)據(jù)庫, 返回SQLITE_BUSY。否則繼續(xù)執(zhí)行
(4) 讀回滾日志文件, 回滾數(shù)據(jù)庫文件
(5) 刪除回滾日志文件
(6) 刪除masterjournal 文件
(7) 釋放PENDINGLOCK和EXCLUSIVELOCK, 但是保留SHAREDLOCK
3. 寫數(shù)據(jù)庫文件步驟
(1) 獲得共享鎖
(2) 獲得RESERVEDLOCK, 如果失敗, 返回SQLITE_BUSY, 否則繼續(xù)執(zhí)行
(3) 生成回滾日志文件, 寫入磁盤, 等待寫完成繼續(xù)執(zhí)行
如果是單個(gè)數(shù)據(jù)庫文件
(4) 請求獲得PENDINGLOCK
(5) 請求獲得EXCLUSIVELOCK
(6) flush/fsync, 將更新寫入磁盤
(7) 刪除回滾日志文件
(8) 釋放EXCLUSIVELOCK, PENDING LOCK, RESERVED LOCK, 獲得SHARED LOCK
如果是多個(gè)數(shù)據(jù)庫文件事務(wù)
(4) 請求獲得PENDINGLOCK 和EXCLUSIVELOCK, 確保所有數(shù)據(jù)庫都獲得EXCLUSIVELOCK
(5) 生成masterjournal文件和每個(gè)數(shù)據(jù)庫的回滾日志文件
(6) flush/fsync, 將更新寫入磁盤
(7) 先刪除masterjournal 文件, 再刪除所有的回滾日志文件
(8) 釋放所有數(shù)據(jù)庫上的EXCLUSIVELOCK, PENDING LOCK
4. SQL事務(wù)
默認(rèn)SQLite autocommit=true
BEGIN TRANSACTION - COMMIT 命令使得SQLite不在autocommit下工作。當(dāng)SQLite執(zhí)行BEGIN命令時(shí), 不會(huì)獲得任何鎖, 直到執(zhí)行到第一個(gè)SELECT, 才獲得一個(gè)SHARED LOCK, 執(zhí)行到UPDATE/INSERT/DELETE才獲得REVERSED LOCK, 當(dāng)緩存滿或者COMMIT時(shí)才請求獲得EXCLUSIVE LOCK。
COMMIT并非真正的將更新寫到磁盤, COMMIT使得SQLITE回到autocommit=true 模式, autocommit會(huì)負(fù)責(zé)將更新寫到磁盤。
posted on 2014-01-24 16:05 順其自然EVO 閱讀(904) 評論(0) 編輯 收藏 所屬分類: 數(shù)據(jù)庫