【技術(shù)補給站】第11期:左手自研,右手開源,技術(shù)揭秘華為云如何領(lǐng)跑容器市場
1428
2022-05-28
我在想,這節(jié)的標(biāo)題叫“通過什么機制可以保證事務(wù)持久化的可靠性?”是否更合適。但是鑒于大家聽到WAL日志這個概念比較多,我還是決定把標(biāo)題寫成現(xiàn)在的樣子。
什么是WAL日志
預(yù)寫式日志(Write-ahead logging,縮寫 WAL)是關(guān)系數(shù)據(jù)庫系統(tǒng)中用于提供原子性和持久性(ACID屬性中的兩個)的一系列技術(shù)。
為什么要使用WAL日志的生動說明
https://blog.csdn.net/WinWill2012/article/details/71719106
預(yù)寫日志(WAL,Write Ahead Log)是關(guān)系數(shù)據(jù)庫系統(tǒng)中用于提供事務(wù)原子性和持久性(ACID屬性中的兩個)的一系列技術(shù)。簡單來說就是,做一個操作之前先將這件事情記錄下來。
舉個例子:很多人都會有自己的備忘錄,記錄自己干了哪些事,這里的WAL日志就好比備忘錄,記錄了你做了哪些操作。
為什么要使用WAL呢?比如你的備忘錄里面有如下記錄:
2015.12.25 理發(fā)
2015.12.28 整容
2015.12.31 修指甲
如果某一天你忘記了自己是如何變成現(xiàn)在這個樣子的,那你可以去翻看你的備忘錄,然后按照備忘錄的記錄依次執(zhí)行,你就能找到答案。
為什么要使用WAL呢?上面的解釋比較秀逗,本節(jié)說一下真正的原因:真正的執(zhí)行操作可能數(shù)據(jù)量會比較大,操作比較繁瑣,并且寫數(shù)據(jù)不一定是順序?qū)懀匀绻恳淮尾僮鞫家却Y(jié)果flush到可靠存儲(比如磁盤)中才執(zhí)行下一步操作的話,效率就太低了。換一種思路,如果我們在做真正的操作之前,先將這件事記錄下來,持久化到可靠存儲中(因為日志一般很小,并且是順序?qū)懀屎芨撸缓笤偃?zhí)行真正的操作。這樣執(zhí)行真正操作的時候也就不需要等待執(zhí)行結(jié)果flush到磁盤再執(zhí)行下一步,因為無論在哪一步出錯,我們都能夠根據(jù)備忘錄重做一遍,得到正確的結(jié)果。
為什么需要WAL日志的技術(shù)解釋
PostgresSQL“可靠性和預(yù)寫式日志”一節(jié)對WAL日志存在的理由給出了很好的說明。摘抄和整理如下,更詳細(xì)地可以訪問鏈接進行了解。
一句話總結(jié)就是,計算機主存和磁盤盤片間存在多層高速緩存,不僅寫的慢,而且加大了將數(shù)據(jù)直接寫到盤片(實現(xiàn)永久存儲)這一過程中因失去電力、操作系統(tǒng)失敗以及硬件失敗等帶來的數(shù)據(jù)丟失風(fēng)險。
http://www.postgres.cn/docs/10/wal.html
可靠性是任何嚴(yán)肅的數(shù)據(jù)庫管理系統(tǒng)的重要屬性。可靠性的一個重要方面就是:一個已提交事務(wù)記錄的所有數(shù)據(jù)應(yīng)該被存儲在一個非易失的區(qū)域, 這樣就不會因為失去電力、操作系統(tǒng)失敗以及硬件失敗(當(dāng)然,除了非易失區(qū)域自身失效之外)等原因?qū)е碌臄?shù)據(jù)丟失。 向計算機的永久存儲(磁盤驅(qū)動器或者等效的設(shè)備)成功寫入數(shù)據(jù)通常可以滿足這個要求。 實際上,即使計算機受到致命損壞,只要磁盤驅(qū)動器幸存下來,那么它們就可以被移動到另外一臺具有類似硬件的計算機上, 而所有已經(jīng)提交的事務(wù)將保持原狀。
周期地強制數(shù)據(jù)進入磁盤盤片看上去像一件簡單的操作,但實際上并非如此。 因為磁盤驅(qū)動器比內(nèi)存和CPU要慢很多,在計算機的主存和磁盤盤片之間存在多層的高速緩存。
首先存在的就是操作系統(tǒng)的高速緩存,該緩存經(jīng)常緩沖常用的磁盤塊且經(jīng)常合并對磁盤的寫入。 幸運的是,所有操作系統(tǒng)都給予應(yīng)用一種強制從高速緩存寫入磁盤的方法,PostgreSQL則使用了那個特性(參閱wal_sync_method參數(shù)調(diào)節(jié)如何完成之)。
然后就是磁盤驅(qū)動器的控制器上可能還有一個高速緩存;這在RAID控制卡上是特別常見的。有些高速緩存是直寫式的,即寫入動作在到達的時候就立刻寫入到磁盤上。其它是回寫式的, 即發(fā)送給驅(qū)動器的數(shù)據(jù)在稍后的某個時間寫入驅(qū)動器。這樣的高速緩存可能會稱為可靠性災(zāi)難,因為磁盤控制器高速緩存的內(nèi)存是易失性的,在發(fā)生電力失敗的情況下會丟失其內(nèi)容。 好一些的控制器卡有后備電池單元(BBU), 即這種卡上面有電池可以在系統(tǒng)電力失敗的情況下提供電力。 在電力恢復(fù)之后,這些數(shù)據(jù)將會被寫入磁盤驅(qū)動器。
最后,大多數(shù)磁盤驅(qū)動器都有高速緩存。有些是直寫的,有些是回寫的, 和磁盤控制器一樣,回寫的磁盤高速緩存也存在數(shù)據(jù)丟失的問題。 消費級別的IDE和SATA驅(qū)動器尤其可能包含回寫式高速緩存,在掉電的情況下很容易丟失數(shù)據(jù)。很多固態(tài)驅(qū)動器(SSD)也具有易失性回寫式高速緩存。
這些高速緩存通常可以被禁用,但是不同的操作系統(tǒng)和驅(qū)動器類型有不同的做法:
l?? 在Linux上,可以使用hdparm -I查詢IDE和SATA驅(qū)動器,如果在Write cache之后有一個*則表示寫高速緩存被啟用。可以用hdparm -W 0來關(guān)閉寫高速緩存。可以使用sdparm查詢SCSI驅(qū)動器。使用sdparm --get=WCE來檢查寫高速緩存是否被啟用,而sdparm --clear=WCE可以用來禁用它。
l?? 在FreeBSD上,IDE驅(qū)動器可以使用atacontrol查詢,而寫高速緩存可以用/boot/loader.conf中的hw.ata.wc=0關(guān)閉。SCSI驅(qū)動器可以使用camcontrol identify查詢,而寫高速緩存的查詢和更改都可以使用sdparm。
l?? 在Solaris上,磁盤的寫高速緩存被format -e控制(Solaris的ZFS文件系統(tǒng)對于開啟的磁盤寫高速緩存是安全的,因為它會發(fā)出它自己的磁盤高速緩存刷寫命令)。
l?? 在Windows上,如果wal_sync_method是open_datasync(默認(rèn)值),寫高速緩存可以通過取消選中My Computer\Open\disk drive\Properties\Hardware\Properties\Policies\Enable write caching on the disk禁用。另一種方法可以通過設(shè)置wal_sync_method為fsync或fsync_writethrough來阻止寫高速緩存。
l?? 在macOS上,通過設(shè)置wal_sync_method為fsync_writethrough可以阻止寫高速緩存。
數(shù)據(jù)庫
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。