oracle資料庫災難挽救應急方案之DDL誤操作恢復(drop)
1、核心業務表誤drop恢復(no purge)
1.1模擬drop誤操作
建立jason業務表,如下:
SQL> create table jason as select * from dba_objects; SQL> create index idx_jason_oid on jason(object_id);
使用者在刪除資料的時候,不小心誤刪jason業務表,如下:
SQL> drop table jason;
1.2透過回收站恢復誤刪資料
首先,檢查誤刪業務表當前所屬使用者的回收站,如下:
SQL> select object_name,original_name,operation,type,ts_name,droptime from user_recyclebin;
如果運氣較好,被誤刪的業務表還保留在回收站中,那麼可以透過回收站進行還原恢復,如下:
SQL> flashback table "BIN$ggkFrmhwKEngUwjSqMDkqA==$0" to before drop rename to JASON_NEW; SQL> alter table JASON rename to JASON_OLD; SQL> alter table JASON_NEW rename to JASON;
檢查回收站功能如果開啟,可選擇關閉,如下:
SQL> ALTER SESSION SET recyclebin = OFF; SQL> ALTER SYSTEM SET recyclebin = OFF SCOPE = SPFILE;
檢查回收站功能如果關閉,可選擇開啟,如下:
SQL> ALTER SESSION SET recyclebin = ON; SQL> ALTER SYSTEM SET recyclebin = ON SCOPE = SPFILE;
2、核心業務表誤drop恢復(purge)
2.1模擬drop誤操作
建立jason業務表,如下:
SQL> create tablespace tabtest datafile '/home/oracle/test/oradata/tabtest01.dbf' size 10m autoextend on; SQL> create table tabtest tablespace tabtest as select * from dba_objects;
使用者在刪除資料的時候,不小心誤刪jason業務表,如下:
SQL> drop table tabtest purge;
2.2將誤刪表所在的表空間設定為只讀
由於表已經誤刪除,因此需要和使用者或業務開發等相關人員確認該業務表所在的表空間,並儘快將此業務表空間設定為只讀模式,在設定之前需要建立與tabtest表擁有相同表結構的tabtest_old表,如下:
SQL> alter system set deferred_segment_creation=false; SQL> create table tabtest_old tablespace tabtest as select * from dba_objects where 1=2; SQL> alter tablespace tabtest read only;
2.3臨時在SYSTEM表空間建立恢復表
由於tabtest表資料恢復,勢必要涉及到IO讀寫操作,如果資料量不大,可臨時設定恢復表的預設表空間為SYSTEM;如果資料量很大,建議為恢復表建立新的預設表空間,如下:
SQL> create table tabtest_new tablespace system as select * from dba_objects where 1=2;
2.4透過日誌挖掘獲取誤刪表data_object_id
首先,手動切換歸檔日誌,並記錄切換後時間戳,如下:
SQL> alter system switch logfile; SQL> alter system switch logfile; SQL> select sysdate from dual; SYSDATE ------------------- 2022-06-20 15:07:11
檢查誤操作發生至歸檔手動切換後系統生成的歸檔日誌,如下:
col name for a60 set line 200 select unique NAME, THREAD#, SEQUENCE#, COMPLETION_TIME from gv$archived_log where thread# = 1 and COMPLETION_TIME >= to_date('2022-05-09 13:15:03', 'yyyy-mm-dd hh24:mi:ss') and COMPLETION_TIME <= to_date('2022-05-09 13:24:47', 'yyyy-mm-dd hh24:mi:ss') order by SEQUENCE#;
新增第一個要載入的歸檔日誌檔案,如下:
SQL> execute dbms_logmnr.add_logfile(logfilename=>'/home/oracle/test/arch/1_84_1106134187.dbf',options=>dbms_logmnr.new);
多次新增要載入的歸檔日誌檔案,如下:
SQL> execute dbms_logmnr.add_logfile(logfilename=>'/home/oracle/test/arch/1_85_1106134187.dbf',options=>dbms_logmnr.addfile);
執行日誌挖掘分析,如下:
SQL> execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
查詢v$logmnr_contents動態效能檢視,獲取歸檔日誌解析資訊,如下:
SQL> select count(*) from v$logmnr_contents; COUNT(*) ---------- 93190 SQL> create table sys.hzmc_logmnr_contents_fordrop as select * from v$logmnr_contents;
關閉日誌挖掘分析,如下:
SQL> execute dbms_logmnr.end_logmnr;
獲取drop purge動作執行的時間,如下:
SQL> select scn,timestamp,sql_redo from sys.hzmc_logmnr_contents_fordrop where operation='DDL' and lower(sql_redo) like '%tabtest%' order by timestamp desc; SCN TIMESTAMP SQL_REDO ---------- ------------------- --------------------------- 266498191 2022-06-20 14:55:43 drop table tabtest purge;
獲取誤刪業務表data_object_id,如下:
SQL> select scn,timestamp,sql_redo from sys.hzmc_logmnr_contents_fordrop where timestamp like '2022-06-20 14:55%' and sql_redo like 'delete%';
2.5透過ROWID嘗試找回誤刪表資料
DBMS_ROWID.ROWID_CREATE包的語法,如下:
DBMS_ROWID.ROWID_CREATE (rowid_type IN NUMBER,object_number IN NUMBER,relative_fno IN NUMBER,block_number IN NUMBER,row_number IN NUMBER) RETURN ROWID;
DBMS_ROWID.ROWID_CREATE傳參解析,如下:
rowid_type Type (restricted or extended). Set the rowid_type parameter to 0 for a restricted ROWID. Set it to 1 to create an extended ROWID. If you specify rowid_type as 0, then the required object_number parameter is ignored, and ROWID_CREATE returns a restricted ROWID.
object_number Data object number (rowid_object_undefined for restricted).
relative_fno Relative file number.
block_number Block number in this file.
row_number Returns row number in this block.
將tabtest_old表的dataobj#修改為2.2.4節獲取到的dataobj#,如下:
SQL> select obj#,dataobj# from obj$ where name='TABTEST_OLD'; SQL> update obj$ set DATAOBJ#=89741 where obj#=89744; SQL> commit;
獲取tabtest_old表所在的資料檔案號和段頭塊號,如下:
set linesize 200 pagesize 200 col owner for a10 col segment_name for a15 select owner, segment_name, header_file, header_block, segment_type from dba_segments where segment_name = 'TABTEST_OLD'; OWNER SEGMENT_NAME HEADER_FILE HEADER_BLOCK SEGMENT_TYPE ---------- --------------- ----------- ------------ ------------------ SYS TABTEST_OLD 8 130 TABLE
先透過dbms_rowid.ROWID_CREATE包獲取第8號資料檔案的第131資料塊的第1行ROWID,再根據ROWID返回TABTEST表的object_id欄位值,透過與dba_objects查詢對比,發現一致,說明透過該方式可以嘗試找回誤刪表的資料,如下:
alter system flush shared_pool; alter system flush shared_pool; alter system flush buffer_cache; alter system flush buffer_cache; SQL> select object_id from tabtest_old where rowid=dbms_rowid.ROWID_CREATE(1,89741,8,131,0); OBJECT_ID ---------- 20 SQL> select object_id from dba_objects where rownum<=1; OBJECT_ID ---------- 20
2.6透過PL/SQL嘗試找回所有誤刪表資料
SET SERVEROUTPUT ON DECLARE nrows number; rid rowid; objd number; ROWSPERBLOCK number; BEGIN ROWSPERBLOCK:=1000; nrows:=0; for i in ( select file_id,block_id,blocks from dba_free_space where tablespace_name='TABTEST' union all select file_id,block_id,8 blocks from dba_extents where segment_name='TABTEST_OLD' ) loop for fblkno in i.block_id..i.block_id+i.blocks-1 loop for fblkrow in 1..ROWSPERBLOCK loop begin rid := dbms_rowid.ROWID_CREATE(1,89741,i.file_id, fblkno,fblkrow-1); insert into sys.tabtest_new select * from sys.tabtest_old a where rowid = rid; if sql%rowcount = 1 then nrows:=nrows+1; end if; if (mod(nrows,1000)=0) then commit; end if; exception when others then null; end; end loop; end loop; end loop; COMMIT; dbms_output.put_line('Total rows: '||to_char(nrows)); END; / Total rows: 86726 PL/SQL procedure successfully completed.
待資料找回後,再將tabtest_new表重新命名為tabtest表,在業務低峰期再對tabtest表做表空間遷移,如下;
SQL> alter table tabtest_new rename to tabtest; SQL> alter tablespace tabtest read write; SQL> alter table tabtest move tablespace tabtes
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30310891/viewspace-2919478/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle資料庫災難挽救應急方案之DDL誤操作恢復(truncate)Oracle資料庫
- oracle資料庫災難挽救應急方案之DML誤操作恢復Oracle資料庫
- MySQL資料災難挽救之drop tableMySql
- MySQL資料災難挽救之ibdata檔案誤刪恢復MySql
- MySQL資料災難挽救之truncate tableMySql
- MySQL資料災難挽救之Delete\UpdateMySqldelete
- 【資料庫資料恢復】ORACLE常見資料災難&資料恢復可能性資料庫資料恢復Oracle
- Oralce 資料庫的災難恢復(轉)資料庫
- oracle誤drop/update資料恢復測試Oracle資料恢復
- 【資料庫資料恢復】誤truncate table的Oracle資料庫資料恢復方案資料庫資料恢復Oracle
- 【oracle資料庫資料恢復】誤操作導致的資料庫誤刪除的資料恢復案例Oracle資料庫資料恢復
- Xtrabackup實現資料庫備份和災難恢復資料庫
- 【資料庫資料恢復】Oracle資料庫誤truncate table的資料恢復案例資料庫資料恢復Oracle
- 【資料庫資料恢復】oracle資料庫誤truncate table怎麼恢復資料?資料庫資料恢復Oracle
- SQL Server災難恢復SQLServer
- oracle之rman恢復資料庫Oracle資料庫
- PostgreSQL資料檔案災難恢復-解析與資料dumpSQL
- 資料庫恢復方案資料庫
- Oracle資料庫恢復之resetlogsOracle資料庫
- 檢查Oracle災難恢復場景下的物理備庫XIOracle
- 資料備份方法及災難恢復探討(轉)
- 【資料庫資料恢復】LINUX環境下ORACLE資料庫誤刪除的資料恢復資料庫資料恢復LinuxOracle
- Oracle恢復誤刪資料Oracle
- 【資料庫資料恢復】HP-UX系統ORACLE資料庫被誤刪除的資料恢復資料庫資料恢復UXOracle
- IT系統災難恢復基本指南
- 恢復Oracle資料庫誤刪除資料的語句Oracle資料庫
- 表資料被誤操作的恢復
- 伺服器資料恢復-誤操作導致mysql資料庫資料丟失的資料恢復案例伺服器資料恢復MySql資料庫
- oracle恢復誤刪除資料Oracle
- 【資料庫資料恢復】LINUX EXT3檔案系統下ORACLE資料庫誤操作導致資料丟失的資料恢復案例資料庫資料恢復LinuxOracle
- mysql資料庫誤刪除後的資料恢復操作說明MySql資料庫資料恢復
- MySQL 資料庫誤刪除後的資料恢復操作說明MySql資料庫資料恢復
- 【資料庫資料恢復】如何恢復Oracle資料庫truncate表的資料資料庫資料恢復Oracle
- 【北亞資料庫資料恢復】誤操作導致資料丟失的華為雲mysql資料恢復案例資料庫資料恢復MySql
- Oracle資料庫備份與恢復之RMANOracle資料庫
- Oracle資料庫RMAN小結之恢復部分Oracle資料庫
- 伺服器資料恢復-UNIX類檔案系統資料災難的資料恢復可能性分析伺服器資料恢復
- Sybase ASE資料庫恢復,Sybase資料恢復,資料誤刪除恢復工具READSYBDEVICE資料庫資料恢復dev