一、快照讀與當前讀
快照讀(SnapShot Read) 是一種一致性不加鎖的讀,是 InnoDB 并發如此之高的核心原因之一,
在 READ COMMITTED 事務隔離級別下,一致性不加鎖的讀是指,總是讀取被鎖定行的最新一份快照資料,因此其它事務修改了該行資料,該事務也能讀取到,這也貼合了 RC 隔離級別下存在幻讀的問題;
在 REPEATABLE READ 事務隔離級別下,一致性不加鎖的讀是指,事務讀取到的資料,要么是事務開始前就已經存在的資料,要么是事務自身插入或者修改過的資料,(下面將以此隔離級別說明);
不加鎖的簡單的 SELECT 都屬于快照讀,例如:
SELECT * FROM t WHERE id=1;
與快照讀相對應的則是當前讀(Current Read),當前讀就是讀取最新資料,而不是歷史版本的資料,加鎖的 SELECT 就屬于當前讀,例如:
SELECT * FROM t WHERE id=1 LOCK IN SHARE MODE;
SELECT * FROM t WHERE id=1 FOR UPDATE;
SELECT...FOR UPDATE 對讀取的行記錄加一個 X 鎖,其它事務不能對已鎖定的行加上任何鎖,
SELECT...LOCK IN SHARE MODE 對讀取的行記錄加一個 S 鎖,其它事務可以向被鎖定的行加 S 鎖,但是如果加 X 鎖,則會被阻塞,
二、基于快照讀的多版本并發控制
多版本并發控制技術的英文全稱是:Multiversion Concurrency Control,簡稱 MVCC,是通過保存資料的歷史版本,通過對資料行的多個版本管理來實作資料庫的并發控制,這樣我們就可以通過比較版本號決定資料是否顯示出來,讀取資料的時候不需要加鎖也可以保證事務的隔離效果(可以理解成樂觀鎖),
多版本并發控制(MVCC)只在可重復讀(REPEATABLE READ)和提交讀(READ COMMITTED)兩個隔離級別下作業,其他兩個隔離級別都和 MVCC 不兼容,因為未提交讀(READ UNCOMMITTED),總是讀取最新的資料行,而不是符合當前事務版本的資料行;而可串行化(SERIALIZABLE) 則會對所有讀取的行都加鎖,
MySQL 的大多數事務型存盤引擎實作的都不是簡單的行級鎖,基于提升并發性能的考慮,它們一般都同時實作了多版本并發控制(MVCC),不僅是 MySQL,包括 Oracle、PostgreSQL 等其他資料庫系統也都實作了 MVCC,但各自的實作機制不盡相同,因為 MVCC 沒有一個統一的實作標準,典型的有樂觀(optimistic)并發控制和悲觀(pessimistic)并發控制,
三、多版本并發控制解決了哪些問題?
1. 讀寫之間阻塞的問題
通過 MVCC 可以讓讀寫互相不阻塞,即讀不阻塞寫,寫不阻塞讀,這樣就可以提升事務并發處理能力,
提高并發的演進思路:
- 普通鎖,只能串行執行;
- 讀寫鎖,可以實作讀讀并發;
- 資料多版本并發控制,可以實作讀寫并發,
2. 降低了死鎖的概率
因為 InnoDB 的 MVCC 采用了樂觀鎖的方式,讀取資料時并不需要加鎖,對于寫操作,也只鎖定必要的行,
3. 解決一致性讀的問題
一致性讀也被稱為快照讀,當我們查詢資料庫在某個時間點的快照時,只能看到這個時間點之前事務提交更新的結果,而不能看到這個時間點之后事務提交的更新結果,
四、InnoDB 的 MVCC 是如何作業的?
1. InnoDB 是如何存盤記錄的多個版本的?
事務版本號: 每開啟一個事務,我們都會從資料庫中獲得一個事務 ID(也就是事務版本號),這個事務 ID 是自增長的,通過 ID 大小,我們就可以判斷事務的時間順序,
行記錄的隱藏列: InnoDB 的葉子段存盤了資料頁,資料頁中保存了行記錄,而在行記錄中有一些重要的隱藏欄位:
DB_ROW_ID:6-byte,隱藏的行 ID,用來生成默認聚簇索引,如果我們創建資料表的時候沒有指定聚簇索引,這時 InnoDB 就會用這個隱藏 ID 來創建聚集索引,采用聚簇索引的方式可以提升資料的查找效率,DB_TRX_ID:6-byte,操作這個資料的事務 ID,也就是最后一個對該資料進行插入或更新的事務 ID,(InnoDB 的插入、更新、洗掉都會更新該事務 ID,同時洗掉會將一個特殊位標記為已洗掉)DB_ROLL_PTR:7-byte,回滾指標,也就是指向這個記錄的 Undo Log 資訊,

Undo Log: InnoDB 將行記錄快照保存在了 Undo Log 里,我們可以在回滾段中找到它們,如下圖所示,回滾指標將資料行的所有快照記錄都通過鏈表的結構串聯了起來,每個快照的記錄都保存了當時的 db_trx_id,也是那個時間點操作這個資料的事務 ID,這樣如果我們想要找歷史快照,就可以通過遍歷回滾指標的方式進行查找,

參考鏈接:MySQL的多版本并發控制(MVCC)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/240443.html
標籤:其他
上一篇:Mysql 資料庫操作查詢記錄
下一篇:mysql的磁區跟分表
