在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

MySQL數據庫是如何應對故障恢復與數據恢復回滾的問題呢?

馬哥Linux運維 ? 來源:稀土掘金 ? 2023-11-27 10:04 ? 次閱讀

介紹

今天這篇文章,我想聊一聊MySQL數據庫是如何應對故障恢復,與數據恢復回滾的問題。一個最基本的數據庫,應當可以做到以下幾點:

數據持久化,可以將數據保存到磁盤,服務重啟數據依然存在。

可以按照某種關系存儲數據,如果你用過IO流,那么你會發現整理數據也是一件復雜的事情。我是該追加寫呢還是找到某條數據位置再進行寫呢?這是個很復雜的問題。

快速查找。你想想自己如果將數據寫入txt,那又如何高效的去找到某條數據?支持隨機查找嗎?

故障恢復與數據回滾,倘若你的服務斷電了,如何確保數據一定是寫入到文件的?若是誤刪或誤改了某條數據,你又如何進行恢復?

MySQL的架構

關于MySQL的簡單架構圖。

c6a1b964-8c57-11ee-939d-92fbcf53809c.jpg

MySQL大致可以分為服務層與存儲引擎層。在單獨抽離了存儲引擎層后,你可以選擇合適的引擎,例如InnoDb,MyIsam,Memory等等。

關于不同的存儲引擎,使用的方式可能不同。我主要想講的是InnoDb引擎,MySQL 5.5 版本后默認的存儲引擎。

MySQL的日志系統

MySQL有三大日志,分別是重做日志(redo log),二進制日志(bin log),以及回滾日志(undo log)。這三個日志非常重要,學習MySQL數據庫一定免不了要和他們打交道。

bin log

bin log是Server層的日志,無論使用的是什么引擎,都可以使用這種日志。這個日志記錄的是邏輯日志,就是SQL語句。例如insert into table set xx = xx在bin log中記錄的也是這樣的一條SQL。而且bin log 采用的是追加寫的形式,也即是說在寫完一個bin log文件之后,不會覆蓋前面的,而是新開一個文件繼續追加寫。

redo log

redo log 是存儲引擎InnoDB所提供的日志模塊。個日志記錄的是,物理日志。記錄的是當前SQL在哪一個數據頁上將什么數據修改為了什么數據。

關于redo log,我很喜歡林曉斌老師在《MySQL實戰45講》中講的例子,酒館的賬本與黑板的例子。在古時候的酒館中,老板會有一本賬本,以及身后的一塊黑板。倘若今天有人去喝酒,賒賬。在很忙的時候,老板會將這條記錄寫在黑板上,后續等到酒館打烊了,不忙的時候,才將這個記錄寫進自己的賬本中。

事實上,在MySQL也是這么做的,如果每一次的更新操作都需要寫進磁盤,然后磁盤也要找到對應的那條記錄,然后再更新,整個過程 IO 成本、查找成本都很高。

而黑板和賬本配合的整個過程,其實就是 MySQL中常說到的WAL(Write-Ahead Logging)技術,WAL 的全稱是 ,它的關鍵點就是先寫日志,再寫磁盤,也就是先寫黑板,等不忙的時候再寫賬本。

具體來說,當有一條記錄需要更新的時候,InnoDB 引擎就會先把記錄寫到 redo log(黑板)里面,并更新內存,這個時候更新就算完成了。同時,InnoDB 引擎會在適當的時候,將這個操作記錄更新到磁盤里面,而這個更新往往是在系統比較空閑的時候做,這就像酒館打烊之后老板做的事。

如果今天賒賬的不多,掌柜可以等打烊后再整理。但如果某天賒賬的特別多,黑板寫滿了,又怎么辦呢?這個時候掌柜只好放下手中的活兒,把粉板中的一部分賒賬記錄更新到賬本中,然后把這些記錄從粉板上擦掉,為記新賬騰出空間。

與此類似,InnoDB 的 redo log 是固定大小的,比如可以配置為一組 4 個文件,每個文件的大小是 1GB,那么這塊“黑板”總共就可以記錄 4GB 的操作。從頭開始寫,寫到末尾就又回到開頭循環寫,如下面這個圖所示。

c6b74a54-8c57-11ee-939d-92fbcf53809c.jpg

write pos 是當前記錄的位置,一邊寫一邊后移。checkpoint 是當前要擦除的位置,也是往后推移并且循環的,擦除記錄前要把記錄更新到數據文件。

