general_log开启导致qps下降22.9%是因同步写入引发i/o阻塞:每条sql执行后必须fsync落盘才响应,高并发下小io拥塞磁盘队列,cpu空转等待,且日志不区分语句类型、默认与数据共盘加剧竞争。

general_log 开启后 QPS 直降 23%
直接看数据:在 SSD 环境、5.7.27 版本下,sysbench 5 分钟压测显示,general_log=OFF 时每秒事务数为 108.48;开启后降到 83.53 —— 性能下降约 22.9%。这不是理论推测,是真实 I/O 阻塞导致的吞吐塌缩。
根本原因在于 general_log 是同步写入:每条 SQL 执行完,MySQL 必须等日志落盘(fsync)成功才返回响应。高并发下,大量小 IO 拥塞磁盘队列,CPU 空转等待,QPS 自然断崖下跌。
- 它不区分语句类型,SELECT 也记、空查询也记,日志量爆炸式增长
- 默认写文件,路径若和数据文件共用同一块磁盘,IO 竞争会进一步放大延迟
-
log_output='TABLE'也不推荐——写入mysql.general_log表本质仍是同步 INSERT,还额外消耗 buffer pool 和锁资源
audit_log 插件比 general_log 更重,但可调
MySQL 官方 audit_log 插件(如 audit_log.so)虽然功能更细(支持 JSON 格式、策略过滤),但开销通常比 general_log 还高 10%~15%,因为它在 Server 层更深的位置拦截事件,并做序列化与权限校验。
但它至少提供可控出口:
-
audit_log_policy='LOGINS'只记录登录,而非全量操作,日志量可压缩 90%+ -
audit_log_rotate_on_size=1048576(1MB)配合定时轮转,避免单文件过大拖慢 fsync -
audit_log_file必须指向独立挂载点(如/mnt/logdisk/audit.log),严禁和datadir共盘
slow_query_log 的影响相对温和,但 long_query_time 设错就失效
slow_query_log 是异步写入(尤其 log_output='FILE' 时),且只记录超时语句,所以对性能冲击小得多。测试中开启后 QPS 下降通常
但常见误配让它“形同虚设”:
-
long_query_time=0在生产环境等于打开general_log,所有语句都记,I/O 压力陡增 - 未设
min_examined_row_limit,导致大量无害的SELECT 1被计入,污染日志 -
log_output='TABLE'+ 高频慢查 →mysql.slow_log表自身成为热点,引发元数据锁争用
真正要命的是日志 + 缺乏归档机制
审计日志性能问题,一半来自写入,另一半来自堆积。比如 audit.log 长期不轮转、不压缩、不清理,文件膨胀到几十 GB 后,每次 rotate 或 grep 查找都会触发巨量磁盘寻道。
这会让问题从“可预测的延迟”滑向“间歇性卡死”:
- rotate 操作本身需要 rename + fsync,可能阻塞后续审计事件写入
- 用
DELETE FROM mysql.audit_log清理表,会锁全表、产生大量 undo log,高峰期极易引发复制延迟或主库夯住 - 没配
audit_log_read_buffer_size,大 JSON 日志解析失败时,插件可能静默丢弃事件,造成审计盲区
日志不是开了就完事,写入路径、保留策略、清理方式,三者缺一不可。少配一项,性能衰减就不是线性下降,而是拐点式恶化。











