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

講講MySQL Innodb ACID 的實(shí)現(xiàn)原理

數(shù)據(jù)庫 MySQL
本文主要探討MySQL InnoDB 引擎下ACID的實(shí)現(xiàn)原理,ACIDMySQL 作為一個(gè)關(guān)系型數(shù)據(jù)庫,以最常見的 InnoDB 引擎來說,是如何保證 ACID 的。

[[410031]]

本文主要探討MySQL InnoDB 引擎下ACID的實(shí)現(xiàn)原理,對(duì)于諸如什么是事務(wù),隔離級(jí)別的含義等知識(shí)請(qǐng)看我前面mysql 系列的文章。

ACID

MySQL 作為一個(gè)關(guān)系型數(shù)據(jù)庫,以最常見的 InnoDB 引擎來說,是如何保證 ACID 的。

  • (Atomicity)原子性:事務(wù)是最小的執(zhí)行單位,不允許分割。原子性確保動(dòng)作要么全部完成,要么完全不起作用;
  • (Consistency)一致性:執(zhí)行事務(wù)前后,數(shù)據(jù)保持一致;
  • (Isolation)隔離性:并發(fā)訪問數(shù)據(jù)庫時(shí),一個(gè)事務(wù)不被其他事務(wù)所干擾。
  • (Durability)持久性: 一個(gè)事務(wù)被提交之后。對(duì)數(shù)據(jù)庫中數(shù)據(jù)的改變是持久的,即使數(shù)據(jù)庫發(fā)生故障。

隔離性

隔離性主要是 鎖 和 MVCC 實(shí)現(xiàn)的。這個(gè)也可以看我前面mysql 系列的文章,這里就不在贅述了。

原子性

MySQL的日志有很多種,如二進(jìn)制日志、錯(cuò)誤日志、查詢?nèi)罩?、慢查詢?nèi)罩镜?此外InnoDB存儲(chǔ)引擎還提供了兩種事務(wù)日志:

redo log(重做日志)和undo log(回滾日志)。其中redo log用于保證事務(wù)持久性;

undo log則是事務(wù)原子性和隔離性實(shí)現(xiàn)的基礎(chǔ)。

undo log ,回滾日志。我們知道隔離性的MVCC就是依靠它來實(shí)現(xiàn)的,原子性也是。實(shí)現(xiàn)原子性的關(guān)鍵,是當(dāng)事務(wù)回滾時(shí)能夠撤銷所有已經(jīng)成功執(zhí)行的sql語句。

當(dāng)事務(wù)對(duì)數(shù)據(jù)庫進(jìn)行修改時(shí),InnoDB會(huì)生成對(duì)應(yīng)的 undo log;如果事務(wù)執(zhí)行失敗或調(diào)用了 rollback,導(dǎo)致事物需要回滾,便可以利用 undo log 中的信息將數(shù)據(jù)回滾到修改之前的樣子。undo log 屬于邏輯日志,它記錄的是sql執(zhí)行相關(guān)的信息。當(dāng)發(fā)生回滾時(shí),InnoDB 會(huì)根據(jù) undo log 的內(nèi)容做與之前相反的工作:

  • 對(duì)于每個(gè) insert,回滾時(shí)會(huì)執(zhí)行 delete;
  • 對(duì)于每個(gè) delete,回滾時(shí)會(huì)執(zhí)行insert;
  • 對(duì)于每個(gè) update,回滾時(shí)會(huì)執(zhí)行一個(gè)相反的 update,把數(shù)據(jù)改回去。

以u(píng)pdate操作為例:當(dāng)事務(wù)執(zhí)行update時(shí),其生成的undo log中會(huì)包含被修改行的主鍵(以便知道修改了哪些行)、修改了哪些列、這些列在修改前后的值等信息,回滾時(shí)便可以使用這些信息將數(shù)據(jù)還原到update之前的狀態(tài)。

持久性

上面講到Innnodb有很多 log,持久性靠的是 redo log。

讀數(shù)據(jù):會(huì)首先從緩沖池中讀取,如果緩沖池中沒有,則從磁盤讀取在放入緩沖池;

寫數(shù)據(jù):會(huì)首先寫入緩沖池,緩沖池中的數(shù)據(jù)會(huì)定期同步到磁盤中(會(huì)產(chǎn)生臟讀);

于是 redo log就派上用場(chǎng)了。

既然redo log也需要存儲(chǔ),也涉及磁盤IO為啥還用它?

1、redo log 的存儲(chǔ)是順序存儲(chǔ),而緩存同步是隨機(jī)操作。

