前言
Binlog(Binary Log)是MySQL中至关重要的日志模块,它直接关系到数据恢复、主从复制等高阶架构设计。无论你是刚入门的新手还是有一定经验的开发者,掌握Binlog的原理和应用都是进阶的必经之路。
BinLog是什么?
Binlog全称Binary Log(二进制日志),以二进制的形式记录所有对数据库的数据修改操作(如DDL、DML),但不会记录单纯的查询(如SELECT)。
它是MySQL服务层的日志(与存储引擎无关),所有引擎的变更操作都会被记录。而事务日志(如InnoDB的Redo Log或Undo Log)则是innoDB引擎层专属。
Binlog的核心作用
- 数据恢复:若数据库意外宕机,可通过Binlog重放所有变更操作,恢复至宕机前的状态。
- 主从复制:主库将Binlog传输给从库,从库重放日志实现数据同步,支撑高可用架构。
bin log对数据备份、主从、主主等都起到了关键作用。
Binlog vs Redo Log:关键区别
对比维度 | Binlog | Redo Log |
---|---|---|
层级 | MySQL服务层生成 | InnoDB存储引擎生成 |
内容类型 | 逻辑日志(记录SQL逻辑) | 物理日志(记录数据页修改) |
用途 | 数据同步、恢复 | 崩溃恢复,保证事务持久性 |
写入时机 | 事务提交时一次性写入 | 事务执行中持续写入 |
Binlog写入机制
写入流程
- Step 1:事务执行时,Binlog暂存于线程的
内存缓存
(Binlog Cache
)。 - Step 2:事务提交时,缓存数据写入
系统缓存(Page Cache)
。 - Step 3:根据策略(sync_binlog参数),将Page Cache数据
刷盘
(fsync)到磁盘。
刷盘策略
- sync_binlog=0:依赖系统自动刷盘(性能高,宕机可能丢数据)。
- sync_binlog=1:每次提交事务强制刷盘(最安全,性能略低)。
- sync_binlog=N:累积N个事务后刷盘(平衡安全性与性能)。
redo log在事务执行过程中可以不断写入
bin log只有在提交事务时才写入
假如事务执行update T set c = 1 where id = 2
,在写完redo log日志后,bin log日志写期间发生了异常,会出现什么情况呢?
由于bin log没写完就异常,这时候bin log里面没有对应的修改记录。因此,之后用bin log日志恢复数据时,就会少这一次更新,恢复出来的这一行c值为0,而原库因为redo log日志恢复,这一行c的值是1,最终数据不一致
。
那有什么解决方案吗?二阶段提交方案。
为什么需要两阶段提交?
若Binlog与Redo Log写入不一致(如Binlog未写完时宕机),会导致主从数据差异。
InnoDB通过两阶段提交解决:
- Prepare阶段:Redo Log标记为“准备中”。
- Commit阶段:Binlog写入成功后,Redo Log标记为“已提交”。
若崩溃恢复时发现Redo Log未提交且无对应Binlog,则回滚事务,确保数据一致。
Binlog实战:查看与配置
查看日志位置
SHOW VARIABLES LIKE '%log_bin%'; -- 输出日志路径及配置
SHOW BINARY LOGS; -- 查看所有Binlog文件列表
- log_bin_basename: 是bin log日志的基本文件名,后面会追加标识来表示每一个文件
- log_bin_index: 是binlog文件的索引文件,这个文件管理了所有的binlog文件的目录
修改配置(my.cnf)
[mysqld]
log-bin = /var/lib/mysql/binlog # 日志存储路径
binlog_expire_logs_seconds = 604800 # 日志保留7天(单位:秒)
max_binlog_size = 100M # 单个日志文件最大100MB
查看日志内容
show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];
示例:
SHOW BINLOG EVENTS IN 'binlog.000001'; -- 解析指定Binlog文件
- IN ‘log_name’ :指定要查询的binlog文件名(不指定就是第一个binlog文件)
- FROM pos :指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算)
- LIMIT [offset] :偏移量(不指定就是0)
- row_count :查询总条数(不指定就是所有行)
Binlog的三种格式
格式 | 特点 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
Statement(默认) | 记录原始每一条SQL语句 | 日志量小,节约IO,提高性能 | sql中存在如now()等依赖环境的函数,会导致主从同步、恢复数据不一致 | 简单SQL,无函数依赖 |
Row | 记录每行数据的变更细节(哪一分区、哪一页、哪一行数据) | 兼容性强,解决Statement模式的缺点 | 一条ID<6000的update会导致同步的log很多,增加磁盘IO、网络带宽开销。 | 复杂操作(如含函数、触发器) |
Mixed混合模式 | 优先用Statement,无法保证一致性时自动切换为Row | 平衡日志量与安全性 |
总结
Binlog是MySQL数据安全的基石,掌握其原理和配置能助你:
- 高效实现数据恢复
- 搭建可靠的主从架构
- 深入理解MySQL内部机制