-
Binlog是什么?有哪几种格式?推荐使用哪种,为什么
Binlog是什么
- Binlog二进制日志是MySQL Server层记录所有更改数据库内容的操作日志的二进制文件,如操作UPDATE,DELETE,INSERT
- Binlog不记录SELECT,SHOW等查询操作
- 使主从复制,数据恢复,审计追踪的核心
- 通常位于数据目录,文件名类似:mysql-bin.000001
通过参数bonlog_format设置格式
- STATEMENT 记录原始SQL语句(默认早期版本使用)
- ROW 记录每一行被修改的具体值(行级变更)
- MINED 自动选择使用STATEMENT 或 ROW,复杂操作使用 ROW,简单操作用 STATEMENT
推荐使用ROW格式
描述 精确 记录数据变更后的具体值,不受环境因素影响 一致性高 主从复制不会出现因 SQL 非确定性引起的数据不一致问题 恢复准确 更容易基于 binlog 做精准恢复 可通过修改MySQL配置文件或使用SQL语句设置Binlog格式
-
修改配置文件
[mysqld] binlog_format = ROW # 可选值:STATEMENT、ROW、MIXED
-
使用SQL语句动态修改
SET GLOBAL binlog_format = 'ROW'; # 可选值:STATEMENT、ROW、MIXED
-
对数据库的操作是先执行,还是先写入binlog中?为什么
总结:事务性操作(如 InnoDB):
执行操作 → 记录 redo log → 写入 binlog → 提交事务通过两阶段提交确保 binlog 与数据变更的一致性。非事务性操作(如 MyISAM):执行操作 → 写入 binlog,存在崩溃导致主从不一致的风险
-
事务性存储引擎(如 InnoDB)的执行流程
对于支持事务的存储引擎,MySQL 采用 两阶段提交 确保 binlog 与数据变更的一致性
- 执行 SQL 并记录 redo log:
- 执行 SQL 语句,修改内存中的数据页(Buffer Pool)。
- 将变更记录到redo log(物理日志),确保崩溃恢复时数据不丢失。
- 准备阶段(Prepare):
- 存储引擎将事务标记为
PREPARED
状态。 - 强制将 redo log 写入磁盘(确保持久性)。
- 存储引擎将事务标记为
- 写入 binlog:将事务的变更写入binlog(逻辑日志)。
- 提交阶段(Commit):
- 存储引擎将事务标记为
COMMITTED
状态。 - 写入commit 标记到 redo log,事务完成。
- 存储引擎将事务标记为
关键点:
- binlog 在事务提交前写入,但在存储引擎真正提交前。
- 通过 redo log 和两阶段提交,保证 binlog 与数据变更的顺序一致,避免主从复制不一致。
二、非事务性存储引擎(如 MyISAM)的执行流程
对于不支持事务的存储引擎:
- 执行 SQL 并修改数据文件:直接执行 SQL,修改数据文件和索引。
- 写入 binlog:操作完成后,将变更记录到 binlog。
风险:
如果在执行 SQL 后、binlog 写入前发生崩溃,可能导致主从数据不一致(主库已执行但从库未复制)。 - 执行 SQL 并记录 redo log:
-
-
如果刚写入binlog,数据库出现异常,没有写入就重启了,会发生什么事情
-
在 MySQL 中,若binlog 已写入但数据未提交时发生异常重启,InnoDB 存储引擎会通过 崩溃恢复和两阶段提交(2PC) 机制确保数据一致性
-
binlog 写入后数据库异常重启,不会导致数据不一致,可能需要通过 redo log 完成未完成的提交操作。是 MySQL 主从复制可靠性的核心保障之一
两阶段提交
- 准备阶段(Prepare):
- 执行 SQL 并记录 redo log。
- InnoDB 将事务标记为
PREPARED
,并写入 redo log。
- 提交阶段(Commit):
- MySQL Server 写入 binlog。
- InnoDB 写入
COMMIT
标记到 redo log,事务完成
-
发生异常的三种场景及处理
-
场景 1:binlog 写入后,InnoDB 未收到提交指令
- 现象:binlog 已写入磁盘,但 InnoDB 未执行
COMMIT
。 - 恢复流程
- 重启后,InnoDB 通过 redo log 发现事务处于
PREPARED
状态。 - 检查 binlog:
- 若 binlog 存在该事务:InnoDB 自动提交事务(与 binlog 保持一致)。
- 若 binlog 不存在:InnoDB 回滚事务。
- 重启后,InnoDB 通过 redo log 发现事务处于
场景 2:binlog 写入失败(如磁盘已满)
- 现象:binlog 写入中断,InnoDB 未收到提交指令。
- 恢复流程
- binlog 写入失败时,MySQL Server 会回滚事务(协调者决定)。
- 重启后,InnoDB 通过 redo log 发现事务未完成,直接回滚。
场景 3:binlog 和 redo log 部分丢失
- 现象:binlog 或 redo log 文件损坏。
- 恢复流程
- 若 binlog 完整但 redo log 丢失,事务会被重新应用(通过 binlog)。
- 若两者均损坏,可能需要从备份恢复或手动修复(极端情况
- 现象:binlog 已写入磁盘,但 InnoDB 未执行
-
-
随着时间的推移,binglog越来越大怎么操作
- 可手动清理或自动清理来管理Binlog
方法:定期清理旧日志,手动PURGE BINARY LOGS
配置自动过期时间
- 可手动清理或自动清理来管理Binlog
-
如何强制创建新的binlog文件,这个操作有什么实际用途
-
强制切换
FLUSH BINARY LOGS;
用途 说明 日志归档 便于日志管理、切分日志 主从同步初始化 主库切换 binlog 文件,让从库能从新起点同步 手动备份配合 binlog 做增量 控制增量恢复的起点
-
-
如何手动清理binlog(只保留当前使用的,删除其他的),自动清理需要如何配置。
-
清除某个 binlog 之前的所有日志
PURGE BINARY LOGS TO 'mysql-bin.000010';
-
或清除指定时间之前的日志
PURGE BINARY LOGS BEFORE '2025-07-10 00:00:00';
不能清除正在被从库读取的日志
-
自动清理配置
在my.cnf中添加:
expire_logs_days = 7 # 保留7天 # 或新版: binlog_expire_logs_seconds = 604800
运行代码重启生效
-
-
binlog 的生命周期和清理机制是什么?如何设置自动过期时间
- 生命周期由参数
binlog_expire_logs_seconds
决定。 - 清理方式分为手动(PURGE)和自动(expire)。
- 自动清理是 MySQL 后台线程定期执行的,保证磁盘空间控制。
- 生命周期由参数
-
如何通过 mysqlbinlog 工具解析 binlog 内容?如何只解析某一个时间段的 binlog
-
基本用法
mysqlbinlog /var/lib/mysql/mysql-bin.000001
-
只解析某一时间段:
mysqlbinlog --start-datetime="2025-07-10 12:00:00" \--stop-datetime="2025-07-10 13:00:00" \/var/lib/mysql/mysql-bin.000001
可以重定向为SQL文件
mysqlbinlog ... > recover.sql
-
-
配置文件中确保开启了binlog,并且使用ROW格式。
-
在my.cnf中配置:
[mysqld] log-bin=mysql-bin binlog_format=ROW server-id=1
然后重启MySQL服务
-
-
对数据库进行全量备份,使用之前创建的任意表格新增3条记录。
-
全量备份 mysqldump
mysqldump -u root -p --all-databases --single-transaction --master-data=2 > full_backup.sql
-
插入记录
insert into student values (1001,'张三',18); insert into student values (1002,'李四',20); insert into student values (1003,'王五',22);
-
-
drop整个表,之后使用binlog还原表,包括新增的3条记录。
-
查找 drop 前的 binlog 位置或时间
-
使用
mysqlbinlog
导出 binlog SQLmysqlbinlog --start-datetime="2025-07-10 10:00:00" \--stop-datetime="2025-07-10 12:00:00" \/var/lib/mysql/mysql-bin.000003 > recover.sql
-
手动编辑文件:只保留建表和插入语句
-
执行SQL恢复数据:
mysql -u root -p < recover.sql
-
-
主从同步中的binlog与relaylog有什么关系
-
从库 I/O 线程将主库 binlog 拉过来,写入 relay log,再由 SQL 线程执行
日志类型 主库 or 从库 作用 Binlog 主库 记录主库的所有更改操作 Relay log 从库 是从库从主库拉过来的 binlog 拷贝
-
-
mysql主从同步时是如何保障数据一致性的
- 日志驱动:主库写操作记录到 binlog,从库 IO 线程拉取 binlog 存为 relay log,SQL 线程顺序执行 relay log 语句,复刻主库变更。
- 顺序执行:从库 SQL 线程串行应用 relay log,严格遵循主库事务提交顺序,避免乱序导致的数据冲突。
- GTID(可选):为事务分配全局唯一 ID,精准标记已同步事务,防重复执行,简化故障切换时的断点定位。
- 故障校验:从库通过心跳检测主从连接,结合
Seconds_Behind_Master
监控延迟,异常时触发重连 / 修复,维持同步链路。
本质是靠日志复制 + 串行重演 + 状态校验,让从库精准复刻主库数据流转,保障最终一致。
-
按照时间顺序,描述主从同步的所有步骤
-
主库记录 binlog
- 所有 DML 操作被写入 binlog。
主库对 DML(增删改)、DDL(建表等)操作,会按binlog_format
(STATEMENT/ROW/MIXED)格式写入 binlog,是复制的基础,
- 所有 DML 操作被写入 binlog。
-
从库 I/O 线程连接主库
- 发起
COM_BINLOG_DUMP
请求。
从库启动后,IO线程
通过CHANGE MASTER TO
配置的主库信息,发起COM_BINLOG_DUMP
协议请求,拉取 binlog
- 发起
-
主库传送 binlog 内容
- 主库的 dump 线程发送 binlog 给从库。
主库响应请求后,会创建dump线程
,持续将 binlog 事件推送给从库
- 主库的 dump 线程发送 binlog 给从库。
-
从库写入 relay log
- I/O 线程把 binlog 内容保存为中继日志(relay log)。
从库IO线程
接收的 binlog,会先落地为中继日志(relay log)
,避免直接应用时中断丢失
- I/O 线程把 binlog 内容保存为中继日志(relay log)。
-
SQL 线程读取 relay log
- 从库 SQL 线程按顺序执行这些操作,实现数据同步。
从库SQL线程
串行解析 relay log,重演 SQL 操作,保证主从数据最终一致
- 从库 SQL 线程按顺序执行这些操作,实现数据同步。
-
完成复制
- binlog 与事务的关联:主库写 binlog 时,会通过两阶段提交(2PC) 保证与 InnoDB redo log 一致,避免主从数据分裂。
- relay log 的管理:从库会自动清理过期 relay log(可通过
relay_log_purge
等参数控制),防止日志膨胀。 - 异常场景处理:若主从网络中断,
IO线程
会自动重连;若 SQL 线程执行报错(如主键冲突),需人工介入修复(如跳过事务、修正数据
-