單機存儲引擎到mysql的思考二

上一篇中我們主要介紹mysql存儲引擎物理結構進而引發對索引的
思考
但是併發事務和鎖機制又是怎樣的,下面我們來探索一下

標題 網址
單機存儲引擎到mysql的思考一 https://blog.csdn.net/xk4848123/article/details/105166855
單機存儲引擎到mysql的思考二 https://blog.csdn.net/xk4848123/article/details/105195921
單機存儲引擎到mysql的思考三 https://blog.csdn.net/xk4848123/article/details/105207797

一條sql語句是如何執行的

•連接器: 身份認證和權限相關(登錄 MySQL 的時候)。
•查詢緩存: 執行查詢語句的時候,會先查詢緩存。
•分析器: 沒有命中緩存的話,SQL 語句就會經過分析器,分析器說白了就是要先看你的 SQL 語句要幹嘛,再檢查你的 SQL 語句語法是否正確。
•優化器: 按照 MySQL 認爲最優的方案去執行。
•執行器: 執行語句,然後從存儲引擎返回數據。

事務併發問題?

MySQL默認開啓自動提交,每執行一條sql語句就自動提交事務。在MySQL中使用事務首先要關閉自動提交,使用手動提交的方式原子執行多個sql語句。當多個事務執行時,併發問題也就出現了。

鎖和MVCC

鎖大體分爲排他鎖和共享鎖,具體來說就是寫鎖和讀鎖(lock in share mode,共享讀鎖,不可寫)
老版本MySQL中使用的MyISAM引擎只支持表鎖,不管線程操作那一個行的數據,都給這張表加鎖,可能其他線程只是操作對該行無任何影響也不能同時進行,只能等待獲取鎖。而新版本中的InnoDB引擎減小了鎖的粒度,支持行鎖,使用哪些行的數據就給對應行上鎖,只要其他線程的操作與上鎖行無關即可同時操作,增大了併發效率。
InnoDB中有意向鎖,索引行鎖,間隙鎖

解釋
意向鎖 加鎖時先提前聲明一個意向,並獲取表級別的意向鎖,如果獲取成功,則稍後將要或正在(才被允許),對該表的某些行加鎖了。
索引行鎖 例子:執行一條SQL語句 SELECT sid FROM table_student WHERE sid = 123;如果sid存在索引(InnoDB會自動根據主鍵創建一個聚簇索引),則根據索引鎖定相應的行,防止在檢索過程中其他線程對該行進行修改。如果該字段沒有索引,則會鎖定整個表。
間隙鎖 MySQL默認情況下使用是REPETABLE READ作爲默認事物隔離級別的,該隔離級別會發生幻讀問題。因此InnoDB爲了防止幻讀問題使用了間隙鎖(Gap locks)。間隙鎖通俗來講就是查詢一個範圍內的數據時給範圍內字段的間隙加鎖,防止幻影行的插入。

next-key是間隙鎖和索引行鎖的組合,主要是爲了防止幻讀
1)、如果更新條件沒有走索引,此時會進行全表掃描,掃表的時候,要阻止其他任何的更新操作,所以上升爲表鎖。
2)、如果更新條件爲索引字段,但是並非唯一索引(包括主鍵索引),那麼此時更新會使用Next-Key Lock。使用Next-Key Lock的原因:
a)、首先要保證在符合條件的記錄上加上排他鎖,會鎖定當前非唯一索引和對應的主鍵索引的值;
b)、還要保證鎖定的區間不能插入新的數據。
3)、如果更新條件爲唯一索引,則使用Record Lock(記錄鎖)。
大家注意上面的鎖對普通的select.....是無效的,這種屬於快照讀,在後文中會講解。RR隔離級別一下select...from...lock in share mode才能加間隙避免幻讀。
幻讀表現:一個事務(同一個read view)在前後兩次查詢同一範圍的時候,後一次查詢看到了前一次查詢沒有看到的行。
針對幻讀兩點需要說明:
1、在可重複讀隔離級別下,普通查詢是快照讀,是不會看到別的事務插入的數據的,幻讀只在當前讀下才會出現。
2、幻讀專指新插入的行,讀到原本存在行的更新結果不算。因爲當前讀的作用就是能讀到所有已經提交記錄的最新值。

當然還有一種方式解決幻讀,就是MVCC(MVCC多版本併發控制),子RR隔離級別下讀事務會保存一個Read View(快照),第一次讀形成Read View,第二次還會沿用這個Read View。而在RC隔離條件下每次都會形成一個新的Read View。

看了上面的next-key大家已經領略到了鎖的風騷了,但是加鎖就會有等待。MVCC給每個表加兩個隱式的列,其中一列存儲行被修改的“時間”,另一列存儲刪除的“時間”
RR隔離級別下
Select
a) 行的修改版本號小於等於該事務號。
b) 行的刪除版本號要麼沒有被定義,要麼 大於事務的版本號。
Insert、Update、Delete
都是用來更新版本號,這裏就不贅述了。

大家思考一下行的修改版本號小於等於該事務號行的刪除版本號要麼沒有被定義,要麼大於事務的版本號是不是已經很好的規避了幻讀。

故障處理

那麼我們的mysql是如何回滾事務,又是如何在宕機的時候重新恢復數據的呢,還有主從複製又是怎麼實現的,大家會說通過日誌,那具體每種對應哪個日誌呢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章