write pos 和 checkpoint 之間的是“黑板”上還空著的部分,可以用來記錄新的操作。如果 write pos 追上 check point,表示“黑板”滿了,這時候不能再執行新的更新,得停下來先擦掉一些記錄,把 checkpoint 推進一下。

有了 redo log,InnoDB 就可以保證即使數據庫發生異常重啟,之前提交的記錄都不會丟失,這個能力稱為crash-safe。

要理解 crash-safe 這個概念,可以想想我們前面賒賬記錄的例子。只要賒賬記錄記在了粉板上或寫在了賬本上,之后即使掌柜忘記了,比如突然停業幾天,恢復生意后依然可以通過賬本和粉板上的數據明確賒賬賬目。

undo log

undo log 記錄的是與執行SQL相反的SQL。例如,在user表,id為1的用戶age為32,那么執行update table user set age = 45 where id = 1,那么undo log中則會記錄update table user set age = 32 where id = 1,如果執行的是delete語句,那么相應的,它會記錄一條insert語句。

undo log是MySQL用于事務模塊的重要日志,其中的MVCC(多版本并發控制技術)就與undo log版本鏈強相關。這篇文章重點不在此,因此不再多說。

MySQL如何做數據恢復

假如在今天的12點鐘,你誤刪了一個表。這種情況下該怎么恢復數據?首先,在使用MySQL時,通常會對其進行全量備份。一般是一天、三天或每周一次。

那么此時應當找到最近的一次全量備份放入臨時庫中。

找到從全量備份的那一刻開始,將bin log重放到誤操作今天的12點鐘。

如此你便拿到了誤操作之前的數據,此時你可以將臨時庫中的數據按需要恢復回去。

MySQL如何做到故障恢復?(Crash-Safe的能力)

在InnoDB引擎下,MySQL支持事務。因此故障恢復還需要考慮到已提交的數據與未提交的數據。單獨靠bin log 或 redo log 是無法保證crash-safe的。

兩階段提交

一條update語句的簡單執行過程

我們再來看執行器和 InnoDB 引擎在執行這個簡單的 update 語句時的內部流程。

執行器先找向存儲引擎找到 id = 1 這一行。id 作為主鍵,存儲引擎直接用B+樹搜索找到這一行。如果id=1 這行所在的數據頁已經在內存中,就直接返回給執行器;否則就先從磁盤讀入內存中,再返回。

執行器拿到存儲引擎給的行數據,把這個值加上 1,比如原來是 n,現在為 n+1,得到了一行新的數據,再調用存儲引擎的接口寫入這一行新的數據。

引擎將這行新數據更新到內存中,同時將這個更新操作記錄到 redo log 里面,此時 redo log 處于prepare狀態。

執行器生成這個操作的 binlog,并把 binlog 寫入磁盤。

執行器調用引擎的提交事務接口,引擎把剛剛寫入的 redo log 改成提交commit狀態。

c6c5ad10-8c57-11ee-939d-92fbcf53809c.jpg

最后三步看起來有點復雜,InnoDB將 redo log 的寫入分為了兩個步驟:prepare階段和commit階段,這就是兩階段提交

圖中白色框表示是在 InnoDB引擎內部執行的,綠色框表示的是在執行器中執行的。

為什么日志需要“兩階段提交”。

由于 redo log 與 bin log 是兩個層單獨的日志,如果不采用兩階段提交的方式,要么是先寫 redo log 再寫 bin log,或采用反的順序。

下面看看這兩種方式會出現什么問題。

仍然使用用前面的 update 語句來做例子。假設當前 id=1 的行,字段 a 的值是 0,再假設執行 update 語句過程中在寫完第一個日志后,第二個日志還沒有寫完期間發生了 crash,會出現什么情況呢?

先寫 redo log 后寫 binlog。假設在 redo log 寫完,binlog 還沒有寫完的時候,MySQL 進程異常重啟。由于我們前面說過的,redo log 寫完之后,系統即使崩潰,仍然能夠把數據恢復回來,所以恢復后這一行 a 的值是 1。但是由于 binlog 沒寫完就 crash 了,這時候 binlog 里面就沒有記錄這個語句。因此,之后備份日志的時候,存起來的 binlog 里面就沒有這條語句。然后你會發現,如果需要用這個 binlog 來恢復臨時庫的話,由于這個語句的 binlog 丟失,這個臨時庫就會少了這一次更新,恢復出來的這一行 a 的值就是 0,與原庫的值不同。

