在 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 读取通过每个归档日志并找到最后一次修改的时间戳。但这会非常慢,并且取决于您的备份策略是否允许您将旧日志文件恢复到上次更改。
我的数据库中有两个 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 读取通过每个归档日志并找到最后一次修改的时间戳。但这会非常慢,并且取决于您的备份策略是否允许您将旧日志文件恢复到上次更改。