处理Oracle undo表空间不释放问题

处理Oracle undo表空间不释放问题

𝓓𝓸𝓷 Lv6

一、确认对应实例的undo表空间

1
2
3
4
5
6
7
SQL> show parameter undo

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 36000
undo_tablespace string UNDOTBS1

二、确认对应实例undo的文件位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
set linesize 500 pagesize 500
col file_name for a50
select file_name, bytes / 1024 / 1024 / 1024 from dba_data_files where tablespace_name like 'UNDOTBS%';

FILE_NAME BYTES/1024/1024/1024
-------------------------------------------------- --------------------
+DATA/yjdb/datafile/undotbs1.263.944176587 31.9999847
+DATA/yjdb/datafile/undotbs2.259.944176967 31.9999847
+DATA/yjdb/datafile/undotbs1.433081.1114765501 31.25
+DATA/yjdb/datafile/undotbs1.191274.1114765505 31.25
+DATA/yjdb/datafile/undotbs1.93780.1114765509 31.25
+DATA/yjdb/datafile/undotbs2.185805.1150563527 31.9999847
+DATA/yjdb/datafile/undotbs2.130309.1200653803 31.9999847

7 rows selected.

三、确认回滚段使用情况

#如果为空则证明该表空间可以被删除,否则要放其他时间处理尤其生产环境下。

1
2
3
4
5
6
7
8
9
select s.username, u.name
from gv$transaction t, gv$rollstat r, v$rollname u, gv$session s
where s.taddr = t.addr
and t.xidusn = r.usn
and r.usn = u.usn
order by s.username;

no rows selected

四、检查undo segment状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
select usn,
xacts,
status,
rssize / 1024 / 1024,
hwmsize / 1024 / 1024,
shrinks
from v$rollstat
order by rssize;


USN XACTS STATUS RSSIZE/1024/1024 HWMSIZE/1024/1024 SHRINKS
---------- ---------- --------------- ---------------- ----------------- ----------
0 0 ONLINE .3671875 .3671875 0
2 0 ONLINE 1.9296875 2457.17969 418
26 0 ONLINE 9.2421875 2687.17969 433
27 0 ONLINE 17.2421875 4042.99219 398
24 0 ONLINE 42.5546875 2165.17969 427
23 0 ONLINE 47.4296875 696.117188 428
25 0 ONLINE 74.3046875 1536.11719 425
28 0 ONLINE 91.1171875 4092.17969 412
6 0 ONLINE 176.304688 3176.11719 403
9 0 ONLINE 205.429688 4032.11719 238
1 0 ONLINE 252.054688 3382.67969 419
21 0 ONLINE 259.242188 4090.11719 432
3 0 ONLINE 578.242188 2816.17969 417
34 0 ONLINE 609.304688 4092.11719 262
32 0 ONLINE 699.835938 4094.17969 330
22 0 ONLINE 1196.11719 2325.11719 387
5 0 ONLINE 1602.05469 2973.92969 374
4 0 ONLINE 2053.42969 3430.24219 391
29 0 ONLINE 2818.86719 4072.99219 377
33 0 ONLINE 2882.64844 4091.35938 336
10 0 ONLINE 2896.61719 4089.11719 241
31 0 ONLINE 3188.85938 4080.67188 360
8 0 ONLINE 3458.15625 4095.79688 372
7 0 ONLINE 3594.17969 4094.17969 403
30 0 ONLINE 3699.61719 4079.11719 366

25 rows selected.



select INST_ID, to_char(BEGIN_TIME,'YYYY/MM/DD HH24:MI:SS') "BEGIN TIME", END_TIME, UNDOBLKS, TXNCOUNT, UNXPBLKRELCNT, ACTIVEBLKS, UNEXPIREDBLKS, EXPIREDBLKS
from gv$undostat order by 2;

