Reputation: 522
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.
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:
02/OCT/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?
I was thinking to execute "DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO" as advised from other blogs. However, my question is if the DML for second table have been monitored, it should have already been flushed.
Both tables ae updated inside different store procedures under the same user ID.
Can anyone share me an idea on how can I get the last DML for the first table? Thanks in advance!
Upvotes: 0
Views: 2768
Reputation: 231651
Realistically, if you need this information, you need to store it in the table, use auditing, or do something else to capture changes (i.e. 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). But Oracle only maintains the mapping of SCN to timestamp for a limited period of time. In the documentation, Oracle guarantees it will maintain the mapping for 120 hours (5 days). If the last modification was more than a few days ago, scn_to_timestamp
will no longer work. 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.
dba_tab_modifications
is used by the optimizer to identify tables that need new stats gathered so that data is even more transient. 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.
If this is something you need going forward, you could
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. But that will be exceedingly slow and depends on your backup strategy allowing you to recover old log files back to the last change.
Upvotes: 2