使用數據泵導出數據庫數據時,發現如下錯誤提示:
ORA-31693:?Table?data?object?"CAMS_CORE"."BP_EXCEPTION_LOG"?failed?to?load/unload?and?is?being?skipped?due?to?error:
ORA-02354:?error?in?exporting/importing?data
ORA-01555:?snapshot?too?old:?rollback?segment?number??with?name?""?too?small
ORA-22924:?snapshot?too?old
1.查看表空間使用率
SELECT?UPPER(F.TABLESPACE_NAME)?AS?"表空間名",
D.TOT_GROOTTE_MB?AS?"表空間大小(M)",
D.TOT_GROOTTE_MB-F.TOTAL_BYTES?AS?"已使用空間(M)",
TO_CHAR(ROUND((D.TOT_GROOTTE_MB?-?F.TOTAL_BYTES)?/?D.TOT_GROOTTE_MB?*?100,2),'990.99')?||?'%'?"使用比",
F.TOTAL_BYTES?AS?"空閑空間(M)",
F.MAX_BYTES?AS?"最大塊(M)"
FROM?(SELECT?TABLESPACE_NAME,
ROUND(SUM(BYTES)?/?(1024?*?1024),?2)?TOTAL_BYTES,
ROUND(MAX(BYTES)?/?(1024?*?1024),?2)?MAX_BYTES
FROM?SYS.DBA_FREE_SPACE
GROUP?BY?TABLESPACE_NAME)?F,
(SELECT?DD.TABLESPACE_NAME,
ROUND(SUM(DD.BYTES)?/?(1024?*?1024),?2)?TOT_GROOTTE_MB
FROM?SYS.DBA_DATA_FILES?DD
GROUP?BY?DD.TABLESPACE_NAME)?D
WHERE?D.TABLESPACE_NAME?=?F.TABLESPACE_NAME
ORDER?BY?1;
2.看到ORA-01555錯誤,還以為是經典錯誤,嘗試調整undo_retention參數
SYS@cams>alter?system?set?undo_retention=30000?scope=both;
修改后再次導出,問題依舊存在,顯然問題和
undo_retention沒關系,再把參數改回去。
3.猜測是表空間有問題,這里嘗試對
CAMS_CORE下的索引和LOB
進行表空間遷移。
(1)新建新的表空間
(2)拼接表空間遷移語句,前面已有文章寫到了表空間遷移方案
(3)執行表空間遷移語句
alter?table?CAMS_CORE.BP_EXCEPTION_LOG?move?lob(EX_STACK)?store?as?(tablespace?cams_core_lob);
執行到該語句的時候提示錯誤:
ORA-01555:?快照過舊:?回退段號??(名稱為?"")?過小
ORA-22924:?快照太舊
這里,問題應該比較明顯了,有部分
LOB數據有問題。
4.尋找問題解決方案(MOS)
使用關鍵字
“expdp ORA-01555 ORA-22924 ?LOB”進行查找:
Export Fails With Errors ORA-2354 ORA-1555 ORA-22924 And How To Confirm LOB Segment Corruption Using Export Utility (文檔 ID 833635.1)
5.參考MOS給出的解決方案,動手處理問題
set?concat?off
create?table?corrupted_lob_data?(corrupted_rowid?rowid);
set?concat?off
declare
error_1555?exception;
pragma?exception_init(error_1555,-1555);
num?number;
begin
for?cursor_lob?in?(select?rowid?r,?&&lob_column?from?&table_owner.&table_with_lob)?loop
begin
num?:=?dbms_lob.instr?(cursor_lob.&&lob_column,?hextoraw?('889911'))?;
exception
when?error_1555?then
insert?into?corrupted_lob_data?values?(cursor_lob.r);
commit;
end;
end?loop;
end;
/
Enter?value?for?table_owner:?EX_STACK
Enter?value?for?table_owner:?CAMS_CORE
Enter?value?for?table_with_lob:?BP_EXCEPTION_LOG
old???6:???for?cursor_lob?in?(select?rowid?r,?&&lob_column?from?&table_owner.&table_with_lob)?loop
new???6:???for?cursor_lob?in?(select?rowid?r,?EX_STACK?from?CAMS_CORE.BP_EXCEPTION_LOG)?loop
old???8:???????num?:=?dbms_lob.instr?(cursor_lob.&&lob_column,?hextoraw?('889911'))?;
new???8:???????num?:=?dbms_lob.instr?(cursor_lob.EX_STACK,?hextoraw?('889911'))?;
PL/SQL?procedure?successfully?completed.
查看存在問題的數據記錄:
select?*?from?CAMS_CORE.BP_EXCEPTION_LOG
where?rowid?in?(?select?*?from?CAMS_CORE.corrupted_lob_data?);
確實存在
3條數據,
CLOB
字段數據大小為
,顯然有問題。
MOS上給出的導出方案是將問題數據exclude掉,這里為了徹底解決問題,將3條數據導出為csv文件,然后刪除。然后再次導出數據庫數據,不再提示報錯。
6.結合應用分析問題的由來。
根據有問題的數據,讓開發人員去檢查應用日志。檢查時發現對應時間點的應用日志有殘缺,不能繼續往下分析。同時,根據問題發生的時間點,了解到當時工程師在給服務器做遷移,結果服務器強制重啟(應用和數據庫一起),導致了部分數據損壞。