SQLite 數(shù)據(jù)庫 WAL 工作模式原理簡介

閃存
  • 對象序列化系列

Android 對象序列化之你不知道的 Serializable
Android 對象序列化之 Parcelable 深入分析
Android 對象序列化之追求完美的 Serial

  • 數(shù)據(jù)序列化系列(待更)

《Android 數(shù)據(jù)序列化之 JSON》
《Android 數(shù)據(jù)序列化之 Protocol Buffer 使用》
《Android 數(shù)據(jù)序列化之 Protocol Buffer 源碼分析》

  • SQLite 存儲系列

Android 存儲選項之 SQLiteDatabase 創(chuàng)建過程源碼分析
Android 存儲選項之 SQLiteDatabase 源碼分析
數(shù)據(jù)庫連接池 SQLiteConnectionPool 源碼分析
SQLiteDatabase 啟用事務源碼分析
SQLite 數(shù)據(jù)庫 WAL 模式工作原理簡介
SQLite 數(shù)據(jù)庫鎖機制與事務簡介
SQLite 數(shù)據(jù)庫優(yōu)化那些事兒


SQLite WAL 模式工作原理分析

什么是 WAL

WAL 的全稱是 Write Ahead Logging(預寫日志)窘俺,它是很多數(shù)據(jù)庫中用于實現(xiàn)原子事務的一種機制罐盔。SQLite 在 3.7.0 版本引入該特性腻扇,在此之前 SQLite 實現(xiàn)原子提交和回滾的方法是 rollback journal(回滾日志)腺劣。

WAL 工作原理
  • Rollback Journal

SQLite 在引入 WAL 模式之前,使用的是 Rollback Journal 機制實現(xiàn)原子事務。Rollback Journal 的原理是,在修改數(shù)據(jù)庫文件中數(shù)據(jù)之前逗爹,先將修改所在分頁中的數(shù)據(jù)備份在另外一個地方,然后才將修改寫入到數(shù)據(jù)庫文件中戳表;如果事務失敗桶至,則將備份數(shù)據(jù)拷貝回來,撤銷修改匾旭;如果事務成功镣屹,則刪除備份數(shù)據(jù)提交修改。

  • WAL

WAL 的方法正好反過來了价涝,原始內(nèi)容保留在數(shù)據(jù)庫文件中女蜈,修改數(shù)據(jù)而是寫入到另外一個稱為 WAL 的文件中,如果事務失敗色瘩,WAL 中的記錄會被忽略伪窖,撤銷修改;如果事務成功居兆,它將隨后的某個時間被寫回到數(shù)據(jù)庫文件中覆山,提交修改。

同步 WAL 文件和數(shù)據(jù)庫文件的行為被稱為 CheckPoint(檢查點)泥栖。

在讀數(shù)據(jù)庫時爹凹,SQLite 將在 WAL 文件中搜索阴绢,找到最后一個寫入點狮暑,記住它庭呜,并忽略在此之后的寫入數(shù)據(jù)(這保證了讀和寫可以并發(fā)執(zhí)行);隨后它確定所要讀的數(shù)據(jù)所在頁是否在 WAL 文件中钢颂,如果在钞它,則讀 WAL 文件中的數(shù)據(jù),如果不在,則直接讀數(shù)據(jù)庫文件中的數(shù)據(jù)遭垛。

在寫入數(shù)據(jù)庫時尼桶,SQLite 將數(shù)據(jù)寫入到 WAL 文件中即可,但是必須保證獨占寫入耻卡,因此寫和寫之間不能并發(fā)執(zhí)行疯汁。WAL 在實現(xiàn)的過程中卵酪,使用了共享內(nèi)存技術谤碳,因此所有的讀寫進程必須在同一個機器上,否則無法保證數(shù)據(jù)的一致性蜒简。

檢查點

當然瘸羡,最終希望將 WAL 文件中附加的所有事務轉(zhuǎn)移回原始數(shù)據(jù)庫。將 WAL 文件事務移回數(shù)據(jù)庫稱為“檢查點”搓茬。

考慮回滾日志和預寫日志之間差異的另一種方法是,在回滾日志方法中卷仑,存在兩種原始操作,即讀取和寫入锡凝,而對于預寫日志粘昨,此時會有三種原始操作:讀取、寫入和檢查點窜锯。

