InnoDB的ACID
ACID模型是一些列資料庫設計原則的集合,旨在提升可靠性,這對商業資料和關鍵應用是至關重要的,MySQL包含諸多組件,例如嚴格遵循ACID模型的InnoDB存盤引擎,以保障資料不會因為軟體崩潰和硬體故障,而導致資料損壞和結果失真,當依賴ACID一致性特性時,你不需要自己再造輪子來進行校驗和故障恢復機制,如果你有額外的軟體保護措施,超可靠的硬體,或者應用可容忍小部分的資料丟失或不一致,你可以調整MySQL配置,通過犧牲一些ACID的可靠性來獲得更高的性能或吞吐量,
InnoDB的多版本(MVCC)
InnoDB是多版本支持的存盤引擎:它為發生變化的行保存了舊版本資訊,來支持并發和回滾的事務特性,資訊存盤在表空間,一個稱為回滾段-roolback segment(在Oracle使用類似的資料結構之后)的資料結構,InnoDB使用回滾段中的資訊來執行一個事務回滾之后的undo操作,這個資訊也同樣被用來在一致讀場景下建立行資料的早期版本,
InnoDB為在資料庫中存盤的每行資料增加了3個欄位,
1、一個6位元的DB_TRX_ID欄位,代表上一個事務的插入/更新行操作的事務識別符號,洗掉在內部被視為更新,行中的特殊位被設定為將其標記為已洗掉,
2、一個7位元的DB_ROLL_PTR欄位,稱為回滾指標,回滾指標指向寫入回滾段的一條undo日志記錄,如果行被更新,那么包含這個資訊的undo日志記錄,在更新前必須重新生成行記錄,
3、一個6位元的DB_ROW_ID欄位,插入新行時單調增加的行ID,如果InnoDB自動生成聚集索引,則索引包含行ID值,否則,該列不會出現在任何索引中,
回滾段中的undo日志分為插入undo日志和更新undo日志,插入undo日志只在事務回滾時需要,并能夠在事務提交時盡快丟棄,而更新undo日志在一致讀中也會使用,只有在不存在InnoDB為其分配了快照的事務之后,才能丟棄這些快照,在一致讀取中,該快照可能需要更新撤消日志中的資訊來構建資料庫行的早期版本,
定期提交事務,包括那些只發出一致讀取的事務,否則,InnoDB無法從update undo日志中丟棄資料,并且回滾段可能會變的過大,占滿你的表空間,
回滾段中undo log記錄的物理大小,通常小于相應的插入行或更新行,你可以使用這個資訊來計算回滾段所需的空間,
在InnoDB的多版本模式中,當你通過sql陳述句洗掉一個記錄行時,它并不會馬上從資料庫中被物理洗掉,InnoDB只有在丟棄 為洗掉寫入的update undo日志記錄時,才會物理洗掉相關的行和索引記錄,這個洗掉操作稱之為purge(清理),并且這個操作執行很快,通常是與執行洗掉的sql陳述句相同數量級的耗時,
如果以大約相同的速率小批量地插入和洗掉表中的行,清理執行緒可能會開始落后,表也會由于所有”死“行記錄的堆積變的越來越大,使得任何事情都受磁盤限制并且非常緩慢,在這種情況下,可以通過調整innodb_max_purge_lag系統變數來限制新行操作,并分配更多資源給清理執行緒,
多版本和二級索引
InnoDB多版本控制(MVCC)在處理二級索引和聚簇索引時有所不同,聚簇索引中的記錄是就地更新,它們的隱藏系統欄位指向undo log,從中可以重建記錄的早期版本,與聚簇索引記錄不同,二級索引記錄并不包含隱藏系統欄位,并且它們也不會就地更新,
當一個二級索引列被更新時,舊的二級索引記錄會被標記洗掉,新的記錄被插入,并且已經標記洗掉的記錄最侄訓被清理,當一個二級索引記錄被標記洗掉,或者二級索引頁被一個新的事務更新時,InnoDB會在聚簇索引中查找資料庫記錄,在聚簇索引中,記錄的DB_TRX_ID會被檢查,如果記錄在讀事務開始之后被修改,那么記錄的正確版本會從undo log中找回,
如果二級索引記錄被標記洗掉,或二級索引頁被更新的事務更改,那么不會使用覆寫索引技術,InnoDB會從聚簇索引中查找記錄,而不是從索引結構中回傳值,
然而,如果開啟了索引條件下推(ICP)優化項,并且部分WHERE條件評估后可以只使用索引覆寫的欄位,MySQL服務器仍然將WHERE條件的這一部分向下推送到存盤引擎,在那里使用索引對其進行評估,如果沒有找到匹配記錄,就會避免聚簇索引查找,如果找到了匹配記錄,哪怕是在標記為洗掉的記錄中,InnoDB也會在聚簇索引中查找記錄,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/245268.html
標籤:其他
上一篇:標簽管理體系之業務應用
