简体   繁体   English

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

[英]Cannot find last modification date for a table in Oracle SQL

I have two tables on my database, and I am trying to get the last DML (Insert, update or delete timestamp) using "SCN_TO_TIMESTAMP(MAX(ora_rowscn))" and "dba_tab_modifications" in Oracle 12DB.我的数据库中有两个表,我正在尝试使用 Oracle 12DB 中的“SCN_TO_TIMESTAMP(MAX(ora_rowscn))”和“dba_tab_modifications”获取最后一个 DML(插入、更新或删除时间戳)。

Following is the information for the two 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

Following is the result:结果如下:

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

Earliest date from dba/all_tab_modifications:来自 dba/all_tab_modifications 的最早日期:

02/OCT/18 22:00:02 02/10/18 22:00:02

Can anyone share me a light why I am not able to get the last DML for Table1, but I ma able to get it for Table2?谁能告诉我为什么我无法获得 Table1 的最后一个 DML,但我可以为 Table2 获得它?

I was thinking to execute "DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO" as advised from other blogs.我想按照其他博客的建议执行“DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO”。 However, my question is if the DML for second table have been monitored, it should have already been flushed.但是,我的问题是如果第二个表的 DML 已被监控,它应该已经被刷新。

Both tables ae updated inside different store procedures under the same user ID.两个表都在同一用户 ID 下的不同存储过程中更新。

Can anyone share me an idea on how can I get the last DML for the first table?任何人都可以分享我如何获得第一个表的最后一个 DML 的想法吗? Thanks in advance!提前致谢!

Realistically, if you need this information, you need to store it in the table, use auditing, or do something else to capture changes (ie triggers that populate a table of modifications).实际上,如果您需要此信息,则需要将其存储在表中、使用审计或执行其他操作来捕获更改(即填充修改表的触发器)。

max(ORA_ROWSCN) will work to give you the last SCN of a modification (note that by default, this is stored at the block level not at the row level, so rows with the max(ora_rowscn) aren't necessarily the most recently modified). max(ORA_ROWSCN)将为您提供修改的最后一个 SCN(请注意,默认情况下,这存储在块级别而不是行级别,因此具有max(ora_rowscn)行不一定是最近修改的)。 But Oracle only maintains the mapping of SCN to timestamp for a limited period of time.但是 Oracle 只在有限的时间内维护 SCN 到时间戳的映射。 In the documentation , Oracle guarantees it will maintain the mapping for 120 hours (5 days).文档中,Oracle 保证它将维护映射 120 小时(5 天)。 If the last modification was more than a few days ago, scn_to_timestamp will no longer work.如果上次修改是在几天前, scn_to_timestamp将不再起作用。 If your system has a relatively constant rate of SCN generation, you could try to build your own function to generate approximate timestamps but that could produce significant inaccuracies.如果您的系统具有相对恒定的 SCN 生成率,您可以尝试构建自己的函数来生成近似时间戳,但这可能会产生明显的不准确性。

dba_tab_modifications is used by the optimizer to identify tables that need new stats gathered so that data is even more transient.优化器使用dba_tab_modifications来识别需要收集新统计信息的表,以便数据更加短暂。 If you have statistics gathering enabled every night, you'd expect that information about some tables would get removed every night depending on which tables had fresh statistics gathered.如果您每晚都启用统计信息收集,您会期望每晚都会删除有关某些表的信息,具体取决于哪些表收集了新的统计信息。 Plus, the timestamp isn't intended to accurately identify the time the underlying table was modified but the time that Oracle wrote the monitoring information.另外,时间戳不是为了准确识别底层表被修改的时间,而是 Oracle 写入监控信息的时间。

If this is something you need going forward, you could如果这是你需要继续做的事情,你可以

  • Add a timestamp to the table that gets populated when a row is modified.向表中添加一个时间戳,在修改行时填充该时间戳。
  • Add some logging to the stored procedures that lets you identify when tables were modified.向存储过程添加一些日志记录,以便您识别表何时被修改。
  • Put a trigger on the table that logs modifications in whatever form is useful to you.在表上放置一个触发器,以对您有用的任何形式记录修改。
  • Use Oracle's built-in auditing to capture DML affecting the table.使用 Oracle 的内置审计来捕获影响表的 DML。

If you're really determined, assuming that the database is in archivelog mode and that you have all the archived log files since each table was last modified, you could use LogMiner to read through each archived log and find the timestamp of the last modification.如果您真的确定,假设数据库处于archivelog模式并且您拥有自上次修改每个表以来的所有归档日志文件,您可以使用 LogMiner 读取每个归档日志并找到上次修改的时间戳。 But that will be exceedingly slow and depends on your backup strategy allowing you to recover old log files back to the last change.但这会非常慢,并且取决于您的备份策略,允许您将旧日志文件恢复到上次更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM