深色模式
数据库审计:开启操作审计与慢查询留痕
摘要:数据库审计回答"谁在什么时候改了哪条数据"。本文给出 MySQL 通用日志/审计插件与 PostgreSQL pgaudit 的配置方法、慢查询留痕、集中转发与告警。
适用环境
bash
cat /etc/os-release
mysql --version 2>/dev/null || psql --version 2>/dev/null
mysql -e "SELECT VERSION();" 2>/dev/null
df -h /var/lib/mysql /var/log 2>/dev/null1
2
3
4
2
3
4
操作步骤
1. 明确审计目标:审计什么、留存多久
- 连接审计:谁、从哪个 IP、什么时候连上来。
- 操作审计:DDL(建表/改表/删库)、DML 写操作、权限变更(GRANT)。
- 慢查询:性能留痕,也是异常批量操作的线索。
- 失败登录:口令爆破迹象。
全量审计 SELECT 会带来巨大开销,通常只审计写操作与 DDL。
2. MySQL:开启错误日志与通用日志(轻量起步)
ini
[mysqld]
log_error = /var/log/mysql/error.log
log_error_verbosity = 2
general_log = OFF # 全量 SQL,开销大,仅排障临时开
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = ON
min_examined_row_limit = 1000
log_timestamps = SYSTEM1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
bash
systemctl restart mysql
mysql -e "SET GLOBAL general_log='ON';" # 临时开启,排障后务必关掉
mysql -e "SHOW VARIABLES LIKE 'slow_query%'; SHOW VARIABLES LIKE 'long_query_time';"1
2
3
2
3
长期开启 general_log 会拖慢数据库并撑爆磁盘
只作为短时排障手段,且必须设置自动关闭时间。生产审计请使用审计插件。
3. MySQL:使用审计插件(企业版/Percona/MariaDB)
Percona/MariaDB 自带 audit plugin:
sql
INSTALL PLUGIN server_audit SONAME 'server_audit.so';
SET GLOBAL server_audit_logging = ON;
SET GLOBAL server_audit_events = 'CONNECT,QUERY_DDL,QUERY_DCL,TABLE';
SET GLOBAL server_audit_file_path = '/var/log/mysql/audit.log';
SET GLOBAL server_audit_file_rotate_size = 1073741824;
SET GLOBAL server_audit_file_rotations = 20;
SHOW VARIABLES LIKE 'server_audit%';1
2
3
4
5
6
7
2
3
4
5
6
7
持久化到配置文件:
ini
[mysqld]
plugin-load-add=server_audit.so
server_audit_logging=ON
server_audit_events=CONNECT,QUERY_DDL,QUERY_DCL,TABLE
server_audit_output_type=file
server_audit_file_path=/var/log/mysql/audit.log
server_audit_file_rotate_size=1073741824
server_audit_file_rotations=201
2
3
4
5
6
7
8
2
3
4
5
6
7
8
4. PostgreSQL:pgaudit
bash
# 安装(包名因版本而异)
dnf install -y pgaudit17_ 2>/dev/null || apt-get install -y postgresql-16-pgaudit1
2
2
ini
# postgresql.conf
shared_preload_libraries = 'pgaudit'
pgaudit.log = 'ddl, role, write, misc_set'
pgaudit.log_catalog = off
pgaudit.log_parameter = on
log_connections = on
log_disconnections = on
log_line_prefix = '%m [%p] %q%u@%d %r '1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
bash
systemctl restart postgresql
psql -c "SHOW shared_preload_libraries;"
psql -c "CREATE EXTENSION IF NOT EXISTS pgaudit;" 2>/dev/null1
2
3
2
3
pgaudit.log 取值:read, write, ddl, role, function, misc, all。生产通常选 ddl,role,write。
5. 慢查询分析
bash
# MySQL 自带工具
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
pt-query-digest /var/log/mysql/slow.log | head -40
# PostgreSQL
# 需开启 log_min_duration_statement
psql -c "ALTER SYSTEM SET log_min_duration_statement = '1000';"
psql -c "SELECT pg_reload_conf();"1
2
3
4
5
6
7
2
3
4
5
6
7
ini
# postgresql.conf 慢查询
log_min_duration_statement = 1000
log_statement = 'ddl'
log_checkpoints = on
log_lock_waits = on1
2
3
4
5
2
3
4
5
6. 日志集中转发与防篡改
bash
cat >/etc/rsyslog.d/50-mysql.conf <<'EOF'
$InputFileName /var/log/mysql/audit.log
$InputFileTag mysql-audit:
$InputFileStateFile stat-mysql-audit
$InputFileSeverity info
$InputRunFileMonitor
EOF
# 或直接由 filebeat/vector 采集送到日志中心
systemctl restart rsyslog1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
数据库服务器本地日志应对应用账号不可读:
bash
chmod 640 /var/log/mysql/audit.log
chown mysql:adm /var/log/mysql/audit.log
ls -l /var/log/mysql/1
2
3
2
3
7. 脱敏:审计日志本身也是敏感数据
- 禁止审计日志出现明文口令、身份证、手机号(尤其是
log_parameter=on时)。 - 日志中心按需做字段脱敏与访问控制。
- 审计员只读,DBA 不能删审计日志。
bash
grep -oE "(password|passwd|id_card|phone)[^ ]*" /var/log/mysql/audit.log | head -51
8. 告警规则建议
- 非工作时间出现
DROP TABLE/TRUNCATE。 - 单账号短时间大量失败连接。
- 从非应用网段直连数据库。
GRANT ALL或新建高权限账号。- 单条 SQL 影响行数异常大(无 WHERE 的 UPDATE/DELETE)。
bash
grep -iE "drop |truncate |grant all" /var/log/mysql/audit.log | tail -10
grep -c "Access denied" /var/log/mysql/error.log1
2
2
验证
bash
# 制造审计事件
mysql -e "CREATE DATABASE audit_test; DROP DATABASE audit_test;"
grep -i "audit_test" /var/log/mysql/audit.log | tail -3
# PostgreSQL
psql -c "CREATE TABLE t_audit_test(id int); DROP TABLE t_audit_test;"
grep -i "t_audit_test" /var/log/postgresql/*.log | tail -3
# 慢查询
mysql -e "SELECT SLEEP(2);"
mysqldumpslow -s t -t 3 /var/log/mysql/slow.log1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
判定标准:DDL 与写操作有记录;日志已集中留存;审计日志不可被 DBA 删除;异常操作触发告警。
常见坑
长期开 general_log / pgaudit.log=all
会带来显著性能损耗和磁盘压力。只审计必要事件类型,并做好容量规划。
审计日志不轮转撑爆磁盘
必须配 logrotate 与 server_audit_file_rotations,并监控磁盘使用率。
审计日志里出现明文参数
pgaudit.log_parameter=on 会记录 SQL 参数值。敏感业务要评估后再开,或配合脱敏。
DBA 账号能删审计日志
审计与操作权限必须分离。DBA 对审计日志只读。
应用用高权限账号,审计无法区分责任人
每个应用独立账号,才能把操作归因到具体系统。