我的数据库中有两个表,我正试图使用"TIMESTAMP(MAX(ora_rowscn((";以及";dba_ tab_;在Oracle 12DB中。
以下是两个表的信息:
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的最早日期:
2018年10月2日22:00:02
有人能告诉我为什么我不能为表1获得最后一个DML,但我可以为表2获得它吗?
我想执行";DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO";正如其他博客所建议的那样。然而,我的问题是,如果第二个表的DML已经被监控,那么它应该已经被刷新了。
在相同的用户ID下,两个表都在不同的存储过程中更新。
有人能告诉我如何才能获得第一张桌子的最后一张DML吗?提前感谢!
实际上,如果您需要这些信息,您需要将其存储在表中,使用审计或执行其他操作来捕获更改(即填充修改表的触发器(。
max(ORA_ROWSCN)
将为您提供修改的最后一个SCN(请注意,默认情况下,它存储在块级别,而不是行级别,所以具有max(ora_rowscn)
的行不一定是最近修改的(。但Oracle只在有限的时间内维护SCN到时间戳的映射。在文档中,Oracle保证将维护映射120小时(5天(。如果最后一次修改发生在几天前,scn_to_timestamp
将不再工作。如果您的系统具有相对恒定的SCN生成速率,您可以尝试构建自己的函数来生成近似的时间戳,但这可能会产生显著的不准确。
优化器使用dba_tab_modifications
来识别需要收集新统计数据的表,以便数据更加瞬态。如果你每晚都启用统计数据收集,你会期望一些表的信息每晚都会被删除,这取决于哪些表收集了新的统计数据。此外,时间戳并不是用来准确识别基础表被修改的时间,而是Oracle写入监控信息的时间。
如果这是你需要的东西,你可以
- 向修改行时填充的表添加时间戳
- 在存储过程中添加一些日志记录,以便识别表何时被修改
- 在表上设置一个触发器,以任何对您有用的形式记录修改
- 使用Oracle的内置审核来捕获影响表的DML
如果您真的确定了,假设数据库处于archivelog
模式,并且您拥有自上次修改每个表以来的所有存档日志文件,那么您可以使用LogMiner来读取每个存档日志,并找到上次修改的时间戳。但这将非常缓慢,并且取决于您的备份策略,该策略允许您将旧日志文件恢复到上次更改。