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