mysql如何实现基础日志系统_mysql项目记录方案

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

MySQL 自带的 general_log 能不能直接用?

能,但不推荐在生产环境长期开启。它会记录所有语句(包括

SELECT
),I/O 压力大、日志体积爆炸、还可能暴露敏感数据。

开启方式:

SET GLOBAL general_log = ON;
,日志默认写入文件(路径由
general_log_file
控制)或表
mysql.general_log
(需设
log_output = 'TABLE'
)。但表模式下查起来慢,且没有索引优化,
SELECT * FROM mysql.general_log
扫全表很卡。

只建议临时排障时开 1–2 分钟,立刻关掉:
SET GLOBAL general_log = OFF;
日志表无主键、无时间索引,按需手动加:
ALTER TABLE mysql.general_log ADD INDEX idx_event_time (event_time);
(但 MySQL 8.0+ 对该表结构有限制,部分字段不可修改)
文件模式下,日志无法按用户/数据库过滤,得靠外部脚本 grep,不灵活

用触发器 + 自定义日志表实现轻量级操作审计

适合记录关键表的增删改(比如用户表、订单表),可控、低侵入、可定制字段。

先建日志表:

CREATE TABLE user_action_log (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  table_name VARCHAR(64) NOT NULL,
  action_type ENUM('INSERT', 'UPDATE', 'DELETE') NOT NULL,
  pk_value VARCHAR(255) NOT NULL,  -- 主键值,字符串兼容 INT/UUID
  old_data JSON,
  new_data JSON,
  operator_user VARCHAR(64),
  ip_address VARCHAR(45),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

触发器里用
USER()
@@hostname
获取操作者信息,但注意:如果是应用连接池统一账号,
USER()
拿不到真实业务用户,得靠应用层传参写入
operator_user
old_data
new_data
JSON_OBJECT()
构造,例如
JSON_OBJECT('name', OLD.name, 'email', OLD.email)
避免在高频写入表上加触发器,否则性能明显下降;单次触发器逻辑别做 HTTP 请求或复杂计算

用 MySQL 8.0+ 的 audit log plugin(企业版)还是社区版替代方案?

MySQL 社区版不带官方 audit plugin(那是企业版功能),但可以用 Percona Server 或 MariaDB 的开源审计插件,或者用

mysqlbinlog
解析 binlog 做事后分析。

mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000001
可读取行格式 binlog,看到具体变更数据,但它是二进制日志,不是“谁在什么时间做了什么”的语义日志
binlog 不记录
SELECT
、不记录失败语句、不包含客户端 IP,且开启
binlog_format = ROW
后体积增大,对主从延迟有影响
如果真要审计级日志,建议在应用层埋点:ORM 拦截 SQL 执行前后,把
user_id
request_id
sql
params
、耗时、结果状态打到 ELK 或本地文件,比 DB 层更准、更可控

日志保留与清理策略怎么定?

没自动清理机制的日志表,半年后就成性能黑洞。别指望 DBA 手动删。

用分区表按天/月切分:
ALTER TABLE user_action_log PARTITION BY RANGE (TO_DAYS(created_at)) (...)
,删除旧分区比
DELETE
快得多
用事件调度器定期清理:
CREATE EVENT cleanup_logs ON SCHEDULE EVERY 1 WEEK DO DELETE FROM user_action_log WHERE created_at 
注意:
DELETE
大表会锁表(尤其 MyISAM),InnoDB 虽支持行锁,但大量删除仍引发碎片和事务日志暴涨,优先选
TRUNCATE PARTITION
或归档后删表

真正难的不是记日志,是定义清楚“哪些操作必须留痕”“保留多久合规”“谁有权查”,技术只是执行环节。字段设计漏了

tenant_id
app_version
,后期补成本极高。

相关推荐