INST_ID BEGIN TIME END_TIME UNDOBLKS TXNCOUNT UNXPBLKRELCNT ACTIVEBLKS UNEXPIREDBLKS EXPIREDBLKS
---------- ------------------- ------------ ---------- ---------- ------------- ---------- ------------- -----------
2 2033/02/26 14:50:05 02-MAR-33 0 0 0 0 0 0
1 2033/02/26 14:52:58 02-MAR-33 0 0 0 0 0 0
1 2033/03/02 05:42:58 02-MAR-33 390 249 0 1008 5636936 164488
2 2033/03/02 05:50:05 02-MAR-33 190 1326 0 768 8125392 24
1 2033/03/02 05:52:58 02-MAR-33 3449 134 0 9200 5190336 602896
2 2033/03/02 06:00:05 02-MAR-33 18 8 0 768 8125392 24
1 2033/03/02 06:02:58 02-MAR-33 2 116 0 1008 5198528 602896
2 2033/03/02 06:10:05 02-MAR-33 5 131 0 768 8125392 24
1 2033/03/02 06:12:58 02-MAR-33 38 130 0 1008 5198528 602896
2 2033/03/02 06:20:05 02-MAR-33 26 17 0 768 8125416 16
1 2033/03/02 06:22:58 02-MAR-33 3 127 0 1008 5198528 602896
2 2033/03/02 06:30:05 02-MAR-33 0 6 0 768 8125416 16
1 2033/03/02 06:32:58 02-MAR-33 1 110 0 1008 5198528 602896
2 2033/03/02 06:40:05 02-MAR-33 26 30 0 768 8124176 0
1 2033/03/02 06:42:58 02-MAR-33 31 424 0 9200 5190336 602896
2 2033/03/02 06:50:05 02-MAR-33 131 125 0 768 8124176 0
1 2033/03/02 06:52:58 02-MAR-33 94530 33521 0 9200 5190336 602896
2 2033/03/02 07:00:05 02-MAR-33 31 274 0 768 296 8124064
1 2033/03/02 07:02:58 02-MAR-33 107710 24943 0 34800 132096 2464192
2 2033/03/02 07:10:05 02-MAR-33 1 35 0 768 296 8124064
1 2033/03/02 07:12:58 02-MAR-33 81823 18953 0 125936 132096 2406848
2 2033/03/02 07:20:05 02-MAR-33 33 411 0 768 296 8124064


五、查看undo表空间使用情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
set num 30
SELECT DISTINCT STATUS,SUM(BYTES)/1024/1024,COUNT(*) FROM DBA_UNDO_EXTENTS GROUP BY STATUS;

select tablespace_name,
round(sum(case
when status = 'EXPIRED' then
blocks
end) * 8 /1024/1024,2) expired_gb,
round(sum(case
when status in ('ACTIVE') then
blocks
end) * 8 /1024/1024,2) active_gb,
round(sum(case
when status in ('UNEXPIRED') then
blocks
end) * 8 /1024/1024,2) unexpired_gb
from dba_undo_extents
where status in ('ACTIVE', 'EXPIRED', 'UNEXPIRED')
group by tablespace_name;

TABLESPACE_NAME EXPIRED_GB ACTIVE_GB UNEXPIRED_GB
------------------------------ ---------- ---------- ------------
UNDOTBS1 0 125.74
UNDOTBS2 0 56.58


SELECT tablespace_name, used_space_mb, total_space_mb, used_space_percent
FROM (SELECT tablespace_name, ROUND(SUM(bytes)/(1024*1024),2) used_space_mb,
ROUND(SUM(maxbytes)/(1024*1024),2) total_space_mb,
ROUND(100*SUM(bytes)/SUM(maxbytes),2) used_space_percent
FROM dba_data_files
WHERE tablespace_name IN (SELECT tablespace_name FROM dba_tablespaces WHERE contents = 'UNDO')
GROUP BY tablespace_name)
ORDER BY used_space_percent DESC;

TABLESPACE_NAME USED_SPACE_MB TOTAL_SPACE_MB USED_SPACE_PERCENT
------------------------------ ------------- -------------- ------------------
UNDOTBS02 10240 32767.98 31.25
UNDOTBS01 10240 32767.98 31.25

---查询 UNDO 表空间的基本信息
set linesize 300 pagesize 300
col file_name for a50
SELECT ts.tablespace_name, ts.status, df.file_name, df.bytes / 1024 / 1024 AS "Size (MB)"
FROM dba_tablespaces ts
JOIN dba_data_files df ON ts.tablespace_name = df.tablespace_name
WHERE ts.contents = 'UNDO';


---查看活跃事务占用undo情况
SELECT
s.sid,
s.serial#,
t.used_ublk,
t.start_time
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE s.status = 'ACTIVE';


The Expired blocks will be reused and hence this should be counted as 'available' space in the Undo segment.

You can check the status of the undo extents via the SQLs below.
select sum(bytes /(1024*1024)) from dba_undo_extents where status='EXPIRED';
select sum(bytes /(1024*1024)) from dba_undo_extents where status='ACTIVE';
select sum(bytes /(1024*1024)) from dba_undo_extents where status='UNEXPIRED';

