首页 > 数据库 >SQL更新执行流程

SQL更新执行流程

时间:2024-03-28 16:23:22浏览次数:27  
标签:binlog log redolog 流程 更新 提交 SQL 日志 数据

SQL 的更新执行流程跟查询流程差不多,假设现在有一条更新语句:UPDATE T SET c = 1 WHERE ID = 1

  • 客户端连接到 MySQL 服务,通过连接器创建连接,权限验证
  • 在更新语句时候,会清空该表的所有查询缓存器数据
  • 之后就是通过分析器进行词法分析和语法分析,查看更新语句是否存在问题
  • 在通过优化器选择索引,找到最合理的执行计划
  • 执行器负责执行,在存储引擎中找到 ID=1 这一行,然后更新

与查询流程不一样的是,更新流程还涉及到两个重要的日志模块:redolog(重做日志)和 binlog(归档日志),这两个日志也是这篇文章重点讨论的。

先来一张图整体看下流程是怎么样的:

一、redolog

1. 什么是 redolog

redolog 是 InnoDB 存储引擎独有的,是保证事物持久性的重要机制。当 mysql 意外宕机或崩溃时,保证已提交的事物,确定持久化到磁盘的一种措施,防止数据丢失;

2. redolog 的作用

Mysql 的数据是以页为单位(16KB),查询一条数据,会从硬盘中把一页的数据都加载出来,加载出来的数据叫做数据页,会放入 Buffer Pool 中,后续的查询都是从 Buffer Pool 中找,如果没有命中再从磁盘中加载,减少硬盘 IO 开销,更新数据也是如此,发现 Buffer Pool 有需要更新的数据,则直接在 Buffer Pool 中进行更新

假设我们只在内存的 Buffer Pool 中更新了页数据,事物提交后突然数据库崩溃,导致内存中的数据丢失了,那么这个更新后的数据也一起丢失了,这肯定是不能接受的。那我们要怎么保证数据的持久性呢?有一个方法就是每次事物提交的时候把该次事物提交修改的所有数据页都更新到磁盘中,但是这样做有一个问题:

  • 仅仅修改了一条记录,却要把整个数据页更新回去,有点浪费
  • 一个事物中可能会包含多条 sql 语句,这些语句可能会对 Buffer Pool 中不相邻的数据页进行操作。当把该事物修改的数据页刷新到磁盘中会产生很多随机 IO,随机 IO 的开销要大于顺序 IO

由于以上种种原因,我们的想法就是想保存事物提交后的数据,即使在数据库崩溃,重启后也能恢复事物提交后的数据;

所以我们可以在事物提交的时候,只需要把这次事物提交修改的数据记录一下,比如:

将第 0 号表空间第 100 号页面中偏移量为 1000 处的值更新为 2。

这就是我们所说的redolog日志,即使数据库崩溃了,重启后只要根据redolog日志恢复即可

innodb_flush_log_at_trx_commit这个参数设置成1的时候,
表示每次事务的redo log都直接持久化到磁盘。这个参数设置成1,这样可以保证MySQL异常重启之后数据不丢失

二、binlog

binlog记录的是语句的原始逻辑,insert inot value(1,2,3)这种语句,所以Mysql数据的数据备份,主备等都离不开binlog日志,需要通过binlog日志来实现数据一致性。

  • binlog是MySQL的Server层实现的,所有引擎都可以使用。
  • binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”。
  • binlog是可以追加写入的。“追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
  • sync_binlog参数设置为1的时候,提交事物的时候就会写入到binlog日志,跟redolog日志刷盘时机是一样的

三、二阶段提交

为什么必须有“两阶段提交”呢?这是为了让两份日志之间的逻辑一致

1. 不使用二阶段提交

如果只写一次的话,那到底先写bin-log还是redo-log呢?

  • 先写bin-log,再写redo-log:当事务提交后,先写bin-log成功,结果在写redo-log时断电宕机了,再重启后由于redo-log中没有该事务的日志记录,因此不会恢复该事务提交的数据。但要注意,主从架构中同步数据是使用bin-log来实现的,而宕机前bin-log写入成功了,就代表这个事务提交的数据会被同步到从机,也就意味着从机会比主机多出一条数据
  • 先写redo-log,再写bin-log:当事务提交后,先写redo-log成功,但在写bin-log时宕机了,主节点重启后,会根据redo-log恢复数据,但从机依旧是依赖bin-log来同步数据的,因此从机无法将这个事务提交的数据同步过去,毕竟bin-log中没有撒,最终从机会比主机少一条数据

2. 使用二阶段提交

为了避免以上的数据不一致问题,Innodb存储引擎使用的两阶段提交方案。
把redolog的写入拆成了两个步骤prepare和commit

  • 如果在binlog日志写入过程中发生了异常,因为mysql通过redolog回复数据时,发现redolog还在prepare阶段,并且没有对应的binlog日志,就会回滚;
  • 如果在redolog提交commit时异常时,虽然redolog处于prepare阶段,但是能通过事物id找到对应的binlog日志,所以mysql认为数据时完整的,就会提交redolog日志,恢复数据;

3.两阶段提交有什么问题

