深色模式
数据库审计
摘要:审计回答「谁、在什么时间、从哪个 IP、对哪张表做了什么操作」。MySQL 社区版可用通用日志或审计插件(如 Percona Audit Log Plugin / MariaDB 审计插件),企业版自带审计。本文给出开启方式与日常审计查询。
适用环境
bash
mysql -uroot -p -e "SELECT @@version, @@log_bin, @@general_log;"
mysql -uroot -p -e "SHOW PLUGINS;" | grep -i audit
ls /usr/lib64/mysql/plugin/ | grep -i audit # 查找可用审计插件1
2
3
2
3
操作步骤
1. 方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 通用日志 general_log | 零依赖,社区版自带 | 记录所有语句,性能开销大,无法细粒度过滤 |
| Percona/MariaDB 审计插件 | 可按用户/库/操作过滤,格式规范 | 需安装插件,重启加载 |
| 企业版 Audit Log | 官方支持、功能完整 | 需商业授权 |
| 代理层审计(ProxySQL 等) | 与应用解耦 | 增加一层组件 |
2. 快速方案:开启通用日志(仅用于临时排查)
sql
SET GLOBAL general_log = ON;
SET GLOBAL log_output = 'TABLE'; -- 写入 mysql.general_log 表,便于 SQL 查询
SELECT event_time, user_host, LEFT(argument, 120) FROM mysql.general_log
WHERE argument LIKE '%DROP%' ORDER BY event_time DESC LIMIT 20;1
2
3
4
2
3
4
危险
生产环境长期开启 general_log 会显著增加 I/O 与磁盘占用,甚至拖慢实例;仅限短时排查,用完立即关闭并把 log_output 改回 FILE。
3. 正式方案:安装审计插件
sql
-- Percona Server / MariaDB 自带的 audit plugin
INSTALL PLUGIN server_audit SONAME 'server_audit.so';
SET GLOBAL server_audit_logging = ON;
SET GLOBAL server_audit_events = 'CONNECT,QUERY_DDL,QUERY_DML';
SET GLOBAL server_audit_file_path = '/data/mysql/log/audit.log';
SHOW VARIABLES LIKE 'server_audit%';1
2
3
4
5
6
2
3
4
5
6
ini
# 持久化到 /etc/my.cnf(重启后仍生效)
plugin-load=server_audit=server_audit.so
server_audit_logging=ON
server_audit_events=CONNECT,QUERY_DDL,QUERY_DML
server_audit_file_rotate_size=100000000
server_audit_file_rotations=101
2
3
4
5
6
2
3
4
5
6
4. binlog 作为补充追溯手段
bash
# 追溯某段时间内的 DDL/DML
mysqlbinlog --start-datetime='2026-10-09 10:00:00' --stop-datetime='2026-10-09 11:00:00' \
--base64-output=DECODE-ROWS -v /data/mysql/data/binlog.000012 | grep -iE 'DROP|DELETE|UPDATE' | head1
2
3
2
3
5. 审计日志的保护与留存
bash
# 日志目录权限收紧,仅管理员可读
sudo chmod 700 /data/mysql/log
sudo chown mysql:mysql /data/mysql/log/audit.log
# 用 logrotate 定期轮转并保留合规要求的天数
sudo vi /etc/logrotate.d/mysql-audit1
2
3
4
5
6
2
3
4
5
6
bash
# 建议同步到集中日志平台(与本地留存互补,防止本机被删)
# filebeat/vector 采集 /data/mysql/log/audit.log → 日志平台1
2
2
验证
sql
-- 用一个测试账号执行一次 DDL/DML
-- 再在审计日志中确认能查到该条记录1
2
2
bash
grep -i 'DROP\|DELETE' /data/mysql/log/audit.log | tail -n 10
mysql -uroot -p -e "SELECT event_time, user_host, LEFT(argument,80) FROM mysql.general_log LIMIT 5;"1
2
2
常见坑
WARNING
审计日志本身包含敏感数据(SQL 中的明文参数),必须设置严格权限并避免直接输出到可被业务读取的位置。
WARNING
审计插件加载需要实例重启或 INSTALL PLUGIN;升级 MySQL 前先确认插件与新版本兼容,否则会导致启动失败。
DANGER
只在本机保存审计日志无法满足合规与取证要求——本机被入侵时日志可被删除;必须实时外送到独立的日志平台。