默認情況下,當 WAL 文件達到 1000 頁的閾值大小時锚扎,SQLite 自動執(zhí)行一個檢查點。使用 WAL 的應用程序不需要執(zhí)行任何附加操作即可享受到 CheckPoint芍秆。但是如果需要應用程序調(diào)整自動檢查點閾值助币,可以使用 SQLITE_DEAULT_WAL_AUTOCHECKPOINT 編譯時選項指定其它默認值。

并發(fā)

在 WAL 模式數(shù)據(jù)庫上開始讀數(shù)據(jù)庫操作時眉菱,它首先會記住 WAL 中最后一個有效提交記錄的位置。將此點稱為“結(jié)束標記”俭缓。由于 WAL 可以在各種讀取器連接到數(shù)據(jù)庫的同時不斷增長并添加新的提交記錄酥郭,因此每個讀取器都可能具有自己的結(jié)束標記愿吹。但是對于任何特定的讀取,結(jié)束標記在事務期間不會改變椿息,從而確保了單個讀取事務只能看到數(shù)據(jù)庫內(nèi)容坷衍,因為它存在于單個時間點。

當讀取需要一頁內(nèi)容時乏矾,它首先檢查 WAL 以查看讀取頁面是否出現(xiàn)在該頁面中迁杨,如果是,它將拉入 WAL 中出現(xiàn)在讀者終點標記之前的頁面的最后副本铅协。如果在 WAL 中沒有頁面的副本位于讀者的結(jié)尾標記之前捷沸,則從原始數(shù)據(jù)庫文件中讀取頁面警医。讀取可以存在于單獨的進程中,因此避免強迫每個讀取掃描整個 WAL 尋找頁面(WAL 文件可以增長到數(shù)兆字節(jié)预皇,具體取決于運行檢查點的頻率),這種數(shù)據(jù)結(jié)構(gòu)成為“wal-index”保留在共享內(nèi)存中序仙,這有助于讀取以最少的 I/O 速度在 WAL 中定位頁面鲁豪。wal-index 大大提高了讀取的性能,但是共享內(nèi)存的使用意味著所有讀取者必須在同一臺計算機上治唤。

寫入者僅將新內(nèi)容附加到 WAL 文件的末尾糙申。因為寫入不做任何會干擾讀取數(shù)據(jù)行為的事情,所以寫和讀可以同時運行。但是粱锐,由于只有一個 WAL 文件扛邑,所以一次只能有一個寫入器。

檢查點操作從 WAL 文件中獲取內(nèi)容恶座,并將其回傳到原始數(shù)據(jù)文件中舱殿。檢查點可以與讀取任務同時運行,但是當檢查點到達 WAL 中的頁面沪袭,超過任何當前讀取任務的結(jié)束標記時樟氢,必須停止埠啃。檢查點必須在該點處停止,因為它可能會覆蓋讀取者正在使用的部分數(shù)據(jù)庫文件碴开。該檢查點會記住(wal-index中)到達的距離眶掌,并繼續(xù)將內(nèi)容從 WAL 傳輸?shù)较乱淮握{(diào)用中斷位置的數(shù)據(jù)庫巴碗。

因此,長時間運行的讀取事務可能會阻止檢查指針運行召噩。但是大概每個讀取事務最終都會結(jié)束逸爵,并且檢查指針將能夠繼續(xù)。

每當發(fā)生寫操作時师倔,寫入者都會檢查指針取得了多少進展,如果整個 WAL 已傳輸?shù)綌?shù)據(jù)庫并進行了同步贞绳,并且如果沒有讀取正在使用 WAL,則寫入者將 WAL 重新從 0 開始俱尼,并在 WAL 開始時進行新交易萎攒。這種機制可以防止 WAL 文件無限制地增長。

性能問題

寫事務非橙杏溃快羊精,絕大多數(shù)情況下,WAL 會提高 SQLite 的事務性能喧锦,因為它們只涉及一次寫入內(nèi)容(相對回滾日志事務而言則是兩次),而且寫入都是順序的束亏。但是在某些極端情況下阵具,卻會導致 SQLite 事務的性能下降。

但是隨著 WAL 文件大小的增加怕敬,讀取性能會下降趁舀,因為每個讀取任務都必須檢查 WAL 文件中的內(nèi)容,并且檢查 WAL 文件所需要的時間與 WAL 文件的大小成正比矮烹。wal-index 有助于更快地在 WAL 文件中查找內(nèi)容奉狈,但是性能隨著 WAL 文件大小的增加而下降。因此為了保持良好的讀取性能仁期,要通過定期運行檢查點來減小 WAL 文件的大小竭恬。

