分类: Mysql/postgreSQL
2013-09-05 18:15:25
InnoDB多版本存储引擎: 保存改变行的版本信息,以支持事务的一致性和回滚,该信息被存储在表空间中一个被称做回滚段(rollback segment)的数据结构中。InnoDB在回滚事务进行取消操作时需要使用该回滚段的信息,也会使用该信息建立被修改行之前的行确保一致读。
多版本内部细节
InnoDB内部对数据中每一行添加三个领域
DB_TRX_ID(6 byte)
DB_ROLL_PTR(7 byte)
DB_ROW_ID(6 byte)
DB_TRX_ID记录最近一次发生insert或update行数据操作的事务标识符,delete对内的操作类似update为删除的行添加一个特别的字节(删除标识)。
每一行都包括一个回滚指针(DB_ROLL_PTR )回滚指针指向写到回滚段中的undo log记录,如进行了update操作,则undo log记录了update之前的行数据。
当insert新行时DB_ROW_ID包含了一个单调递增的行ID,如果InnoDB自动产生聚合索引,则索引中包含行ID,否者DB_ROW_ID不会出现在任何索引中。
undo log在回滚段中被分成insert和update两块undo log,只有当事务回滚时用到insert undo log,并且当事务提交后被快速丢弃。update undo log 则用于一致读,但是只有当InnoDB分配的快照(为保证一致读在update undo log建立的较早版本的行数据)不再被事务调用时才被丢弃。
定期提交你的事务,包括那些仅发生一致读的事务。否则InnoDB将无法丢弃update undo log以致表空间被回滚段添满。
undo log记录在回滚段中的物理尺寸比相应insert或update行小,你可以使用这些信息计算回滚段所需的空间。
InnoDB多版本模式,当执行delete语句时数据行并不会被立即删除,仅当update undo log记录被弃用并注明删除标识时,相应的行和索引才会被真正的删除。该操作被称为purge,purge操作非常快,通常可能delete语句发生之后随之发生。
如果对一张表进行频繁的小批量insert和delete,purge线程处理会产生延时,表会因为这些“死”行(没有发生物理删除)变得越来越大。而导致性能下降。这种情况,减少对新行的操作,并通过调整innodb_max_purge_lag参数为线程分配更多的资源。
个人按照原文理解的机制是,当插入数据DATA (1,2,3,4,5)时记录事务id和行id。当对数据行更新为DATA (10,20,30,40,50),旧的数据被换到update undo log中,旧数据被用于回滚操作。而发生读操作时,update undo log 中的旧数据被用于保证读一致性。
不知道这么理解是否正确。其中还有几个问题需要请教高手: