MVCC原理(多版本並發控制)


MVCC原理(多版本並發控制)

說明

Innodb通過在讀取的時刻建立快照,來保證一個事務中的讀取一致性。

  • 在該時刻之前的數據是可以查詢到的
  • 在該時刻之后的數據是查詢不到的
  • 有一個例外需要注意,如果事務修改了該時刻后面的數據,那么當前事務在查詢時就會讀取到該條數據
演示一
事務A 事務B
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
Empty set (0.00 sec)
mysql> insert into user values(1,'fc');
Query OK, 1 row affected (0.00 sec)
mysql> select * from user;
+----+———+
| id | name |
+----+———+
| 1 | fc |
mysql> select * from user;
Empty set (0.00 sec)

結論:從第一個查詢操作開始建立快照,該快照應用於整個事務中。

演示二
事務A 事務B
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
Empty set (0.00 sec)
mysql> select * from user;
Empty set (0.00 sec)
mysql> insert into user values(2,'tt');
Query OK, 1 row affected (0.00 sec)
mysql> select * from user;
+----+———+
| id | name |
+----+———+
| 1 | fc |
+----+------+
1 row in set (0.00 sec)
mysql> select * from user;
Empty set (0.00 sec)
mysql> update user set name = 'xtt' where id = 2;
注意此時事務B的新增語句並沒有提交,這里會一直阻塞,等待事務B的提交
mysql> commit;
Query OK, 1 row affected (29.31 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from user;
+----+------+
| id | name |
+----+------+
| 2 | xtt |
+----+------+
1 row in set (0.00 sec)

總結:如果當前事務A修改其他事務B新增未提交的數據,那么會出現阻塞的情況,直到事務B提交事務。那么如果事務B又將該數據刪除了呢,或者事務B是修改了未提交呢?

演示三
事務A 事務B
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+———+
| id | name |
+----+———+
| 2 | tt |
+----+------+
1 row in set (0.00 sec)
mysql> update user set name = 'niufuren' where id =2;
Query OK, 1 row affected (0.00 sec)
mysql> update user set name = 'tt' where id = 2;
注意此時事務B的新增語句並沒有提交,這里會一直阻塞,等待事務B的提交
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 等待超時 mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+------+
| id | name |
+----+------+
| 2 | xtt |
+----+------+
1 row in set (0.00 sec) 這里一致性讀,依然讀的快照

總結:如果事務B又將該數據刪除了呢,或者事務B是修改了未提交,事務A再去刪除或者修改該數據時都會阻塞,但是事務A是可以正常讀取的,也就是可重復讀。

快照的創建

  1. RR隔離級別下:當事務中第一個需要讀取的操作時創建快照,也可以通過命令在事務開始時就創建快照

    • 通用select開啟事務

    • 通過start transaction with consistent snapshot;

  2. RC隔離界別下:事務中每一個一致性讀的操作都會建立自己的新快照

一致性讀不適用與DDL語句

  • 當事務A在事務中已經建立了user表的快照是后,其他事務是無法對user表進行DDL的,DDL是直接生效的沒有經過事務提交
  • 在RR和RC隔離界別下,一致性讀是不會對行加鎖的

參考:

https://dev.mysql.com/doc/refman/5.6/en/innodb-consistent-read.html

https://www.cnblogs.com/digdeep/p/4947694.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM