崩潰一致性:你的程序真的正確保存了數(shù)據(jù)嗎?

      網(wǎng)友投稿 874 2025-04-02

      我們解決什么問題?


      先設(shè)想一個(gè)場(chǎng)景:你熬夜寫完了論文,終于覺得可以喘一口氣,然后舒舒服服地按下了CTRL+S保存文件。就在這時(shí),你家的貓大爺拔掉了你的電源,你的文件還在嗎(圖片來自網(wǎng)絡(luò))?

      你肯定會(huì)想:這軟件那么多用戶,那么多專業(yè)的程序員,肯定沒事吧?最多就是我最后沒保存的幾個(gè)錯(cuò)別字沒改過來唄。

      這可不一定哦!這個(gè)問題更學(xué)術(shù)一點(diǎn)的定義叫“崩潰一致性(crash consistency)”。這個(gè)概念最早出現(xiàn)在文件系統(tǒng)的研究中——文件系統(tǒng)是一個(gè)龐大的數(shù)據(jù)結(jié)構(gòu),而一個(gè)文件操作通常需要對(duì)數(shù)據(jù)結(jié)構(gòu)的多個(gè)部分進(jìn)行修改,因此在諸如斷電、系統(tǒng)故障等情況下保持文件系統(tǒng)的一致性就成為了一個(gè)挑戰(zhàn)。崩潰一致性的基本概念在Remzi的經(jīng)典教科書“Operating Systems: Three Easy Pieces”[2]中可以找到。

      之前的研究工作表明,無論是SSD硬件[3]、數(shù)據(jù)庫(kù)系統(tǒng)[4]還是系統(tǒng)軟件[5],在現(xiàn)有的文件系統(tǒng)實(shí)現(xiàn)(ext4, btrfs, NTFS, ...)上多少都有一些崩潰一致性的問題。連那么厲害的專業(yè)程序員、久經(jīng)考驗(yàn)的開源和商業(yè)項(xiàng)目都沒搞定的事情,想必遍地的新手程序員們也會(huì)犯類似的錯(cuò)誤吧(在讀完宗師大佬們的文章以后,我的內(nèi)心就是這么想的)?你猜對(duì)了。

      事實(shí)是,你的文本編輯器真的有可能摧毀你的文件。不僅文本編輯器有這個(gè)問題,相當(dāng)多的其他類型的應(yīng)用軟件也存在這個(gè)問題。我們的論文就解決一個(gè)問題:

      讓檢測(cè)應(yīng)用程序崩潰一致性bug的過程盡量簡(jiǎn)單,簡(jiǎn)單到只要按一個(gè)鍵就可以了。

      從一個(gè)Bug例子說起

      我是一名苦逼的程序員,為了養(yǎng)家糊口在外包公司做一個(gè)文本編輯器的項(xiàng)目。今天我完成的功能是存盤,在按下存盤鍵以后,將打開的文件保存。小case,我在Stackoverflow上搜索了“Java write file”,然后搞到了如下(簡(jiǎn)化的)代碼:

      void?writeTextFile(String?path,?String?content)?{ ????PrintWriter?writer?=?new?PrintWriter(path); ????writer.write(content); ????writer.close();}

      作為一名優(yōu)秀的程序員,我想了想這樣好像不太對(duì)……萬一在write的時(shí)候出了什么狀況,用戶的文件不就丟了么?所以最好先做個(gè)備份,肯定就萬無一失了。于是我把代碼改成了下面這樣,跑完測(cè)試就愉快地回家逗貓玩了。

      void?safelyWriteTextFile(String?path,?String?content)?{ ????backupPath?=?path?+?".tmp"; ????writeTextFile(backupPath,?content); ????deleteItem(path); ????renameItem(backupPath,?path);}

      然而事情沒那么簡(jiǎn)單。POSIX說,你確實(shí)是按照open -> write -> delete -> rename的順序執(zhí)行了操作,但我才沒有規(guī)定從文件系統(tǒng)的角度看,它們是按照你執(zhí)行的順序完成的呢!什么?這意味著……

      如果系統(tǒng)偷偷調(diào)換write和delete操作的順序,并且在刪除操寫入磁盤后立即斷電,那不就等于把用戶的文件給刪掉了么?也就是說,如果貓大爺真的在保存文件的時(shí)候拔掉了電源,這文件整個(gè)就沒了啊(論文就沒有了啊喂)!更可怕的是,現(xiàn)在的文件系統(tǒng)(比如默認(rèn)設(shè)置下的ext4)因?yàn)橹槐A袅嗽獢?shù)據(jù)的日志而沒有保存數(shù)據(jù)操作的日志,這樣的“亂序”是真正能被觀察到的[5, 6]!

      這段代碼來自文本編輯器Ted,所幸的是這個(gè)bug成功地被我們的工具檢測(cè)到。

      崩潰一致性的自動(dòng)檢測(cè)

      現(xiàn)在我們有足夠的動(dòng)機(jī)去做一個(gè)工具檢測(cè)應(yīng)用程序的崩潰一致性了。對(duì)于程序猿來說,最好的工具就是拿來就能用的工具。所以我們的工具Crash Consistency Checker (C3)只需要被測(cè)程序的可執(zhí)行文件和一個(gè)測(cè)試用例,方法大致分為3步(對(duì)技術(shù)細(xì)節(jié)沒有興趣的可以直接跳過):

      運(yùn)行一遍程序,取得我們認(rèn)為對(duì)于應(yīng)用來說“正確”的文件系統(tǒng)快照。

      什么是“正確”的快照呢?我們認(rèn)為程序猿不會(huì)傻傻地把重要的用戶文件刪掉。所以,我們認(rèn)為所有元數(shù)據(jù)操作執(zhí)行完畢后,內(nèi)存中的文件系統(tǒng)快照代表了程序猿定義的“正確”狀態(tài)。實(shí)現(xiàn)上,我們用ptrace攔截程序發(fā)出的系統(tǒng)調(diào)用,并在系統(tǒng)調(diào)用結(jié)束后從內(nèi)存中抓取快照。

      回到之前保存文件的例子,“正確”的快照中至少包含一個(gè)文件的內(nèi)容。

      使用一個(gè)虛擬的磁盤捕獲所有的I/O請(qǐng)求,然后生成可能的崩潰現(xiàn)場(chǎng)。這個(gè)技術(shù)和已有的技術(shù)[4,5,6]十分類似。

      實(shí)現(xiàn)上,我們寫了一個(gè)ramdisk的驅(qū)動(dòng),它從外面看表現(xiàn)得和正常的磁盤一模一樣,但在后臺(tái)悄悄記錄了所有I/O操作的內(nèi)容。根據(jù)這些I/O操作,就可以生成在Linux設(shè)備驅(qū)動(dòng)規(guī)約允許條件下的各種崩潰現(xiàn)場(chǎng)。

      對(duì)于之前保存文件的例子,我們將會(huì)得到原文件被刪除、備份文件尚未寫入的一個(gè)文件系統(tǒng)快照。

      對(duì)每個(gè)崩潰現(xiàn)場(chǎng)計(jì)算與“正確”文件系統(tǒng)快照的編輯距離,如果距離很大,那這個(gè)崩潰現(xiàn)場(chǎng)就看起來很可疑。

      兩個(gè)文件系統(tǒng)快照的編輯距離定義為通過連續(xù)內(nèi)容的刪除/移動(dòng)/重命名操作將一個(gè)快照變?yōu)榱硪粋€(gè)的最小次數(shù)。不過直接計(jì)算這個(gè)編輯距離是NP-Complete的,我們用了一些小技巧做了一個(gè)近似,求解一個(gè)它的下界(我才不會(huì)告訴你最后就是給你兩個(gè)數(shù)組A和B,判斷能不能把A里刪掉一些元素重排以后變成B,現(xiàn)在小學(xué)生都會(huì)做這個(gè)題啦!)。

      顯然,對(duì)于一個(gè)沒有任何數(shù)據(jù)的文件系統(tǒng)快照,是無法通過編輯操作變成一個(gè)有數(shù)據(jù)的“正確”快照的,自然就被報(bào)告為可疑的bug了。

      實(shí)驗(yàn)結(jié)果

      我們從兩大類(命令行工具和生產(chǎn)力工具)挑選了總共25個(gè)應(yīng)用,并對(duì)每個(gè)應(yīng)用的一個(gè)簡(jiǎn)單測(cè)試用例進(jìn)行了測(cè)試,測(cè)試軟件在ext4默認(rèn)設(shè)置下的崩潰一致性。結(jié)果是我們找到了14個(gè)崩潰一致性bug,其中11個(gè)是開發(fā)者先前未知的bug,讓我們看一看:

      列舉一些有代表性的bug:

      對(duì)in-place的處理很容易出錯(cuò)。比如sort F -o F、用于兼容古老版本的功能就變成了有危險(xiǎn)的操作,提供原地替換的perl也有類似的問題。

      gzip和bzip2犯了和之前例子類似的錯(cuò)誤:在刪除舊文件之前沒有等待數(shù)據(jù)同步,從而導(dǎo)致了“壓縮等于刪除”的可能。各類生產(chǎn)力工具所犯的錯(cuò)誤五花八門,保存文件的方式也各不相同,但很多都導(dǎo)致了同樣的后果——數(shù)據(jù)丟失。

      最后,gmake的問題在于,在你運(yùn)行的腳本(如gcc)崩潰后,目標(biāo)文件的時(shí)間戳被更新,內(nèi)容卻損壞了,這樣如果這個(gè)文件最后被直接打包,就可能會(huì)導(dǎo)致嚴(yán)重的后果。雖然說這可以算是gcc的問題,但(1) gcc并不必須要提供崩潰一致性,而且(2) 這個(gè)問題最終影響gmake的用戶,我們覺得讓gmake的用戶知道這件事可能發(fā)生是很重要的。

      在驚訝于這么多程序都有這類bug的同時(shí),我們也對(duì)剩下通過測(cè)試的應(yīng)用提出表?yè)P(yáng),比如著名的Vim和Emacs。

      最后的提醒

      小心處理你的文件。看了這么多血淋淋的例子,我想你以后在保存數(shù)據(jù)的時(shí)候也會(huì)格外小心了吧。

      庫(kù)函數(shù)的支持非常重要。在和開源社區(qū)交互的過程中,我們很高興地看到很多庫(kù)都開始提供安全的文件操作(例如Qt中的QSaveFile和GTK中的g_file_replace)。與此同時(shí),更多的新興平臺(tái)則做得不夠好。比如Atom的開發(fā)者意識(shí)到了這類bug (而且真的有人在使用中觸發(fā)了這個(gè)bug),但Node.js的系統(tǒng)庫(kù)卻缺乏可移植的方案讓他們能更好地避免這種問題。

      留意崩潰一致性問題。gmake的例子警示我們,崩潰一致性問題不僅是那些保存數(shù)據(jù)的人需要關(guān)心的,也許哪天就悄悄地影響了你。所以如果你覺得這篇文章很有趣,請(qǐng)轉(zhuǎn)發(fā)它讓更多的人能意識(shí)到這個(gè)問題的存在。

      參考文獻(xiàn)

      [1] Y Jiang, H Chen, F Qin, C Xu, X Ma, J Lu. Crash consistency validation made easy. In?Proceedings of the Symposium on the Foundations of Software Engineering?(FSE), 133--143, 2016.

      [2] R H Arpaci-Dusseau, A C Arpaci-Dusseau.?Operating Systems: Three Easy Pieces(v0.91), Arpaci-Dusseau Books, 2015.

      [3] M Zheng, J Tucek, F Qin, M Lillibridge. Understanding the robustness of SSDS under power fault. In?Proceedings of the USENIX Conference on File and Storage Technologies?(FAST), 271--284, 2013.

      [4] M Zheng, J Tucek, D Huang, F Qin, M Lillibridge, E S Yang, B W Zhao, S Singh. Torturing databases for fun and profit. In?Proceedings of the Conference on Operating Systems Design and Implementation?(OSDI), 449--464, 2014.

      [5] T S Pillai, V Chidambaram, R Alagappan, S Al-Kiswany, A C Arpaci-Dusseau, R H Arpaci-Dusseau. All file systems are not created equal: On the complexity of crafting crash-consistent applications. In?Proceedings of the Conference on Operating Systems Design and Implementation?(OSDI), 433--448, 2014.

      [6] J Yang, C Sar, D Engler. EXPLODE: A lightweight, general system for finding serious storage system errors. In?Proceedings of the Conference on Operating Systems Design and Implementation?(OSDI), 131--146, 2006.

      原文轉(zhuǎn)載自:https://zhuanlan.zhihu.com/p/25188921

      崩潰一致性:你的程序真的正確保存了數(shù)據(jù)嗎?

      云硬盤 存儲(chǔ)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:輸入文字時(shí),文字下面帶點(diǎn),怎么去除?(打字下邊帶點(diǎn)怎樣去掉)
      下一篇:WPS表格辦公利用ISPMT函數(shù)輕松計(jì)算貸款利息
      相關(guān)文章
      亚洲国产精品免费观看 | 久久久无码精品亚洲日韩按摩| 亚洲成av人片在线观看天堂无码| 亚洲AV综合色区无码二区爱AV| 亚洲黄网站wwwwww| 亚洲图片一区二区| 337p欧洲亚洲大胆艺术| 亚洲综合男人的天堂色婷婷| 久久久无码精品亚洲日韩按摩 | 亚洲youwu永久无码精品 | 久久久久亚洲AV成人无码网站| 精品亚洲综合久久中文字幕| 国产亚洲色婷婷久久99精品| 国产av无码专区亚洲av桃花庵 | 亚洲人成图片网站| 亚洲色大18成人网站WWW在线播放| 一本色道久久综合亚洲精品蜜桃冫| 日本亚洲色大成网站www久久| 亚洲欧洲AV无码专区| 国产精品亚洲AV三区| 国产亚洲情侣久久精品| 亚洲AV无码一区二区三区鸳鸯影院 | 亚洲色婷婷综合久久| 亚洲高清国产AV拍精品青青草原| 国产成人无码综合亚洲日韩| 久久亚洲精品成人综合| 久久亚洲私人国产精品| 亚洲日本国产精华液| 国产精品亚洲精品| 亚洲AV无码片一区二区三区| 亚洲情侣偷拍精品| 亚洲AV永久无码精品水牛影视| 亚洲不卡中文字幕无码| 亚洲AV日韩AV永久无码久久| 亚洲狠狠狠一区二区三区| 2020国产精品亚洲综合网| 亚洲sm另类一区二区三区| 亚洲国产精品成人久久蜜臀| 亚洲欧洲自拍拍偷精品 美利坚| 国产亚洲精品美女久久久| 亚洲天天做日日做天天欢毛片|