动态

详情 返回 返回

技術分享 | Oracle undo表空間warp#超出最大值修復 - 动态 详情

本文為墨天輪數據庫管理服務團隊第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

user avatar xyjzfx 头像 ivictor 头像 qcloudcommunity 头像 skychx 头像 hz_linmu 头像
点赞 5 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.