96SEO 2026-02-20 09:08 10
。

但是偏偏有时候事务执行到一半会出现一些情况#xff0c;比如#xff1a;
情况一#xff1a;事务执行过程中可能遇到各种错误也就是事务中的操作要么全部完成要么什么也不做。
但是偏偏有时候事务执行到一半会出现一些情况比如
情况一事务执行过程中可能遇到各种错误比如服务器本身的错误操作系统错误甚至是突然断电导致的错误。
这两种情况都会导致事务执行到一半就结束但是事务执行过程中可能已经修改了很多东西为了保证事务的原子性我们需要把东西改回原先的样子这个过程就称之为回滚英文名rollback这样就可以造成这个事务看起来什么都没做所以符合原子性要求。
INSERT、DELETE、UPDATE都需要把回滚时所需的东西都给记下来。
比方说
你插入一条记录时至少要把这条记录的主键值记下来之后回滚的时候只需要把这个主键值对应的记录删掉。
你删除了一条记录至少要把这条记录中的内容都记下来这样之后回滚时再把由这些内容组成的记录插入到表中。
你修改了一条记录至少要把修改这条记录前的旧值都记录下来这样之后回滚时再把这条记录更新为旧值。
log/undo日志。
这里需要注意的一点是由于查询操作SELECT并不会修改任何用户记录所以在查询操作执行时并不需要记录相应的
在只读事务中不可以对普通的表其他事务也能访问到的表进行增、删、改操作但可以对用户临时表做增、删、改操作。
对于只读事务来说只有在它第一次对某个用户创建的临时表执行增、删、改操作时才会为这个事务分配一个事务
的提示这个表明在执行该查询语句时会用到内部临时表。
这个所谓的内部临时表和我们手动用
对于读写事务来说只有在它第一次对某个表包括用户创建的临时表执行增、删、改操作时才会为这个事务分配一个事务
有的时候虽然我们开启了一个读写事务但是在这个事务中全是查询语句并没有执行增、删、改的语句那也就意味着这个事务并不会被分配一个事务
服务器会在内存中维护一个全局变量每当需要为某个事务分配一个事务
之后赋值给我们前边提到的全局变量因为在上次关机时该全局变量的值可能大于
记录行格式的时候重点强调过聚簇索引的记录除了会保存完整的用户数据以外而且还会自动添加名为
一个事务在执行过程中可能新增、删除、更新若干条记录也就是说需要记录很多条对应的
当我们向表中插入一条记录时最终导致的结果就是这条记录被放到了一个
数据页中。
如果希望回滚这个插入操作那么把这条记录删除就好了也就是说在写对应的
日志中只需要把该列占用的存储空间大小和真实值记录下来如果记录中的主键包含多个列那么每个列占用的存储空间大小和对应的真实值都需要记录下来。
当我们向某个表中插入一条记录时实际上需要向聚簇索引和所有的二级索引都插入一条记录。
不过记录
日志时我们只需要考虑向聚簇索引插入记录时的情况就好了因为其实聚簇索引记录和二级索引记录是一一对应的我们在回滚插入操作时只需要知道这条记录的主键信息然后根据主键信息做对应的删除操作做删除操作时就会顺带着把所有二级索引中相应的记录也删除掉。
属性组成一个单向链表我们把这个链表称之为正常记录链表被删除的记录其实也会根据记录头信息中的
属性组成一个链表只不过这个链表中的记录占用的存储空间可以被重新利用所以也称这个链表为垃圾链表。
Page
语句把正常记录链表中的最后一条记录给删除掉其实这个删除的过程需要经历两个阶段
阶段一将记录的delete_mask标识位设置为1这个阶段称之为delete
1但是并没有被加入到垃圾链表。
也就是此时记录处于一个中间状态。
在删除语句所在的事务提交之前被删除的记录一直都处于这种所谓的中间状态。
阶段二当该删除语句所在的事务提交之后会有专门的线程后来真正的把记录删除掉。
所谓真正的删除就是把该记录从正常记录链表中移除并且加入到垃圾链表中然后还要调整一些页面的其他信息比如页面中的用户记录数量PAGE_N_RECS、上次插入记录的位置PAGE_LAST_INSERT、垃圾链表头节点的指针
PAGE_GARBAGE、还有页目录的一些信息等等。
这个阶段称之为
把阶段二执行完了这条记录就算是真正的被删除掉了。
这条已删除记录占用的存储空间也可以被重新利用了。
从上边的描述中我们也可以看出来在删除语句所在的事务提交之前只会经历阶段一也就是
阶段提交之后我们就不用回滚了所以只需考虑对删除操作的阶段一做的影响进行回滚。
InnoDB
中就会产生一种称之为TRX_UNDO_DEL_MARK_REC
日志。
比方说在一个事务中我们先插入了一条记录然后又执行对该记录的删除操作这个过程的示意图就是这样
在不更新主键的情况下又可以细分为被更新的列占用的存储空间不发生变化和发生变化的情况。
更新记录时对于被更新的每个列来说如果更新后的列和更新前的列占用的存储空间都一样大那么就可以进行就地更新也就是直接在原记录的基础上修改对应列的值。
再次强调一边是每个列在更新前后占用的存储空间一样大有任何一个被更新的列更新前比更新后占用的存储空间大或者更新前比更新后占用的存储空间小都不能进行就地更新。
在不更新主键的情况下如果有任何一个被更新的列更新前和更新后占用的存储空间大小不一致那么就需要先把这条旧的记录从聚簇索引页面中删除掉然后再根据更新后列的值创建一条新的记录插入到页面中。
操作而是真正的删除掉也就是把这条记录从正常记录链表中移除并加入到垃圾链表中并且修改页面中相应的统计信息比如
等这些信息。
由用户线程同步执行真正的删除操作真正删除之后紧接着就要根据各个列更新后的值创建的新记录插入。
这里如果新创建的记录占用的存储空间大小不超过旧记录占用的空间那么可以直接重用被加入到垃圾链表中的旧记录所占用的存储空间否则的话需要在页面中新申请一段空间以供新记录使用如果本页面内已经没有可用的空间的话那就需要进行页面分裂操作然后再插入新记录。
不更新主键的情况包括上边所说的就地更新和先删除旧记录再插入新记录InnoDB
在聚簇索引中记录是按照主键值的大小连成了一个单向链表的如果我们更新了某条记录的主键值意味着这条记录在聚簇索引中的位置将会发生改变比如你将记录的主键值从
之间的话那么这两条记录在聚簇索引中就有可能离得非常远甚至中间隔了好多个页面。
针对
操作把它加入到垃圾链表中。
这里一定要和我们上边所说的在不更新记录主键值时先真正删除旧记录再插入新记录的方式区分开
操作是因为别的事务同时也可能访问这条记录如果把它真正的删除加入到垃圾链表后别的事务就访问不到了。
这个功能就是所谓的
根据更新后各列的值创建一条新记录并将其插入到聚簇索引中需重新定位插入的位置。
由于更新后的记录主键值发生了改变所以需要重新从聚簇索引中定位这条记录所在的位置然后把它插进去。
我们前边说明表空间的时候说过表空间其实是由许许多多的页面构成的页面默认大小为
的页面用于存储表空间头部信息的还有其他各种类型的页面其中有一种称之为FIL_PAGE_UNDO_LOG
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback