InnoDB 存储引擎<五>undo log, redo log,以及双写缓冲区
目录
撤销⽇志 - Undo Log
双写缓冲区 - Doublewrite Buffer
重做⽇志 - Redo Log
本篇是继承自上篇InnoDB存储引擎的磁盘文件
上篇链接:InnoDB 存储引擎<四>磁盘文件一
撤销⽇志 - Undo Log

1.什么是撤销⽇志?
解答问题:
1.当事务对数据进⾏修改的时候,每个修改操作都会在磁盘上创建与之对应的Undo Log,当事务需要回滚时,会根据Undo Log逐⼀进⾏撤销操作,从⽽保证事务的原⼦性。也就是说撤销⽇志是为事务的回滚操作⽽诞⽣的机制,它是⼀个撤销操作记录的集合。2.Undo⽇志保存在Undo⽇志段中,Undo⽇志段位于回滚段中,回滚段位于undo表空间和全局临时表空间中
衍⽣问题:1. 撤销⽇志的写⼊时机?在事务执⾏每个DML之前,会根据DML构建对应的撤销⽇志,并申请⼀个 undo logsegments (撤销⽇志段),把⽇志记录在申请到的撤销段中,再执⾏真正的DML操作,执⾏过程如下所⽰:

2.撤销⽇志在撤销表空间中的组织形式是怎样的?
前置知识:.Undo⽇志保存在Undo⽇志段中,Undo⽇志段位于回滚段中,回滚段位于undo表空间和全局临时表空间中分析过程:撤销⽇志在撤销表空间中的组织结构图,如下图所示

1.Undo log segments (撤销⽇志段)也称为撤销段,⼀个撤销⽇志段可以保存多个事务的回滚⽇志,但在同⼀时间只能被⼀个活跃事务使⽤,对应的空间在事务提交或回滚后才可以被重⽤。2.rollback segments (回滚段)中包含撤销⽇志段,通常位于undo表空间和全局临时表空间中,使⽤系统变量 Innodb_rollback_segments 可以定义分配给每个undo表空间和全局临时表空间的回滚段的数量,默认值为128,取值范围是[1, 128];3.⼀个回滚段⽀持的事务数取决于回滚段中的undo slots(槽数)和每个事务所需的undo⽇志数,⼀个回滚段中的undo槽数可以根据InnoDB⻚⾯⼤⼩进⾏计算,公式是(InnoDB Page Size / 16),⽐如默认情况下 InnoDB Page Size ⼤⼩为 16KB ,那么⼀个回滚段就可以包含 1024 个 undo slot ⽤来存储事务的撤销⽇志。4.回滚段中还记录了 History List 的头节点 History List Base Node ,以及回滚段的⼤小5.通过系统变量 innodb_rollback_segments 可以设置Undo表空间中的回滚段数量,最⼤值和默认值都是128
# 查看Undo表空间中的回滚段数量
mysql> show variables like 'innodb_rollback_segments';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_rollback_segments | 128 |
+--------------------------+-------+
1 row in set, 1 warning (0.01 sec)# 设置Undo表空间中的回滚段数量
mysql> SET GLOBAL innodb_rollback_segments = 128;
Query OK, 0 rows affected (0.00 sec)
解答问题:撤销表空间中包含 rollback segments (回滚段),每个回滚段中包含若⼲undo slots(槽数),每个槽对应⼀个 Undo log segments (撤销⽇志段),撤销⽇志段中包含具体的撤销⽇志
3.撤销⽇志的格式是怎样的?(撤销日志的结构)
分析过程:撤销⽇志格式⽰意图如下:与数据行的格式进行比较

解答问题:一 条记录在Undo Log⻚中的Undo Log⽇志⼤体包含两部分:分别是记录了Undo类型、表ID、上 ⼀条、下⼀条⽇志的偏移地址等在内的"基本信息",以及记录了不同操作和数据的"操作信息"衍⽣问题1. 在事务中不同的DML操作对应的撤销⽇志是否不同?(不同的DML操作对应不同的撤销日志)在执⾏DML语句操作数据库时,不同SQL语句对应的撤销操作不同,不同的撤销操作对应的Undo Log存储格式也不相同,按照增、删、改等不同的DML操作,⽣成对应的撤销⽇志2.不同操作对应的撤销⽇志如何区分?(1)Undo类型有很多种,最常⻅的就是增、删、改,分别⽤ TRX_UNDO_INSERT_REC 、TRX_UNDO_DEL_MARK_REC 和 TRX_UNDO_UPD_EXIST_REC 表⽰,示意图如下所⽰

(2)新增( TRX_UNDO_INSERT_REC )时的Undo Log操作信息相对简单,只记录了主键值,主键⻓度等主键信息;
(3)删除( TRX_UNDO_DEL_MARK_REC )时除了记录主键信息之外,还记录了旧的事务ID,旧的ROLL_POINTER信息,⽤来构建有序的Undo版本链,还会记录⼀些被索引字段的信息;(4)更新( TRX_UNDO_UPD_EXIST_REC )时较为复杂,如果不更新主键则和删除时类似,会记录主键信息、旧的事务ID、旧的ROLL_POINTER信息、被索引字段的信息和被更新的信息;如果更新了主键,则会记录两条Undo Log ,⼀条删除的和⼀条新增的;对于更新主键的操作,本质上都是删除旧的数据行,新增一个新数据行

4.撤销⽇志是如何组织在⼀起的?(通过撤销日志页)
分析过程:
撤销⽇志的组织⽰意图如下:
对于这里的undo page header,undo log segment header和undo log header中存储的主要字段信息

解答问题:
1.⼀条条Undo Log会被逐⼀放在Undo Log⻚中,Undo Log⻚和其他类型的⻚⼀样都会包含头尾信息,除此之外还有Undo Log特有的信息,包括:(1)UNDO PAGE HEADER :记录了Undo Log⻚类型、⽇志偏移位置,下⼀⻚链表引⽤等信息(2)UNDO LOG SEGMENT HEADER :记录了回滚段信息(3)UNDO LOG HEADER :记录了产⽣这条⽇志的事务Id:Trx ID;事务的提交顺序:Trx No和其他事务相关信息2.在这三个特有的头信息之外,其他空间都会⽤来记录Undo Log⽇志,如果某个事务很⼤,⼀个Undo Log⻚没有办法完整记录,就需要申请新的Undo Log⻚,然后通过 UNDO PAGE HEADER 中链表引⽤信息链接到前⼀个⻚,后⾯的这些⻚只需要记录Undo Log并不需要记录Undo头信息。3.这个由Undo Log构成的链表称做Undo链,在事务中会起到⾮常重要的作⽤。衍⽣问题:
1.事务提交后Undo Log是否就可以删除了?
对于新增操作所记录的Undo Log⽇志,在事务提交之后就可以直接删除了,⽽删除和更新的Undo Log⽇志还需要服务事务的MVCC,所以并不能直接删除,⽽是加⼊到 hisotry list 中。因些InnoDB为了最⼤程度节省空间提升效率对Undo Log进⾏了分类
5.撤销⽇志如何分类?
前置知识:
1.这里的分类是为了方便管理日志而进行的分类
2.关于上个问题中UNDO PAGE HEADER 中记录了Undo Log⻚类型,意义是啥

解答问题:1.Undo Log分为两⼤类:⼀类只记录新增操作,事务提交后可以直接清除;另⼀类记录删除和更新操作,所以相应的回滚链也会被区分为2个:Insert Undo链 和 Update Undo链(Delete + Update)2.另外普通表和临时表分别对应这两类Undo链,如是⼀个事务既有新增⼜有修改并且⽤到了临时表,那么这个事务最多可以分配四个撤销⽇志,也就是四个Undo链,分别是:(1)对⽤⼾定义的普通表进⾏ INSERT 操作(2)对⽤⼾定义的普通表进⾏ UPDATE 和 DELETE 操作(3)对⽤⼾定义的临时表进⾏ INSERT 操作(4)对⽤⼾定义的临时表进⾏ UPDATE 和 DELETE 操作对于前两个是保存在系统或用户创建的撤销表空间,后两个是保存在临时表空间中,临时表空间中有一个回滚段专门用来保存undo 日志3. 根据事务的操作按需要写⼊Undo⽇志,⽐如,在普通表和临时表执⾏ INSERT 、 UPDATE 和 DELETE 操作的事务需要会写⼊以上四种类型的撤销⽇志;只在普通表上执⾏ INSERT 操作的事 务只需要⼀个撤消⽇志4.对普通表执⾏操作的事务将从指定的系统表空间或undo表空间的回滚段分配undo⽇志。对临时表执⾏操作的事务从指定的临时表空间回滚段分配undo⽇志
6. InnoDB最⼤⽀持并发读写事务的数量如何计算?
解答问题:
可以⽤以下公式计算InnoDB能够⽀持的并发读写事务的数量(1) 如果每个事务执⾏ INSERT 或 UPDATE 或 DELETE 操作,注意只执⾏⼀种类型的操作,并发读 写事务数为:
# 最⼤⽀持 (16384 / 16) * 128 * 127 = 16,646,144
(innodb_page_size / 16) * innodb_rollback_segments * number of undo tablespaces
从左向右为页大小,回滚段的数量以及撤销表空间的个数
(2)如果每个事务执⾏ INSERT 和 UPDATE (和的意思为一个事务要使用两个撤销日志段)或 DELETE 操作,并发读写事务数为:
# 最⼤⽀持 (16384 / 16 / 2) * 128 * 127 = 8,323,072
(innodb_page_size / 16 / 2) * innodb_rollback_segments * number of undo tablespaces
(3)如果⼀个事务在临时表上执⾏ INSERT 操作,并发读写事务数为:
# 临时表最⼤⽀持 (16384 / 16) * 128 = 131,072
(innodb_page_size / 16) * innodb_rollback_segments
(4)如果⼀个事务在临时表上执⾏ INSERT 和 UPDATE 或 DELETE 操作,并发读写事务数为:
# 临时表最⼤⽀持 (16384 / 16 / 2) * 128 = 65,536
(innodb_page_size / 16 / 2) * innodb_rollback_segments
7.如何理解Undo链?
解答问题:
1.Insert Undo链 和 Update Undo链采⽤了不同的组织⽅式;2.对于新增操作,Insert Undo链中的每个Undo Log都会对应⼀条新的数据⾏,这个数据⾏中⽤ ROLL_POINTER 信息来关联Undo Log,在回滚时就可以通过它找到需要回滚的Undo Log了,即一条新增的数据行对应一条undo日志,他们之间是一对一的关系

