【问题标题】:Cannot find last modification date for a table in Oracle SQL在 Oracle SQL 中找不到表的最后修改日期
【发布时间】:2020-10-29 03:28:01
【问题描述】:

我的数据库中有两个表,我正在尝试使用 Oracle 12DB 中的“SCN_TO_TIMESTAMP(MAX(ora_rowscn))”和“dba_tab_modifications”获取最后一个 DML(插入、更新或删除时间戳)。

以下是两个表的信息:

Table Name | Create Date | Last DML           | SCN_TO_TIMESTAMP(MAX(ora_rowscn))
           |             |(as given from user)|
-----------+-------------+--------------------+-----------------------------------
Table1     | 25 SEP 2017 | 13 OCT 2020        |ORA-08181: specified number is not a valid system change number
           |             |                    |ORA-06512: at "SYS.SCN_TO_TIMESTAMP"
Table2     | 30 JAN 2017 | 29 OCT 2020

结果如下:

Table Name | SCN_TO_TIMESTAMP(MAX(ora_rowscn))    |dba/all_tab_modifications
-----------+--------------------------------------+-------------------------
Table1     |ORA-08181: specified number is not a  | NULL (0 row returned)
           | valid system change number           |
           |ORA-06512: at "SYS.SCN_TO_TIMESTAMP"  |
Table2     |29/OCT/20 03:40:15.000000000 AM       | 29/OCT/20 03:50:52

dba/all_tab_modifications 的最早日期:

02/OCT/18 22:00:02

谁能告诉我为什么我无法获得 Table1 的最后一个 DML,但我能够获得 Table2 的最后一个 DML?

我正在考虑按照其他博客的建议执行“DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO”。但是,我的问题是,如果第二个表的 DML 已经被监控,它应该已经被刷新了。

两个表都在同一用户 ID 下的不同存储过程中更新。

谁能分享我如何获得第一张桌子的最后一个 DML 的想法?提前致谢!

【问题讨论】:

    标签: sql database oracle12c


    【解决方案1】:

    实际上,如果您需要此信息,则需要将其存储在表中、使用审核或执行其他操作来捕获更改(即填充修改表的触发器)。

    max(ORA_ROWSCN) 将为您提供修改的最后一个 SCN(请注意,默认情况下,它存储在块级别而不是行级别,因此带有 max(ora_rowscn) 的行不一定是最近的修改的)。但是 Oracle 只在有限的时间段内维护 SCN 到时间戳的映射。在the documentation 中,Oracle 保证它将维护映射 120 小时(5 天)。如果最后一次修改是几天前,scn_to_timestamp 将不再起作用。如果您的系统具有相对恒定的 SCN 生成速率,您可以尝试构建自己的函数来生成近似时间戳,但这可能会产生严重的不准确性。

    dba_tab_modifications 被优化器用来识别需要收集新统计信息的表,以便数据更加短暂。如果您每晚都启用了统计信息收集,您会希望每晚都会删除有关某些表的信息,具体取决于哪些表收集了新的统计信息。另外,时间戳并不是为了准确识别基础表的修改时间,而是 Oracle 写入监控信息的时间。

    如果这是你需要的东西,你可以

    • 向表中添加时间戳,在修改行时填充该表。
    • 向存储过程添加一些日志记录,以便您识别何时修改表。
    • 在表上放置一个触发器,以对您有用的任何形式记录修改。
    • 使用 Oracle 的内置审计来捕获影响表的 DML。

    如果您真的确定,假设数据库处于archivelog 模式并且您拥有自上次修改每个表以来的所有归档日志文件,您可以使用 LogMiner 读取每个归档日志并找到时间戳的最后一次修改。但这会非常慢,并且取决于您的备份策略是否允许您将旧日志文件恢复到上次更改。

    【讨论】:

    • 知道了!谢谢。老实说,我之所以确定表 1,是因为我在修改 table1 的 SP 上有自己的日志。非常感谢!很有帮助!
    猜你喜欢
    • 2011-05-22
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    相关资源
    最近更新 更多