偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

為什么 MySQL 需要 binlog、undo log、redo log 三種日志?

數(shù)據(jù)庫
工作或者面試中,經(jīng)常會遇到 MySQL 數(shù)據(jù)庫 binlog、undo log、redo log 相關(guān)的知識點(diǎn),今天我們就來一起深入分析這三種 log。

工作或者面試中,經(jīng)常會遇到 MySQL 數(shù)據(jù)庫 binlog、undo log、redo log 相關(guān)的知識點(diǎn),今天我們就來一起深入分析這三種 log。

申明:本文基于 MySQL 8.0.30,默認(rèn)為 InnoDB 引擎;InnoDB 由 Innobase Oy公司所開發(fā),2006年五月時由甲骨文公司并購。

前言

在正式進(jìn)入主題之前,我們先看一張 MySQL的架構(gòu)示意圖:

上述示意圖中的紅色字體:binlog、undo log、redo log 就是我們今天的主角。binlog是 server層生成的日記,而 undo log、redo log 是Innodb 存儲引擎層生成的日志

為了對這三種日志有更好的體感,我們在本地安裝了 MySQL,然后看下 log日志在磁盤目錄上的具體位置(此處是Mac os安裝 MySQL):

binlog

binlog,是 binary log的英文縮寫,翻譯為二進(jìn)制日志或者歸檔日志(帶有業(yè)務(wù)含義),它是從 MySQL 3.23.14版本引入的。binlog是在 MySQL Server層實(shí)現(xiàn),因此所有數(shù)據(jù)庫引擎都可以使用它。

1.包含的信息

binlog主要包含兩種信息:

  • MySQL數(shù)據(jù)庫所有的表結(jié)構(gòu)變更以及表數(shù)據(jù)修改的二進(jìn)制日志(像 select,show這種查詢類的操作,不會記錄);
  • 每條語句使用更新數(shù)據(jù)多長時間的信息;

2.三個用途

binlog的用途有 3個:

  • 歸檔日志
  • 主從復(fù)制
  • 數(shù)據(jù)恢復(fù)

3.三種類型

binlog有 3種類型:

  • 語句模式(Statement-based logging): 包含產(chǎn)生數(shù)據(jù)更改(插入、更新、刪除)的 SQL語句;
  • 行模式(Row-based logging): 用于記錄單個行的更改,從 MySQL 5.1版本引入;
  • 混合模式(Mixed logging): 默認(rèn)使用語句模式,可以按需自動切換到行模式,從 MySQL 5.1版本引入;

接下來,我們通過 MySQL的指令來查看下 binlog文件的信息格式。

首先,生成 binlog,這里以創(chuàng)建一張user表,然后對 user表進(jìn)行增刪改查操作為例,具體 sql執(zhí)行如下圖:

接著,對上面生成的 binlog進(jìn)行查看,指令和結(jié)果截圖如下:

 查看 binlog是否開啟,8.0.30 默認(rèn)是開啟的
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.02 sec)

# 查看所有的binlog日志文件
mysql> show binary logs;

# 查看某個 binlog的具體信息,通過指令也可以看出binlog是以 event的方式存儲
mysql> show binlog events in 'binlog.000001'

從上面的 binlog日志我們可以看出:在 binlog文件中,并沒有把我們執(zhí)行的 SQL語句直接存儲,而是轉(zhuǎn)換成了內(nèi)部的一些邏輯指令,所以, binlog它是一種邏輯日志。

undo log

undo log, 中文翻譯為撤銷日志或回滾日志,用于事務(wù)回滾,保證了事務(wù) ACID 特性中的原子性(Atomicity),同時還可以配合 ReadView 實(shí)現(xiàn)多版本控制(MVCC)。

1.相關(guān)參數(shù)

可以通過 show variables like ‘%undo%’; 指令查看 undo log相關(guān)參數(shù):

