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

这边会介绍MySQL中的两种更新日志,binlog和InnoDB的redo log,这两块是MySQL比较重要也跑不掉的两个知识点。

binlog

介绍

binlog主要是数据库server层的东西在
mysql基础架构 有讲到server层和储存引擎层的一些关系。binlog给MySQL带来了crash-safe的能力(crash-safe这块DBA接触的比较多也比较偏运维,简单来说我的理解就是保证已提交事务数据依然存在,未提交事务自动回滚。其实单库还好主从同步的时候可以避免一些链路中断的情况)

启用

修改配置文件 mysql.cnf

1
2
3
4
5
6
7
8
9
10
11
#第一种方式
#开启binlog日志
log_bin=ON
#binlog日志的基本文件名
log_bin_basename=/var/lib/mysql/mysql-bin
#binlog文件的索引文件,管理所有binlog文件
log_bin_index=/var/lib/mysql/mysql-bin.index

#第二种方式,等同于上面三行
log-bin=/var/lib/mysql/mysql-bin
binlog_format = row #行的日志格式

查看binlog是否正常启用

1
show variables like '%log_bin%';

binlog的几种数据格式

格式 格式介绍 优点 缺点
STATEMENT(SBR) 记录每一句sql语句 日志量相对较小 必须记录上下文UUID等随机函数哦豁
ROW(RBR) 行的复制 每一条记录记录更安全,每一行修改更高效,数据恢复更方便 日志量大
MIXED 上面的混合 系统决定用行或段,数据量大小由sql决定 -

redo log

介绍

redo log 是InnoDB引擎的日志,它实现了Write-Ahead Logging(WAL)技术,顾名思义它是预写入日志,保证了即使异常重启数据也不会丢失(crash-safe)。它可以设置文件大小与文件个数,比如一个文件1G一共4个redo log文件,它会在满足一定规律后进行刷盘操作checkpoint。InnoDB的事物也是依赖于redo logundo log进行的。

binlog 和 redo log的差异

名称|引擎|大小|
:-:|:-:
redo log|InnoDB|循环写入刷入磁盘
binlog|mysql server层|累加

一条update语句在日志中的操作

1.执行器先找引擎取ID=2的一行,引擎直接用搜索树找到这条数据,如果在内存中直接返回没在磁盘中读入内存返回。
2.执行器拿到引擎行数据,直接加1操作得到新的一行,再调用引擎接口写入这行数据
3.引擎讲数据更新到内存中,同时记录redo log,此时redo log处于prepare状态,告知执行器完成随时可以提交事务。
4.执行器生成这个操作的binlog,并写入磁盘
5.执行器调用引擎提交事务,引擎redo log改成提交状态

总结

  • 这边采用了一个分段提交,增加了binlog日志的准确性,是维持数据逻辑一致性的常用方案
  • 数据恢复/数据库扩容 是先同步当天备份后同步binlog日志
  • redo log 用于保证crash-safe能力
  • innodb_flush_log_at_trx_commit sync_binlog 建议设为1保证数据不被丢失
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

请我喝杯咖啡吧~