欢送来到 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 公布!