在 Oracle SQL 中找不到 table 的最后修改日期

Cannot find last modification date for a table in Oracle SQL

我的数据库中有两个 table,我正在尝试使用 "SCN_TO_TIMESTAMP(MAX(ora_rowscn ))" 和 Oracle 12DB 中的 "dba_tab_modifications"。

以下是两个table的信息:

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/1822:00:02

谁能告诉我为什么我无法获取表 1 的最后一个 DML,但我可以获取表 2 的最后一个 DML?

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

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

任何人都可以告诉我如何获得第一个 table 的最后一个 DML 的想法吗?提前致谢!

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

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

优化器使用

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

如果这是你需要推进的事情,你可以

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

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