mysql数据库中的命令历史记录与权限审计

来源:这里教程网 时间:2026-02-28 20:52:09 作者:

MySQL 命令历史默认不保存,
~/.mysql_history
需手动启用且不可靠

MySQL 客户端(

mysql
命令行工具)默认会把执行过的 SQL 写入用户家目录下的
~/.mysql_history
文件,但这个行为受多个条件限制:
• 只有在未设置环境变量
MYSQL_HISTFILE
/dev/null
或空字符串时才生效
• 若用户以
mysql -e "SELECT 1"
方式执行命令,语句不会写入历史文件
~/.mysql_history
是纯文本、无时间戳、无用户标识、无连接上下文,无法区分是哪个账号、连的哪台实例、何时执行的
• 文件权限若配置不当(如被其他用户可读),反而构成安全风险

真正的权限审计必须依赖 MySQL 服务端日志,不是客户端历史

要审计“谁在什么时候对哪些表执行了什么操作”,必须开启并解析服务端日志,而非依赖客户端文件。关键选项如下:

general_log = ON
:记录所有语句(含 SELECT),但 I/O 开销大,仅建议临时开启
audit_log = ON
(需安装
audit_log.so
插件):专为审计设计,支持按用户、命令类型、库/表过滤,输出为 JSON 或 XML
binlog
不适合直接审计:它记录的是数据变更的逻辑事件(如
Write_rows_event
),不含原始 SQL、不记录 SELECT、且需解析二进制格式

INSTALL PLUGIN audit_log SONAME 'audit_log.so';
SET GLOBAL audit_log_policy = 'ALL';
SET GLOBAL audit_log_format = 'JSON';

performance_schema
实时抓取活跃会话与最近语句(无需重启)

如果无法开启通用日志或审计插件(例如云数据库 RDS 通常禁用这些功能),可用

performance_schema
作为轻量替代方案,但它只保留内存中的近期数据:
performance_schema.threads
显示当前连接线程及
PROCESSLIST_USER
/
PROCESSLIST_HOST

performance_schema.events_statements_current
包含每个线程最后执行的完整 SQL(字段
SQL_TEXT

• 注意:默认只保留最近 100 条/线程,且重启后清空;需提前确认
performance_schema
已启用,并调大相关 consumer 表容量

SELECT THREAD_ID, USER, HOST, SQL_TEXT 
FROM performance_schema.events_statements_current 
JOIN performance_schema.threads USING (THREAD_ID) 
WHERE SQL_TEXT IS NOT NULL AND SQL_TEXT NOT LIKE 'SELECT %';

权限变更本身必须查
mysql.user
mysql.db
表快照,不能靠日志回溯

MySQL 不自动记录 “张三的 SELECT 权限何时被授予 test.*” 这类元操作。权限修改(

GRANT
/
REVOKE
)虽会记入通用日志(如果开着),但更可靠的方式是定期导出权限快照:
• 执行
SELECT User, Host, Select_priv, Insert_priv, ... FROM mysql.user;

• 执行
SELECT User, Host, Db, Select_priv, ... FROM mysql.db;

• 将结果保存为带时间戳的 CSV,用 diff 工具比对差异
• 注意:直接查询
mysql
系统库需
SELECT
权限,且部分字段(如密码哈希)在 8.0+ 中已移至
mysql.user
authentication_string

权限审计真正难的不是“怎么记”,而是“记下来之后谁来读、多久读一次、异常如何告警”。
~/.mysql_history
连基础溯源都做不到,别把它当审计依据。

相关推荐