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

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

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

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

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

前言

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

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

為了對(duì)這三種日志有更好的體感,我們?cè)诒镜匕惭b了 MySQL,然后看下 log日志在磁盤(pán)目錄上的具體位置(此處是Mac os安裝 MySQL):

binlog

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

1.包含的信息

binlog主要包含兩種信息:

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

2.三個(gè)用途

binlog的用途有 3個(gè):

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

3.三種類(lèi)型

binlog有 3種類(lèi)型:

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

接下來(lái),我們通過(guò) MySQL的指令來(lái)查看下 binlog文件的信息格式。

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

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

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

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

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

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

undo log

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

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

可以通過(guò) 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:一個(gè) undo log文件對(duì)應(yīng)的最大值,默認(rèn) 1G;
  • innodb_undo_directory:undo log文件存放的目錄;
  • innodb_undo_log_encrypt:是否對(duì) undo log文件開(kāi)啟空間壓縮,默認(rèn)是關(guān)閉;
  • innodb_undo_log_truncate:?jiǎn)蝹€(gè)文件超過(guò)最大值時(shí),是否對(duì) undo log文件進(jìn)行切分,默認(rèn)為打開(kāi)狀態(tài);
  • innodb_undo_tablespaces:?jiǎn)蝹€(gè)文件超過(guò)最大值時(shí),undo log文件會(huì)被切分為幾份,默認(rèn)是 2;

2.事務(wù)回滾

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

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

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

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

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

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

Redo log

1.redo log

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

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

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

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

2.為什么需要 redo log?

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

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

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

整個(gè)過(guò)程如下圖:

常見(jiàn)問(wèn)題

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

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

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

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

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

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

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

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

總結(jié)

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

2023-11-23 13:17:39

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

2024-05-30 08:03:17

2020-08-20 12:10:42

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

2025-06-06 07:02:43

2025-01-15 13:19:09

MySQL日志事務(wù)

2024-06-11 00:00:02

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

2021-01-26 13:47:08

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

2024-12-16 00:00:05

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

2021-07-28 08:32:03

MySQLRedo存儲(chǔ)

2018-08-21 10:05:59

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

2024-03-14 14:18:58

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

2025-01-20 08:20:00

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

2022-10-12 08:01:08

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

2021-02-09 10:07:23

面試MySQL存儲(chǔ)

2011-08-30 10:30:50

OracleUNDO LOG日志回

2022-03-15 11:31:17

MySQL日志格式

2021-10-04 09:23:30

Redo日志內(nèi)存

2020-11-11 07:32:18

MySQL InnoDB 存儲(chǔ)

2021-05-28 11:18:50

MySQLbin logredo log

2010-01-06 09:30:51

Oracle Redo
點(diǎn)贊
收藏

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