突然停電了,我的數據還沒保存到數據庫……
瀏覽量: 次 發布日期:2023-09-11 09:47:38
突然停電了,我的數據還沒保存到數據庫……
作者 l 陳亮
來源 l 作者授權IT服務圈兒原創發布,如需轉載請聯系圈兒微信號
最近看到全國各地都在“拉閘限電”,嚇的我趕緊登上后臺服務器,看了看MySQL數據庫是否有問題,還好一切如常,也沒聽說北京有停電通知,好歹松了一口氣。
忽然想到一個問題,萬一數據庫正在執行寫入操作,突然斷電了,會是怎么樣的呢?
從MySQL V5.5開始,InnoDB成為了默認的存儲引擎。InnoDB中將頁作為磁盤管理的最小單位,數據校驗和數據寫入到磁盤都是以頁為單位操作的,通常情況下默認每個頁的大小為16KB。但由于文件系統對數據頁(16KB)的寫入多數情況下都不是原子操作,意味著當服務器斷電時可能只寫了部分數據。
一個數據頁的大小是16K,假設在把內存中的臟頁(頁中有記錄被更新過)寫到磁盤時,寫了2K突然掉電,則前2K數據是新的,后14K是舊的,那么磁盤中的這個數據頁就是不完整的,是一個壞掉的數據頁。
可能有經驗的DBA會想到,如果發生寫失效,可以利用redo log進行恢復。
這也許能夠解決部分問題,但redo log中記錄的是對頁的物理操作,redo log只能加上舊的、校檢完整的數據頁恢復一個臟塊,不能修復壞掉的數據頁。如果數據頁本身已經發生了損壞,再對其進行重做是沒有意義的。
那么就沒有其它辦法了嗎?當然不是!這個時候double write就閃亮登場了。
開啟了Double write(兩次寫/雙寫)后,在將內存中的臟頁寫入到磁盤之前,會先保存該頁的副本,當磁盤中的數據頁壞掉時,可以利用副本來還原該頁,再執行重做,這就完美的解決了redo log無法修復壞頁的問題啦。
Double write由兩部分組成,一部分是內存中的double write緩存,共有128個頁(2MB);另一部分是磁盤上共享表空間中連續的128個頁(2MB)。
下面我們來看一下將數據頁寫入磁盤的過程:
1 拷貝:當一系列機制觸發數據頁緩沖池中的臟頁(圖中黃色塊)刷新時,并不直接寫入磁盤數據文件中,而是先拷貝到內存中的double write緩存中;
2 順序寫:接著將double write緩存區中的數據分兩次順序寫入到磁盤的共享表空間中,每次寫入1MB。共享表空間中的double write頁是連續存儲的,采用順序寫的方式能夠很迅速的完成寫回操作,開銷較小。
3 離散寫:將double write緩存區中的臟頁數據寫入到實際的各個表空間文件。當臟頁里的數據完全寫回磁盤后,即可將double write中的頁標記為可覆蓋。
如果在將臟頁刷新回磁盤的過程中發生崩潰,在恢復時,InnoDB存儲引擎可以從共享表空間中的double write中找到該頁的最近的一個副本,將其復制到表空間文件,再利用redo log進行重做,就完成了恢復過程。
因存在副本,媽媽再也不用擔心我的電腦突然斷電了!
有人可能會問,在寫redo log的時候是否需要double write支持呢?
答案是不需要的,因為redo log在往磁盤中記錄信息的時候是以512字節為單位進行寫入的,而磁盤IO的最小單位恰巧也是512字節,那么就無所謂數據損壞啦。
有人可能會覺得開啟double write會帶來性能的損耗,其實呢,內存中的double write緩存對應的磁盤共享表空間的文件是連續存儲的,寫入時是順序寫。順序寫的性能非常高,稍微犧牲一點性能來保證數據頁的完整是非常有必要的!
有償征稿IT服務圈兒正式開啟投稿通道,稿費:60~5000元不等,長期有效!!!
點此查看詳情
1、微信QQ等主流應用上線國產系統UOS:界面曝光
2、阿里徹底拆中臺了!
3、誰家的JDK,會嚇尿Oracle?華為,阿里,還是騰訊?
4、再見,殺毒軟件之父,王江民!
識別關注我們
了解更多精彩內容
點分享
宿遷數據恢復
點點贊