成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

糟了,數據庫崩了,又好像沒崩

數據庫 其他數據庫
先說結論,不會丟。因為 Redo log buffer 中的數據已經被寫入到 Redo log 了,就算數據庫宕機了,在下次重啟的時候 MySQL 也會將 Redo log 文件內容恢復到 Buffer Pool 中進行重放。

前言

2023 年某一天周末,新手程序員小明因為領導安排的一個活來到公司加班,小明三下五除二,按照領導要求寫了一個跑批的數據落庫任務在測試環境執行 ,突然間公司停電了,小明大驚,“糟了,MySQL 還在跑任務,會不會因為突然斷電,導致數據庫崩了”。

這時候,傍邊的同事云淡風清的說了一句,“沒事,小明,MySQL 有一套預寫日志機制就是應對這種情況的。你的落庫任務啟用了事務沒,啟用了的話,就等來電重新跑一下任務就行了。”

聽了同事的話,小明懸著的心放了下來。“哦哦,我啟用了事務,那我還是等周一來重新跑一遍”。

回家的公交車上,小明默默的打開百度,搜索 MySQL 預寫日志 ,寫下了這篇文章 ??。

本文思維導圖本文思維導圖

什么是預寫日志機制?

一般情況下,大部分數據庫都是將表和索引存儲在磁盤文件中。當新增數據時,數據庫系統會先寫入內存,然后將其寫入磁盤上的數據文件。

那為什么不直接寫入磁盤嘞?主要是每次新增都直接寫入磁盤性能很低,放在內存中,可以批量寫入磁盤以提升性能。

但有一個問題,如果數據在寫入磁盤文件中途斷電怎么辦?當來電恢復后,我們重啟數據庫,發現數據不一致,又該如何處理。

所以我們需要一些其他機制來避免斷電引發的數據不一致,其實 MySQL 已經考慮到了這一點,內部已經實現一套 WAL(預寫日志)機制來避免這一點。

MySQL 設計有健壯的恢復機制,特別是使用 InnoDB 存儲引擎的情況下,它能夠在斷電后重啟而不會崩潰。InnoDB 存儲引擎使用預寫日志(WAL)機制來確保數據的一致性和原子性。

預寫日志機制是一種數據庫事務日志技術,它要求在任何數據庫修改被寫入到永久存儲(也就是磁盤)之前,先將這些修改記錄到日志中。

這樣當 MySQL 遇到意外的斷電情況時,它會在重啟后利用 Redo log 來恢復已提交但未寫入數據文件的事務繼續寫入數據文件,從而保證一致性,再利用 undo log 來撤銷未提交事務的需改,從而保證原子性。

MySQL 中的預寫日志機制

在 MySQL 中,InnoDB 存儲引擎實現了 WAL 機制。包含 Redo log buffer、Redo log、Undo Log 等,來記錄事務已提交但未寫入數據文件的數據變更以及事務回滾后的數據還原。

為了給大家講清楚 MySQL 的預寫日志機制,會涉及到 MySQL 架構中的以下內容,

Buffer Pool(緩沖池)

Buffer Pool (緩沖池)是 InnoDB 存儲引擎中非常重要的內存結構,顧名思義,緩沖池就是起到一個緩存的作用,因為我們都知道 MySQL 的數據最終是存儲在磁盤中的,如果沒有這個 Buffer Pool 那么我們每次的數據庫請求都會磁盤中查找,這樣必然會存在 IO 操作,這肯定是無法接受的。

但是有了 Buffer Pool 就是我們第一次在查詢的時候會將查詢的結果存到 Buffer Pool 中,這樣后面再有請求的時候就會先從緩沖池中去查詢,如果沒有再去磁盤中查找,然后在放到 Buffer Pool 中。

Redo log buffer(日志緩沖區)

Redo log buffer 是用作數據變更記錄寫入 Redo log 文件前的一塊內存區域。日志緩沖區大小由 innodb_log_buffer_size 變量定義,默認大小為 16MB。

日志緩沖區的內容會定期刷新到 Redo log 文件中,大型日志緩沖區允許大型事務運行,而無需在事務提交之前將 Redo log 數據寫入磁盤。因此如果事務涉及的更新、插入或刪除操作數據量較大時,可以增加日志緩沖區的大小可以節省磁盤 I/O。

MySQL 提交事務的時候,會將 Redo log buffer 中的數據寫入到 Redo log 文件中,刷磁盤可以通過 innodb_flush_log_at_trx_commit 參數來設置

  • 值為 0 表示不刷入磁盤
  • 值為 1 表示立即刷入磁盤
  • 值為 2 表示先刷到 os cache

為了提高性能,MySQL 首先將修改操作寫入到日志緩沖區,之后以 innodb_flush_log_at_trx_commit 參數設置落盤時機,將日志緩沖區刷入到磁盤的 Redo log 文件中去。

Redo Log

MySQL Redo Log 是 InnoDB 存儲引擎中的一個重要組件,它是一種磁盤基礎的數據結構,用于在崩潰重啟期間修復由已提交事務但未寫入數據文件的數據。

在正常操作中,Redo log 記錄了由 SQL 語句執行導致的表數據變更記錄。將 Redo log buffer 中的數據持久化到磁盤中,就是將 Redo log buffer 中的數據寫入到 Redo log 磁盤文件中。

數據在由 Redo log buffer 寫入 Redo log 時的觸發時機如下,

  • MySQL 正常關閉時觸發
  • 當 Redo log buffer 中記錄的寫入量大于 Redo log buffer 內存空間的一半時,會觸發落盤
  • InnoDB 的后臺線程每隔 1 秒,將 Redo log buffer 持久化到磁盤
  • 每次事務提交時都將緩存在 redo log buffer 里的 redo log 直接持久化到磁盤(這個策略就是由上文提高 innodb_flush_log_at_trx_commit 參數控制)

Redo log 是 WAL 機制的核心,它記錄了事務所做的所有修改。如果數據庫發生故障,可以使用 Redo 日志來重做事務,從而確保數據的一致性。

Undo Log

Undo Log 記錄了如何撤銷一個事務的修改。如果需要回滾事務或在執行事務時還未提交,數據庫就發生了崩潰,這時我們就需要將未提交事務前的數據回滾回去,難道這個操作有我們自己來做嗎?顯然 MySQL 也考慮到了這一點。

MySQL 會使用 Undo log 來撤銷未提交的修改。在操作數據前,MySQL 首先將數據備份到 Undo log,然后進行數據修改。

如果出現錯誤或者用戶執行了 Rollback 語句,系統可以利用 Undo log 中的備份將數據恢復到事務操作前的狀態。

通過 Undo log 撤銷修改,從而確保數據的原子性。


結合 Buffer Pool、Redo log buffer、Redo log、Undo log 后,我們在MySQL 中更新一條數據的流程如下,

圖片圖片

圖片來源https://pdai.tech/md/db/sql-mysql/sql-mysql-execute.html

  • 準備更新一條 SQL 語句
  • MySQL(innodb)會先去緩沖池(Buffer Pool)中去查找這條數據,沒找到就會去磁盤中查找,如果查找到就會將這條數據加載到緩沖池(Buffer Pool)中
  • 在加載到 Buffer Pool 的同時,會將這條數據的原始記錄保存到 undo 日志文件中
  • innodb 會在 Buffer Pool 中執行更新操作
  • 更新后的數據會記錄在 Redo log buffer 中
  • MySQL 提交事務的時候,會將 Redo log buffer 中的數據寫入到 Redo log 文件中,刷磁盤可以通過 innodb_flush_log_at_trx_commit 參數來設置
  • MySQL 重啟的時候會將 Redo log 恢復到緩沖池中

額外知識:檢查點(Checkpoint)

檢查點是什么?為什么有了 Redo log、Undo log 還要引入檢查點。

明明借助 Redo log、Undo log 我們就可以實現 MySQL 的故障恢復了。

雖然數據在寫入 Redo log 文件后,就代表數據變更已經生效了,但是還未寫入到數據文件,也就是還沒有完成事務的持久性。

那么檢查點就是幫助 MySQL 實現事務的持久性。

如果說 Redo log 可以無限地增大,能夠保存所有數據庫變更的數據,那么在發生宕機時完全可以通過 Redo log 來恢復數據庫系統的數據到宕機發生前的情況。

然而現實是我們的物理磁盤文件大小是有效的。即使達成無限了,如果數據庫運行了很久后發生宕機,那么使用 Redo log 進行恢復的時間也會非常的久。

所以在 Redo log 文件容量是有限的情況下,還需要定期將 Redo log 寫入數據文件完成數據的持久化,在這樣的情況下,就引入了 Checkpoint(檢查點)技術。

