开启mysql通用查询日志会拖慢系统,仅在高并发写日志时明显;因其逐条记录所有语句并产生i/o压力,生产环境应禁用,改用精准审计方案。

MySQL开启通用查询日志会拖慢系统吗
会,但只在高并发写日志场景下明显。通用查询日志(general_log)是逐条记录所有客户端语句的,包括 SELECT、SET、SHOW 这类轻量操作,I/O 压力直接取决于查询频次和日志落盘方式。
实操建议:
- 生产环境禁用
general_log = ON,改用更精准的审计方案(如 MySQL Enterprise Audit 或 Percona Audit Log Plugin) - 若必须临时开启排查问题,优先设为写入文件(
log_output = 'FILE'),避免写表引发锁争用 - 注意
general_log_file路径权限:MySQL 进程需有写权限,且不能放在/tmp等可能被定时清理的目录 - 日志体积增长极快,不设轮转机制时,单个文件几天就可达 GB 级,磁盘满会导致 MySQL 挂起
用 MySQL 自带 audit_log 插件记录谁查了哪些表
原生 audit_log 插件(MySQL 5.6+ 企业版)能记录连接、查询、退出事件,但默认不区分“查了哪张表”——它只记录完整 SQL 字符串,解析表名得靠外部工具或正则提取。
实操建议:
- 启用前确认是企业版:社区版无
audit_log.so,强行安装会报错Plugin 'audit_log' is not loaded - 关键配置项:
audit_log_policy = ALL(记录所有事件)、audit_log_format = JSON(结构化易解析)、audit_log_file = '/var/lib/mysql/audit.json' - JSON 日志里
"query"字段含原始 SQL,但敏感字段(如密码、token)不会自动脱敏,需在采集层处理 - 插件加载后不重启 MySQL,但需执行
INSTALL PLUGIN audit_log SONAME 'audit_log.so',失败常见原因是路径不对或 SELinux 拦截
审计日志中如何识别内部员工的真实身份而非 proxy 用户
很多公司用统一代理账号连 MySQL(如 app_user),导致日志里所有操作都显示同一个用户名,无法定位到具体员工。根本解法不是靠日志字段,而是从连接源头控制。
实操建议:
- 强制应用层在连接时传入真实标识:用
CONNECT事件中的program_name或自定义user_comment(MySQL 8.0+ 支持SET PERSIST connection_control_failed_connections_threshold = 0配合应用埋点) - 如果走中间件(如 ProxySQL、ShardingSphere),配置其在转发时注入
/* user:zhangsan */注释,MySQL 会原样记入general_log或audit_log - 禁止应用复用长连接池里的连接上下文;每次新请求应重置
USER()可见身份,例如执行SET @real_user = 'zhangsan'并在业务逻辑里主动写入审计表 - 数据库账号本身按人分配(哪怕只读),比事后解析日志可靠得多;权限粒度控制到
GRANT SELECT ON db1.table_a TO 'zhangsan'@'%',而非全库只读
审计日志文件被删或权限异常导致 MySQL 启动失败
MySQL 在启动时会尝试打开已配置的审计日志路径。如果 audit_log_file 指向一个被删除的文件,或目录不存在、权限不足,MySQL 可能拒绝启动,并报错 Failed to open audit log file 或卡在初始化阶段。
实操建议:
- 检查路径是否存在且属主为
mysql用户:ls -ld /var/lib/mysql/audit/,缺失就mkdir -p /var/lib/mysql/audit && chown mysql:mysql /var/lib/mysql/audit - 不要手动
rm正在写的审计日志文件;要用FLUSH LOGS触发轮转,再清理旧文件 - 若已发生启动失败,临时注释掉 my.cnf 中的
audit_log_file和audit_log相关行,先启库,再修复路径后重新加载插件 - 审计日志路径别放在根分区,尤其避免与
datadir同盘;否则日志撑爆磁盘会连带导致主库不可用
审计这件事,最难的从来不是开个开关,而是让每条日志背后都能对上一个可追责的动作——这要求权限体系、连接方式、日志格式、存储策略全链路对齐,缺一环,查的时候就只剩猜测。