mysql> show variables like '%undo%';
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| innodb_max_undo_log_size | 1073741824 |
| innodb_undo_directory    | ./         |
| innodb_undo_log_encrypt  | OFF        |
| innodb_undo_log_truncate | ON         |
| innodb_undo_tablespaces  | 2          |
+--------------------------+------------+
5 rows in set (0.01 sec)
  • innodb_max_undo_log_size:一個 undo log文件對應(yīng)的最大值,默認(rèn) 1G;
  • innodb_undo_directory:undo log文件存放的目錄;
  • innodb_undo_log_encrypt:是否對 undo log文件開啟空間壓縮,默認(rèn)是關(guān)閉;
  • innodb_undo_log_truncate:單個文件超過最大值時,是否對 undo log文件進(jìn)行切分,默認(rèn)為打開狀態(tài);
  • innodb_undo_tablespaces:單個文件超過最大值時,undo log文件會被切分為幾份,默認(rèn)是 2;

2.事務(wù)回滾

在事務(wù)提交之前,MySQL 會將更新前的數(shù)據(jù)記錄到 undo log 日志文件里,當(dāng)事務(wù)回滾時,可以利用 undo log 來進(jìn)行回滾。如下圖:

每當(dāng) InnoDB 引擎執(zhí)行一條更新操作(修改、刪除、新增)時,就會生成對應(yīng)的一條回滾指令記錄在 undo log 里,比如:

  • InnoDB 引擎執(zhí)行 insert 操作,則會在 undo log 日志里面保存一條相反的 delete 語句;比如:insert into t(id, name) values(1,’zhangsan’); 則 undo log 對應(yīng)的回滾日志為 delete from t where id = 1;
  • InnoDB 引擎執(zhí)行 delete 操作,則會在 undo log 日志里面保存一條相反的 insert 語句;比如:delete from t where id = 1; 則 undo log 對應(yīng)的回滾日志為 insert into t(id, name) values(1,’zhangsan’);
  • InnoDB 引擎執(zhí)行 update 操作,則會在 undo log 日志里面保存一條相反的 update 語句;比如:update t set name = ‘lisi’ where id = 1; 則 undo log 對應(yīng)的回滾日志為 update t set name = ‘zhangsan’ where id = 1;

3.undo log 和 ReadView 實(shí)現(xiàn)多版本控制(MVCC)

在 InnoDB引擎中,可以多個事務(wù)對同一條數(shù)據(jù)記錄進(jìn)行更新操作,當(dāng)出現(xiàn)異常時,能及時進(jìn)行數(shù)據(jù)回滾,那么 InnoDB是如何能精確地把數(shù)據(jù)回滾到具體的哪一個版本呢?這就是 InnoDB的多版本控制機(jī)制。

如下圖:有 3個事務(wù)分別對表中id = 1行記錄進(jìn)行更新操作,因此,在undo log文件中就會產(chǎn)生3條邏輯回滾日志 

Redo log

1.redo log

redo log,翻譯成重做日志,用于crash-safe,即當(dāng)數(shù)據(jù)庫發(fā)生異常重啟,可以保證之前提交的記錄不會丟失,它是 InnoDB引擎獨(dú)有的日志。

redo log 是物理日志,記錄了某個數(shù)據(jù)頁做了什么修改,比如對某表空間中的 某數(shù)據(jù)頁某偏移量的地方做了某更新,每當(dāng)執(zhí)行一個事務(wù)就會產(chǎn)生這樣的一條或者多條物理日志。

在事務(wù)提交時,只要先將 redo log 持久化到磁盤即可,可以不需要等到將緩存在 Buffer Pool 里的臟頁數(shù)據(jù)持久化到磁盤。

當(dāng)系統(tǒng)崩潰時,雖然臟頁數(shù)據(jù)沒有持久化,但是 redo log 已經(jīng)持久化,接著 MySQL 重啟后,可以根據(jù) redo log 的內(nèi)容,將所有數(shù)據(jù)恢復(fù)到最新的狀態(tài)。

2.為什么需要 redo log?

為了防止斷電導(dǎo)致數(shù)據(jù)丟失的問題,當(dāng)有一條記錄需要更新的時候,InnoDB 引擎就會先更新內(nèi)存(同時標(biāo)記為臟頁),然后將本次對這個頁的修改以 redo log 的形式記錄下來,這個時候更新就算完成了。

后續(xù),InnoDB 引擎會在適當(dāng)?shù)臅r候,由后臺線程將緩存在 Buffer Pool 的臟頁刷新到磁盤里,這就是 WAL (Write-Ahead Logging)技術(shù)。

