淺談mysql事物原理

這裏只說innodb,因爲myisam和memory不支持事物,mysql還有一些其他的存儲引擎這裏也不是我們討論的範疇。
大家去建一個表,你會發現的默認行格式是compact,5.7之後是DYNAMIC,這裏所講的dynamic是默認的行格式,其實他可以支持多種。dynamic和compact的主要區別其實就是頁溢出的處理方式不同,dynamic會在第一個頁儲存更多的數據。加快了查詢速度。
以5.6爲例。如果innodb沒有設置主鍵,會找唯一列作爲主鍵,如果沒有唯一列,會默認生成一個隱式行id作爲主鍵,還有一個事物id trx_id,以及回滾指針 roll_pointer。事物id顧名思義,記錄事物的,此外還有兩個事物日誌,redoundo。innodb支持事物其實就是行格式有這些隱藏列,myisam則沒有。所以myisam不支持事物。
undo日誌存的就是數據被修改之前的值。這裏操作系統修改文件其實都是在內存中進行修改,然後再寫回磁盤,數據發生修改的時候,數據是從磁盤讀到數據庫緩存池,在buffer pool中進行修改。那麼這個時候如果數據庫掛了,這個在內存的數據並沒有持久化,那麼會發生數據丟失,這個時候數據庫重啓會先讀這個日誌,持久化到磁盤,數據保持一致。
回到主題,當某一個操作發生修改後,此時會記錄一個事物id,回滾指針指向undo存的日誌。當發生回滾的時候,首先會執行redo,再執行undo,因爲undo是這條數據最最最最開始之前的數據,先執行redo再執行undo不會破壞數據的一致性。
下面來講如何控制事物,這裏涉及幾個概念,一個是MVCC機制,一個是事物版本控制鏈,還有個是readview,readview是記錄當前活躍的事物id,在讀已提交的情況下,readview所存活躍事物的id會隨着事物的提交改變而改變。其實你去做一個讀操作,其實要根據readview的活躍事物的id去過濾,一直找到底到它不在那個事物id,這就是你要讀的數據。這就避免了 在讀已提交的情況下不會讀取未提交的數據,因爲他的readview記錄了未提交的事物id,這個時候他並不會去讀取他。 可重複讀也用到了readview,他的readview不隨着事物關閉而會修改,也就是從始至終的都是那個readview所以他重複讀的數據是一樣的。
前面只說了讀怎麼去控制事物隔離級別,下面來說一說發生寫的事物控制隔離級別。
這裏涉及到了X鎖,S鎖,間隙鎖。innodb支持行鎖,myisam不支持行鎖。
普通的select是不加鎖的,不會加讀鎖。
lock in share mode 加讀鎖, for update加寫鎖
讀已提交 不管你是索引查還是不是索引查,加寫鎖只對所查出的行進行加鎖。
可重複讀,就會加間隙鎖。
其實mvcc機制加這個鎖解決了大部分的幻讀。

參考:https://blog.csdn.net/yu757371316/article/details/81081669
https://baijiahao.baidu.com/s?id=1629409989970483292&wfr=spider&for=pc

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