1 创建sql_audit 表存储raw data
drop table if exists sql_audit;
CREATE TABLE `sql_audit` (
`sql_info` longtext NOT NULL,`base` varchar(50) NOT NULL,
`tablename` longtext,
`field` varchar(200) DEFAULT NULL,
`count` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2 从审计系统中导出近7天数据到sql_audit库表中
#获取raw data
insert into sql_audit(sql_info,base) select `db-ticket2`.`core_sqlrecord`.`sql`,`db-ticket2`.`core_sqlrecord`.`base` from `db-ticket2`.`core_sqlrecord` where TO_DAYS(NOW()) - TO_DAYS(`db-ticket2`.`core_sqlrecord`.date) <= 7 and `db-ticket2`.`core_sqlrecord`.`sql` like 'UPDATE%';
3 创建存储过程
#存储过程sql_audit,实现获取每个update语句的tablename, field
drop PROCEDURE if exists sql_audit;
DELIMITER ;;
CREATE DEFINER=`root`@`10.117.52.118` PROCEDURE `sql_audit`()
begin
declare pos1 int;#记录set位置
declare pos2 int;#记录=位置
declare pos3 int;#记录空格位置
declare sql_item longtext;
declare tablename VARCHAR(200);
declare stop int default 0;
DECLARE cursor_select CURSOR FOR select sql_info from sql_audit; #因为要遍历select中的每一条记录,所以要用到游标,这里声明一个游标
declare CONTINUE HANDLER FOR SQLSTATE '02000' SET stop = null;
OPEN cursor_select;
FETCH cursor_select INTO sql_item;
WHILE ( stop is not null) DO
set @pos1 = (select INSTR(sql_item,'set'));#获取sql_item中set所在的位置
#set @tablename = substring(sql_item, 7, @pos1-1);#取sql_item中从第7个字符到所set在位置之间的字符串,即tablename
set @pos2 = (select INSTR(sql_item,'='));#获取sql_item中=所在的位置
if (locate('update',sql_item) > 0) then
set @pos3 = (select INSTR(replace(replace(sql_item,'UPDATE','update'),'update ',''),' '));
update sql_audit set tablename = substring(sql_item, 7, @pos3),field = substring(sql_item, @pos1+4, @pos2-@pos1-4) where sql_info = sql_item;
elseif (locate('a inner',sql_item) > 0) then
set @pos3 = (select locate('a inner',sql_item));
update sql_audit set tablename = substring(sql_item, 7, @pos3-7),field = substring(sql_item, @pos1+4, @pos2-@pos1-4) where sql_info = sql_item;
elseif (locate('inner',sql_item) > 0) then
set @pos3 = (select locate('inner',sql_item));
update sql_audit set tablename = substring(sql_item, 7, @pos3-7),field = substring(sql_item, @pos1+4, @pos2-@pos1-4) where sql_info = sql_item;
end if;
COMMIT;
FETCH cursor_select INTO sql_item;#游标下移
END WHILE;
CLOSE cursor_select;
end;;
DELIMITER ;
4 存储过程调用
call sql_audit();
5 对结果集进行排序,并更新到表count字段
#更新count统计结果
update sql_audit a set a.count = (select b.count from (select tablename as tablename, field as field, count(*) as count from sql_audit group by tablename,field) b where a.field = b.field and a.tablename = b.tablename);
6 查询count统计结果
#查询count统计结果
select distinct base,tablename,field, count from sql_audit order by count desc;