2、緩存同步是以數(shù)據(jù)頁為單位的,每次傳輸?shù)臄?shù)據(jù)大小大于redo log。

redo log采用的是WAL(Write-ahead logging,預(yù)寫式日志),所有修改先寫入日志,再更新到Buffer Pool,保證了數(shù)據(jù)不會(huì)因MySQL宕機(jī)而丟失,從而滿足了持久性要求。

既然redo log也需要在事務(wù)提交時(shí)將日志寫入磁盤,為什么它比直接將Buffer Pool中修改的數(shù)據(jù)寫入磁盤(即刷臟)要快呢?主要有以下兩方面的原因:

1、刷臟是隨機(jī)IO,因?yàn)槊看涡薷牡臄?shù)據(jù)位置隨機(jī),但寫redo log是追加操作,屬于順序IO。

2、刷臟是以數(shù)據(jù)頁(Page)為單位的,MySQL默認(rèn)頁大小是16KB,一個(gè)Page上一個(gè)小修改都要整頁寫入;而redo log中只包含真正需要寫入的部分,無效IO大大減少。

redo log 與binlog的區(qū)別:

1、作用不同:redo log是用于crash recovery的,保證MySQL宕機(jī)也不會(huì)影響持久性;binlog是用于point-in-time recovery的,保證服務(wù)器可以基于時(shí)間點(diǎn)恢復(fù)數(shù)據(jù),此外binlog還用于主從復(fù)制。

2、層次不同:redo log是InnoDB存儲(chǔ)引擎實(shí)現(xiàn)的,而binlog是MySQL的服務(wù)器層(可以參考文章前面對(duì)MySQL邏輯架構(gòu)的介紹)實(shí)現(xiàn)的,同時(shí)支持InnoDB和其他存儲(chǔ)引擎。

3、內(nèi)容不同:redo log是物理日志,內(nèi)容基于磁盤的Page;binlog的內(nèi)容是二進(jìn)制的,根據(jù)binlog_format參數(shù)的不同,可能基于sql語句、基于數(shù)據(jù)本身或者二者的混合。

4、寫入時(shí)機(jī)不同:binlog在事務(wù)提交時(shí)寫入;redo log的寫入時(shí)機(jī)相對(duì)多元:

默認(rèn)刷盤策略:當(dāng)事務(wù)提交時(shí)會(huì)調(diào)用fsync對(duì)redo log進(jìn)行刷盤;修改innodb_flush_log_at_trx_commit參數(shù)可以改變?cè)摬呗?,但事?wù)的持久性將無法保證。

其他刷盤時(shí)機(jī):如master thread每秒刷盤一次redo log等,這樣的好處是不一定要等到commit時(shí)刷盤,commit速度大大加快。

我們看看一條SQL更新語句怎么運(yùn)行的:

比如:

update t set age=20 where id=1;

持久性肯定和寫有關(guān),MySQL 用到了 WAL 技術(shù),WAL 的全稱是 Write-Ahead Logging,它的關(guān)鍵點(diǎn)就是先寫日志,再寫磁盤。

[redo log]

redo log 就是這個(gè)日志,當(dāng)有一條記錄要更新時(shí),InnoDB 引擎就會(huì)先把記錄寫到 redo log(并更新內(nèi)存),這個(gè)時(shí)候更新就算完成了。在適當(dāng)?shù)臅r(shí)候(上文提到的刷盤時(shí)機(jī)),將這個(gè)操作記錄更新到磁盤里面,redo log 有兩個(gè)特點(diǎn):

大小固定,循環(huán)寫

  • crash-safe(只要刷入磁盤的數(shù)據(jù),都會(huì)從 redo log 中抹掉,數(shù)據(jù)庫重啟后,直接把 redo log 中的數(shù)據(jù)都恢復(fù)至內(nèi)存就可以了。這就是為什么 redo log 具有 crash-safe 的能力)

對(duì)于redo log 是有兩階段的:commit 和 prepare 如果不使用“兩階段提交”,數(shù)據(jù)庫的狀態(tài)就有可能和用它的日志恢復(fù)出來的庫的狀態(tài)不一致.

[Buffer Pool]

Buffer Pool 中包含了磁盤中部分?jǐn)?shù)據(jù)頁的映射,作為訪問數(shù)據(jù)庫的緩沖:

  • 當(dāng)讀取數(shù)據(jù)時(shí),會(huì)先從Buffer Pool中讀取,如果Buffer Pool中沒有,則從磁盤讀取后放入Buffer Pool;
  • 當(dāng)向數(shù)據(jù)庫寫入數(shù)據(jù)時(shí),會(huì)首先寫入Buffer Pool,Buffer Pool中修改的數(shù)據(jù)會(huì)定期刷新到磁盤中。