binlog 和 redolog 在内存中都对应的缓存空间,binlog 会缓存在 binlog cache,redolog 会缓存在 redolog buffer,它们持久化到磁盘的时机分别由下面这两个参数控制。
一般我们为了避免日志丢失的风险,会将这两个参数设置为 1:

  • 当 sync_binlog = 1 的时候,表示每次提交事务都会将 binlog cache 里的 binlog 直接持久到磁盘;
  • 当 innodb_flush_log_at_trx_commit = 1 时,表示每次事务提交时,都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘;

可以看到,如果 sync_binlog 和 当 innodb_flush_log_at_trx_commit 都设置为 1,那么在每个事务提交过程中, 都会至少调用 2 次刷盘操作,一次是 redo log 刷盘,一次是 binlog 落盘,所以这会成为性能瓶颈。


我是一零贰肆,一个关注Java技术和记录生活的博主。

欢迎扫码关注“一零贰肆”的公众号,一起学习,共同进步,多看路,少踩坑。

标签:binlog,log,redolog,流程,更新,提交,SQL,日志,数据
From: https://www.cnblogs.com/sun2020/p/18101984

相关文章

  • BOSHIDA DC电源模块的设计与制造流程
    BOSHIDADC电源模块的设计与制造流程 DC电源模块是一种用于将交流电转换为直流电的设备。它广泛应用于各种电子设备中,如电子产品、工业仪器、电视等。下面是DC电源模块的设计与制造流程的简要描述: 1.需求分析:在设计DC电源模块之前,首先需要进行需求分析。这包括确定输出电......
  • MySQL索引18连问,谁能顶住
    前言过完这个节,就要进入金银季,准备了18道MySQL索引题,一定用得上。作者:感谢每一个支持:github1.索引是什么索引是一种数据结构,用来帮助提升查询和检索数据速度。可以理解为一本书的目录,帮助定位数据位置。索引是一个文件,它要占用物理空间。2.MySQL索引有哪些......
  • KingbaseES生成动态SQL
    1.动态SQL动态SQL在程序启动时会根据输入参数替换相应变量。使用动态SQL可以创建更强大和灵活的应用程序,但在编译时SQL语句的全文不确定,因此运行时编译会牺牲一些性能。动态SQL可以是代码或SQL语句的一部分,动态部分要么由开发人员输入,要么由程序本身创建。1.1动态SQL使用场景......
  • (毕业设计)基于Java+Vue+Mysql的网上订餐系统
    前言:网上订餐系统是一个综合性的在线服务平台,旨在为用户提供便捷的点餐、支付、配送等一体化服务。下面是对系统列出的各个功能模块的详细解释:一、个人中心个人中心是用户登录后的主要界面,展示用户的个人信息、订单记录、优惠券、积分等。用户可以在此查看并管理自己的账户......
  • (毕业设计)基于Java+Vue+Mysql的大学生租房平台
     前言:大学生租房平台是一个专门为大学生提供租房服务的在线平台。这个平台不仅简化了租房流程,还提供了多种功能,如房源搜索、在线沟通、合同签订等,让大学生能够轻松、安全地找到适合自己的房源。以下是针对系统列出的七个平台功能的详细解释:一、个人中心个人中心是用户在使......
  • (毕业设计)基于Java+Vue+Mysql的学生心理咨询评估系统
     前言:学生心理咨询评估系统是一个集成了多个功能模块的综合性系统,旨在为学生提供心理咨询服务和评估。以下是对系统的五个主要功能模块的详细解释:一、个人中心个人中心是用户的个人空间,主要用于展示和管理用户的基本信息、心理评估记录、咨询历史等。学生可以在这里查看自......
  • pgsql 批量操作
    批量写入INSERTINTOjinxudong.movie(name)VALUES('杨戬'),('沉香'),('西游记');doupdateset插入更新upsertonconflict(id)主键或者唯一索引相同存在则执行updateexcluded为虚拟表接受传过来的新值INSERTINTOjinxudong.movie(id,name)VALUES(7,'悟空1......
  • Flask python 开发篇:模型(model)Flask-SQLAlchemy的使用
    Flask-SQLAlchemy实现模型一、为什么使用模型?二、Flask-SQLAlchemy的引入三、使用Flask-SQLAlchemy构建模型文件3.1、安装扩展3.2、配置3.3、实战使用3.4、与蓝图相结合使用一、为什么使用模型?上一篇分享了蓝图的使用,也说蓝图相当于了php中控制器+路由的使用,那根......
  • Sql Sever 游标案例
    --声明变量DECLARE@IdNVARCHAR(100)DECLARE@indexintset@index=1--声明游标DECLAREMyCursorCURSORFORselectIdfromSheet3--打开游标OPENMyCursor--从游标中取得第一行数据FETCHNEXTFROMMyCursorINTO@Id--循环遍历游标中的所有行WHILE......
  • [转帖]Arm更新Neoverse产品路线图:N3/V3内核曝光,能效及AI性能大涨
    https://new.qq.com/rain/a/20240222A0495O00 +关注2月22日,半导体IP大厂Arm宣布推出新一代ArmNeoverse技术。其中包括,通过性能效率更优异的N系列新IP扩展ArmNeoverse计算子系统(CSS)产品路线图。与NeoverseCSSN2相比,NeoverseCSSN3的每瓦性能可提高......