画图理解mysql日志机制

行文思路:理解总图->分别解析redo log->bin log->undo log

先放一张总图

redolog

1.redolog有单独的文件 可通过一些参数进行调整

innodb_log_files_in_group:设置 redo log 文件的个数,命名方式如: ib_logfile0, iblogfile1... iblogfileN。默认 2 个,最大 100 个。

sql 复制代码
show variables like '%innodb_log_files_in_group%';

innodb_log_file_size:设置单个 redo log 文件大小,默认值为 48M。最大值为 512G,注意最大值指的是整个 redo log 系列文件之和,即 (innodb_log_files_in_group * innodb_log_file_size) 不能大于最大值 512G。

sql 复制代码
show variables like '%innodb_log_file_size%';

2.redo log 写入磁盘过程分析:

redo log 从头开始写,写完一个文件继续写另一个文件,写到最后一个文件末尾就又回到第一个文件开头循环写。

  • write pos:是当前记录的位置,一边写一边后移,写到最后一个文件末尾后就回到 0 号文件开头。
  • checkpoint:是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件里。

write pos 和 checkpoint 之间的部分就是空着的可写部分,可以用来记录新的操作。如果 write pos 追上 checkpoint,表示 redo log 写满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。

3.redo log刷盘配置

innodb_flush_log_at_trx_commit:控制redo log刷盘策略,三种取值:

  • 设置为0:事务提交,日志留在redo log buffer;每秒后台线程统一刷OS缓存再落盘,数据库宕机丢数据。
  • 设置为1(默认):事务提交直接fsync落地磁盘,数据最安全,线上推荐,性能偏低。
  • 设置为2:事务提交写入OS的page cache,不落地磁盘;库宕不丢数据,操作系统整机宕机会丢缓存内日志。
  • 补充:InnoDB后台线程每秒1次,把redo log buffer数据write进page cache、再fsync持久磁盘。

binlog

1.binlog开启 MySQL5.7:binlog默认关闭;MySQL8.0:binlog默认开启,log_bin=OFF代表关闭binlog。 开启方式:修改my.ini(Windows)/my.cnf(Linux),在[mysqld]添加配置后重启服务。

重启后data目录生成2个文件: mysql-bin.000001:binlog数据日志 mysql-bin.index:binlog索引,记录所有binlog文件清单

2.binlog 的日志格式(参数:binlog_format)

  • STATEMENT:记录执行的原始 SQL,日志体积小性能高;含UUID()、SYSDATE()等动态函数时,主从执行结果不一致。
  • ROW:记录每行数据变更明细,规避函数主从异常;日志量大、IO 开销高。
  • MIXED:混合模式,普通 SQL 用 STATEMENT,含不确定结果函数自动切 ROW,生产推荐。

3.binlog 刷盘策略(参数:sync_binlog,默认 0)

  • 0:事务提交只写到 OS page cache,系统自主落盘;性能好,宕机会丢缓存内 binlog。
  • 1:每次提交立刻 fsync 落地磁盘;最安全,生产标配。
  • N (N>1):提交写缓存,攒 N 个事务再统一落盘;宕机最多丢 N 个事务日志。

4.binlog 新建文件触发条件

  1. MySQL 服务启停
  2. 手动执行flush logs;
  3. 文件达到max_binlog_size(默认 1GB)

5.日志恢复数据

原理:回放 binlog 内记录的 SQL,找回误删数据

两种恢复方式

按 pos 点位恢复(推荐)

css 复制代码
mysqlbinlog --no-defaults --start-position=219 --stop-position=701 --database=test 日志路径 | mysql -uroot -p123456 -v test

按时间恢复

bash 复制代码
mysqlbinlog --no-defaults --start-datetime="2023-1-27 23:32:24" --stop-datetime="2023-1-27 23:34:23" --database=test 日志路径 | mysql -uroot -p123456 -v test

数据恢复规范

  1. 纯靠全量 binlog 恢复整库极少用(binlog 量大、早期日志常过期清理)
  2. 生产标准方案:每日全量备份 (mysqldump) + 备份后 binlog 增量恢复

undo log

undo log 回滚日志InnoDB 对 undo log 文件的管理采用段的方式,也就是回滚段(rollback segment)。每个回滚段记录了 1024 个 undo log segment,每个事务只会使用一个 undo log segment。

在 MySQL5.5 的时候,只有一个回滚段,那么最大同时支持的事务数量为 1024 个。在 MySQL 5.6 开始,InnoDB 支持最大 128 个回滚段,故其支持同时在线的事务限制提高到了 128*1024。

1 innodb_undo_directory:设置 undo log 文件所在的路径。该参数的默认值为 "./",即 innodb 数据文件存储位置,目录下 ibdata1 文件就是 undo log 存储的位置。

2 innodb_undo_logs:设置 undo log 文件内部回滚段的个数,默认值为 128。

3 innodb_undo_tablespaces:设置 undo log 文件的数量,这样回滚段可以较为平均地分布在多个文件中。设置该参数后,会在路径 innodb_undo_directory 看到 undo 为前缀的文件。

undo log 日志什么时候删除新增类型的,在事务提交之后就可以清除掉了。修改类型的,事务提交之后不能立即清除掉,这些日志会用于 mvcc。只有当没有事务用到该版本信息时才可以清除。

相关推荐
huzhongqiang1 小时前
120行代码实现一个极简 Agent
后端·agent
XIAOHEZIcode1 小时前
进程、会话与终端——一次真实的 Linux Session 解剖
linux·后端·命令行
javahongxi1 小时前
Spring Cloud Trace 链路实现
java·spring boot·spring cloud
枕星而眠1 小时前
【数据结构】树与二叉树基础知识点总结
数据结构·c++·后端·算法·运维开发
海梨花1 小时前
腾讯面试高频算法题
java·算法·面试
于先生吖1 小时前
Java消息队列优化抢单逻辑,同城搬家拉货多场景业务数据库架构设计
java·开发语言·数据库架构
极光技术熊1 小时前
从零构建在线Excel:一个Java全栈工程师的实战记录
前端·后端
小谢小哥1 小时前
68-持续集成详解
java·后端·架构