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

面試官:MySQL 為什么使用 MVCC?原理是什么?

數(shù)據(jù)庫 MySQL
其實在實際使用中,我們在一個事務(wù)中很少用到重復(fù)讀的情況,這種情況多數(shù)是代碼寫的有問題。所以好多公司會修改 MySQL 的默認隔離級別,改成讀已提交。

大家好,我是君哥。

MVCC 中文名稱叫多版本并發(fā)控制,是 InnoDB 引擎為了提高并發(fā)效率引入的協(xié)議。今天來聊一聊 MVCC。

1.基礎(chǔ)知識

數(shù)據(jù)庫事務(wù)并發(fā)通常會遇到三個問題:

  • 臟讀:事務(wù) A 讀取了事務(wù) B 未提交的修改數(shù)據(jù)。如果事務(wù) B 回滾,事務(wù) A 讀取的數(shù)據(jù)就是無效的臟數(shù)據(jù)。
  • 不可重復(fù)讀:同一事務(wù)內(nèi)多次讀取同一行數(shù)據(jù),這條數(shù)據(jù)因為被其他事務(wù)修改過并且已經(jīng)提交事務(wù),導(dǎo)致多次讀取到的結(jié)果不一致。
  • 幻讀:同一事務(wù)內(nèi)多次查詢同一范圍內(nèi)的數(shù)據(jù),因其他事務(wù)插入或刪除符合條件的數(shù)據(jù),導(dǎo)致事務(wù)在后面讀取到的結(jié)果集不一樣,像產(chǎn)生了幻覺。

其實出現(xiàn)幻讀也會造成不可重復(fù),所以幻讀和不可重復(fù)讀有時容易混淆。不可重復(fù)度主要針對的是老數(shù)據(jù)的修改,而幻讀針對的是數(shù)據(jù)插入或數(shù)據(jù)刪除。

針對這三個并發(fā)問題,數(shù)據(jù)庫引入了隔離級別,不同隔離級別可以解決不同的問題。下面介紹的隔離級別隔離性依次變?nèi)?,并發(fā)性能依次變強。

串行化(Serializable):事務(wù)對數(shù)據(jù)讀寫都是串行化的。 

可重復(fù)讀(Repeatable Read):事務(wù)執(zhí)行過程中,多次讀取同一行數(shù)據(jù),讀取結(jié)果一致。MySQL 默認隔離級別就是可重復(fù)讀。 

讀已提交數(shù)據(jù)(Read Committed):事務(wù)執(zhí)行過程中,如果有其他事務(wù)修改了數(shù)據(jù)并且提交事務(wù),當(dāng)前事務(wù)可以讀取到最新提交的數(shù)據(jù)。 

讀未提交數(shù)據(jù)(Read Uncommitted):事務(wù)執(zhí)行過程中,可以讀取到其他事務(wù)未提交的數(shù)據(jù)。

下表展示了這四種隔離級別對臟讀、幻讀、可重復(fù)讀的解決情況。

隔離級別/并發(fā)問題

臟讀

不可重復(fù)讀

幻讀

串行化

x

x

x

可重復(fù)度

x

x

x

讀已提交

x

?

?

讀未提交

?

?

?

可重復(fù)讀并沒有完全解決幻讀,配合 MySQL 中的 Next-Key Lock 來解決。

2.MVCC

上面講了數(shù)據(jù)庫事務(wù)并發(fā)存在的問題和 MySQL 的事務(wù)隔離級別。那什么是 MVCC 呢?

2.1 版本鏈

MVCC 是對同一行數(shù)據(jù),記錄多個事務(wù)的修改版本,這些版本串聯(lián)起來,保存在 undolog 中。

InnoDB 引擎在每行記錄中會添加了 3 個隱藏的列:

  • DB_TRX_ID:修改(插入、更新或刪除)這一條數(shù)據(jù)的事務(wù) id;
  • DB_ROLL_PTR:回滾指針,指向修改前的歷史版本,用于回滾操作;
  • DB_ROW_ID:當(dāng)表中不定義主鍵時用作主鍵來自動生成聚簇索引。

MVCC 通過上面兩個字段,把每個事務(wù)修改后的數(shù)據(jù)和修改前的歷史版本串聯(lián)起來,形成一個版本鏈。

舉一個例子,我們有一張記錄賬戶余額的表 t_account,字段包括 id、account(賬戶)、amount(金額)。初始階段,id = 10,account = 1100  的這條記錄在事務(wù) 1 提交后這個賬戶剩余金額是 100,事務(wù) 2 把剩余金額改成了 150,事務(wù) 3 把剩余金額改成了 200。

