在数据库日常运维和开发场景中,记录存储过程的执行信息是审计和故障排查的重要依据。通过编写带审计逻辑的存储过程,能自动将执行时间、执行人、入参、执行状态等信息写入监控表,方便后续追溯操作轨迹。

审计监控表设计
首先需要创建专门存储存储过程执行记录的监控表,表结构需要覆盖核心审计维度,以下是通用的表结构设计示例:
-- 创建存储过程审计监控表
CREATE TABLE proc_audit_log (
log_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '日志ID',
proc_name VARCHAR(100) NOT NULL COMMENT '存储过程名称',
exec_user VARCHAR(50) NOT NULL COMMENT '执行用户',
exec_start_time DATETIME NOT NULL COMMENT '执行开始时间',
exec_end_time DATETIME COMMENT '执行结束时间',
exec_status TINYINT NOT NULL COMMENT '执行状态 1成功 0失败',
input_params TEXT COMMENT '输入参数',
error_msg TEXT COMMENT '错误信息',
affect_rows INT DEFAULT 0 COMMENT '影响行数'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='存储过程执行审计日志表';
基础审计存储过程编写
编写存储过程时,需要在执行核心逻辑前后插入审计记录写入的逻辑,同时捕获执行过程中的异常,保证无论执行成功还是失败都能记录日志。以下是带审计功能的存储过程示例:
-- 创建带审计功能的示例存储过程,实现用户数据插入并记录审计日志
DELIMITER //
CREATE PROCEDURE insert_user_data(
IN p_user_name VARCHAR(50),
IN p_user_age INT,
OUT p_result_code INT
)
BEGIN
-- 定义变量存储审计相关值
DECLARE v_start_time DATETIME;
DECLARE v_end_time DATETIME;
DECLARE v_error_msg TEXT;
DECLARE v_affect_rows INT DEFAULT 0;
DECLARE v_exec_status TINYINT DEFAULT 1;
DECLARE v_proc_name VARCHAR(100) DEFAULT 'insert_user_data';
DECLARE v_exec_user VARCHAR(50);
-- 获取当前执行用户
SELECT CURRENT_USER() INTO v_exec_user;
-- 记录执行开始时间
SET v_start_time = NOW();
-- 开启事务
START TRANSACTION;
-- 核心业务逻辑:插入用户数据
INSERT INTO user_info (user_name, user_age) VALUES (p_user_name, p_user_age);
-- 获取影响行数
SET v_affect_rows = ROW_COUNT();
-- 提交事务
COMMIT;
SET p_result_code = 0;
-- 异常处理块
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
-- 获取错误信息
GET DIAGNOSTICS CONDITION 1
v_error_msg = MESSAGE_TEXT;
-- 回滚事务
ROLLBACK;
-- 标记执行失败
SET v_exec_status = 0;
SET p_result_code = 1;
END;
-- 记录执行结束时间
SET v_end_time = NOW();
-- 写入审计日志到监控表
INSERT INTO proc_audit_log (
proc_name,
exec_user,
exec_start_time,
exec_end_time,
exec_status,
input_params,
error_msg,
affect_rows
) VALUES (
v_proc_name,
v_exec_user,
v_start_time,
v_end_time,
v_exec_status,
CONCAT('user_name:', p_user_name, ',user_age:', p_user_age),
v_error_msg,
v_affect_rows
);
END //
DELIMITER ;
审计逻辑核心要点
- 执行时间记录:需要在存储过程最开始记录开始时间,在核心逻辑执行完成后记录结束时间,保证时间记录的准确性。
- 异常捕获:必须使用
DECLARE HANDLER捕获SQL异常,避免存储过程执行失败后没有日志记录,同时保证事务能正确回滚。 - 参数记录:输入参数需要拼接成字符串写入监控表,方便后续查看执行时的入参情况,复杂参数可以序列化为JSON格式存储。
- 用户信息获取:通过
CURRENT_USER()函数获取当前执行存储过程的数据库用户,保证审计信息的真实性。
审计日志查询示例
存储过程执行后,可以通过查询监控表获取执行记录,以下是常用的查询示例:
-- 查询最近7天的存储过程执行审计日志
SELECT
log_id,
proc_name,
exec_user,
exec_start_time,
exec_end_time,
CASE exec_status WHEN 1 THEN '成功' ELSE '失败' END AS status_desc,
input_params,
error_msg,
affect_rows
FROM proc_audit_log
WHERE exec_start_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
ORDER BY exec_start_time DESC;
注意事项
审计日志表需要定期清理历史数据,避免表数据量过大影响写入性能,建议保留3-6个月的历史审计数据,超过期限的数据可以归档到其他表或者备份到文件。
如果存储过程有嵌套调用的情况,可以在审计表中增加父日志ID字段,记录调用链路,方便追溯多层存储过程的执行关系。同时建议给监控表的proc_name、exec_start_time字段添加索引,提升审计日志的查询效率。