来自mysql手册关于innodb多版本控制:
在内部,innodb向数据库中存储的每一行添加三个字段。6字节的db\u trx\u id字段表示插入或更新行的最后一个事务的事务标识符。此外,删除在内部被视为更新,行中的特殊位被设置为将其标记为已删除。每行还包含一个7字节的db\u roll\u ptr字段,称为滚动指针。滚动指针指向写入回滚段的撤消日志记录。如果行已更新,撤消日志记录将包含在更新行之前重建行内容所需的信息。一个6字节的db\u row\u id字段包含一个随着新行插入而单调增加的行id。如果innodb自动生成聚集索引,则索引包含行id值。否则,db\u row\u id列不会出现在任何索引中。
但是,我找不到任何关于这些隐藏列到底是如何工作的信息( DB_TRX_ID
, DB_ROLL_PTR
以及 DB_ROW_ID
)用于构建上一个快照,算法是什么?
手册中关于只读事务的另一页说明了以下内容:
innodb可以避免为已知为只读的事务设置事务id(trx\u id字段)带来的开销。只有可能执行写操作或锁定读取(如选择)的事务才需要事务id。。。更新。消除不必要的事务ID可以减少每次查询或数据更改语句构造读视图时所查询的内部数据结构的大小。
考虑到上述语句,由于只读事务没有关联 TRX_ID
,则应该有与当前事务相关的其他内容与 DB_TRX_ID
现有行的值,以便能够确定该特定行是否应包含在生成的快照中。
请描述高级算法,以及只读事务的情况,如果它使流程不同。
1条答案
按热度按时间pn9klfpd1#
如果有多个连接修改同一行,则该行的“历史记录列表”中有该行的多个化身。这个
TRX_ID
控制可见性:如果一个化身比x早,那么连接可以“看到”它。否则,这个版本(比如mvcc中的v)对此连接还不可见(注:transaction_isolation
级别被分解为“可见性”。)我怀疑
DB_ROLL_PTR
(思考)ROLLBACK
)只有在ROLLBACK
是被要求的(或者是一场车祸要求的)。我猜只读事务使用
TRX_ID
,但不会创建新值,因为它不会创建任何新值来保存历史更改或回滚。更多血淋淋的细节(以及检查我所说内容的有效性),请参阅jcole的博客。