3.对于删除和更新,Update Undo链中的每个Undo Log也都对应⼀个数据⾏,每次更新都会通过 Undo Log中的 ROLL_POINTER 进⾏关联,从⽽每个数据⾏都会构成⼀个Undo Log版本链,回滚的时候就可以依序撤销,这个版本链在事务的MVCC中起到了⾮常重要的作⽤,⽤于解决事务的"隔离性"

4.以下是⼀个关于更新操作的Undo链
8.撤销⽇志为什么需要落盘?
分析过程:
1.在对数据进⾏修改时,都是在内存中操作的,也就是在Buffer Pool中修改对应的数据⻚,在修改数据⻚之前先把对应的撤销⽇志记录在内存中,如果此时事务回滚直接根据内存中的撤销⽇志做回滚操作即可;
2.在修改完成提交事务后,脏⻚进⾏落盘操作,此时事务已提交,不能回滚,所以撤销⽇志也就失效了;
3.当服务器崩溃时,如果事务没有提交,所有的修改都在内存中,还没有落盘,对于修改直接丢弃;如果事务已经提交,则根据重做⽇志和双写缓冲区中的备份进⾏恢复;4.通过分析看上去撤销⽇志并不需要落盘,其实以上的分析场景并没有考虑到全部的场景,⽐如⼤事务的运⾏、MVCC中版本链什么时候可以销毁、事务的不同隔离级别等因素;解答问题:undo log落盘必须在真实数据页落盘之前1. 在运⾏⼤事务时,InnoDB为了避免⼤事务提交时统⼀落盘操作带来的性能问题,允许在事务进⾏ 的过程中就进⾏落盘操作并记录对应的UndoLog,当发⽣崩溃恢复时,通过回放UndoLog把未提 交的事务进⾏回滚;2.如果⼀个事务已经提交,但还有其他事务需要访问版本链中对应的UndoLog,那么也需要把相应的撤销⽇志保存到 hisotry list 中。3.不同隔离级别下,没有提交的事务也可能会落盘,回滚时依然要完成撤销操作衍⽣问题1. 撤销⽇志在内存中如何记录?(1) 与数据⻚在内存中的保存⽅式相同,撤销⽇志在内存中也保存在Buffer Pool中,与磁盘中的 UndoLog⻚结构⼀致,内存中每个UndoLog⻚通过控制块管理(2) 在内存中使⽤四个链表来管理正在使⽤的UndoLog⻚和空闲UndoLog⻚,根据不同的⽇志类型分 为:Insert List :正在被使⽤的⽤来管理Insert类型的UndoLog ⻚Insert Cache List :空闲的或被清理后可以被后续事务重⽤的Insert类型UndoLog⻚Update List :正在被使⽤的⽤来管理Update类型的UndoLog ⻚Update Cache List :空闲的或被清理后可以被后续事务重⽤的Update类型UndoLog⻚

2.撤销⽇志的写⼊过程是怎样的? ----先写内存,再按需落盘
(1)当写事务开始时,会先分配⼀个处理 ACTIVE 状态的 Rollback Segment ;(2)当第⼀次DML操作产⽣Undo Record时,会轮询当前 Rollback Segment 中可⽤的 Slot ,以便获取⼀个 Undo Log Segment ;(3)根据撤销⽇志的类型获取UndoLog⻚,并挂载到对应的List当中;(4)在UndoLog⻚顺序写⼊⽇志,当⼀个UndoLog⻚写满之后,会获取新的UndoLog⻚以便继续写⼊当前事务⽣成的⽇志,这⾥注意:单条UndoLog不能跨⻚存储,也就是说当某条⽇志在当前⻚中放不下时,会整体保存下⼀⻚中;(5)由后台线程把⽇志刷⼊磁盘;(6)当事务结束之后(commit或者rollback), insert ⽇志类型对应的 Undo Log Segment 和UndoLog page 会直接回收,⽽ update ⽇志类型对应的 Undo Log Segment 和UndoLog page 会等待后台的清理操作完成后,确保⽇志不会有事务再访问后进⾏回收,回收的UndoLog⻚被挂载到Cache List中

