log_output=TABLE 不会自动创建 mysql.slow_log 表;需手动建表且 slow_query_log 必须为 ON,否则无记录;生产慎用,因 CSV 引擎无索引、TRUNCATE 会阻塞 DDL/DML,双模式更增 I/O 与运维风险。

log_output=TABLE 会触发 mysql.slow_log 表自动创建吗
不会。MySQL 5.7.8+ 版本才原生支持 log_output='TABLE' 直接写入系统表,但前提是 mysql.slow_log 表必须已存在且结构正确。如果该表不存在,MySQL 不会自动建表,而是静默丢弃慢查询日志 —— 你查不到任何记录,也看不到报错。
手动创建方式(仅需执行一次):
CREATE TABLE IF NOT EXISTS mysql.slow_log ( start_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), user_host MEDIUMTEXT NOT NULL, query_time TIME(6) NOT NULL, lock_time TIME(6) NOT NULL, rows_sent INTEGER NOT NULL, rows_examined INTEGER NOT NULL, db VARCHAR(512) NOT NULL, last_insert_id INTEGER NOT NULL, insert_id INTEGER NOT NULL, server_id INTEGER UNSIGNED NOT NULL, sql_text MEDIUMTEXT NOT NULL, thread_id BIGINT UNSIGNED NOT NULL ) ENGINE=CSV AVG_ROW_LENGTH=256 CHARACTER SET utf8mb4 COMMENT='Slow log';
注意:ENGINE=CSV 是官方推荐(非 InnoDB),因为写入频繁、只读分析场景多;用 InnoDB 可能引发锁争用和日志刷盘压力。
set global log_output='TABLE' 后为什么 still no records in mysql.slow_log
常见原因有三个,按优先级排查:
-
slow_query_log本身是 OFF:必须先SET GLOBAL slow_query_log = 'ON',否则log_output设置无效 -
long_query_time过高(比如还是默认的 10),导致实际执行的 SQL 没超时;建议临时设为SET GLOBAL long_query_time = 0.1验证是否写入 - 权限不足:执行
SELECT的用户需有SELECT权限 onmysql.slow_log,而写入依赖 MySQL 内部线程,若mysql库被显式REVOKE过写权限(如某些加固脚本),也会失败
验证当前状态用这两条命令:
SHOW VARIABLES LIKE 'slow_query_log';<br>SHOW VARIABLES LIKE 'log_output';
log_output=TABLE 在生产环境有没有风险
有,而且不小。核心风险不是“写不进去”,而是“写进去后卡住整个库”:
-
TRUNCATE TABLE mysql.slow_log会触发全局 MDL 锁,期间所有 DDL 和部分 DML(尤其是涉及表元数据的操作)会被阻塞,监控脚本查information_schema.tables就可能直接拖垮业务 -
mysql.slow_log是 CSV 引擎,不支持索引;当记录量 >10 万行后,SELECT * FROM mysql.slow_log WHERE start_time > ...查询极慢,甚至拖慢mysqld线程调度 - 磁盘上会额外生成
slow_log.CSN文件,出错时(如磁盘满、文件损坏)MySQL 可能反复重试写入并报Incorrect key file for table 'slow_log',进一步加剧 I/O 压力
所以生产环境真要用表模式,建议搭配 EVENT 定期归档 + TRUNCATE,且必须避开业务高峰;更稳妥的做法是只用 FILE,再用 pt-query-digest 或自研脚本定时解析。
log_output='FILE,TABLE' 能否兼顾安全与便利
不能。双模式看似保险,实则放大问题:
- 日志写入是同步的:一条慢 SQL 必须同时写成功 FILE 和 TABLE 才算完成,任一路径失败(如磁盘满、
slow_log.CSN损坏),整条日志丢失,且无告警 - 资源开销翻倍:FILE 模式走文件系统缓存,TABLE 模式走引擎层写入,两者并发刷盘容易打满 I/O,尤其在高并发慢查询场景下
- 运维复杂度陡增:你要同时监控两个日志源的大小、轮转、权限、备份策略 ——
slow_query_log_file和mysql.slow_log的生命周期完全不一致
真正需要双路备份的场景,应该用 FILE 输出 + 外部日志采集器(如 Filebeat)实时推送到 ELK 或 S3,而不是依赖 MySQL 自身的双写机制。











