mysql隔離級別實現(xiàn)原理探究
關(guān)于這個話題,在網(wǎng)上看到了多種說法谷炸,總是擼不通思路北专,于是決定自己探究,先把結(jié)論貼出來
未提交讀寫時加排他鎖旬陡,寫完釋放拓颓;(讀時不加鎖;)
提交讀寫時加排他鎖描孟,事務(wù)結(jié)束后釋放
讀時通過mvcc驶睦,訪問的是創(chuàng)建版本最大&&刪除版本為空的記錄
重復(fù)讀寫時加排他鎖,事務(wù)結(jié)束后釋放
讀時通過mvcc画拾,訪問的是創(chuàng)建版本小于等于當(dāng)前版本&&(刪除版本大于當(dāng)前版本 ||?刪除版本為空)的記錄
結(jié)論純粹是個人推測出來的,憑個人的實驗驗證和進(jìn)一步的猜想得來菜职,但不一定就是正確的G嗯住!酬核!
簡單驗證一下提交讀情況下蜜另,寫時加排他鎖,事務(wù)結(jié)束后釋放的情況:
事務(wù)1和事務(wù)2是基于相同的背景的嫡意,關(guān)閉了自動提交举瑰,設(shè)置隔離級別為提交讀,然后開始了事務(wù)蔬螟。
接下來我們可以看到此迅,事務(wù)2對id為1的記錄做了修改,這個時候并沒有提交旧巾,此時事務(wù)1也嘗試對該記錄做修改耸序,但卻失敗了,報錯說鎖等待超時鲁猩。
之后我將事務(wù)2提交了坎怪,事務(wù)1再次執(zhí)行修改語句,成功了廓握。
從上面的實驗可以得出一個結(jié)論搅窿,隔離級別為提交讀的情況下嘁酿,對記錄的修改會加上排他鎖,且直到事務(wù)結(jié)束時才釋放男应。
其他隔離級別下的寫時加鎖情況可以依據(jù)上面的實驗去推出結(jié)論闹司,請有興趣的讀者自行驗證。
至于讀時加鎖或者借助mvcc機制的情況殉了,等我進(jìn)一步學(xué)習(xí)mvcc后再來補充开仰。
https://blog.csdn.net/aigoogle/article/details/42558075谷歌搜到這篇博文與本文的思想是一樣的。
繼續(xù)探究了mysql的mvcc實現(xiàn)后薪铜,有了一些新的理解:
在mysql內(nèi)部維護(hù)著很多的日志表众弓,其中有一個叫做undo日志表(記錄原始數(shù)據(jù),主要用于事務(wù)回滾操作隔箍,也可以用于mvcc機制)谓娃,同時還使用了一個叫做read view的表來做可見性判斷。
在mysql中蜒滩,mvcc是通過在表中插入三個隱藏字段實現(xiàn)的滨达,這三個隱藏字段如下:
6字節(jié)的事務(wù)ID? DB_TRX_ID)?
7字節(jié)的回滾指針(DB_ROLL_PTR)?
隱藏的ID
假設(shè)我們有記錄如下
現(xiàn)在我們開啟一個事務(wù)1,并對該記錄做修改
這個時候如果有另外一個事務(wù)2俯艰,并且這個事務(wù)2的版本小于事務(wù)1捡遍,現(xiàn)在,事務(wù)1要查詢這條記錄竹握。
在真實表中画株,數(shù)據(jù)已被修改,但因為事務(wù)2的版本小于事務(wù)1的版本啦辐,這條修改對事務(wù)2來說是不可見的谓传,于是就根據(jù)這條記錄的回滾id找到了undo log中原來的數(shù)據(jù)。
在真實情況中芹关,并發(fā)的事務(wù)數(shù)量大续挟,對數(shù)據(jù)的可見性需要統(tǒng)一管理,于是就有了read view侥衬。
在可重復(fù)讀級別下诗祸,開啟一個事務(wù),這個時候mysql就要將此刻所有活躍的事務(wù)拷貝到一個新的read view表中轴总, 假定其中最大最小的事務(wù)版本號分別為max_id,min_id贬媒,現(xiàn)要查詢的記錄版本號為trx_id。有以下幾種情況:
1肘习、trx_id<min_id际乘,說明在開啟事務(wù)前,記錄已存在漂佩,可見脖含。
2罪塔、trx_id>max_id,說明在開啟事務(wù)時养葵,記錄還不存在征堪,不可見。
3关拒、min_id<trx_id<max_id佃蚜,這時候我們需要遍歷read view表,看看是否有對應(yīng)的事務(wù)版本號着绊。如果有谐算,說明在開啟事務(wù)時,記錄處于活躍狀態(tài)归露,此時需要對照回滾id洲脂,找到undo表中相應(yīng)的記錄。如果沒有剧包,說明開啟事務(wù)時恐锦,修改了該條記錄的另一個事務(wù)已經(jīng)結(jié)束,記錄可見疆液。
在提交讀的級別下一铅,不同的地方在于每次執(zhí)行語句時,都會重新計算一個新的read view表堕油,這樣就可以達(dá)到讀取已提交記錄的目的潘飘。
參考文章:http://www.imooc.com/article/17290
https://liuzhengyang.github.io/2017/04/18/innodb-mvcc/