3.撤销⽇志的回滚过程是怎样的?
(1)回滚操作可以是⽤⼾通过rollback主动触发,也可能发⽣在崩溃恢复时,不论是哪种触发条件,回滚操作都是相同的,基本过程就是读取该事务的Undo Log,从后向前依次进⾏逆向操作,从⽽恢复索引记录;(2)对于 Insert 类型的回滚操作就是 Delete ,在删除的过程中会重新调整主键索引和⼆级索引;(3)对于Update和Delete类型的回滚操作,主要是回退这次操作在所有主键索引和⼆级索引的影响,可能包括重新插⼊被删除的⼆级索引记录、去除⾏管理信息中的Delete Mark标记、将主索引记录修改回之前的值等;(4)完成回滚的Undo Log会进⾏回收,将不再使⽤的UndoLog⻚的磁盘空间还给 Undo LogSegment ,这个过程是写⼊过程的逆操作。4.撤销⽇志的清理过程是怎样的?(1)InnoDB通过保存多份Undo Log的历史版本来实现MVCC,当某个历史版本已经确认不会被任何现有的和未来的事务访问时,就应该被清理掉;(2)当开启⼀个事务时都会被分配⼀个事务编号 trx_id ,⽽事务进⾏读操作时会创建⼀个ReadView,并记录当前所有事务中的最⼩活跃事务编号 m_low_limit_id ,如果版本链中 ⽇志的 trx_id < m_low_limit_id ,则表⽰当前读操作发⽣时,⽇志对应的事务已提交,其修改的新版本是可⻅的, 因此不再需要通过Undo版本链构建之前的版本,这个事务的Undo Log也就可以被清理了。(3)Undo的清理⼯作是由专⻔的后台线程进⾏扫描和分发,并由多个线程进⾏清理,并可以通过系统变量 innodb_purge_threads 配置清理线程数,系统变量 innodb_purge_batch_size可以配置每次清理的⻚数
双写缓冲区 - Doublewrite Buffer

1.双写缓冲区的作⽤?
解答问题:双写缓冲区是磁盘上的⼀个存储区域,当 InnoDB 将缓冲池中的数据⻚写⼊到磁盘上表空间数据⽂件之前,先将对应的⻚写到双写缓冲区;如果在数据真正落盘的过程中出现了意外退出,⽐如操作系统、存储⼦系统崩溃或异常断电的情况, InnoDB 在崩溃恢复时可以从双写缓冲区中找到⼀份完好的⻚副本

衍⽣问题:1.双写缓冲区中的数据保存在哪⾥?在MySQL 8.0.20之前, doublewrite 缓冲区位于InnoDB系统表空间中。从MySQL 8.0.20开始, doublewrite 缓冲区默认存储区域位于数据⽬录下的 doublewrite ⽂件中。
root@guangchen-vm:/var/lib/mysql# ll
total 92948
drwxr-x--- 8 mysql mysql 4096 11⽉ 5 11:15 ./
drwxr-xr-x 73 root root 4096 10⽉ 30 12:07 ../
# ...省略
# 默认创建两个双写缓冲区⽂件
-rw-r----- 1 mysql mysql 196608 11⽉ 5 11:15 '#ib_16384_0.dblwr' # ⽂件1
-rw-r----- 1 mysql mysql 8585216 11⽉ 1 10:34 '#ib_16384_1.dblwr' # ⽂件2
# ...省略
2.如何配置双写缓冲区?
解答问题:1.是否启⽤ doublewrite 缓冲区可以通过系统变量 innodb_doublewrite[=ON|OFF] 控制,默认为启⽤,如果真实的业务场景更关注性能⽽不是数据完整性,可以考虑禁⽤doublewrite缓冲区,例如在执⾏测试的环境中;2.doublewrite ⽂件所在⽬录通过系统变量 innodb_doublewrite_dir (MySQL 8.0.20中引⼊)指定,如果不指定则在 innodb_data_home_dir ⽬录(默认为data⽬录)下创建;如果指定doublewrite⽬录,建议设置在最快的存储介质上,以提⾼效率;
root@guangchen-vm:/var/lib/mysql# ll
total 92948
drwxr-x--- 8 mysql mysql 4096 11⽉ 5 11:15 ./
drwxr-xr-x 73 root root 4096 10⽉ 30 12:07 ../
# ...省略
# 默认创建两个双写缓冲区⽂件
-rw-r----- 1 mysql mysql 196608 11⽉ 5 11:15 '#ib_16384_0.dblwr' # ⽂件1
-rw-r----- 1 mysql mysql 8585216 11⽉ 1 10:34 '#ib_16384_1.dblwr' # ⽂件2
# ...省略
命名⽅式为: #ib_page_size_file_number.dblwr ,以上 #ib_16384_0.dblwr 的⽂件 表⽰当前数据⻚的⼤⼩为16KB,编号为0
3.双写⽂件的数量通过系统变量 innodb_doublewrite_files 设置,默认情况下,为每个缓冲
池实例创建两个doublewrite⽂件,也就是说⽂件数量为 innodb_buffer_pool_instances * 2 ;此变量⽤于⾼级性能调优,⼤多数场景使⽤默认设置即可;
重做⽇志 - Redo Log