Buffer Pool 的使用大大提高了讀寫數(shù)據(jù)的效率,但是也帶了新的問題:如果MySQL宕機(jī),而此時(shí) Buffer Pool 中修改的數(shù)據(jù)還沒有刷新到磁盤,就會(huì)導(dǎo)致數(shù)據(jù)的丟失,事務(wù)的持久性無法保證。

所以加入了 redo log。 當(dāng)數(shù)據(jù)修改時(shí),除了修改Buffer Pool中的數(shù)據(jù),還會(huì)在redo log記錄這次操作;

當(dāng)事務(wù)提交時(shí),會(huì)調(diào)用fsync接口對(duì)redo log進(jìn)行刷盤。

如果MySQL宕機(jī),重啟時(shí)可以讀取redo log中的數(shù)據(jù),對(duì)數(shù)據(jù)庫進(jìn)行恢復(fù)。

一致性

一致性是事務(wù)追求的最終目標(biāo),實(shí)現(xiàn)一致性的措施包括:

  • 保證原子性、持久性和隔離性,如果這些特性無法保證,事務(wù)的一致性也無法保證.
  • 數(shù)據(jù)庫本身提供保障,例如不允許向整形列插入字符串值、字符串長度不能超過列的限制等
  • 應(yīng)用層面進(jìn)行保障,例如如果轉(zhuǎn)賬操作只扣除轉(zhuǎn)賬者的余額,而沒有增加接收者的余額,無論數(shù)據(jù)庫實(shí)現(xiàn)的多么完美,也無法保證狀態(tài)的一致.

CAP 和ACID中的一致性

CAP 定理中的數(shù)據(jù)一致性,其實(shí)是說分布式系統(tǒng)中的各個(gè)節(jié)點(diǎn)中對(duì)于同一數(shù)據(jù)的拷貝有著相同的值;而 ACID 中的一致性是指數(shù)據(jù)庫的規(guī)則,如果 schema 中規(guī)定了一個(gè)值必須是唯一的,那么一致的系統(tǒng)必須確保在所有的操作中,該值都是唯一的,由此來看 CAP 和 ACID 對(duì)于一致性的定義有著根本性的區(qū)別。

總結(jié)

事務(wù)的 ACID 四大基本特性是保證數(shù)據(jù)庫能夠運(yùn)行的基石,但是完全保證數(shù)據(jù)庫的 ACID,尤其是隔離性會(huì)對(duì)性能有比較大影響,在實(shí)際的使用中我們也會(huì)根據(jù)業(yè)務(wù)的需求對(duì)隔離性進(jìn)行調(diào)整,除了隔離性,數(shù)據(jù)庫的原子性和持久性相信都是比較好理解的特性,前者保證數(shù)據(jù)庫的事務(wù)要么全部執(zhí)行、要么全部不執(zhí)行,后者保證了對(duì)數(shù)據(jù)庫的寫入都是持久存儲(chǔ)的、非易失的,而一致性不僅是數(shù)據(jù)庫對(duì)本身數(shù)據(jù)的完整性的要求,同時(shí)也對(duì)開發(fā)者提出了要求 - 寫出邏輯正確并且合理的事務(wù)。

最后,也是最重要的,當(dāng)別人在講一致性的時(shí)候,一定要搞清楚他的上下文。

 

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2019-04-03 09:27:01

MySQLInnoDB務(wù)ACID

2024-12-30 13:58:14

2021-09-17 12:50:10

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

2019-01-29 09:36:10

MySQLACID特性

2024-04-08 10:11:15

MYSQL數(shù)據(jù)庫事務(wù)

2020-11-13 07:11:23

MySQL復(fù)制日志

2020-02-13 10:14:11

MySQL事務(wù)ACID

2020-12-08 06:17:11

MycatMySQL分離

2021-09-27 07:11:18

MySQLACID特性

2020-12-15 09:57:51

InnoDB架構(gòu)MySQ

2020-07-28 00:58:20

IP地址子網(wǎng)TCP

2021-07-23 13:34:50

MySQL存儲(chǔ)InnoDB

2024-10-07 10:02:28

2024-10-10 08:27:39

2021-06-30 18:16:38

MySQLWal策略

2023-01-30 18:44:45

MVCC事務(wù)

2024-12-02 08:37:04

2010-11-23 12:39:05

MySQL InnoD

2017-11-28 15:24:14

ETA配送構(gòu)造

2025-01-15 15:47:36

點(diǎn)贊
收藏

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