Oracle UNDO表空间占满的解决场景
点击标题下「蓝色微信名」可快速关注
Oracle的UNDO是很多功能的核心基础,如果了解UNDO的原理,像一致性读、事务回滚、实例恢复等特性,就会更容易理解。徐老师写的这篇文章《实用小技巧:UNDO 100%占用不释放解决办法》,给我们介绍了UNDO空间占满不释放的一个场景,以及相应的解决,这是我们日常工作中可能碰到的,解决步骤可以直接借鉴参考。
1、问题现像
这个问题的起因是客户的存储没空间了,目前RAC1节点UNDOTBS1占用200多G,想要将UNDO释放一下。
undo_retention设置的是900,按说不应该增长到很大才对,以前确实没有注意,只是加过几次undo数据文件。
数据库的版本为12CR2,操作系统为solaris 11。
查看发现有大量unexpired,

Oracle Undo段中区3种状态(DBA_UNDO_EXTENTS的STATUS列):ACTIVE、EXPIRED和UNEXPIRED。
ACTIVE即未提交的Undo信息(活动):表示事物还在活动,该值对应的Undo段的DBA_ROLLBACK_SEGS.STATUS一定是ONLINE状态,一旦没有活动的事务在使用Undo段,那么对应的Undo段就变成OFFLINE状态。ACTIVE状态的Undo区不会被覆盖。
EXPIRED即过期的Undo信息(过期):表示事务已经提交且超过了UNDO_RETENTION指定时间,该状态可以被覆盖使用。
UNEXPIRED即提交的Undo信息(未过期):表示事务已经提交但是还没有超过UNDO_RETENTION指定时间,该状态可以被覆盖使用。
2、解决UNDO过大的问题
2.1、修改隐藏参数关闭autotune
查看隐藏参数_undo_autotune默认状态为true,
SELECT ksppinm, ksppstvl, ksppdesc
FROM x$ksppi x, x$ksppcv y
WHERE x.indx = y.indx AND ksppinm = '_undo_autotune';
方法1,限制undo retention最大时间,就是在自动调整的结果上强制限制最大时间(试了效果不大)。
alter system set "_highthreshold_undoretention"=50000 scope=spfile;
隔了一天再检查,

再检查状态基本都为expired状态,
select status, count(*) Num_Extents, sum(blocks) Num_Blocks, round((sum(bytes)/1024/1024),2) MB
from dba_undo_extents
group by status order by status;
数据库的版本是12.2。默认使用LOCAL UNDO。
先切换到PDB,
SQL> alter session set container=pdb;
Session altered.