MySQL InnoDB多版本機制(MVCC)

1.InnoDB多版本簡介
InnoDB爲一個多版本存儲引擎:爲了支持像併發和回滾等事務特性,InnoDB保存被修改數據行的舊版本信息。這些舊版本信息存儲於叫做回滾段(沿用Oracle中類似的數據結構)表空間內。InnoDB使用回滾段中的信息來進行事務回滾所需的取消操作。其也使用這些就版本信息來構建舊版本數據行來完成一致性讀。內部地,InnoDB爲數據庫中存儲的每個數據行增加了三個域。一個6字節db_trx_id域表示insert或update該數據行的最後事務的事務鑑定符。同時,delete操作內部也被當做update處理,其中,該數據行的一個特定位被設置標示該行已被刪除。每個數據行也包含一個叫做滾動指針的7字節db_roll_ptr域,滾動指針指向一個寫入回滾段的取消日誌記錄。如果該數據行被修改了,該取消日誌記錄包含重建該數據行修改前內容的必要信息。一個6字節db_row_id域包含一個新數據行插入時單調遞增的行ID。如果InnoDB自動產生了一個簇索引,則該索引包含該行ID值。否則,db_row_id列不會出現在任何索引中。
回滾段內的取消日誌分爲insert和update取消日誌。insert取消日誌僅在事務回滾時需要,一旦事務提交就會被拋棄。update取消日誌也被用於一致性讀,其僅在InnoDB不再爲任何事務分配重構數據行較早版本而需要這些update取消日誌信息的快照時,纔會被拋棄。
定期提交事務,包括那些只發布一致性讀的事務。否則,InnoDB不能拋棄update取消日誌,從而導致回滾段變的很大,最終耗光表空間。
回滾段內的一條取消日誌記錄的物理大小通常比插入或修改的數據行要小。因此,可以用這個信息計算所需回滾端的空間。
InnoDB多版本機制中,當用SQL語句刪除一個數據行時,物理上並非立即從庫中將其刪除。InnoDB僅在拋棄該刪除操作寫入的update取消日誌記錄時,纔會物理上移除相應的數據行。這個移除操作叫做一個purge,其運行非常快,通常只需SQL語句執行刪除時同等數量級的時間。
如果insert和delete按照同等速率小批量刪除表中的數據行,purge線程可能會落後,且表會變的越來越大,因爲所有的這些“死”數據行,並且會使所有的操作都磁盤受限和很慢。這種情況下,限制新數據行的操作,並通過調整innodb_max_purge_lag系統變量來爲purge線程分配更多的資源。
2.多版本和二級索引
InnoDB多版本併發控制(MVCC)對待二級索引與簇索引不同。簇索引中的記錄就地被修改,它們的隱藏系統列指向重構記錄較早版本所需的取消日誌項。不像簇索引記錄,二級索引記錄並不包含隱藏系統列,同時,它們也不是被就地修改。當二級索引記錄被修改時,就的二級索引數據行被標示爲刪除,新的記錄被插入,被標示爲刪除的記錄最終被purge掉。當二級索引記錄被標示爲刪除,或二級索引數據頁被新事務修改時,InnoDB將在簇索引中查找該數據記錄。簇索引中該記錄的db_trx_id被檢查,如果讀事務初始化後該記錄被修改,則從相應取消日誌獲取該記錄的正確版本。
如果二級索引記錄被標示爲刪除,或二級索引數據頁被較新事務修改,則不會用到覆蓋索引技術。而是從二級索引結構中獲取數值,InnoDB從簇索引中查找該記錄。
然而,如果索引條件下推(index condition pushdown,ICP)優化開啓,部分where條件能通過索引字段評估,mysql服務器還是會將這部分where條件下推到存儲引擎,然後,再通過該索引進行評估。如果沒發現匹配記錄,將避免簇索引查找。如果發現了匹配記錄,甚至是表示爲刪除的記錄,InnoDB將在簇索引中查找該記錄。

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