InnoDB多版本控制实现
本篇翻譯自 MySQL 5.7 Reference Manual / The InnoDB Storage Engine / InnoDB Multi-Versioning,主要講述的是在InnoDB中多版本控制協(xié)議的實現(xiàn):
InnoDB 是一個多版本控制存儲引擎,它記錄改變行的歷史信息來保證事務的一致性和回滾。這些歷史信息保存在表空間的一個叫rollback segment的數(shù)據(jù)結(jié)構(gòu),InnoDB利用這個數(shù)據(jù)結(jié)構(gòu)來完成回滾中的撤銷操作,并且為一致性讀取建立歷史版本。
InnoDB為每行增加了3個區(qū)域,6字節(jié)的DB_TRX_ID字段指示插入或更新該行的最后一個事務的事務標識符。另外,刪除被視為更新操作,其中行中的一個特殊位被設置標記為已刪除。每一行還包含一個名為roll pointer的7字節(jié)DB_ROLL_PTR字段,roll pointer指向?qū)懭雛ollback segment的undo log記錄,如果更新了行,undo log將記錄在更新行之前重建該行內(nèi)容所需的信息。最后是6字節(jié)的DB_ROW_ID字段,它記錄一個行ID,該行ID隨著插入新行而單調(diào)遞增,如果InnoDB自動生成一個聚集索引,則該索引包含行ID值。否則,DB_ROW_ID不會出現(xiàn)在任何索引中。
rollback segment中的undo log 分為inster undo log和update undo log。inster undo log只在事務回滾中需要,會在事務提交時立即丟棄。update undo log用于保證讀取一致性,但他們只能在沒有需要update undo log中的信息來保證一致性讀取的事務存在的時候才能被丟棄。所以你最好定期提交你的事務,包括哪些只有讀取的事務,否則InnoDB不能update undo log,這樣一來rollback segment將會越來越大,填滿你的表空間。
rollback segment中的undo log的物理大小通常小于相應的插入或更新行。你可以使用此信息來計算rollback segment所需的空間。
在InnoDB多版本控制方案中,當你使用SQL語句刪除一行時,它不會立即從數(shù)據(jù)庫的磁盤上刪除。InnoDB只有在丟棄為刪除而編寫的update undo log記錄時,才會從磁盤上刪除相應的行及其索引記錄。這個刪除操作稱為清除,它非常快,通常使用與執(zhí)行刪除操作的SQL語句相同的時間順序。
如果在表中以差不多的速度少量的插入和刪除行,清除線程可能會開始滯后,由于所有的“死”行,表可能會變得越來越大,這使得所有內(nèi)容都被磁盤讀取速度所限制,以至于速度非常慢。在這種情況下,通過調(diào)優(yōu)innodb_max_purge_lag系統(tǒng)變量,控制新的行操作,并為清除線程分配更多的資源。
總結(jié)
以上是生活随笔為你收集整理的InnoDB多版本控制实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从源码理解ReentrantLock
- 下一篇: java中两个整形相除,向上取整