一、故事背景
这个问题在测试环境碰到多次了,今天又碰到了,详细记录下
在无业务情况下,存在一部分undo unexpired状态即使超过undo_retention参数的时间也不转换为expired状态,重启数据库也没用
二、问题分析
碰到这个问题,我首先看了下_undo_autotune是什么值,为false,那么undo保留时间就是按照undo_retention参数来的
然后再看下了v$undostat 试图看看undo_retention字段,也没问题,但时间范围有点奇怪,2030年
看到这,我去翻了翻操作系统历史命令,发现修改过时间,改到过2030年,然后又改回来过
到这怀疑和修改过时间有关系,然后抱着上MOS搜搜有没有undo和时间变动有关的bug之类的
然后找到了(Doc ID 2649640.1),里面介绍了undo会记录最后事务提交的时间戳,只有这个时间+undo_retention undo才会变成expired
询问项目组后了解到,项目组向后调整时间进行跑批测试,测试完成后再调整时间回来,至此问题已得到答案
三、测试
# 修改操作系统时间到2030年
[root@cesdb1 ~]# date -s "2030-05-15 `date|awk '{print $4}'`"
Wed May 15 13:24:04 CST 2030
# 数据库删除一个表
TEST@orcl_dg3> delete from test;
92293 rows deleted.
# 查看当前会话
TEST@orcl_dg3> select distinct sid from v$mystat;
SID
-------
107
# 另开个窗口查看使用的undo段
XID USERNAME START_TIME SID SERIAL# SQL_ID USN SEGMENT_NAME STATUS MB
---------------- --------------- -------------------- ------ ------- --------------- ------ ----------------------- -------- --------
1F03000002000000 TEST 05/15/30 13:27:49 107 1527 cb5m2z04qzgzn 799 _SYSSMU799_3805507432$ ONLINE 26
# 之前的事务提交,让undo 从active变成unexpired
TEST@orcl_dg3> commit;
Commit complete.
# 修改操作系统时间回来
[root@cesdb1 ob]# date -s "2025-05-15 `date|awk '{print $4}'`"
Thu May 15 13:29:13 CST 2025
# 这里等待超过undo_retention的时间,查看undo状态还是UNEXPIRED,符合MOS描述的情况
SYS@orcl_dg3> select SEGMENT_NAME,STATUS,count(*) from dba_undo_extents where segment_name='_SYSSMU799_3805507432$' group by SEGMENT_NAME,STATUS;
SEGMENT_NAME STATUS COUNT(*)
------------------------------ --------- ----------
_SYSSMU799_3805507432$ UNEXPIRED 41
# 这里进行dump undo头进行查下
SYS@orcl_dg3> oradebug setmypid
Statement processed.
SYS@orcl_dg3> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/orcl_dg/orcl_dg3/trace/orcl_dg3_ora_67572.trc
SYS@orcl_dg3> alter system dump undo header '_SYSSMU799_3805507432$';
System altered.
# undo header dump文件我也看不太懂,看不懂就要看猜, **Commit Time: 1905053305** ,一看就知道是我要找的东西
view /u01/app/oracle/diag/rdbms/orcl_dg/orcl_dg3/trace/orcl_dg3_ora_67572.trc
Retention Table
-----------------------------------------------------------
Extent Number:0 Commit Time: 1905053305
Extent Number:1 Commit Time: 1905053305
Extent Number:2 Commit Time: 1905053305
Extent Number:3 Commit Time: 1905053305
......
Extent Number:37 Commit Time: 1905053305
Extent Number:38 Commit Time: 1905053305
Extent Number:39 Commit Time: 1905053305
Extent Number:40 Commit Time: 1905053305
# 这个一看长度10位,那么大概就是从1970-01-01到现在的秒数,这里转换看下,确实是事务提交的时间
SYS@orcl_dg3> select to_char(timestamp '1970-01-01 08:00:00' + numtodsinterval(1905053305,'second'),'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(TIMESTAMP'1
-------------------
2030-05-15 13:28:25
UNDO Tablespace Problem With Changing Operating System (OS) Date/Time (Doc ID 2649640.1)
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




