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

2次阅读

mysql客户端历史文件~/.mysql_history默认不可靠,权限审计必须依赖服务端日志(如audit_log插件或general_log)或performance_schema实时监控,辅以mysql.user/db表快照比对。

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

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 插件):专为审计设计,支持按用户、命令类型、库/表过滤,输出为 jsonxml
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.usermysql.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.userauthentication_string

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

text=ZqhQzanResources