本文為墨天輪數據庫管理服務團隊第105期技術分享,內容原創,作者為技術顧問陳坤,如需轉載請聯繫小墨(VX:modb666)並註明來源。如需查看更多文章可關注【墨天輪】公眾號。
問題概述
undo表空間某個slot warp#超出最大值0xffffffff(轉換為10進製為4294967259)時undo表空間出現異常,影響數據庫操作,導致業務中斷。
問題原因
這是一個數據庫機制問題。根據文檔(Doc ID 19700135.8)描述,在slot上的seq#增長到0xe6666666時(0xffffffff的90%,即3865470566),則開始顯示為負值-429496730 ,當繼續使用,則會呈現為-429496729,-429496728 ……,當接近為-0時,slot的seq#(wrap#)將會用盡。則該rollback segment再無法使用,有新的transaction落在該rollback segment則可能導致數據損壞報錯 ORA-600 [4187] 。
可能觸發的wrap#暴漲的原因:
目前已知的原因是:ORA-600 [4187] is more likely happening on RAC when \_gc\_undo_affinity set to false (Doc ID 2920387.1)。
在RAC環境中,如果\_gc\_undo_affinity設置為false時,有可能導致wrap在使用中分配不均,導致某一個segment的wrap異常增長。
解決方案
預防方案
1、增加巡檢項可以有效預防此問題:
select b.segment_name, b.tablespace_name
,a.ktuxeusn "Undo Segment Number"
,a.ktuxeslt "Slot"
,a.ktuxesqn "Wrap#"
from x$ktuxe a, dba_rollback_segs b
where a.ktuxesqn > -429496730 and a.ktuxesqn < 0
and a.ktuxeusn = b.segment_id;
語句釋義:
"Wrap#"代表每個rollback segment中的slot被使用過的次數(上限值為0xffffffff,即4294967295)。根據文檔(Doc ID 19700135.8)描述,在slot上的seq#增長到0xe6666666時(0xffffffff的90%,即3865470566),則開始顯示為負值-429496730 ,當繼續使用,則會呈現為-429496729,-429496728 ……,當接近為-0時,slot的seq#(wrap#)將會用盡。則該rollback segment再無法使用,有新的transaction落在該rollback segment則可能導致數據損壞報錯 ORA-600 [4187] 。
此語句可以輸出哪一個 undo segment超過最大值的90%,官方建議此語句輸出的segment都應當提前清理。
2、保持\_gc\_undo_affinity為默認值(true)時,可以有效規避此問題的發生。
解決方案
如果發現該問題,可以創建新的undo tbs。
將對應節點的undo_tablespace參數設置為新的undo tbs。
確認老的undo無人使用後,將老的undo刪除。
1、確定當前節點undo表空間
oem134db1> show parameter undo_tablespace
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string UNDOTBS1
2、查看當前表空間大小
oem134db1>
SELECT tablespace_name,
ROUND(SUM(bytes) / 1024 / 1024, 2) AS "Total Size (MB)",
ROUND(SUM(maxbytes) / 1024 / 1024, 2) AS "Max Size (MB)",
ROUND(SUM(user_bytes) / 1024 / 1024, 2) AS "Used Size (MB)",
ROUND(SUM(bytes - user_bytes) / 1024 / 1024, 2) AS "Free Space (MB)"
FROM dba_data_files
GROUP BY tablespace_name;
TABLESPACE_NAME Total Size (MB) Max Size (MB) Used Size (MB) Free Space (MB)
------------------------------ --------------- ------------- -------------- ---------------
SYSTEM 1024 30720 1023 1
UNDOTBS2 11264 61440 11262 2
SYSAUX 8192 61440 8190 2
UNDOTBS1 2048 61440 2046 2
TBS_BIZ 2048 0 2047 1
USERS 1024 30720 1023 1
GOLDENGATE 100 32767.98 99 1
3、創建新的表空間
Create undo tablespace UNDOTBS3 datafile '+DATADG' size 1G autoextend on;
4、設置當前實例為新的undo表空間
alter system set undo_tablespace=UNDOTBS3 sid='oem134db1';
5、在確認舊 undo tbs 無人使用
select tablespace_name , status , count(*) from dba_rollback_segs where tablespace_name='UNDOTBS3' group by tablespace_name , status ;
select count(*) from dba_rollback_segs where tablespace_name='{0}' AND status!='OFFLINE';
select SEGMENT_NAME,TABLESPACE_NAME,sum(bytes)/1024/1024 size_m,status from dba_undo_extents
where status in('ACTIVE','UNEXPIRED') and TABLESPACE_NAME = 'UNDOTBS1'
group by SEGMENT_NAME,status,TABLESPACE_NAME
order by 1,3;
select SEGMENT_NAME,TABLESPACE_NAME,status from dba_undo_extents
where status in('ACTIVE','UNEXPIRED') and TABLESPACE_NAME = 'UNDOTBS1';
確認沒有ACTIVE以及UNEXPIRED即可刪除。
6、檢查當前tbs最新checkpoint時間
select NAME,CHECKPOINT_TIME from v$datafile where name like '%undotbs3%';
7、刪除老的undo表空間
DROP TABLESPACE old_undo_tablespace_name INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS;
8、觀察新 undo tbs 是否有繼承 undo wrap# 的情況
select b.segment_name, b.tablespace_name
,a.ktuxeusn "Undo Segment Number"
,a.ktuxeslt "Slot"
,a.ktuxesqn "Wrap#"
from x$ktuxe a, dba_rollback_segs b
where a.ktuxesqn > -429496730 and a.ktuxesqn < 0
and a.ktuxeusn = b.segment_id;
9、但如果上述語句中返回的undo segment仍存在active transactions,則會存在無法替換undo的情況,將上述語句返回的undo segment記錄下來
然後設置
alter system set '_corrupted_rollback_segments'='_SYSSMU1$','_SYSSMU2$','_SYSSMU3$'
重啓數據庫使其生效,再執行替換表空間
墨天輪從樂知樂享的數據庫技術社區蓄勢出發,全面升級,提供多類型數據庫管理服務。墨天輪數據庫管理服務旨在為用户構建信賴可託付的數據庫環境,併為數據庫廠商提供中立的生態支持。
墨天輪數據庫服務官網:https://www.modb.pro/service