环境:mysql 8.0.14 社区版
阅读文本需要的背景知识:对数据库的基本概念(触发器、存储过程、事件),mysql下general log的配置指令
背景:因审计需要,对于数据库操作需要留痕。实际访问数据库的有程序及客户端人工,程序化访问会产生大量的垃圾日志。过滤并记录我们指定要的日志,是本文要解决的问题。
调研了解到mysql有多种日志,其中最丰富的是查询日志(general log),其他都不满足要求,但其只有输出到TABLE才有执行sql对应用户的信息。
以下指令都是在mysql库下,用root用户执行。
SET global log_output='TABLE';
设置时间格式与本机一致
set global log_timestamps='SYSTEM';
开始记录日志
SET global general_log=1;
这时,日志已经写到mysql.general_log表中已经有了日志。
但sql执行量大,该表被认定为系统表,不可附加触发器在他上面(被数据库报错),不能用delete去删除我们不要的数据(被数据库报错,带锁),但是这张表可以truncate。
如果我们不写table,而写入到file又没有我们要的字段。
于是,可以这么做:
1、创建一个自定义表,其结构与系统表相似。
CREATE TABLE 目标表名 LIKE general_log;
2、将系统表中你要的数据复制到自定义表中。
INSERT INTO 目标表名 (列1,列2,列3,...) SELECT 列1,列2,列3,...
FROM general_log WHERE 条件;
3、清理系统表,留出空间
truncate table general_log;
4、智能一点,每分钟跑一次
创建一个MySQL事件,用于定时执行(可以将上述几部放到存储过程里)
CREATE EVENT event_name
ON SCHEDULE AT EVERY 1 MINITE
DO
CALL procedure_name();
如果默认没有启动事件,要启用
SET GLOBAL event_scheduler = ON;
对了,完事儿之后,
有/var/lib/mysql/目标表名.csv可以直接拷给审计,哈哈哈哈哈。
最后,
点赞、收藏、关注