檢查點確實需要同步操作痊硕,以避免斷點或硬重啟后數(shù)據(jù)庫損壞的可能性押框。在將內(nèi)容從 WAL 移到數(shù)據(jù)庫之前,必須將 WAL 同步到持久性存儲橡伞,并且在重置 WAL 之前必須同步數(shù)據(jù)庫文件。CheckPoint 還需要更多尋求刚盈。檢查指針會盡最大努力對數(shù)據(jù)庫進行順序的頁面寫入挂脑,但是即使這樣,頁面寫入之間通常也會散布著許多查找操作谴分。這些因素共同導致檢查點比寫入事務慢镀脂。

默認策略是允許連續(xù)的寫事務增長 WAL忘伞,直到 WAL 變?yōu)榇蠹s 1000 頁,然后為每個后續(xù) COMMIT 運行檢查點操作翘魄,直到 WAL 重置為小于 1000 頁為止舀奶。默認情況下,檢查點將由執(zhí)行 COMMIT 的同一線程自動運行但荤,該線程是 WAL 超過其大小限制涧至。這會導致大多數(shù) COMMIT 操作非常快南蓬,但偶爾的 COMMIT(觸發(fā)檢查點的操作)會慢的多。如果不希望這種影響烧颖,則應用程序可以禁用自動檢查點,并在單獨的線程或單獨的進程中運行定期檢查點拆火。

WAL 的優(yōu)點與缺點

優(yōu)點:

  1. 讀操作不會阻塞寫操作鳖悠,同時寫操作也不會阻塞讀操作。這是并發(fā)管理的“黃金準則”憎账。
  2. 在大多數(shù)操作場景中卡辰,與回滾日志相比,WAL 相當快反砌。
  3. 磁盤 I/O 變得更可預見萌朱,更少的 fsync 系統(tǒng)調(diào)用,因為所有的 WAL 寫操作是線性寫入日志文件晶疼,很多 I/O 變的連續(xù)并能夠按計劃執(zhí)行翠霍。

缺點:

  1. 所有的處理被綁定到單個主機上。也就是說寒匙,不能再如 NFS 這樣的網(wǎng)絡文件系統(tǒng)上使用 WAL。
  2. 為滿足 WAL 和相關共享內(nèi)存的需要考蕾,使用 WAL 引入了里兩個額外的半持久性文件-wal 和-shm棵癣。對于那些使用SQLite 數(shù)據(jù)庫作為應用程序文件格式是不具有吸引力的。這也影響了只讀環(huán)境喜命,因為-shm文件必須是可寫的,并且/或數(shù)據(jù)庫所在目錄也必須是可寫的矛紫。
  3. 對于非常大的事務牌里,WAL 的性能將會降低。雖然 WAL 是一個高性能選項喳篇,但是非常大或運行時間非常長的事務會引入額外的開銷态辛。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市炊邦,隨后出現(xiàn)的幾起案子熟史,更是在濱河造成了極大的恐慌,老刑警劉巖碘菜,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炉媒,死亡現(xiàn)場離奇詭異昆烁,居然都是意外死亡缎岗,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門鼠渺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眷细,“玉大人,你說我怎么就攤上這事普舆。” “怎么了祖能?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵蛾洛,是天一觀的道長。 經(jīng)常有香客問我钞螟,道長谎碍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任太援,我火速辦了婚禮提岔,結(jié)果婚禮上笋敞,老公的妹妹穿的比我還像新娘。我一直安慰自己夯巷,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著后雷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪勉抓。 梳的紋絲不亂的頭發(fā)上候学,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天梳码,我揣著相機與錄音伍掀,去河邊找鬼翎承。 笑死,一個胖子當著我的面吹牛叨咖,可吹牛的內(nèi)容都是我干的甸各。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼聘惦,長吁一口氣:“原來是場噩夢啊……” “哼儒恋!你這毒婦竟也來了诫尽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤剂跟,失蹤者是張志新(化名)和其女友劉穎酣藻,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體送淆,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡坊夫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年撤卢,在試婚紗的時候發(fā)現(xiàn)自己被綠了梧兼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡到推,死狀恐怖惕澎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情唧喉,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站干跛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏哥捕。R本人自食惡果不足惜嘉熊,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸽捻。 院中可真熱鬧泽腮,春花似錦、人聲如沸厚满。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丰榴。三九已至秆撮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背戈二。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工觉吭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留仆邓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓绒北,卻偏偏與公主長得像察署,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子贴汪,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容