先寫 binlog 后寫 redo log。如果在 binlog 寫完之后 crash,由于 redo log 還沒寫,崩潰恢復以后這個事務無效,所以這一行 a 的值是 0。但是 binlog 里面已經記錄了 “把 a 從 0 改成 1” 這個日志。所以,在之后用 binlog 來恢復的時候就多了一個事務出來,恢復出來的這一行 a 的值就是 1,與原庫的值不同。

可以看到,如果不使用“兩階段提交”,那么數據庫的狀態就有可能和用它的日志恢復出來的庫的狀態不一致。

簡單說,redo log 和 binlog 都可以用于表示事務的提交狀態,而兩階段提交就是讓這兩個狀態保持邏輯上的一致。

總結

學習了挺久的MySQL,突然又對其的數據恢復和故障恢復起了興趣,往深入了解又發現了之前一些之前無法理解的問題突然迎刃而解了。

MySQL的數據恢復與故障恢復依賴著幾個日志,bin log 與 redo log。bin log 是邏輯日志,記錄的是原始SQL語句,redo log 是InnoDB引擎支持的,是物理日志,記錄了在哪個數據頁修改了哪些數據,并且redo log 是循環寫日志。

MySQL需要按照一定時間進行全量備份,這樣我們可以依靠最近一次全量備份點,以及從該點開始記錄的bin log進行數據重放恢復

MySQL在使用了InnoDB引擎后,支持了事務,因此故障恢復需要確保可以區分已提交事務與未提交事務。這個依賴于redo log 的二階段提交。

鏈接:https://juejin.cn/post/7304886129774805032







審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • SQL
    SQL
    +關注

    關注

    1

    文章

    764

    瀏覽量

    44130
  • MYSQL數據庫
    +關注

    關注

    0

    文章

    96

    瀏覽量

    9390

