應用升級後,一條 UPDATE ... WHERE 1=1 錯誤 SQL 導致某表多欄位被更新為相同值。錯誤發生於週五,週日才發現,中間隔近 2 天。RMAN 備份已被刪除,無法做時間點恢復 (PITR);Flashback Query 報 ORA-01555。唯一可行路徑:LogMiner 分析歸檔日誌。
V$ARCHIVED_LOG 找出錯誤時間範圍內的歸檔檔案序號與 SCN 範圍。-- 找出錯誤預估時間前的最大 first_time
select max(first_time) from v$archived_log where first_time < to_date('200909251900','yyyymmddhh24mi');
-- 列出該時間點後的歸檔日誌
select sequence#, first_time, name,
to_char(first_change#,'xxxxxxxx') first_change,
to_char(next_change#,'xxxxxxxx') next_change
from v$archived_log
where first_time >= to_date('200909251707','yyyymmddhh24mi')
order by 2;
嘗試在早期歸檔中搜尋目標表 TBL_FORM_FORM 及特徵值 SGS0900021BNc10:
exec sys.dbms_logmnr.add_logfile(logfilename=>'/arch/db1_1_4038.arc');
exec sys.dbms_logmnr.add_logfile(logfilename=>'/arch/db1_1_4039.arc');
exec sys.dbms_logmnr.start_logmnr(options=>sys.dbms_logmnr.dict_from_online_catalog);
col sql_redo for a50
select scn, timestamp, username, sql_redo
from v$logmnr_contents
where Operation='UPDATE'
and upper(sql_redo) like '%TBL_FORM_FORM%'
and sql_redo like '%SGS0900021BNc10%'
order by scn, timestamp;
exec sys.dbms_logmnr.end_logmnr;
前幾個歸檔未發現,若繼續逐個分析耗時過久,業務已停擺。
DBA_EXTENTS 取得首個 extent 的檔號與區塊號(段頭後第一個資料區塊)。alter system dump datafile 16 block 25482;0x0000.88d7af30。因錯誤發生時間極近,且系統允許少量資料遺失,直接使用 Flashback Query 依時間點建立新表:
create table tbl_form_form_new
as select * from tbl_form_form
as of timestamp to_date('2009-09-27 09:08:00','yyyy-mm-dd hh24:mi:ss');
閃回查詢成功,大型 UNDO 表空間確保保留足夠歷史版本。此法已多次實戰證實有效。