MVCC

Innodb多版本实现机制:
为了实现多版本,INNODB必须在表空间中保存行的旧版本信息,这些信息被保存在回滚段中;
在内部,innodb为每个行增加两个域,1个6byte的域来指示最后插入或更新这个行的事务标识符(db_trx_id/trx id),删除标志也被认为是一个更新,因为它在提交前只是在行上做了个标记,另外一个7-byte的域被称为回滚段指针(db_roll_ptr/roll pointer),回滚指针指向一个由回滚段写入的undo日志记录,undo日志记录包含了重建这行更新前信息的一些必要数据;
7字节的DB_ROLL_PTR,指向undo tablespace的回滚指针,undo tablespace存储了行记录记录修改前后变化的数据,而不是整行记录(所以如果undo log损坏的话,会导致事务回滚失败,无法恢复数据,innodb报错);
6字节的DB_ROW_ID,指向对应的行记录,每次新写入一行,该IO自增,innodb没指定主键而自动创建隐含的聚集索引时,则该索引会包含该ROWID的值(自主创建聚集索引时,则不会包含ROWID的值);
Innodb使用回滚段的信息来执行事务回滚必须的一些undo操作,而且也使用这些信息来重建更新前的行信息;
回滚段中undo日志被分为插入日志和更新日志,插入日志仅在事务回滚的时候用,事务提交之后就马上删除掉,更新日志在一致性读的时候需要使用,但是,如果当前没有事务再可能使用回滚段中的记录的时候,这些记录就会被删除了;
Read only transaction 从5.7开始支持;
回滚段中undo日志记录的事务大小比其对应的插入或是更新的行要小很多;
在多版本方式下当你使用SQL语句删除某一行的时候,该行并不会马上从数据库的物理文件上移除,只有当innodb能够删除掉更新日志记录的时候,那些行及其对应的索引记录才会真正从物理上删除掉,这个移除操作称为purge;
Rollback segment(回滚段)保存历史修改版本信息,历史版本数据放在undo log里;
UNDO log里面是区分insert,update(delete认为是特殊的update)的,insert事务提交后,立即可以purge了,而update事务必须等所有一致性读事务都提交后,确认无需再次读取了,才能purge,此外,update产生的undo比insert产生的undo大;
所有事务尽快提交,包括一致性只读事务,否则一些update产生的undo log没办法及时释放,导致rollback seg,undo log越来越大;
Delete事务删除的行记录并不是真正立即被删除,而是先打标记,直到所有相关事务都结束,然后才执行purge操作;
适当调整innodb_max_purge_lag ,避免失误purge堆积,影响性能;
当purge list大于innodb_max_purge_lag时,新产生的insert,update,delete请求都会延迟((purge_lag/innodb_max_purge_lag)*10)-5毫秒;
适当调整innodb_max_purge_lag,避免事务purge堆积,影响性能(如果有频繁的insert,delete 小事务提交,但不能及时释放/purge的话,会导致undo越来越大需要适当调小;
update产生的undo比insert 产生的undo要大很多;
MVCC innodb事务的基础 并发的基础.

你可能感兴趣的:(MySQL)