从MySQL manual开始,有关InnoDB多版本:
在内部,InnoDB将三个字段添加到数据库中存储的每一行。 6字节的DB_TRX_ID字段指示最后插入或更新该行的事务的事务标识符。同样,删除在内部被视为更新,在该更新中,行中的特殊位被设置为将其标记为已删除。每行还包含一个7字节的DB_ROLL_PTR字段,称为滚动指针。回滚指针指向写入回滚段的撤消日志记录。如果行已更新,则撤消日志记录将包含在更新行之前重建行内容所必需的信息。 6字节的DB_ROW_ID字段包含一个行ID,该行ID随着插入新行而单调增加。如果InnoDB自动生成聚集索引,则该索引包含行ID值。否则,DB_ROW_ID列不会出现在任何索引中。
但是,我找不到有关如何使用这些隐藏列(DB_TRX_ID
,DB_ROLL_PTR
和DB_ROW_ID
)来构建先前的快照的任何信息,算法是什么?
关于只读事务的手册中的other page指出:
InnoDB可以避免与为已知为只读的事务设置事务ID(TRX_ID字段)相关的开销。仅对于可能执行写操作或锁定读取的事务(例如SELECT ... FOR UPDATE),才需要事务ID。消除不必要的事务ID可以减少每次查询或数据更改语句构造读取视图时都要查询的内部数据结构的大小。
考虑到以上陈述,由于只读事务没有关联的TRX_ID
,因此应该将与当前事务相关的其他事物与现有事务的DB_TRX_ID
的价值进行比较行,以确定是否应将特定行包含在构建的快照中。
请描述高级算法,并说明只读事务的情况(如果它使流程有所不同)。
答案 0 :(得分:1)
如果有多个连接修改同一行,则该行的“历史列表”中该行有多个化身。 TRX_ID
控制可见性:如果化身早于X,则Connection可以“看到”它。否则,它是 this 连接尚不可见的版本(请考虑MVCC中的V)。 (注意:transaction_isolation
级别已计入“可见性”。)
我怀疑只有在要求DB_ROLL_PTR
(或崩溃要求它)时才需要ROLLBACK
(认为ROLLBACK
)。
我猜想只读事务将使用TRX_ID
,但不会创建新的事务,因为它不会创建任何新值来保存历史记录更改或回滚。 >
有关更多细节(以及检查我所说内容的有效性),请参见blogs by JCole。