Oracle誤刪除資料和表的恢復辦法
在工作中我們操作資料庫的時候經常會發生一個不該發生的問題:使用者意外的刪除一個非常重要的表或者是表中的資料而且沒有備份,需要儘快的恢復,以下就是解決的辦法:
主要是利用Oracle回收站的閃回特性oracle 回收站recyclebin是10g才有的新特性,當我們drop table cube_scope 【purge】時,如果不指定purge時,系統只是將這個表重新命名為BIN$開頭的名稱,並在資料字典中修改了相關資料,表所佔用的物理空間並沒有真正的回收,此時所佔用的空間還是原來的表空間,當表空間不夠用時,ORACLE會跟據DROPSCN#自動進行逐個清理回收站中對像所佔用的空間,10g預設是打開回收站功能的。
一、delete 資料 誤刪除
1、 刪除資料之後表結構沒有變化
直接使用表閃回,表閃回要求使用者必須要有flash any table許可權
先確定刪除資料的時間(在刪除資料之前的時間就行,不過最好要具體到刪除資料的時間點)
alter table 表名 enable row movement //開啟行移動功能
flashback table 表名 to timestamp to_timestamp('刪除時間點','yyyy-mm-dd hh24:mi:ss')
//恢復資料到刪除時間點之前的狀態
Alter table 表名 disable row movement //關閉行移動功能(一定不能忘記)
2、 刪除資料之後表結構發生了變化
select * from 表名 as of timestamp to_timestamp('刪除時間點','yyyy-mm-dd hh24:mi:ss')
//找出被刪除的資料
insert into 表名 (select * from 表名 as of timestamp to_timestamp('刪除時間點','yyyy-mm-dd hh24:mi:ss')); //把刪除的資料重新插回原表,但注意主鍵不要重複
二 、drop命令 刪除表
由於oracle在刪除表時,沒有直接清空表所佔的塊,oracle把這些已刪除的表的資訊放到了一個虛擬容器“回收站”中,而只是對該表的資料塊做了可以被覆寫的標誌,所以在塊未被重新使用前還可以恢復。
查看回收站中的表
select object_name,original_name,partition_name,type,ts_name,createtime,droptimefrom recyclebin;
可以看到被刪除的表在回收站被命名為’BIN$0z+2cCjdSjqkx1nsP/re7w==$0’
flashback table 原表名 to before drop (rename to 新表名) //閃回原表(重新命名新表名)
或者
flashback table "回收站中的表名(如:BIN$0z+2cCjdSjqkx1nsP/re7w==$0)" to before drop (rename to 新表名) //使用者可能會經常多次建立和刪除同一個表就需要找到回收站的表名閃回相應的表版本
但是用這種方法只是把我們的表給找回來了,我們的索引和約束都沒有回來。所以我們一定要重新建立索引和約束。如果
oracle 閃回功能還可以閃回整個資料庫,使資料庫回到過去某一狀態。
alter database flashback on
flashback database to scn SCNNO; //使用SCN號閃回或者使用時間戳閃回
flashback database to timestamp to_timestamp('2007-10-25 12:00:00','yyyy-mm-dd hh24:mi:ss');
如果想要不經過回收站直接刪除並釋放所佔空間
drop table 表名 purge //此命令相當於truncate+drop 操作,一般不建議這麼做。
手工清除回收站中的物件。
prug table 表空間.表名 //清除具體的物件
prug tablespace 表空間 //清除指定的表空間物件
purge tablespace 表空間 user 使用者名稱 //刪除表空間指定使用者下的所有對像
purge recyclebin //刪除回收站
purge dba_recyclebin //刪除全體使用者在回收站的資料
ORACLE空間利用原則
1. 使用現有的表空間的未使用空間
2. 如果沒有了空閒空間,則檢查回收站,對於回收站的物件按照先進先出的原則,對於最先刪除的物件,oracle在空間不足之時會最先從
回收站刪除以滿足新分配空間的需求
3. 如果回收站也沒有物件可以清理,則檢查表空間是否自擴充套件,如果自擴充套件則擴充套件表空間,然後分配新空間
4.如果表空間非自擴充套件,或者已經不能自擴充套件(到達最大限制),則直接報表空間不足錯誤,程式終止
* drop tablespace :會將recyclebin中所有屬於該tablespace的對像清除
* drop user :會將recyclebin中所有屬於該使用者的對像清除
* drop cluster : 會將recyclebin中所有屬於該cluster的成員對像清除
* drop type : 會將recyclebin中所有依賴該type對像清除
另外還需要注意一種情況,對像所在的表空間要有足夠的空間,不然就算drop掉經過recyclebin由於空間不足oracle會自動刪除的哦(切記)!
三、truncate刪除資料
1、使用閃回特性
因為truncate不是DML語句,是DDL語句,不能使用閃回查詢的方式恢復表資料,這裡介紹一種通過flashback database(閃回整個資料庫)
的方式恢復資料的方法。在11g下,可以在mount和open模式來執行該命令
select status from v$instance; 檢視資料庫模式
alterdatabaseopen; //或者是mount
alter database flashback on
flashback database to timestamp to_timestamp('2007-10-25 12:00:00','yyyy-mm-dd hh24:mi:ss');
在執行完flashback database 命令之後,可以使用多種方式修復資料庫:
1). 直接alter database open resetlogs 開啟資料庫,指定scn 或者timestamp 時間點之後產生的資料統統丟失。
2). 先執行alter database open read only 命令以read-only 模式開啟資料庫,檢視恢復後的資料是否滿足要求,如果滿足要求,
則通過resetlogs開啟資料庫,否則,重新執行flashback 操作。
3). 先執行alter database open read only 命令以read-only 模式開啟資料庫,然後立刻通過邏輯匯出的方式將誤操作涉及表的資料匯出,再執行recover database 命令以重新應用資料庫產生的redo,將資料庫修復到flashback database 操作前的狀態,然後再通過邏輯匯入的方式,將之前誤操作的表重新匯入,這樣的話對現有資料的影響最小,不會有資料丟失。
這裡演示第二種方法
alter
database
open
read
only;
檢視資料是否符合要求不符合繼續
flashback database to timestamp to_timestamp
如果符合
startup mount force
;
alter
database
open
resetlog;
第三種方法
閃回之後 alter database open read only
exp 使用者名稱/使用者密碼file=t.dmptables=表名; //匯出被truncate表的資料 如果不熟悉exp命令的話,可以去看exp/expdp 與 imp/impdp命令匯入匯出資料庫詳解
shutdownimmediate //重啟資料庫恢復到閃回之前的時間點
startupmount;
recover database;
alter database open;
然後匯入剛才匯出的資料
imp 使用者名稱 /密碼 file=t.dmp tables=表名 ignore=y;
2 、使用FY_Recover_Data 包
FY_Recover_Data