1.重做⽇志的作⽤?
解答问题:1.重做⽇志在保证事务的持久性和⼀致性⽅⾯起到了⾄关重要的作⽤2.重做⽇志⽤于在数据库崩溃后恢复已提交事务还没有来的及落盘的数据。重做⽇志以⽂件的形式保存在磁盘上,在正常的操作过程中,MySQL根据受影响的记录进⾏编码并写⼊重做⽇志⽂件,这些数据称为"Redo",在重新启动时⾃动读取重做⽇志进⾏数据恢复。

衍⽣问题:1.为什么要⽤Redo Log,⽽不是直接写磁盘?(1)⾸先明确⼀点,我们对数据进⾏的DML操作都会包含在事务当中,当完成修改并且提交事务之后,在内存中被修改的数据⻚就要刷新到磁盘完成持久化;(2)那么如果这次DML操作对应的修改开始刷盘的话,当服务器崩溃,没有被刷到磁盘的数据⻚就从内存中丢失,这时这个事务的修改在磁盘上就是不完整的,也就是没有保证事务的⼀致性(3)为了解决这个问题,InnoDB在执⾏每个DML操作时,当内存中的数据⻚修改完成之后,把修改的内容以⽇志的形式保证在磁盘上,然后再对数据⻚进⾏真正的落盘操作,这样做就相当于对修改进⾏了⼀次备份,即使当服务器崩溃也不会受到影响,当服务器重启之后,可以从磁盘上的⽇志⽂件中找到上次崩溃之前没有来的及落盘的数据继续执⾏落盘操作;(4)InnoDB引擎的事务采⽤了 WAL 技术 (Write-Ahead Logging) ,基本思想是先写⽇志,再写磁盘,只有⽇志写⼊成功,事务才算提交成功,这⾥的⽇志就是Redo Log。当发⽣宕机且数据未刷到磁盘的时候,可以通过Redo Log来恢复,保证ACID中的持久性,这也是Redo Log的作⽤。undo日志保证事务的原子性2.Redo Log的写⼊时机?当发⽣数据修改操作时追加重做⽇志,已落盘数据对应的⽇志位置被记录为⼀个检查点,检查点之前的数据被置为⽆效,所以重做⽇志⽂件可以循环使⽤。以⼀个更新操作为例,重做⽇志的写⼊过程与时机,如下图所⽰:

使用Log Buffer的原因:因为每次进⾏DML操作都会进⾏⼀次磁盘I/O,这样会严重影响效率,所以把⽇志统⼀写⼊内存中的Log Buffer,根据刷盘策略统⼀进⾏落盘操作,可以实现⼀次磁盘I/O写⼊多条⽇志,从⽽提升效率。
2.Redo Log的格式是怎样的?
分析过程:
1.在介绍RedoLog的格式之前,先来分析⼀下RedoLog中需要记录哪些内容
(1)当进⾏DML操作时,⾸先要修改内存中的数据⻚,但是修改的数据有可能只是数据⻚中很少的⼀部分内容,甚⾄有可能只修改了⼏个字节,那么在RedoLog中是要记录整个数据⻚吗?当然不是,如果每次保存整个数据⻚的话就有太多的⽆⽤数据写⼊⽇志,严重影响效率⽽且浪费空间(2)为了节省空间提⾼效率,RedoLog只记录被修改的内容,⽐如当前的DML修改了哪个表空间、表空间中的哪个数据⻚,数据⻚中多少偏移量处的值修改成了什么,⽐如:# ⼀个例⼦1 号表空间中的⻚编号为 50 的数据⻚中偏移量为 1000 处的整型值修改为 100在示例中明确了当前日志对应的文件,要修改的起始位置,要修改的长度和新值(3)这样就可以⽤很⼩的⽇志记录当前对数据⻚所做的修改,⼤⼤节省了空间解答问题1.RedoLog本质上只是记录了事务对数据库做了哪些修改,修改操作包含多种场景,⽐如对数据⾏、索引⻚的增删改,对范围的修改与删除等等,不同场景的 redo ⽇志定义了不同的类型,但是绝⼤部分类型的 redo ⽇志都有下边这种通⽤的结构包括:(1)Type : ⽇志类型, 1BTYE(2)Space ID : 操作所属的表空间, 4BTYE(3)Page no : 操作的数据⻚在表空间中的编号, 4BTYE(4)data :⽇志的内容,⻓度不固定

