You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何查看数据库某表含存储过程的全部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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:54:34