什么是UndoLog?Undo:表示撤消或取消,以撤销操作为目的,返回某种状态的操作。UndoLog:在数据库事务开始之前,将要修改的记录放入Undolog。当事务回滚或数据库崩溃时,UndoLog可以用来撤销未提交的事务对数据库的影响。UndoLog是事务原子性的保证。事务中更新数据的前置操作其实就是先写一个UndoLog。如何理解一个UndoLog事务需要保证原子性,即一个事务中的所有操作要么完成,要么什么都不做。但是有时候在事务执行的过程中会出现一些情况,比如:情况一:事务执行过程中可能会遇到各种错误,比如服务器本身的错误,操作系统的错误,甚至突然断电引起的错误。Case2:DBA可以在事务执行过程中手动输入ROLLBACK语句,结束当前事务的执行。当出现上述情况时,我们需要将数据改回原来的状态。这个过程称为回滚。每当我们要对一条记录进行更改时(这里的更改可以指INSERT、DELETE、UPDATE),我们需要记下回滚所需要的东西。例如:当你插入一条记录时,你至少要记下这条记录的主键值,然后回滚时,只需要删除主键值对应的记录即可。(对于每一次INSERT,InnoDB存储引擎都会完成一次DELETE)如果删除一条记录,至少要记下这条记录的内容,这样回滚时,这些内容组成的记录才会插入到表中以后够了。(对于每一次DELETE,InnoDB存储引擎都会执行一次INSERT)如果你修改了一条记录,你至少要记录修改这条记录之前的旧值,以便后面回滚的时候可以把这条记录更新为旧值。好吧。(对于每一次UPDATE,InnoDB存储引擎都会进行一次相反的UPDATE,将修改前的行放回原处)MySQL将记录的用于回滚的内容称为undolog或rollbacklog(即UndoLog)。注意,由于查询操作(SELECT)不会修改任何用户记录,所以查询操作行时不需要记录相应的Undolog。另外UndoLog会产生RedoLog,也就是UndoLog的产生会伴随RedoLog的产生,因为UndoLog也需要持久化保护。UndoLog的功能提供了数据回滚的原子性。当事务回滚或数据库崩溃时,可以使用UndoLog进行数据回滚。多版本并发控制(MVCC)-隔离是指MVCC在InnoDB存储引擎中的实现是通过UndoLog来完成的。当用户读取一行记录时,如果该记录已经被其他事务占用,则当前事务可以通过UndoLog读取上一行的版本信息,实现非锁读。UndoLog存储结构RollbackSegment和UndoPageInnoDB对UndoLog进行分段管理,即回滚段(rollbacksegment)。每个回滚段记录1024个UndoLog段,在每个UndoLog段段中进行Undo页面申请。在InnoDB1.1版本之前(不包括1.1版本),只有一个回滚段,所以并发在线事务的限制是1024。虽然对于大多数应用来说已经足够了。从1.1版本开始,InnoDB最多支持128个回滚段,因此并发在线事务的限制提高到128*1024。mysql>showvariableslike'innodb_undo_logs';+------------------+------+|变量名|值|+------------------+------+|innodb_undo_logs|128|+----------------+-------+虽然InnoDB1.1版本支持128个回滚段,但这些回滚段都存储在共享表空间ibdata。从lnnoDB1.2开始,可以通过参数进一步设置回滚段。这些参数包括:innodb_undo_directory:设置回滚段文件所在的路径。这意味着回滚段可以存储在共享表空间以外的位置,即可以设置为一个独立的表空间。该参数默认值为“./”,表示当前InnoDB存储引擎的目录。innodb_undo_logs:设置回滚段数,默认值为128。在InnoDB1.2版本中,该参数用于替换之前版本的参数innodb_rollback_segments。innodb_undo_tablespaces:设置组成回滚段的文件个数,使回滚段可以更均匀地分布在多个文件中。设置该参数后,会在innodb_undo_directory路径下看到一个以undo为前缀的文件,代表回滚段文件。回滚段和事务1、每个事务只会使用一个回滚段(rollbacksegment),一个回滚段可能同时为多个事务服务。2.当一个事务开始时,会建立一个回滚段。在事务过程中,当数据被修改时,原始数据会被复制到回滚段中。3、在回滚段中,事务会不断地填充磁盘,直到事务结束或者空间全部用完。如果当前extent不够用,事务会请求扩展segment中的下一个extent。如果所有分配的区都用完了,如果回滚段允许,事务将覆盖原来的区或扩展新的区。面板来使用。4.回滚段存在于Undo表空间中。数据库中可以有多个Undo表空间,但同时只能使用一个Undo表空间。5、当事务提交时,InnoDB存储引擎会做以下两件事:1、将UndoLog放入链表中,以供后续的purge(清洗、清除)操作2、判断UndoLog所在页是否可以被重用(小于3/4可以被重用),如果可以分配给下一个事务,使用回滚段中的数据分类未提交的回滚数据(uncommittedundo信息):这个数据关联的事务还没有被committed,用于实现读一致性,所以数据不会被其他事务的数据覆盖。Committedbutnotexpiredrollbackdata(committedundoinformation):与此数据关联的事务已提交,但仍受undo保留参数的hold时间影响。Transactionhassubmittedandexpireddata(expiredundoinformation):事务已经提交,数据存储时间超过了undo保留参数指定的时间,属于过期数据。当回滚段已满时,它会首先覆盖“事务已提交并过期的数据”。Undopagereuse当我们开始一个事务,需要写入Undolog时,首先要到UndoLog段找空闲位置。当有空格时,我们会申请Undo页面。在这个应用的Undo页面中写入UndoLog。我们知道MySQL默认的页面大小是16k。为每个事务分配一个页面是非常浪费的(除非你的事务很长),假设你的应用的TPS(每秒处理的事务数)是1000,那么1s需要1000个页面,大约16M用于存储,大约1分钟需要1G的存储空间。长此以往,除非MySQL非常勤奋地清理,否则磁盘空间会随着时间的推移增长得非常快,会浪费大量的空间。所以Undo页面被设计成可重复使用的。当事务被提交时,Undo页面不会立即被删除。因为复用,这个Undo页面可能会和其他事务的UndoLog混在一起。UndoLog被commit后,会放到一个链表中,然后判断Undopage使用的空间是否小于3/4。如果小于3/4,说明当前的Undo页面可以重复使用,所以不会使用。循环使用,可以在当前Undo页面后面记录其他事务的UndoLog。由于UndoLog是离散的,清理相应的磁盘空间效率不高。UndoLog的存储机制如上图所示。可以看出,UndoLog不仅存储了数据更新前的记录,还记录了RowID、事务ID、回滚指针。事务ID每次递增,如果是第一次INSERT语句回滚指针为NULL,第二次UPDATE后UndoLog的回滚指针会指向刚才的UndoLog日志,以此类推,会形成一条UndoLog回滚链,方便查找记录的历史版本。UndoLog的工作原理在更新数据之前,MySQL会预先生成UndoLog。当事务提交时,UndoLog不会立即被删除,因为后面可能需要回滚操作。当执行回滚(ROLLBACK)操作时,从缓存中读取数据。UndoLog日志的删除是通过后台purge线程回收的。事务A执行更新操作。此时事务还没有提交,数据会被备份到对应的UndoBuffer中,然后UndoBuffer会被持久化到磁盘上的UndoLog文件中。此时UndoLog保存了提交前的操作。log,然后将操作的数据,即test表的数据,持久化到InnoDB的数据文件IBD中。此时事务B执行查询操作,直接从UndoBuffer缓存中读取。此时事务A还没有提交事务。如果它要回滚(ROLLBACK)事务,它不读磁盘,先直接从UndoBuffer缓存中读取。.UndoLog的种类在InnoDB存储引擎中,UndoLog分为:insertUndoLogininsertUndoLog是指插入操作时产生的UndoLog。因为插入操作的记录只对事务本身可见,对其他事务不可见(这是事务隔离的要求),事务提交后直接删除UndoLog。不需要清洗操作。updateUndoLogupdateUndoLog记录了删除和更新操作产生的UndoLog。UndoLog可能需要提供MVCC机制,事务提交时不能删除。提交时放入UndoLog链表,等待purge线程执行最后的删除。UndoLog生命周期的简单生成过程如下:Undo+Redo事务的简化过程:假设有2个值,A=1,B=2,然后修改A为3,B为41。开始事务;2.RecordA=1toUndoLog;3.更新A=3;4。记录A=3到RedoLog;5.记录B=2到UndoLog;6.更新B=4;7。记录B=4到RedoLog;8.刷新RedoLog到磁盘;9.Commit如果在步骤1-8中的任何一步系统宕机,事务没有提交,则事务不会对磁盘??上??的数据产生任何影响。如果停机时间在8-9之间。RedoLog用于恢复UndoLog发现有事务没有完成,回滚。如果9点后系统宕机,内存映射中变化的数据来不及刷回磁盘,那么等系统恢复后,可以根据RedoLog将数据刷回磁盘。流程图:UndoLog配置参数innodb_max_undo_log_size:Undolog文件的最大值,默认为1GB,初始大小为10minnodb_undo_log_truncate:表示是否开启自动缩减UndoLog表空间的操作independenttablespaces,默认为0,表示不开启独立表空间,Undologs保存在ibdata1innodb_undo_directory:Undologs存放的目录位置innodb_undo_logs:回滚次数默认为128。)
