Chinaunix首页 | 论坛 | 博客
  • 博客访问: 31849
  • 博文数量: 9
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 82
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-02 00:25
文章分类
文章存档

2015年(1)

2013年(7)

2012年(1)

我的朋友

分类: 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 中的旧数据被用于保证读一致性。
      不知道这么理解是否正确。其中还有几个问题需要请教高手:

  1. Update的时候DB_ROW_ID是否会递增?
  2. 由于该案例是插入单行数据,如果DB_ROW_ID递增,当插入多行数据时DB_ROW_ID是如何增长?
  3. 根据《MySQL高可用》中的INNODB在repeatable隔离级别下的MVCC机制,SELECT需比对事务版本号(是指DB_TRX_ID?)和行版本号(DB_ROW_ID?),只有当DB_TRX_ID ≥ DB_ROW_ID时,查询的结果才会被反馈。对于多行数据DB_ROW_ID如果是逐行递增,DB_ROW_ID不是很容易超过DB_TRX_ID?
阅读(1653) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~