MySQL日志系统:一条SQL更新语句是如何执行的?

1、提问

MySQL日志系统:一条SQL更新语句是如何执行的?

2、流程

大体来说,MySQL更新一条记录,要经历取和存两个过程。举例

update table set c=c+1 where id = 2;

要更新id=2的记录,首先需要从表中找到这条记录,在内存中完成更新后,最后刷新到磁盘中。

在这里插入图片描述

3、日志

3.1、redolog

MySQL的innodb特有的日志模块redolog,可以把它理解为一个固定大小的文件,遇到更新操作时,会把更新后的值记录在这个文件,空闲时间再刷新到磁盘。

这里有两个关键点:checkpoint和write pos,即write pos开始一直往右边写数据,checkpoint一直往右边擦数据,始终保持checkpoint不超过write pos。
在这里插入图片描述

3.2、binlog

MySQL的server层的日志模块binlog,是一个归档日志模块,记录的是逻辑日志,即在某一行某一字段加1,更直观就是SQL语句。

4、crash-safe

由于MySQL自带的引擎MyISAM无crash-safe功能,需引入innodb来实现crash-safe功能。即流程图中的两阶段提交。

试想下,如果没有两阶段提交,将会是什么现象:

  • 先写redolog,再写binlog
    写完redolog后,还没写binlog时,系统崩溃重启,导致binlog未被记录,如果用binlog恢复临时数据库时,则会少了一次更新。形象比喻,就是买东西,东西买了,但银行钱没有扣。

  • 先写binlog,再写redolog
    写完binlog后,还没写redolog时,系统崩溃重启,导致redolog未被记录,如果用binlog恢复临时数据库时,则会多了一次更新。形象比喻,就是东西没买成功,但银行钱扣了。

小结

MySQL 里面最重要的两个日志,即物理日志 redo log 和逻辑日志 binlog。

redo log 用于保证 crash-safe 能力。innodb_flush_log_at_trx_commit这个参数设置成 1 的时候,表示每次事务的 redo log 都直接持久化到磁盘。这个参数我建议你设置成 1,这样可以保证 MySQL 异常重启之后数据不丢失。sync_binlog这个参数设置成 1 的时候,表示每次事务的 binlog 都持久化到磁盘。这个参数我也建议你设置成 1,这样可以保证 MySQL 异常重启之后 binlog 不丢失。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值