原文標題:探究MySQL的bin log 與 redo log 在數據故障恢復的作用

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    基于Linux EXT3的MySQL數據庫數據恢復

    本文作者是北亞數據恢復中心總工程師張宇, 主要研究服務器及非WINDOWS平臺下的數據災難恢復。 [數據
    發表于 11-03 12:38 ?0次下載

    SQL SERVER數據庫數據恢復案例

    數據庫數據恢復環境: 某品牌存儲存放大小約80TB的SQL SERVER數據庫數據庫包含兩個LDF文件,每10天生成一個500GB大小的
    的頭像 發表于 09-29 11:39 ?1258次閱讀
    SQL SERVER<b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>案例

    數據庫數據恢復-Oracle數據庫文件出現壞塊的數據恢復案例

    打開oracle數據庫報錯:“system01.dbf需要更多的恢復來保持一致性,數據庫無法打開”。 北亞企安數據恢復工程師檢測
    的頭像 發表于 07-18 15:10 ?707次閱讀
    <b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>-Oracle<b class='flag-5'>數據庫</b>文件出現壞塊的<b class='flag-5'>數據</b><b class='flag-5'>恢復</b>案例

    數據庫數據恢復-oracle數據庫常見故障數據恢復分析

    作為存儲和處理數據的系統,oracle數據庫在使用過程中不可避免會出現各種導致數據丟失和數據損壞的故障。北亞企安
    的頭像 發表于 07-27 15:01 ?659次閱讀

    數據庫數據恢復-Syabse數據庫數據恢復案例

    數據庫恢復環境: Sybase版本:SQL Anywhere 8.0。 數據庫故障數據庫所在的設備意外斷電后,
    的頭像 發表于 07-28 14:38 ?1272次閱讀
    <b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>-Syabse<b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>案例

    數據庫數據恢復-Oracle ASM故障數據恢復案例

    數據庫數據恢復環境: Oracle數據庫ASM磁盤組有4塊成員盤。 數據庫故障&分析:
    的頭像 發表于 08-11 15:27 ?1316次閱讀
    <b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>-Oracle ASM<b class='flag-5'>故障</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>案例

    數據庫數據恢復-oracle數據庫報錯無法打開的數據恢復案例

    oracle數據庫數據恢復環境: 一臺服務器,底層由12塊硬盤組成一組磁盤陣列,上層操作系統上運行oracle數據庫。 oracle數據庫
    的頭像 發表于 10-12 14:00 ?852次閱讀

    數據庫數據恢復MySQL數據庫表誤刪除記錄的數據恢復案例

    數據庫數據恢復環境: 一臺本地windows sever操作系統服務器,服務器上部署mysql數據庫單實例,引擎類型為innodb,表內
    的頭像 發表于 11-09 15:16 ?1334次閱讀
    <b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>—<b class='flag-5'>MySQL</b><b class='flag-5'>數據庫</b>表誤刪除記錄的<b class='flag-5'>數據</b><b class='flag-5'>恢復</b>案例

    數據庫數據恢復—未開啟binlog的Mysql數據庫數據恢復案例

    mysql數據庫數據恢復環境: 本地服務器,windows server操作系統 ,部署有mysql單實例,
    的頭像 發表于 12-08 14:18 ?1138次閱讀
    <b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>—未開啟binlog的<b class='flag-5'>Mysql</b><b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>案例

    數據庫數據恢復—SQL Server數據庫出現823錯誤的數據恢復案例

    SQL Server數據庫故障: SQL Server附加數據庫出現錯誤823,附加數據庫失敗。數據庫沒有備份,無法通過備份
    的頭像 發表于 09-20 11:46 ?351次閱讀
    <b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>—SQL Server<b class='flag-5'>數據庫</b>出現823錯誤的<b class='flag-5'>數據</b><b class='flag-5'>恢復</b>案例

    Oracle數據恢復—異常斷電后Oracle數據庫報錯的數據恢復案例

    Oracle數據庫故障: 機房異常斷電后,Oracle數據庫報錯:“system01.dbf需要更多的恢復來保持一致性,
    的頭像 發表于 09-30 13:31 ?305次閱讀
    Oracle<b class='flag-5'>數據</b><b class='flag-5'>恢復</b>—異常斷電后Oracle<b class='flag-5'>數據庫</b>啟<b class='flag-5'>庫</b>報錯的<b class='flag-5'>數據</b><b class='flag-5'>恢復</b>案例

    Sybase數據恢復—Sybase數據庫無法啟動怎么恢復數據

    數據庫數據恢復工程師經過檢測,發現Sybase數據庫出現故障的原因是:異常斷電造成Sybase數據庫
    的頭像 發表于 11-30 16:45 ?120次閱讀
    Sybase<b class='flag-5'>數據</b><b class='flag-5'>恢復</b>—Sybase<b class='flag-5'>數據庫</b>無法啟動怎么<b class='flag-5'>恢復數據</b>?

    數據庫數據恢復MYSQL數據庫ibdata1文件損壞的數據恢復案例

    mysql數據庫故障mysql數據庫文件ibdata1、MYI、MYD損壞。 故障表現
    的頭像 發表于 12-09 11:05 ?154次閱讀

    數據庫數據恢復Mysql數據庫表記錄丟失的數據恢復流程

    Mysql數據庫故障Mysql數據庫表記錄丟失。 Mysql
    的頭像 發表于 12-16 11:05 ?152次閱讀
    <b class='flag-5'>數據庫</b><b class='flag-5'>數據</b><b class='flag-5'>恢復</b>—<b class='flag-5'>Mysql</b><b class='flag-5'>數據庫</b>表記錄丟失的<b class='flag-5'>數據</b><b class='flag-5'>恢復</b>流程
    主站蜘蛛池模板: 很黄网站| 成人亚洲欧美综合| 亚洲色图88| 你懂的在线免费观看| 影音先锋色天使| 欧美性满足hd1819| 天堂网最新版中文| 成人欧美一区二区三区| аⅴ天堂中文在线网| 真实偷清晰对白在线视频| 久久久久88色偷偷| 久久久精品波多野结衣| 老师办公室高h文小说| 免费四影虎ww4hu10| 全免费一级午夜毛片| 黄网站色视频免费看无下截| 农村妇女高清毛片一级| 手机福利在线| 最近2018免费中文字幕视频 | 四虎影院免费视频| 综合丁香| 亚洲福利视频一区二区三区| 欧美亚洲天堂| 美人岛福利| 性在线视频| 永久免费在线观看| 啪啪福利视频| 国产一卡二卡≡卡四卡无人| а8天堂资源在线官网| 色香欲综合成人免费视频| 天天躁狠狠躁| 中文字幕11页| a欧美在线| 免费的黄视频| 国产激情在线观看| 亚洲欧美经典| 精品女视频在线观看免费| 亚洲操综合| 欧美成人高清性色生活| 国产午夜免费一区二区三区| 色妞在线|