如下圖,事務(wù)回滾的時候,可以根據(jù) DB_ROLL_PTR 指向的版本,回滾到這個版本的數(shù)據(jù)。

圖片圖片

2.2 ReadView

上面講了 MVCC 中的版本鏈,那如果現(xiàn)在有一個事務(wù)要讀取 id = 10,account = 1100  的這條記錄,這時候版本鏈上面有多個版本,這個事務(wù)應(yīng)該讀取哪個版本呢?

這時我們引入一個新的概念 ReadView(讀視圖),用來控制當(dāng)前事務(wù)應(yīng)該讀取上面版本鏈中的那一個版本數(shù)據(jù),它只作用于可重復(fù)讀和讀已提交這兩個隔離級別。它主要包含 4 個屬性: 

MVCC 是指對同一行數(shù)據(jù),記錄多個事務(wù)的修改版本,這些版本串聯(lián)起來,保存在 undolog 中。

InnoDB 引擎在每行記錄中會添加了 3 個隱藏的列:

  • DB_TRX_ID:修改(插入、更新或刪除)這一條數(shù)據(jù)的事務(wù) id;
  • DB_ROLL_PTR:回滾指針,指向修改前的歷史版本,用于回滾操作;
  • DB_ROW_ID:如果表中沒有定義主鍵,這個字段用作主鍵來自動生成聚簇索引。

ReadView 對可重復(fù)讀和讀已提交這 2 個隔離級別來說,有下面的不同:

  • 已提交讀:事務(wù)中每次查詢操作,都會創(chuàng)建一個新的 ReadView。在上面的例子中,m_ids 集合是 {2,3},這時事務(wù) 4 開始,查詢 t_account 中 id = 10 的記錄,會新建一個 ReadView,查詢到 amount = 100,如果事務(wù) 4 執(zhí)行過程中,事務(wù) 2 提交,事務(wù) 4 中再次查詢查詢 t_account 中 id = 10 的記錄,會再次創(chuàng)建一個 ReadView,查到 amount = 150。如下圖:

圖片圖片

  • 可重復(fù)讀:只有事務(wù)開始的時候,創(chuàng)建一個新的 ReadView,后面的讀操作都公用這個 ReadView。在上面的例子中,m_ids 集合是 {2,3},這時事務(wù) 4 開始,查詢 t_account 中 id = 10 的記錄,會創(chuàng)建一個 ReadView,查詢到 amount = 100,如果事務(wù) 4 執(zhí)行過程中,事務(wù) 2 提交,事務(wù) 4 中再次查詢查詢 t_account 中 id = 10 的記錄,還是使用之前的 ReadView,查到 amount = 100。如下圖:

圖片圖片

2.3 修改隔離級別

其實在實際使用中,我們在一個事務(wù)中很少用到重復(fù)讀的情況,這種情況多數(shù)是代碼寫的有問題。所以好多公司會修改 MySQL 的默認隔離級別,改成讀已提交。

改成讀已提交還有一個好處就是可以減少死鎖發(fā)生。

當(dāng)然,讀已提交不能解決幻讀問題。比如在一個事務(wù)中,查詢了兩次訂單量,兩次查詢中間又有新訂單生成,訂單數(shù)量會發(fā)現(xiàn)不一樣。這類情況就要看業(yè)務(wù)上能不能接受了。

總結(jié)

MVCC 是 MySQL 中非常重要的一個并發(fā)優(yōu)化,從事務(wù)隔離級別、版本鏈、ReadView 這幾個方面著手,很容易理解 MVCC 的原理。

責(zé)任編輯:武曉燕 來源: 君哥聊技術(shù)
相關(guān)推薦

2024-12-23 13:00:00

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

2025-07-18 07:19:00

2024-11-19 15:13:02

2023-12-27 18:16:39

MVCC隔離級別幻讀

2024-04-19 08:23:06

2022-07-06 13:48:24

RedisSentinel機制

2023-12-06 09:10:28

JWT微服務(wù)

2025-03-05 00:01:00

ReduxReact

2022-12-27 08:39:54

MySQL主鍵索引

2020-10-24 15:50:54

Java值傳遞代碼

2021-02-19 10:02:57

HTTPSJava安全

2025-09-24 17:05:02

2021-01-21 07:53:29

面試官Promis打印e

2021-12-02 08:19:06

MVCC面試數(shù)據(jù)庫

2025-03-07 00:36:01

VuePiniaVuex

2025-10-09 01:11:00

2023-12-20 14:35:37

Java虛擬線程

2025-09-23 07:56:31

2021-12-20 10:30:33

forforEach前端

2021-06-03 08:55:54

分布式事務(wù)ACID
點贊
收藏

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