在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在Oracle数据库中,如何查找,定位一张表最后一次的DML操作的时间呢? 方式有三种,不过都有一些局限性,下面简单的解析、总结一下。 1:使用ORA_ROWSCN伪列获取表最后的DML时间 ORA_ROWSCN伪列是Oracle 10g开始引入的,可以查询表中记录最后变更的SCN。然后通过 SELECT MAX(ORA_ROWSCN), SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)) FROM xxx.xxx; 如下所示,我们可以创建一个表TEST,然后查一查TEST表最后的DML的操作时间。如下所示: SQL> CREATE TABLE TEST.TEST ( ID NUMBER); Table created. SQL> COL OWNER FOR A12; SQL> COL TABLE_NAME FOR A32; SQL> COL MONITORING FOR A32; SQL> SELECT OWNER, TABLE_NAME, MONITORING 2 FROM DBA_TABLES 3 WHERE OWNER='TEST' 4 AND TABLE_NAME='TEST'; OWNER TABLE_NAME MONITORING ------------ -------------------------------- -------------------------------- TEST TEST YES SQL> INSERT INTO TEST.TEST VALUES(1); 1 row created. SQL> COMMIT; Commit complete. SQL> SELECT sysdate FROM DUAL; SYSDATE ------------------- 2018-11-19 14:34:12 SQL> SELECT MAX(ORA_ROWSCN), SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)) FROM TEST.TEST; MAX(ORA_ROWSCN) SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)) --------------- -------------------------------------------------------------- 52782810 19-NOV-18 02.34.03.000000000 PM SQL> 使用ORA_ROWSCN伪列获取表最新的DML时间,也有一些不足和缺陷,具体如下所示: 1:使用SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN))获取表最后的DML操作时,有可能会遇到ORA-08181错误。
SCN和时间戳的这种转换要依赖于数据库内部的数据记录,而这些数据记录就来自SMON_SCN_TIME基表,具体来说,SMON_SCN_TIME基表用于记录过去时间段中SCN(system change number)与具体的时间戳(timestamp)之间的映射关系,因为是采样记录这种映射关系,所以SMON_SCN_TIME可以较为粗糙地(不精确地)定位某个SCN的时间信息。实际的SMON_SCN_TIME是一张簇表。而且从10g开始SMON也会定期清理SMON_SCN_TIME中的记录,所以对于比较久远的SCN则不能转换。也就出现了数据库某些表使用SCN_TO_TIMESTAMP函数时,会遇到ORA-08181错误,如下所示,我们用比基表SMON_SCN_TIME中MIN(SCN)的还小1的SCN做转换时,就会遇到ORA-08181这个错误。 根据官方文档来看: SMON进程每5分钟采集一次插入到
2: 使用ORA_ROWSCN伪列获取表中某一行的DML操作时间可能不准确,当然对于获取表最后的DML时间是准确的。 默认情况下,每行记录的ORA_ROWSCN是基于数据块(block)的,这样对于某一行最后的DML时间是不准确的,除非在建表的时候执行开启行级跟踪(create table … rowdependencies),这样才会是在行级记录级别的SCN。而每个数据块(block)在头部是记录了该数据块(block)最近事务的SCN,所以默认情况下,只需要从块的头部直接获取这个值就可以了,不需要其他任何的开销。但是这明显是不精确的,一个数据块(block)中会有很多行记录,每次事务不可能影响到整个数据块(block)中所有的行,所以这是一个非常不精准的估算值,同一个数据块(block)的所有记录的ORA_ROWSCN都会是相同的.如下实验所示, 当然对于获取表最后的DML时间是准确的。所以对于每一行的ORA_ROWSCN要求精确的话,就必须开启行级跟踪。 SQL> SELECT * FROM TEST.TEST; ID ---------- 1 SQL> SELECT ID, SCN_TO_TIMESTAMP(ORA_ROWSCN) FROM TEST.TEST; ID SCN_TO_TIMESTAMP(ORA_ROWSCN) ---------- ------------------------------------------------------------------- 1 19-NOV-18 02.34.03.000000000 PM SQL> INSERT INTO TEST.TEST VALUES(2); 1 row created. SQL> COMMIT; Commit complete. SQL> INSERT INTO TEST.TEST VALUES(3); 1 row created. SQL> COMMIT; Commit complete. SQL> SELECT ID, SCN_TO_TIMESTAMP(ORA_ROWSCN) FROM TEST.TEST; ID SCN_TO_TIMESTAMP(ORA_ROWSCN) ---------- --------------------------------------------------------------- 1 19-NOV-18 03.41.01.000000000 PM 2 19-NOV-18 03.41.01.000000000 PM 3 19-NOV-18 03.41.01.000000000 PM 3:假如表的数据被TRUNCATE掉或全部DELETE后,也会导致无法定位最后一次DML操作的时间。如下所示: 2:使用DBA_TAB_MODIFICATIONS来查找、定为最后的DML操作时间
使用DBA_TAB_MODIFICATIONS来查看表最后DML的操作时间,如下测试所示 SQL> CREATE TABLE TEST.TEST (ID NUMBER); Table created. SQL> COL OWNER FOR A12; SQL> COL TABLE_NAME FOR A32; SQL> COL MONITORING FOR A32; SQL> SELECT OWNER, TABLE_NAME, MONITORING 2 FROM DBA_TABLES 3 WHERE OWNER='TEST' 4 AND TABLE_NAME='TEST'; OWNER TABLE_NAME MONITORING ------------ -------------------------------- -------------------------------- TEST TEST YES SQL> INSERT INTO TEST.TEST VALUES(1); 1 row created. SQL> COMMIT; Commit complete. SQL> ALTER SESSION SET NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"; Session altered. SQL> SELECT INSERTS,UPDATES,DELETES,TRUNCATED,TIMESTAMP 2 FROM DBA_TAB_MODIFICATIONS 3 WHERE TABLE_NAME='TEST' AND TABLE_OWNER='TEST'; no rows selected SQL> EXEC DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO; PL/SQL procedure successfully completed. SQL> SELECT INSERTS,UPDATES,DELETES,TRUNCATED,TIMESTAMP 2 FROM DBA_TAB_MODIFICATIONS 3 WHERE TABLE_NAME='TEST' AND TABLE_OWNER='TEST'; INSERTS UPDATES DELETES TRU TIMESTAMP ---------- ---------- ---------- --- ------------------- 1 0 0 NO 2018-11-20 10:34:24 但是用DBA_TAB_MODIFICATIONS来定位表最后的DML操作时间也有一定的局限性。如下所示,有些局限性会影响定位最后DML操作的时间的准确性。 1:如果表没有设置MONITORING属性,那么DBA_TAB_MODIFICATIONS视图是不会收集相关表的数据的呢。 假如某张表之前没有设置MONITORING属性,那么无法查找最后一次DML操作的时间,设置MONITORING属性后,DBA_TAB_MODIFICATIONS视图里面收集的是这个设置时间点后面的DML操作时间。 2:需要执行EXEC DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO后,视图才会有数据。 3:DML操作不提交或回滚,也会记录到视图中。这样就会导致数据不准确。 未提交情况: 回滚情况: 3:收集完统计信息(ANALYZE或dbms_stats包收集统计信息)后,视图中相关表记录会置空 SQL> SELECT INSERTS,UPDATES,DELETES,TRUNCATED,TIMESTAMP 2 FROM DBA_TAB_MODIFICATIONS 3 WHERE TABLE_NAME='TEST' AND TABLE_OWNER='TEST'; INSERTS UPDATES DELETES TRU TIMESTAMP ---------- ---------- ---------- --- ------------------- 6 0 4 YES 2018-11-20 13:14:08 SQL> exec dbms_stats.gather_table_stats('TEST','TEST'); PL/SQL procedure successfully completed. SQL> SELECT INSERTS,UPDATES,DELETES,TRUNCATED,TIMESTAMP 2 FROM DBA_TAB_MODIFICATIONS 3 WHERE TABLE_NAME='TEST' AND TABLE_OWNER='TEST'; no rows selected SQL> 4:CTAS建立的插入信息不会记录。如下测试所示: SQL> CREATE TABLE TEST.TEST1 2 AS 3 SELECT * FROM TEST.TEST; Table created. SQL> exec dbms_stats.flush_database_monitoring_info; PL/SQL procedure successfully completed. SQL> SELECT INSERTS,UPDATES,DELETES,TRUNCATED,TIMESTAMP 2 FROM DBA_TAB_MODIFICATIONS 3 WHERE TABLE_NAME='TEST1' AND TABLE_OWNER='TEST'; no rows selected 5:DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO收集数据会有几秒的延时,这个时间只能接近最后DML时间,而不是精准的。 SQL> COL OWNER FOR A12; SQL> COL TABLE_NAME FOR A32; SQL> COL MONITORING FOR A32; SQL> SELECT OWNER, TABLE_NAME, MONITORING 2 FROM DBA_TABLES 3 WHERE OWNER='TEST' 4 AND TABLE_NAME='TEST1'; OWNER TABLE_NAME MONITORING ------------ -------------------------------- -------------------------------- TEST TEST1 YES SQL> SQL> SELECT SYSDATE FROM DUAL; SYSDATE ------------------- 2018-11-20 10:46:39 SQL> INSERT INTO TEST.TEST VALUES(10); 1 row created. SQL> SELECT SYSDATE FROM DUAL; SYSDATE ------------------- 2018-11-20 10:46:57 SQL> COMMIT; Commit complete. SQL> SELECT SYSDATE FROM DUAL; SYSDATE ------------------- 2018-11-20 10:47:07 SQL> exec dbms_stats.flush_database_monitoring_info; PL/SQL procedure successfully completed. SQL> SELECT INSERTS,UPDATES,DELETES,TRUNCATED,TIMESTAMP 2 FROM DBA_TAB_MODIFICATIONS 3 WHERE TABLE_NAME='TEST' AND TABLE_OWNER='TEST'; INSERTS UPDATES DELETES TRU TIMESTAMP ---------- ---------- ---------- --- ------------------- 3 0 0 NO 2018-11-20 10:47:13 3:触发器捕获最后DML操作时间 使用触发器捕获DML操作的最后时间是最准确的,但是也是性能开销最大的,不推荐使用。 总结 以上所述是小编给大家介绍的ORACLE中查找定位表最后DML操作的时间小结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对极客世界网站的支持! |
请发表评论