WAL 技術(shù)指的是, MySQL 的寫操作并不是立刻寫到磁盤上,而是先寫日志,然后在合適的時間再寫到磁盤上。

整個過程如下圖:

常見問題

1.MySQL 如何辨別 binlog 的完整性?

  • statement 格式的 binlog,文件末尾有 COMMIT;
  • row 格式的 binlog,文件末尾有一個 XID event。

2.redo log 和 binlog 是怎么關(guān)聯(lián)起來的?

它們有一個共同的數(shù)據(jù)字段,叫 XID。崩潰恢復(fù)的時候,會按順序掃描 redo log:如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;如果碰到只有 parepare、而沒有 commit 的 redo log,就拿著 XID 去 binlog 找對應(yīng)的事務(wù)。

3.處于 prepare 階段的 redo log 加上完整 binlog,重啟就能恢復(fù),MySQL 為什么要這么設(shè)計(jì)?

其實(shí),這個問題還是跟我們在反證法中說到的數(shù)據(jù)與備份的一致性有關(guān)。在時刻 B,也就是 binlog 寫完以后 MySQL 發(fā)生崩潰,這時候 binlog 已經(jīng)寫入了,之后就會被從庫(或者用這個 binlog 恢復(fù)出來的庫)使用。所以,在主庫上也要提交這個事務(wù)。采用這個策略,主庫和備庫的數(shù)據(jù)就保證了一致性。

4.為什么需要兩階段提交呢?

兩階段提交是經(jīng)典的分布式系統(tǒng)問題,并不是 MySQL 獨(dú)有的。如果必須要舉一個場景,來說明這么做的必要性的話,那就是事務(wù)的持久性問題。對于 InnoDB 引擎來說,如果 redo log 提交完成了,事務(wù)就不能回滾(如果這還允許回滾,就可能覆蓋掉別的事務(wù)的更新)。而如果 redo log 直接提交,然后 binlog 寫入的時候失敗,InnoDB 又回滾不了,數(shù)據(jù)和 binlog 日志又不一致了。兩階段提交就是為了給所有人一個機(jī)會,當(dāng)每個人都說“我 ok”的時候,再一起提交。

總結(jié)

  • undo log(回滾日志):是 Innodb 存儲引擎層的邏輯日志,實(shí)現(xiàn)了事務(wù)中的原子性,主要用于事務(wù)回滾和 MVCC。
  • redo log(重做日志):是 Innodb 存儲引擎層的物理日志,是循環(huán)寫,實(shí)現(xiàn)了事務(wù)中的持久性,主要用于掉電等故障恢復(fù);
  • binlog (歸檔日志):是 Server 層生成的日志,所有引擎都可使用,主要用于數(shù)據(jù)備份、數(shù)據(jù)恢復(fù)和主從復(fù)制;
責(zé)任編輯:趙寧寧 來源: 猿java
相關(guān)推薦

2024-05-30 08:03:17

2023-11-23 13:17:39

MySQL?數(shù)據(jù)庫

2020-08-20 12:10:42

MySQL日志數(shù)據(jù)庫

2025-06-06 07:02:43

2025-01-15 13:19:09

MySQL日志事務(wù)

2024-06-11 00:00:02

MySQL數(shù)據(jù)庫系統(tǒng)

2021-01-26 13:47:08

MySQL存儲數(shù)據(jù)

2024-12-16 00:00:05

MySQL二進(jìn)制數(shù)據(jù)

2025-10-09 02:22:00

MySQLMVCC庫存數(shù)量

2021-07-28 08:32:03

MySQLRedo存儲

2018-08-21 10:05:59

MySQLbinlog數(shù)據(jù)庫

2024-03-14 14:18:58

MySQL業(yè)務(wù)設(shè)計(jì)事務(wù)

2025-01-20 08:20:00

redo logMySQL數(shù)據(jù)庫

2025-08-11 09:08:41

2022-10-12 08:01:08

MySQL日志數(shù)據(jù)庫

2025-08-29 07:58:42

2021-02-09 10:07:23

面試MySQL存儲

2011-08-30 10:30:50

OracleUNDO LOG日志回

2022-03-15 11:31:17

MySQL日志格式

2021-10-04 09:23:30

Redo日志內(nèi)存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號