衍⽣问题:1.data 部分的具体内容是什么?data 部分⼜可以分为:数据⻚中的偏移量,修改内容的⻓度和具体的修改内容
3.RedoLog的类型分为哪些?
分析过程:查看RedoLog的类型,最完整最直观的⽅式就是通过阅读源代码,如下所⽰:
/** @file include/mtr0types.hMini-transaction buffer global typesCreated 11/26/1995 Heikki Tuuri*******************************************************/
// 省略...
/** @name Log item types
The log items are declared 'byte' so that the compiler can warn if val
and type parameters are switched in a call to mlog_write_ulint. NOTE!
For 1 - 8 bytes, the flag value must give the length also! @{ */
enum mlog_id_t {/** if the mtr contains only one log record for one page,i.e., write_initial_log_record has been called only once,this flag is ORed to the type of that first log record */MLOG_SINGLE_REC_FLAG = 128,/** one byte is written */MLOG_1BYTE = 1,/** 2 bytes ... */MLOG_2BYTES = 2,/** 4 bytes ... */MLOG_4BYTES = 4,/** 8 bytes ... */MLOG_8BYTES = 8,/** Record insert */MLOG_REC_INSERT_8027 = 9,/** Mark clustered index record deleted */MLOG_REC_CLUST_DELETE_MARK_8027 = 10,/** Mark secondary index record deleted */MLOG_REC_SEC_DELETE_MARK = 11,/** update of a record, preserves record field sizes */MLOG_REC_UPDATE_IN_PLACE_8027 = 13,
/*!< Delete a record from a page */MLOG_REC_DELETE_8027 = 14,/** Delete record list end on index page */MLOG_LIST_END_DELETE_8027 = 15,/** Delete record list start on index page */MLOG_LIST_START_DELETE_8027 = 16,/** Copy record list end to a new created index page */MLOG_LIST_END_COPY_CREATED_8027 = 17,/** Reorganize an index page in ROW_FORMAT=REDUNDANT */MLOG_PAGE_REORGANIZE_8027 = 18,/** Create an index page */MLOG_PAGE_CREATE = 19,/** Insert entry in an undo log */MLOG_UNDO_INSERT = 20,/** erase an undo log page end */MLOG_UNDO_ERASE_END = 21,/** initialize a page in an undo log */MLOG_UNDO_INIT = 22,/** reuse an insert undo log header */MLOG_UNDO_HDR_REUSE = 24,/** create an undo log header */MLOG_UNDO_HDR_CREATE = 25,/** mark an index record as the predefined minimum record */MLOG_REC_MIN_MARK = 26,/** initialize an ibuf bitmap page */MLOG_IBUF_BITMAP_INIT = 27,
#ifdef UNIV_LOG_LSN_DEBUG/** Current LSN */MLOG_LSN = 28,
#endif /* UNIV_LOG_LSN_DEBUG *//** this means that a file page is taken into use and the priorcontents of the page should be ignored: in recovery we must not
trust the lsn values stored to the file page.Note: it's deprecated because it causes crash recovery problemin bulk create index, and actually we don't need to reset pagelsn in recv_recover_page_func() now. */MLOG_INIT_FILE_PAGE = 29,/** write a string to a page */MLOG_WRITE_STRING = 30,/** If a single mtr writes several log records, this logrecord ends the sequence of these records */MLOG_MULTI_REC_END = 31,/** dummy log record used to pad a log block full */MLOG_DUMMY_RECORD = 32,/** log record about creating an .ibd file, with format */MLOG_FILE_CREATE = 33,/** rename a tablespace file that starts with (space_id,page_no) */MLOG_FILE_RENAME = 34,/** delete a tablespace file that starts with (space_id,page_no) */MLOG_FILE_DELETE = 35,/** mark a compact index record as the predefined minimum record */MLOG_COMP_REC_MIN_MARK = 36,/** create a compact index page */MLOG_COMP_PAGE_CREATE = 37,/** compact record insert */MLOG_COMP_REC_INSERT_8027 = 38,/** mark compact clustered index record deleted */MLOG_COMP_REC_CLUST_DELETE_MARK_8027 = 39,/** mark compact secondary index record deleted; this logrecord type is redundant, as MLOG_REC_SEC_DELETE_MARK isindependent of the record format. */MLOG_COMP_REC_SEC_DELETE_MARK = 40,/** update of a compact record, preserves record field sizes */MLOG_COMP_REC_UPDATE_IN_PLACE_8027 = 41,/** delete a compact record from a page */MLOG_COMP_REC_DELETE_8027 = 42,
/** delete compact record list end on index page */MLOG_COMP_LIST_END_DELETE_8027 = 43,/*** delete compact record list start on index page */MLOG_COMP_LIST_START_DELETE_8027 = 44,/** copy compact record list end to a new created index page */MLOG_COMP_LIST_END_COPY_CREATED_8027 = 45,/** reorganize an index page */MLOG_COMP_PAGE_REORGANIZE_8027 = 46,/** write the node pointer of a record on a compressednon-leaf B-tree page */MLOG_ZIP_WRITE_NODE_PTR = 48,/** write the BLOB pointer of an externally stored columnon a compressed page */MLOG_ZIP_WRITE_BLOB_PTR = 49,/** write to compressed page header */MLOG_ZIP_WRITE_HEADER = 50,/** compress an index page */MLOG_ZIP_PAGE_COMPRESS = 51,/** compress an index page without logging it's image */MLOG_ZIP_PAGE_COMPRESS_NO_DATA_8027 = 52,/** reorganize a compressed page */MLOG_ZIP_PAGE_REORGANIZE_8027 = 53,/** Create a R-Tree index page */MLOG_PAGE_CREATE_RTREE = 57,/** create a R-tree compact page */MLOG_COMP_PAGE_CREATE_RTREE = 58,/** this means that a file page is taken into use.We use it to replace MLOG_INIT_FILE_PAGE. */MLOG_INIT_FILE_PAGE2 = 59,/** Table is being truncated. (Marked only for file-per-table) *//* MLOG_TRUNCATE = 60, Disabled for WL6378 *//** notify that an index tree is being loaded without writing
redo log about individual pages */MLOG_INDEX_LOAD = 61,/** log for some persistent dynamic metadata change */MLOG_TABLE_DYNAMIC_META = 62,/** create a SDI index page */MLOG_PAGE_CREATE_SDI = 63,/** create a SDI compact page */MLOG_COMP_PAGE_CREATE_SDI = 64,/** Extend the space */MLOG_FILE_EXTEND = 65,/** Used in tests of redo log. It must never be used outside unit tests. */MLOG_TEST = 66,MLOG_REC_INSERT = 67,MLOG_REC_CLUST_DELETE_MARK = 68,MLOG_REC_DELETE = 69,MLOG_REC_UPDATE_IN_PLACE = 70,MLOG_LIST_END_COPY_CREATED = 71,MLOG_PAGE_REORGANIZE = 72,MLOG_ZIP_PAGE_REORGANIZE = 73,MLOG_ZIP_PAGE_COMPRESS_NO_DATA = 74,MLOG_LIST_END_DELETE = 75,MLOG_LIST_START_DELETE = 76,/** biggest value (used in assertions) */MLOG_BIGGEST_TYPE = MLOG_LIST_START_DELETE
};
// 省略...
解答问题:
RedoLog的类型根据数据操作的不同场景和对⽇志的优化⽅式有⼏⼗种之多,总体可以分为:(1)⽤于数据⻚的⽇志类型,⽐如对数据⻚的修改(2)⽤于表空间⽂件的⽇志类型,⽐如对表空间的修改(3)提供额外信息的⽇志类型
相关文章:
InnoDB 存储引擎<五>undo log, redo log,以及双写缓冲区
目录 撤销⽇志 - Undo Log 双写缓冲区 - Doublewrite Buffer 重做⽇志 - Redo Log 本篇是继承自上篇InnoDB存储引擎的磁盘文件 上篇链接:InnoDB 存储引擎<四>磁盘文件一 撤销⽇志 - Undo Log 1.什么是撤销⽇志? 解答问题&a…...
Find My运动耳机|苹果Find My技术与耳机结合,智能防丢,全球定位
运动耳机是为运动时候佩带的耳机,而是一种区别于一般耳机的能稳定固定在佩戴部位的耳机,该种耳机不会因为身体运动而使耳机从耳朵里掉落,普遍带有防滴溅、轻便等特性,透气性能较好,属于开放式耳机。 在智能化加持下&…...
书生大模型实战营Linux+InternStudio 关卡任务
一、端口映射 使用以下命令进行端口映射 ssh -p {YOUR_PORT} rootssh.intern-ai.org.cn -CNg -L 7860:127.0.0.1:7860 -o StrictHostKeyCheckingno 命令解释: -p 37367:是指定 SSH 连接的端口为 37367。rootssh.intern-ai.org.cn:表示要以…...
研究实锤:别让大模型「想」太多,OpenAI o1准确率竟下降36.3%
思维链(CoT)已被证明可以在许多任务(如多步骤推理)上显著提升大模型的性能。然而,在哪些情况下,CoT 会系统性地降低大模型的性能,这仍然是一个有待进一步讨论的问题。 如今,来自普林…...
C++游戏开发
C游戏开发概述 C 是游戏开发中的主要编程语言之一,因其性能、控制和广泛的生态系统而受到开发者的青睐。随着游戏行业的迅速发展,C 被用来构建许多成功的游戏和游戏引擎。本文将深入探讨 C 在游戏开发中的应用,包括基础概念、技术栈、示例代…...
ChatGPT中的RAG;大模型微调;通过正确的提问和回答数据进行问答系统的微调;
目录 ChatGPT中的RAG 1.检索器: 2.生成器: 3.结合使用: 大模型微调 通过正确的提问和回答数据进行问答系统的微调 ChatGPT中的RAG 在ChatGPT中,RAG(Retrieval-Augmented Generation)是一种结合了检索与生成的技术,旨在提高模型的回答质量和准确性。 RAG模型通常由两个…...
6款IntelliJ IDEA插件,让Spring和Java开发如虎添翼
文章目录 1、SonarLint2、JRebel for IntelliJ3、SwaggerHub插件4、Lombok插件5、RestfulTool插件6、 Json2Pojo插件7、结论 对于任何Spring Boot开发者来说,两个首要的目标是最大限度地提高工作效率和确保高质量代码。IntelliJ IDEA 是目前最广泛使用的集成开发环境…...
源代码加密解决方案:文档加密与沙盒加密的比较分析
源代码加密是保护企业知识产权和市场竞争力的关键手段。在众多源代码加密技术中,文档加密类软件和沙盒加密类软件SDC是两种重要的解决方案。以下是对这两种技术的分析: 文档加密类软件: 这类软件主要采用APIHOOK应用层透明加密技术࿰…...
Spring Boot 与 Vue 共筑高校网上订餐卓越平台
作者介绍:✌️大厂全栈码农|毕设实战开发,专注于大学生项目实战开发、讲解和毕业答疑辅导。 🍅获取源码联系方式请查看文末🍅 推荐订阅精彩专栏 👇🏻 避免错过下次更新 Springboot项目精选实战案例 更多项目…...
【数据仓库】Hive 拉链表实践
背景 拉链表是一种数据模型,主要是针对数据仓库设计中表存储数据的方式而定义的;顾名思义,所谓拉链表,就是记录历史。记录一个事务从开始一直到当前状态的所有变化的信息。 拉链表可以避免按每一天存储所有记录造成的海量存储问题…...
【python_pandas_将列表按照某几列进行分组,再求和,按照原列表的字段顺序返回】
说明: 1、按照[“行描述”,”‘公司代码’, ‘科目代码’, ‘预算项目代码’] 进行分组。 2、对“贷方”列进行求和。 3、最后按照之前的表头顺序进行排序,返回结果列表。 #-*- coding:utf-8-*import pandas as pd def consolidate_salary_provisions(l…...
Vue的双向绑定
Vue的双向绑定特性介绍 在现代前端开发中,数据的管理和UI的更新是至关重要的。Vue.js作为一个渐进式JavaScript框架,提供了强大的双向数据绑定机制,极大地简化了这些操作。在本文中,我们将深入探讨Vue的双向绑定特性。 什么是双…...
谷歌浏览器安装 Vue.js devtools 插件
文章目录 1. 安装2. 使用3. 注意 1. 安装 ① 搜索极简插件:https://chrome.zzzmh.cn/index ② 搜索框输入 Vue,选择 Vue.js devtools ③ 从历史版本里面选择并下载,选择 6.4 版本的就行 ④ 打开浏览器,右上角三个点 → 扩展程序…...
LWIP通信协议UDP发送、接收源码解析
1.UDP发送函数比较简短,带操作系统和裸机一样。以下是udp_sendto源码解析; 2.LWIP源码UDP接收数据 2.1.UDP带操作系统接收数据,以下是源码解析; 2.2.UDP裸机接收数据,以下是源码解析...
Linux—进程学习-01
目录 Linux—进程学习—11.冯诺依曼体系结构2.操作系统2.1操作系统的概念2.2操作系统的目的2.3如何理解管理2.4计算机软硬件体系的理解2.5系统调用和库函数的概念 3.进程3.1进程是什么3.2管理进程3.2.1描述进程-PCB3.2.2组织进程3.2.3总结 3.3查看进程 4.与进程有关的系统调用 …...
FR动态数据源插件支持配置模板中某个数据集进行数据连接的切换
1 需求背景 该插件的需求来源于官方帮助文档: 动态数据源/数据库- FineReport帮助文档 - 全面的报表使用教程和学习资料 官方的方案的缺点是会暴露数据库IP,端口密码等,不安全。...
epoll 技术为什么用rbtree而不用hashmap呢?
目录 1.epoll 技术为什么用rbtree而不用hashmap呢?2 .红黑树支持顺序遍历,这对于epoll的事件管理机制可能非常有用, 怎么理解 epoll 理解,可以参考这个 https://zhuanlan.zhihu.com/p/64746509 1.epoll 技术为什么用rbtree而不用…...
关于Android Studio Koala Feature Drop | 2024.1.2下载不了插件的解决办法
解决 androidStudio Settings->Plugins下载插件,点击install后没反应,同时插件描述相关显示不出来 第一步: 第二步: 点击设置,勾选Auto-detect proxy settings,输入网址 https://plugins.jetbrains.com…...
公共命名空间,2024年11月的笔记
进行类比思维。对于在电脑上显示字符的任务,需要字符集。曾经有人研究算法,希望编出一个神奇的程序,能够显示所有字符。但最终的结果是,需要字符集,人工地把所有字符收集起来,让电脑一个个记住,…...
登录功能设计(php+mysql)
一 登录功能 1. 创建一个登录页面(login.php),包含一个表单,用户输入用户名和密码。 2. 在表单的提交事件中,使用PHP代码处理用户输入的用户名和密码。 3. 首先,连接MySQL数据库。然后&a…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
