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

2次阅读

能,但不推荐在生产环境长期开启;它会记录所有语句,导致i/o压力大、日志爆炸、暴露敏感数据,仅建议临时排障开1–2分钟并立即关闭。

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

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_datanew_dataJSON_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_idrequest_idsqlparams、耗时、结果状态打到 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_idapp_version,后期补成本极高。

text=ZqhQzanResources