qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請?jiān)L問 http://qaseven.github.io/

          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ù)庫

          <2014年1月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 德安县| 西盟| 额尔古纳市| 洛隆县| 惠水县| 蓬安县| 灯塔市| 旬邑县| 如皋市| 内乡县| 城固县| 宜宾县| 徐水县| 博野县| 互助| 台前县| 唐河县| 兴业县| 沙洋县| 遂宁市| 泰来县| 特克斯县| 景宁| 平邑县| 乳源| 南岸区| 阿巴嘎旗| 图木舒克市| 汝城县| 平遥县| 三亚市| 大同市| 桂东县| 拉萨市| 大名县| 张家港市| 舞钢市| 旬阳县| 乃东县| 碌曲县| 佛坪县|