MySQL事務實現原理
MySQL事務隔離級別的實現原理
知識儲備
只有InnoDB支援事務,所以這裡說的事務隔離級別是指InnoDB下的事務隔離級別
-
隔離級別
讀未提交:一個事務可以讀取到另一個事務未提交的修改。這會帶來髒讀,幻讀,不可重複讀問題
讀已提交:一個事務只能讀取另一個事務已經提交的修改。其避免了髒讀,仍然存在不可以重複讀和幻讀問題
可重複讀:同一個事務中多次讀取相同的資料返回的結果是一樣的。其避免了髒讀和不可重複讀問題,但是幻讀依然存在
序列化:事務序列之行。避免了以上所有問題
以上是SQL-92標準中定義的四種隔離級別。在MySQL中,預設的隔離級別是REPEATABLE-READ(可重複讀),並且解決了幻讀問題。
不可重複讀重點在於Update和delete,而幻讀的重點在於insert
MVCC
MVCC的全稱是多版本併發控制。MVCC使得InnoDB的事務隔離級別下執行一致性讀操作有了保證。簡單說就是為了查詢一些正在被另一個事務更新的行,並且可以看到它們被更新之前的值。這是一個用來增強併發性的強大技術,可以使得查詢不用等待另一個事務釋放鎖。
MVCC會給每一行增加三個欄位。分別是DB-TRX-ID DB-ROLL-PTR,DB-ROW-ID
-
增刪查改
在InnoDB中,給每行增加兩個隱藏欄位來實現MVCC,一個用來記錄資料行的建立時間,另一個用來記錄行的過期時間,在實際操作中,儲存的並不是時間,而是事務版本號,每開啟一個新事務,事務的版本號就會遞增。所以增刪改查中對版本號的作用如下:將當前事務版本號儲存至行的刪除版本號
新插入一行,並以當前事務版本號作為新行的建立版本號,同時將原記錄行的刪除版本號設定為當前事務版本號
將當前事務的版本號儲存至行的建立版本號
讀取建立版本小於或等於當前事務版本號,並且刪除版本為空或大於當前事務版本的記錄。這樣可以保證在讀取之前記錄都是存在的
select:
insert:
update
delete
-
快照讀和當前讀
快照讀:讀取的是快照版本,也就是歷史版本
當前讀:讀取的是最新版版
普通的select就是快照讀,而update,delete,insert,select...LOCK In SHARE MODE,SELECT...for update就是當前讀
一致性非鎖定讀和鎖定讀
鎖定讀
-
在一個事務中,標準的SELECT語句是不會加鎖,但是有兩種情況例外。SELECT ... LOCK IN SHARE MODE 和 SELECT ... FOR UPDATE。
SELECT ... LOCK IN SHARE MODE:給記錄假設共享鎖,這樣其他事務職能讀不能修改,直到當前事務提交
SELECT ... FOR UPDATE:給索引記錄加鎖,這種情況跟UPDATE的加鎖情況是一樣的
一致性非鎖定讀
consistent read(一致性讀),InnoDB用多版本來提供查詢資料庫在某個時間點的快照。如果隔離級別是REPEATABLE READ,那麼在同一個事務中的所有一致性讀都讀的是事務中第一個的讀讀到的快照;如果是READ COMMITTED,那麼一個事務中的每一個一致性讀都會讀到它自己重新整理的快照版本。Consistent read(一致性讀)是READ COMMITTED和REPEATABLE READ隔離級別下普通SELECT語句預設的模式。一致性讀不會給它鎖訪問的表加任何形式的鎖,因此其他事務可以同時併發的修改它們
鎖
Record Locks(記錄鎖):在索引記錄上加鎖
Gap Locks(間隙鎖):在索引記錄之間加鎖,或者在第一個索引記錄之前加鎖,或者在最後一個索引記錄之後加鎖
Next-Key Locks:在索引記錄上加鎖,並且在索引記錄之前的間隙加鎖。相當於Record Locks與Gap Locks的一個結合
假如一個索引包含以下幾個值:10,11,13,20.那麼這個索引的next-key鎖將會覆蓋以下區間:
(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)
理論分析
-
在預設的隔離級別中,普通的SELECT用的是一致性讀不加鎖。而對於鎖定讀,UPDATE和DELETE,則需要加鎖,至於加什麼鎖是有不同情況的。如果對一個唯一索引使用了唯一的檢索條件,那麼只需要鎖定相應的索引記錄就好;如果是沒有使用唯一索引作為檢索條件,或者用到了索引範圍掃描,那麼將會使用間隙鎖或者next-key鎖來以此阻塞其他會話向這個範圍內的間隙插入資料
利用MVCC實現一致性非鎖定讀,保證在同一個事務中多次讀取相同的資料返回的結果是一樣的,解決了不可重複讀問題
利用Gap Locks和Next-key可以阻止其他事務在鎖定區間內插入資料,解決了幻讀問題
綜上所述,MySQL的預設隔離級別的實現依賴於MVCC和鎖,準確點說就是一致性讀和鎖
例項分析
客戶端A
客戶端A開始一個事務,並以主鍵唯一索引作為檢索條件進行更新
客戶端B
客戶端B開始一個事務,由於客戶端A已經開始了事務並以主鍵索引作為檢索條件,所以會造成該索引被鎖定。其他索引以及其他範圍則不會被鎖定可以正常操作
客戶端A
當客戶端A重新開始一個事務並沒有使用唯一索引作為檢索條件
客戶端B
客戶端B開始一個事務,由於客戶端A的事務操作,那麼mysql會使用next-key和間隙鎖以此阻塞其他會話對錶的操作
原文出處:https://www.cnblogs.com/develop-SZT/p/10339138.html
作者:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4686/viewspace-2820862/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 搞懂MySQL InnoDB事務ACID實現原理MySql
- MySQL 事務隔離級別實現原理MySql
- 【原創】Mysql中事務ACID實現原理MySql
- 【Mysql核心技術】聊聊事務的實現原理MySql
- Kafka事務實現原理Kafka
- 【Spring】事務實現原理Spring
- Spring事務實現原理Spring
- 深入學習MySQL事務:ACID特性的實現原理MySql
- MySQL事務(二)事務隔離的實現原理:一致性讀MySql
- MySQL資料庫分散式事務XA的實現原理分析MySql資料庫分散式
- MySQL 執行原理【事務】MySql
- 詳解MySQL事務原理MySql
- MySQL事務原理淺析MySql
- 分散式事務(3)---RocketMQ實現分散式事務原理分散式MQ
- 深入理解MySQL中事務隔離級別的實現原理MySql
- Mysql事務原理與最佳化最佳實踐MySql
- MySQL是如何實現事務的ACIDMySql
- MySQL高階12-事務原理MySql
- MySQL資料庫本地事務原理MySql資料庫
- MySQL實現事務的提交和回滾MySql
- 資料庫分散式事務的實現原理!資料庫分散式
- 分散式事務之JTA原理與實現(三)分散式
- 一文帶你看通透,MySQL事務ACID四大特性實現原理MySql
- Spring事務專題(三)事務的基本概念,Mysql事務處理原理SpringMySql
- 面試題:MySQL事務的ACID如何實現?面試題MySql
- 真實的面試翻車經歷,我以為我對Mysql(ACID原理、事務隔離級別、Mysql的鎖機制、事務底層實現原理)事務很熟,直到我遇到了阿里面試官。。。面試MySql阿里
- 實戰與原理:如何基於RocketMQ實現分散式事務?MQ分散式
- MySQL MVCC實現原理MySqlMVC
- MySQL——索引實現原理MySql索引
- MySQL中的事務原理和鎖機制MySql
- MySQL資料庫事務隔離性的實現MySql資料庫
- MySQL 中基於 XA 實現的分散式事務MySql分散式
- MySQL原理簡介—8.MySQL併發事務處理MySql
- 如何實現跨Mysql、Redis和Mongo分散式事務? - dongfuMySqlRedisGo分散式
- 分散式事務與Seate框架(3)——Seata的AT模式實現原理分散式框架模式
- MySQL 事務MySql
- mysql事務MySql
- MySQL事務(一)認識事務MySql