For more detailed information, please refer to:
Master Note: High Undo Space Usage ( Doc ID 1578639.1 )


---检查undo表空间文件是否自动扩展
SET linesize 1000 pagesize 1000
COL FILE_NAME FOR A50
COL TABLESPACE_NAME FOR A50
COL AUTOEXTENSIBLE FOR A15
COL STATUS FOR A10
COL MAXBYTES FOR A15
select FILE_NAME,TABLESPACE_NAME,AUTOEXTENSIBLE,STATUS,MAXBYTES/1024/1024/1024 MAX_GB,USER_BYTES/1024/1024/1024 USER_GB from dba_data_files where tablespace_name like '%UNDO%';


---计算过去7*24小时undo平均使用量
set linesize 1000 pagesize 1000
col undo_retention for a50
col db_block_size for a50
select ur undo_retention,
dbs db_block_size,
((ur * (ups * dbs)) + (dbs * 24))/1024 /1024 as "used(MB)"
from (select value as ur from v$parameter where name = 'undo_retention'),
(select (sum(undoblks) / sum(((end_time - begin_time) * 86400))) ups
from v$undostat),
(select value as dbs from v$parameter where name = 'db_block_size');

UNDO_RETENTION DB_BLOCK_SIZE used(MB)
-------------------------------------------------- -------------------------------------------------- ------------------------------
36000 8192 43560.817242874279604662685477

六、确认undo表空间SQL语句占用情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
select *
from (select maxqueryid, round(sum(undoblks) * 8 / 1024) consumed_size_MB
from v$undostat
group by maxqueryid
order by consumed_size_MB desc)
where rownum < 50;

MAXQUERYID CONSUMED_SIZE_MB
------------- ----------------
0rc4km05kgzb9 374528
0cd1z0ss788nq 33342
00myywmd5qpy0 5475
5kkm0p9hh3dzg 2176
b7udzu0wpu0r8 1846
0jmmxyha33h9k 208
dhhd6rs34az40 27
fc05q7sm5c31j 3
0
9 rows selected.

七、确认当前哪个用户或哪个会话占用undo

1
2
3
4
select a.sid, a.serial#, a.username, b.used_urec, b.used_ublk
from v$session a,
v$transaction b
where a.saddr = b.ses_addr;

八、创建新的undo表空间并进行切换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
SQL> create pfile='/home/oracle/pfile.ora' from spfile;

SQL> create undo tablespace undotbs01 datafile '+DATA' size 10240m autoextend on next 100m;
alter tablespace undotbs01 add datafile '+DATA' size 10240m autoextend on next 100m;
alter tablespace undotbs01 add datafile '+DATA' size 10240m autoextend on next 100m;

SQL> create undo tablespace undotbs02 datafile '+DATA' size 10240m autoextend on next 100m;
alter tablespace undotbs02 add datafile '+DATA' size 10240m autoextend on next 100m;

节点1:
SQL> show parameter undo

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 36000
undo_tablespace string UNDOTBS1

SQL> alter system set undo_tablespace=undotbs01 scope=both;

System altered.

SQL> show parameter undo

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 36000
undo_tablespace string UNDOTBS01


节点2:
SQL> show parameter undo

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 36000
undo_tablespace string UNDOTBS2

SQL> alter system set undo_tablespace=undotbs02 scope=both;

System altered.

SQL> show parameter undo

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 36000
undo_tablespace string UNDOTBS02

九、等待undo表空间segment状态变更为offline

1
2
3
4
5
6
SQL> select t.segment_name, t.tablespace_name, t.segment_id, t.status
from dba_rollback_segs t
where t.tablespace_name in ('UNDOTBS1','UNDOTBS2')
and t.status != 'OFFLINE';

no rows selected

十、删除原undo表空间以及数据文件

1
2
3
SQL> drop tablespace UNDOTBS1 including contents and datafiles;

SQL> drop tablespace UNDOTBS2 including contents and datafiles;
  • Title: 处理Oracle undo表空间不释放问题
  • Author: 𝓓𝓸𝓷
  • Created at : 2025-07-03 16:18:36
  • Updated at : 2025-07-04 10:09:39
  • Link: https://www.zhangdong.me/oracle-undo-tablespace-usage.html
  • License: This work is licensed under CC BY-NC-SA 4.0.
评论