求助:如何查看数据库某表含存储过程的全部DML执行历史
看来你已经做了不少排查工作了——试过v$sql、查过常规SQL日志,但还是抓不到存储过程内部执行的DML,确实挺头疼的。针对Oracle数据库,我给你几个靠谱的方案,按场景来选:
方案1:启用Oracle原生审计(Audit)
这是最直接的原生方案,能捕获所有层级的DML操作(包括存储过程/触发器内部执行的语句)。
- 首先确认审计是否开启,执行:
如果返回SHOW PARAMETER audit_trail;NONE,需要修改参数开启(需重启数据库):
重启后再次确认参数生效。ALTER SYSTEM SET audit_trail=DB,EXTENDED SCOPE=SPFILE; - 针对目标表开启DML审计:
AUDIT DELETE, INSERT, UPDATE ON your_table_name BY ACCESS;BY ACCESS会记录每一次操作,而非会话级汇总,更适合排查单条删除这类精准场景。 - 查询审计记录:
使用dba_common_audit_trail视图获取完整记录,比如:
这里的SELECT timestamp, userhost, os_username, username, sql_text, obj_name FROM dba_common_audit_trail WHERE obj_name = 'YOUR_TABLE_NAME' AND action_name IN ('DELETE', 'INSERT', 'UPDATE') ORDER BY timestamp DESC;sql_text会包含存储过程内部执行的实际DML语句,哪怕是动态SQL也能捕获到(前提是开启了EXTENDED审计)。
方案2:细粒度审计(FGA)
如果只关心特定条件的DML(比如删除某类行),FGA比原生审计更灵活,还能捕获更多上下文信息。
- 创建FGA策略:
BEGIN DBMS_FGA.ADD_POLICY( object_schema => 'YOUR_SCHEMA', object_name => 'YOUR_TABLE_NAME', policy_name => 'AUDIT_YOUR_TABLE_DML', audit_condition => '1=1', -- 可自定义条件,比如"id > 1000" audit_column => NULL, -- 审计所有列 enable => TRUE, statement_types => 'DELETE,INSERT,UPDATE', audit_trail => DBMS_FGA.DB + DBMS_FGA.EXTENDED ); END; / - 查询FGA记录:
SELECT timestamp, db_user, os_user, sql_text, object_name FROM dba_fga_audit_trail WHERE object_name = 'YOUR_TABLE_NAME' ORDER BY timestamp DESC;
方案3:使用LogMiner挖掘归档日志
如果你的数据库开启了归档模式,LogMiner可以直接从归档日志里提取所有DML操作,适合事后回溯排查(比如已经发生了删除,现在要找根源)。
- 首先确认归档模式:
只有返回SELECT log_mode FROM v$database;ARCHIVELOG才能使用该方案。 - 启动LogMiner:
BEGIN DBMS_LOGMNR.START_LOGMNR( STARTTIME => TO_DATE('2024-05-01 00:00:00','YYYY-MM-DD HH24:MI:SS'), -- 替换为排查起始时间 ENDTIME => SYSDATE, OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.CONTINUOUS_MINE ); END; / - 查询挖掘到的DML记录:
SELECT timestamp, username, sql_redo, sql_undo FROM v$logmnr_contents WHERE table_name = 'YOUR_TABLE_NAME' AND operation IN ('DELETE', 'INSERT', 'UPDATE') ORDER BY timestamp DESC;sql_redo是执行的原始语句,sql_undo是可用于回滚的语句,非常实用。 - 结束LogMiner:
EXEC DBMS_LOGMNR.END_LOGMNR;
注意事项
- 审计功能会占用一定的存储资源,排查完成后记得关闭不必要的审计策略,避免性能影响。
- 如果是事后排查且之前没开启审计,LogMiner是唯一能回溯历史操作的方案(前提是归档日志未被清理)。
内容的提问来源于stack exchange,提问作者glatorre
相关产品推荐
相关产品推荐

