SQL Server用Audit功能审计存储过程执行,MySQL通过general_log或audit_log插件,PostgreSQL依赖log_statement与pg_stat_statements组合;三者均不记录参数值,需扩展机制或应用层埋点。

SQL Server 中如何开启存储过程执行审计
SQL Server 本身不自动记录谁调用了哪个存储过程,必须主动启用跟踪或日志机制。最直接有效的方式是用 SQL Server Audit 功能,它底层基于 Extended Events,开销低、权限粒度细、支持写入文件或安全日志。
- 必须在
master数据库中创建服务器审核(CREATE SERVER AUDIT),再绑定到具体数据库的审核规范(CREATE DATABASE AUDIT SPECIFICATION) - 要审计存储过程执行,得在规范中添加
EXECUTE ON DATABASE::[YourDB] BY [public]操作——注意不是ON OBJECT::[proc_name],那是针对单个对象的权限检查,不是执行行为捕获 - 审核默认不记录参数值,只记
object_name和session_id;如果需要参数内容,得配合fn_get_audit_file()解析原始事件,或改用 Extended Events 单独捕获rpc_completed事件
MySQL 8.0 怎么记录 CALL 执行行为
MySQL 没有原生“存储过程执行审计”开关,但可通过 general_log 或 audit_log 插件实现。前者简单粗暴,后者更可控但需企业版或 MySQL Enterprise Edition。
- 开启
general_log后,所有语句(包括CALL proc_name())都会被记录,但无法区分是应用直连执行还是通过事件/触发器间接调用,且日志体积增长快、影响性能 -
audit_log插件可过滤出command_class = 'call_procedure'的事件,但要求 MySQL 版本 ≥ 8.0.19 且插件已安装启用;配置项audit_log_policy必须设为ALL或LOGINS才能捕获执行动作 - 日志里不会显示传入的具体参数值,只有
CALL proc_name字符串;如需参数,只能靠应用层打点或在存储过程中手动插入审计表
PostgreSQL 如何追踪 SELECT * FROM pg_proc + EXECUTE
PostgreSQL 不提供开箱即用的过程调用审计,但能组合 pg_stat_statements 扩展和日志参数实现近似效果。关键在于:它不记录“谁调了”,而记录“哪条语句被高频执行”,所以必须配合连接信息补全上下文。
- 启用
log_statement = 'mod'或'all'可让日志包含CALL proc_name(),但会混在大量 DML 日志中;建议同时设置log_line_prefix = '%u@%d %h %t '来带上用户名、数据库名、客户端 IP 和时间 -
pg_stat_statements能统计每个CALL的执行次数和耗时,但query字段只保留模板(如CALL my_proc($1, $2)),不存实际参数值 - 若需精确到用户+过程+参数,唯一可靠方式是在每个存储过程中显式插入审计表,例如:
INSERT INTO audit_log(user_name, proc_name, args, exec_time) VALUES (current_user, 'my_proc', current_query(), now());
审计日志里看不到参数值是常态,别指望自动补齐
几乎所有主流数据库的内置审计机制都把参数值当作敏感内容默认剥离,这不是配置遗漏,而是设计取舍。想拿到真实参数,要么改用 Extended Events / MySQL audit plugin 的原始事件解析,要么在业务逻辑层埋点——后者虽然多写几行,但可控、可过滤、不依赖 DBA 权限。
尤其要注意:某些 ORM(比如 Hibernate)会把 CALL 包装成 SELECT 发送,导致审计日志里根本看不到 CALL 关键字;这时只能从网络层抓包或在数据库驱动里加拦截器。










