乐趣区

关于mysql:技术分析-通过DML语句浅谈binlog和redo-log

欢送来到 GreatSQL 社区分享的 MySQL 技术文章,如有疑难或想学习的内容,能够在下方评论区留言,看到后会进行解答

  • GreatSQL 社区原创内容未经受权不得随便应用,转载请分割小编并注明起源。

1. 导言

咱们在采纳 InnoDB 引擎的状况下,编写 SQL 语句 WHERE 条件的时候,能够通过 AND 操作符来进步数据的过滤能力,当然,在应用 AND 操作符也有许多须要留神的中央,就好比一条更新语句:

mysql>update testtable set price = 52.0,name = 'test_name';

本意是将表内对应字段重置为指定信息,可是当初不小心写成了:

mysql>update testtable set price = 52.0 and name = 'test_name';

这个时候,咱们查看表发现:

mysql> select * from testtable;
+----+----------+------------+
| id | name     | price      |
+----+----------+------------+
| 1  | old_name |  0.00      |
| 2  | old_name |  0.00      |
+----+----------+------------+

显然,零碎会把 AND 当做判断条件进行逻辑判断,这里所有列都不满足条件,所以后果为 0。此时,咱们能够利用事务回滚个性,回滚这个 update,而为了更好地了解,咱们须要从新来看看这一条 update 语句

2. binlog 和 redo log

现有一条 SQL 语句:

mysql>update testtable set price = price + 1 where id = 5;

咱们晓得,这条语句在分析器是进行词法和语法解析,并且晓得这是一条更新语句。并由优化器决定要应用 id 这个索引。而后,执行器负责具体执行,找到这一行,而后更新。说到更新流程,说到更新操作,咱们不得不提到两个日志模块:binlog 和 redo log

2.1 binlog

先来说一说 binlog,该日志存在于 Server 档次中,是应用存储引擎都能够应用的日志模块,binlog 是逻辑日志,记录的是这个语句的原始逻辑,比方“给 id= 5 这一行的 price 字段值加 1”
binlog 的日志文件是能够追加写入的。“追加写入”是指 binlog 日志文件写到肯定大小后会切换到下一个文件进行写入,能够设置 sync_binlog 为 1,让每次事务的 binlog 都长久化保留到磁盘中

2.2 redo log

而重做日志 redo log 是 MySQL 中 InnoDB 引擎才有的日志,它是物理日志,即记录的内容是“在某个数据页上做了什么批改“

MySQL 对于每一次的更新操作如果都须要写进磁盘,而后磁盘也要找到对应的那条记录,而后再更新,过程中的 IO 老本、查找老本都很高。redo log 无效的晋升了更新效率

redo log 是固定大小的,比方能够配置为一组 4 个文件,每个文件的大小是 1GB,那么总共就能够有 4GB 的空间去记录咱们进行的操作。从头开始写,写到开端就又回到结尾循环写,如下图:

write pos 是以后记录的地位,一边写一边后移,写到第 log_3 文件开端后就回到 log_0 文件结尾。checkpoint 是以后要开释的地位,也是往后推移并且循环的,开释记录前要把记录更新到数据文件。如果 write pos 追上 checkpoint,那就表明全副空间都满了,这时候不能再执行新的更新,得停下来先开释掉一些地位,让 checkpoint 持续推动

当有一条记录须要更新的时候,InnoDB 引擎就会先将数据更新到内存,再把记录写到 redo log 外面,这个时候更新就算实现了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘外面,而这个更新往往是在零碎比拟闲暇的时候做, 能够设置 innodb_flush_log_at_trx_commit 为 1,示意每次事务的 redo log 都间接长久化到磁盘中

2.3 binlog 和 redo log 的区别

3. InnoDB 引擎下模仿执行过程

可参考下图:

  • 执行器先通过引擎取到 id= 5 的这一行。id 是为该表主键,因而引擎依据 BTREE 索引查找找到 id= 5 的这一行。如果该行所在的数据页原本就在内存中,就间接返回给执行器;否则,须要先从磁盘读入内存,而后再返回
  • 执行器拿到引擎给的行数据,把 price 值加上 1,失去新的一行数据,再调用引擎接口写入这行新数据
  • 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 外面,此时 redo log 处于 prepare 状态。而后告知执行器执行实现了,随时能够提交事务。执行器生成这个操作的 binlog,并把 binlog 写入磁盘
  • 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交 commit 状态,更新实现

Enjoy GreatSQL :)

文章举荐:

GreatSQL MGR FAQ
https://mp.weixin.qq.com/s/J6…

万答 #12,MGR 整个集群挂掉后,如何能力主动选主,不必手动干涉
https://mp.weixin.qq.com/s/07…

『2021 数据技术嘉年华·ON LINE』:《MySQL 高可用架构演进及实际》
https://mp.weixin.qq.com/s/u7…

一条 sql 语句慢在哪之抓包剖析
https://mp.weixin.qq.com/s/AY…

万答 #15,都有哪些状况可能导致 MGR 服务无奈启动
https://mp.weixin.qq.com/s/in…

技术分享 | 为什么 MGR 一致性模式不举荐 AFTER
https://mp.weixin.qq.com/s/rN…

对于 GreatSQL

GreatSQL 是由万里数据库保护的 MySQL 分支,专一于晋升 MGR 可靠性及性能,反对 InnoDB 并行查问个性,是实用于金融级利用的 MySQL 分支版本。

Gitee:
https://gitee.com/GreatSQL/Gr…

GitHub:
https://github.com/GreatSQL/G…

Bilibili:
https://space.bilibili.com/13…

微信 &QQ 群:
可搜寻增加 GreatSQL 社区助手微信好友,发送验证信息“加群”退出 GreatSQL/MGR 交换微信群

QQ 群:533341697
微信小助手:wanlidbc

本文由博客一文多发平台 OpenWrite 公布!

退出移动版