Checkpoint(檢查點)技術不僅僅是會同步 Redo log 寫入數據文件,也會同步臟頁數據寫入數據文件。

檢查點的觸發時機有兩種如下,

Sharp Checkpoint(完全檢查點)

將內存中所有臟頁全部寫到磁盤就是完全檢查點,比如數據庫實例關閉時。

Fuzzy Checkpoint(模糊檢查點)

將部分臟頁刷新到磁盤,就是模糊檢查點,一般就是臟頁達到一定數量時觸發。數據庫實例運行過程產生的檢查基本上就是這種類型的檢查點。

因此其實 Checkpoint 就是指一個觸發點(時間點),當發生 Checkpoint 時,會將臟頁寫回磁盤,以確保數據的持久性和一致性。并且 Redo log、Undo log 文件也可以重新覆寫,這樣可以保證重啟時不會因為 Redo log、Undo log 文件太大而導致重啟時間過長。

斷電故障恢復案例

OK,假如我們正在使用 MySQL 添加數據。在提交事務的過程中,突然發生了斷電,那么這個數據會丟嗎?

我們結合上文MySQL 中更新一條數據的流程,來給大家分析下具體場景,

數據在寫入 Buffer Pool、Redo log buffer 中時,發生斷電

先說結論,會丟。因為數據沒有寫入 Redo log 前,MySQL 是沒辦法保證數據一致性的。但是這沒關系的,因為 MySQL 會認為本次事務是失敗的,在重啟后可以根據 Undo log 文件將數據恢復到更新前的樣子,并不會有任何的影響。

數據在寫入 Redo log 文件后,發生斷電

先說結論,不會丟。因為 Redo log buffer 中的數據已經被寫入到 Redo log 了,就算數據庫宕機了,在下次重啟的時候 MySQL 也會將 Redo log 文件內容恢復到 Buffer Pool 中進行重放。

參考資料


責任編輯:武曉燕 來源: waynblog
相關推薦

2023-07-18 19:11:21

配置信令系統

2019-12-24 09:44:02

界面12306系統

2021-06-09 06:35:26

iOS 15 App 蘋果

2020-02-21 14:15:40

SimpleDateFJava多線程

2023-10-26 18:22:16

前端CSSFlex 布局

2023-03-29 08:36:33

國產數據庫開源

2023-09-26 22:10:34

iOS 17蘋果

2019-03-22 09:13:47

淘寶12306閑魚

2022-09-28 07:31:59

索引數據庫查詢

2016-03-21 09:05:06

2020-11-17 06:42:21

MySQL數據庫開源

2018-10-17 09:47:38

微博搜索全面技術儲備

2020-08-05 16:44:55

運維架構技術

2023-12-31 12:06:51

2021-11-19 11:50:48

MyBatisforeachJava

2020-03-10 20:06:38

釘釘微博熱搜

2019-12-27 08:35:43

GitHub代碼開發者

2022-10-10 08:05:34

線程池OOM問題

2019-07-03 09:16:30

數據庫原理二叉樹

2021-07-15 09:50:31

服務器實踐 架構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 最新国产精品 | 国产成人精品久久二区二区91 | 国产精品久久毛片av大全日韩 | 国产婷婷精品av在线 | 日批免费在线观看 | 欧洲色综合 | 蜜臀av日日欢夜夜爽一区 | 伊人久久大香线 | 国产精品免费大片 | 中文字幕加勒比 | 久久男人| 亚洲精品自拍视频 | 色综合久久久久 | 精品国产一区二区在线 | 国产激情视频在线免费观看 | 日韩一二三区视频 | 国产高清视频在线 | 最新av片| 国产精品一区在线 | 成人在线免费视频 | 亚洲精品久久久一区二区三区 | 一级片片 | 亚洲色图综合 | 午夜精品在线观看 | 亚洲一区久久 | 国产福利在线视频 | 大陆一级毛片免费视频观看 | 亚洲欧洲精品一区 | 国产亚洲网站 | 女女爱爱视频 | 国产二区三区 | 美国av片在线观看 | 婷婷开心激情综合五月天 | 中文字幕在线观看www | 一区二区三区中文字幕 | 免费在线一区二区三区 | 在线观看视频亚洲 | 亚洲欧美中文日韩在线v日本 | 欧美一级精品片在线看 | 一区二区三区精品在线视频 | 欧美性video 精品亚洲一区二区 |