我們知道,mysql的innodb采用的是行鎖,而且采用了多版本并發(fā)控制來提高讀操作的性能。 什么是多版本并發(fā)控制呢 ?其實(shí)就是在每一行記錄的后面增加兩個(gè)隱藏列,記錄創(chuàng)建版本號(hào)和刪除版本號(hào), 而每一個(gè)事務(wù)在啟動(dòng)的時(shí)候,都有一個(gè)唯一的遞增的版本號(hào)。 1、在插入操作時(shí) : 記錄的創(chuàng)建版本號(hào)就是事務(wù)版本號(hào)。 比如我插入一條記錄, 事務(wù)id 假設(shè)是1 ,那么記錄如下:也就是說,創(chuàng)建版本號(hào)就是事務(wù)版本號(hào)。
2、在更新操作的時(shí)候,采用的是先標(biāo)記舊的那行記錄為已刪除,并且刪除版本號(hào)是事務(wù)版本號(hào),然后插入一行新的記錄的方式。 比如,針對(duì)上面那行記錄,事務(wù)Id為2 要把name字段更新 update table set name= 'new_value' where id=1;
3、刪除操作的時(shí)候,就把事務(wù)版本號(hào)作為刪除版本號(hào)。比如 delete from table where id=1;
4、查詢操作: 從上面的描述可以看到,在查詢時(shí)要符合以下兩個(gè)條件的記錄才能被事務(wù)查詢出來: 1) 刪除版本號(hào) 大于 當(dāng)前事務(wù)版本號(hào),就是說刪除操作是在當(dāng)前事務(wù)啟動(dòng)之后做的。 2) 創(chuàng)建版本號(hào) 小于或者等于 當(dāng)前事務(wù)版本號(hào) ,就是說記錄創(chuàng)建是在事務(wù)中(等于的情況)或者事務(wù)啟動(dòng)之前。 這樣就保證了各個(gè)事務(wù)互不影響。從這里也可以體會(huì)到一種提高系統(tǒng)性能的思路,就是: 通過版本號(hào)來減少鎖的爭用。 另外,只有read-committed和 repeatable-read 兩種事務(wù)隔離級(jí)別才能使用mVcc read-uncommited由于是讀到未提交的,所以不存在版本的問題 而serializable 則會(huì)對(duì)所有讀取的行加鎖。 |
|