【Oracle數(shù)據(jù)庫(kù)】手滑刪錯(cuò)數(shù)據(jù),一步步教你如何挽救纯命?

前言

常在河邊走西剥,哪能不濕鞋?

今天有客戶聯(lián)系說(shuō)誤更新數(shù)據(jù)表亿汞,導(dǎo)致數(shù)據(jù)錯(cuò)亂了瞭空,希望能幫忙恢復(fù)下。數(shù)據(jù)庫(kù)版本為 11.2.0.1咆畏,操作系統(tǒng)是 Windows64 位,數(shù)據(jù)已經(jīng)被更改超過(guò)1周時(shí)間吴裤,數(shù)據(jù)庫(kù)已開(kāi)啟歸檔模式旧找、沒(méi)有DG容災(zāi)有RMAN備份麦牺,希望將這張表恢復(fù)到 一周前 的指定時(shí)間點(diǎn)钮蛛。

一、分析

以下只列出常規(guī)恢復(fù)手段:

1剖膳、數(shù)據(jù)已經(jīng)誤操作超過(guò)一周魏颓,所以排除使用UNDO快照來(lái)找回。
2潮秘、沒(méi)有DG容災(zāi)環(huán)境琼开,排除使用DG閃回。
3枕荞、主庫(kù)已開(kāi)啟歸檔模式柜候,并且存在RMAN備份,可使用RMAN異機(jī)恢復(fù)表對(duì)應(yīng)表空間躏精,使用DBLINK撈回?cái)?shù)據(jù)表渣刷。
4、Oracle 12C后支持單張表恢復(fù)矗烛。

結(jié)論:安全起見(jiàn)辅柴,使用RMAN異機(jī)恢復(fù)表空間來(lái)?yè)苹財(cái)?shù)據(jù)表。

二瞭吃、思路

客戶希望將表數(shù)據(jù)恢復(fù)到 2021/06/08 17:00:00 之前某個(gè)時(shí)間點(diǎn)。
大致操作步驟如下:

1歪架、主庫(kù)查詢誤更新數(shù)據(jù)表對(duì)應(yīng)的表空間和無(wú)需恢復(fù)的表空間和蚪。
2止状、新主機(jī)安裝Oracle 11.2.0.1數(shù)據(jù)庫(kù)軟件烹棉,無(wú)需建庫(kù)怯疤,目錄結(jié)構(gòu)最好保持一致。
3集峦、主庫(kù)拷貝參數(shù)文件伏社,密碼文件至新主機(jī),根據(jù)新主機(jī)修改參數(shù)文件和創(chuàng)建新實(shí)例所需目錄洛口。
4凯沪、新主機(jī)使用修改后的參數(shù)文件打開(kāi)數(shù)據(jù)庫(kù)實(shí)例到nomount狀態(tài)妨马。
5、主庫(kù)拷貝備份的控制文件至新主機(jī)烘跺,新主機(jī)使用RMAN恢復(fù)控制文件滤淳,并且MOUNT新實(shí)例。
6铺敌、新主機(jī)RESTORE TABLESPACE恢復(fù)至?xí)r間點(diǎn) 2021/06/08 16:00:00 屁擅。
7派歌、新主機(jī)RECOVER DATABASE SKIP TABLESPACE恢復(fù)至?xí)r間點(diǎn) 2021/06/08 16:00:00
8匾嘱、新主機(jī)實(shí)例開(kāi)啟到只讀模式早抠。
9霎烙、確認(rèn)新主機(jī)實(shí)例的表數(shù)據(jù)是否正確吼过,若不正確則重復(fù) 第7步 調(diào)整時(shí)間點(diǎn)慢慢往 2021/06/08 17:00:00 推進(jìn)恢復(fù)咪奖。
10羊赵、主庫(kù)創(chuàng)建連通新主機(jī)實(shí)例的DBLINK,通過(guò)DBLINK從新主機(jī)實(shí)例撈取表數(shù)據(jù)闲昭。

注意:選擇表空間恢復(fù)是因?yàn)橹鲙?kù)數(shù)據(jù)量比較大序矩,如果全庫(kù)恢復(fù)需要大量時(shí)間跋破。

三毒返、測(cè)試環(huán)境模擬

為了數(shù)據(jù)脫敏,因此以測(cè)試環(huán)境模擬場(chǎng)景進(jìn)行演示劲绪。

1盆赤、環(huán)境準(zhǔn)備

節(jié)點(diǎn) 主機(jī)版本 主機(jī)名 實(shí)例名 Oracle版本 IP地址
主庫(kù) rhel6.9 orcl orcl 11.2.0.1 10.211.55.111
新主機(jī) rhel6.9 orcl 不創(chuàng)建實(shí)例 11.2.0.1 10.211.55.112
環(huán)境部署可以通過(guò) Oracle一鍵安裝腳本 進(jìn)行初始化環(huán)境弟劲,然后手動(dòng)安裝即可兔乞。

主庫(kù):./OracleShellInstall.sh -i 10.211.55.111 -m Y -txh Y
新主機(jī):./OracleShellInstall.sh -i 10.211.55.112 -m Y -txh Y

2、模擬測(cè)試場(chǎng)景

主庫(kù)開(kāi)啟歸檔模式
--設(shè)置歸檔路徑
alter system set log_archive_dest_1='LOCATION=/archivelog';
--重啟開(kāi)啟歸檔模式
shutdown immediate
startup mount
alter database archivelog霍骄;
--打開(kāi)數(shù)據(jù)庫(kù)
alter database open;

創(chuàng)建測(cè)試數(shù)據(jù)
sqlplus / as sysdba
--創(chuàng)建表空間
create tablespace lucifer datafile '/oradata/orcl/lucifer01.dbf' size 10M autoextend off;
create tablespace ltest datafile '/oradata/orcl/ltest01.dbf' size 10M autoextend off;
--創(chuàng)建用戶
create user lucifer identified by lucifer;
grant dba to lucifer;
--創(chuàng)建表
conn lucifer/lucifer
create table lucifer(id number not null,name varchar2(20)) tablespace lucifer;
--插入數(shù)據(jù)
insert into lucifer values(1,'lucifer');
insert into lucifer values(2,'test1');
insert into lucifer values(3,'test2');
commit;

測(cè)試數(shù)據(jù)
進(jìn)行數(shù)據(jù)庫(kù)全備
run {
allocate channel c1 device type disk;
allocate channel c2 device type disk;
crosscheck backup;
crosscheck archivelog all; 
sql"alter system switch logfile";
delete noprompt expired backup;
delete noprompt obsolete device type disk;
backup database include current controlfile format '/backup/backlv0_%d_%T_%t_%s_%p';
backup archivelog all DELETE INPUT;
release channel c1;
release channel c2;
}

備份記錄
模擬數(shù)據(jù)修改
sqlplus / as sysdba
conn lucifer/lucifer
delete from lucifer where id=1;
update lucifer set name='lucifer' where id=2;
commit;

修改后數(shù)據(jù)

注意:為了模擬客戶環(huán)境,假設(shè)無(wú)法通過(guò)UNDO快照找回米间,當(dāng)前刪除時(shí)間點(diǎn)為:2021/06/17 18:10:00屈糊。

如果使用UNDO快照,比較方便:
--查找UNDO快照數(shù)據(jù)是否正確
select * from lucifer.lucifer as of timestamp to_timestamp('2021-06-17 18:05:00','YYYY-MM-DD HH24:MI:SS');
--將UNDO快照數(shù)據(jù)撈至新建表中
create table lucifer.lucifer_0617 as select * from lucifer.lucifer as of timestamp to_timestamp('2021-06-17 18:05:00','YYYY-MM-DD HH24:MI:SS');

undo快照恢復(fù)數(shù)據(jù)

四夫晌、RMAN完整恢復(fù)過(guò)程

主庫(kù)查詢誤更新數(shù)據(jù)表對(duì)應(yīng)的表空間和無(wú)需恢復(fù)的表空間

--查詢誤更新數(shù)據(jù)表對(duì)應(yīng)表空間
select owner,tablespace_name from dba_segments where segment_name='LUCIFER';
--查詢所有表空間
select tablespace_name from dba_tablespaces;

查詢表空間
查詢所有表空間

主庫(kù)拷貝參數(shù)文件,密碼文件至新主機(jī)凶掰,根據(jù)新主機(jī)修改參數(shù)文件和創(chuàng)建新實(shí)例所需目錄

##生成pfile參數(shù)文件
sqlplus / as sysdba
create pfile='/home/oracle/pfile.ora' from spfile;
##拷貝至新主機(jī)
su - oracle
scp /home/oracle/pfile.ora 10.211.55.112:/tmp
scp $ORACLE_HOME/dbs/orapworcl 10.211.55.112:$ORACLE_HOME/dbs
###新主機(jī)根據(jù)實(shí)際情況修改參數(shù)文件并且創(chuàng)建目錄
mkdir -p /u01/app/oracle/admin/orcl/adump
mkdir -p /oradata/orcl/
mkdir -p /archivelog
chown -R oracle:oinstall /archivelog
chown -R oracle:oinstall /oradata

參數(shù)文件

新主機(jī)使用修改后的參數(shù)文件打開(kāi)數(shù)據(jù)庫(kù)實(shí)例到nomount狀態(tài)

sqlplus / as sysdba
startup nomount pfile='/tmp/pfile.ora';

startup nomount

主庫(kù)拷貝備份的控制文件至新主機(jī)锄俄,新主機(jī)使用RMAN恢復(fù)控制文件勺拣,并且MOUNT新實(shí)例

rman target /
list backup of controlfile;
##拷貝備份文件至新主機(jī)
scp /backup/backlv0_ORCL_20210617_107548592* 10.211.55.112:/tmp
scp /u01/app/oracle/product/11.2.0/db/dbs/0c01l775_1_1 10.211.55.112:/tmp
##新主機(jī)恢復(fù)控制文件并開(kāi)啟到mount狀態(tài)
rman target /
restore controlfile from '/tmp/backlv0_ORCL_20210617_1075485924_9_1';
alter database mount;

通過(guò) list backup of controlfile; 可以看到控制文件位置药有。
list controlfile
拷貝備份文件
恢復(fù)控制文件

新主機(jī)RESTORE TABLESPACE恢復(fù)至?xí)r間點(diǎn) 2021/06/17 18:06:00

##新主機(jī)注冊(cè)備份集
rman target /
catalog start with '/tmp/backlv0_ORCL_20210617_107548592';
crosscheck backup;
delete noprompt expired backup;
delete noprompt obsolete device type disk;
##恢復(fù)表空間LUCIFER和系統(tǒng)表空間苇经,指定時(shí)間點(diǎn) `2021/06/17 18:06:00`
run {
sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';
set until time '2021-06-17 18:06:00';
allocate channel ch01 device type disk;
allocate channel ch02 device type disk;
restore tablespace SYSTEM,SYSAUX,UNDOTBS1,USERS,LUCIFER;
release channel ch01;
release channel ch02;
}

restore恢復(fù)表空間

新主機(jī)RECOVER DATABASE SKIP TABLESPACE恢復(fù)至?xí)r間點(diǎn) 2021/06/17 18:06:00

rman target /
run {
sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';
set until time '2021-06-17 18:06:00';
allocate channel ch01 device type disk;
recover database skip tablespace LTEST,EXAMPLE;
release channel ch01;
}

recover恢復(fù)
這里有一個(gè)小BUG:客戶環(huán)境是Windows扇单,執(zhí)行這一步最后報(bào)錯(cuò)蜘澜,手動(dòng)offline數(shù)據(jù)文件依然無(wú)法開(kāi)啟數(shù)據(jù)庫(kù)响疚。
windows恢復(fù)報(bào)錯(cuò)
解決方案:
--將恢復(fù)跳過(guò)的表空間都o(jì)ffline drop掉忿晕,執(zhí)行以下查詢結(jié)果
select 'alter database datafile '|| file_id ||' offline drop;' from dba_data_files where tablespace_name in ('LTEST','EXAMPLE');
--再次開(kāi)啟數(shù)據(jù)庫(kù)
alter database open read only;

注意:如果顯示缺歸檔日志,可以參考如下步驟:
##查詢恢復(fù)需要的歸檔日志號(hào)時(shí)間 
alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"; 
select first_time,sequence# from v$archived_log where sequence#='7';

##通過(guò)備份RESTORE吐出所需的歸檔日志 
rman target / 
catalog start with '/tmp/0c01l775_1_1'; 
crosscheck archivelog all; 
run { 
allocate channel ch01 device type disk; 
SET ARCHIVELOG DESTINATION TO '/archivelog';
restore ARCHIVELOG SEQUENCE 7; 
release channel ch01; 
}

##再次recover進(jìn)行恢復(fù)至指定時(shí)間點(diǎn) 2021-06-17 18:06:00 
run { 
sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"'; 
set until time '2021-06-17 18:06:00'; 
allocate channel ch01 device type disk; 
recover database skip tablespace LTEST,EXAMPLE; 
release channel ch01; 
} 

新主機(jī)實(shí)例開(kāi)啟到只讀模式

sqlplus / as sysdba
alter database open read only;

開(kāi)啟到只讀

確認(rèn)新主機(jī)實(shí)例的表數(shù)據(jù)是否正確

select * from lucifer.lucifer;

校驗(yàn)恢復(fù)數(shù)據(jù)
注意:若不正確則重復(fù) 第7步 調(diào)整時(shí)間點(diǎn)慢慢往 2021/06/17 18:10:00 推進(jìn)恢復(fù):
##關(guān)閉數(shù)據(jù)庫(kù)
sqlplus / as sysdba
shutdown immediate;

##開(kāi)啟數(shù)據(jù)庫(kù)到mount狀態(tài)
startup mount pfile='/tmp/pfile.ora';

##重復(fù) 第7步,往前推進(jìn)1分鐘渔伯,調(diào)整時(shí)間點(diǎn)為 `2021/06/08 18:07:00`
rman target /
run {
sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';
set until time '2021-06-17 18:07:00';
allocate channel ch01 device type disk;
recover database skip tablespace LTEST,EXAMPLE;
release channel ch01;
}

主庫(kù)創(chuàng)建連通新主機(jī)實(shí)例的DBLINK咱旱,通過(guò)DBLINK從新主機(jī)實(shí)例撈取表數(shù)據(jù)

sqlplus / as sysdba
CREATE PUBLIC DATABASE LINK ORCL112
CONNECT TO lucifer
IDENTIFIED BY lucifer
USING '(DESCRIPTION_LIST=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=10.211.55.112)(PORT=1521))
(CONNECT_DATA=
(SERVICE_NAME=orcl)
)
)
)';
--通過(guò)dblink撈取數(shù)據(jù)
create table lucifer.lucifer_0618 as select /*+full(lucifer)*/ * from lucifer.lucifer@ORCL112;
select * from lucifer.lucifer_0618;

創(chuàng)建DBLINK
通過(guò)dblink恢復(fù)數(shù)據(jù)
至此吐限,整個(gè)RMAN恢復(fù)過(guò)程就結(jié)束了褂始。

總之崎苗,有備份什么都好說(shuō)。所以肌蜻,作為DBA必尼,備份一定要做好!6雇臁券盅!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锰镀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子私蕾,更是在濱河造成了極大的恐慌胡桃,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件自脯,死亡現(xiàn)場(chǎng)離奇詭異斤富,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)焕参,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)叠纷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)潦嘶,“玉大人,你說(shuō)我怎么就攤上這事航厚∶膛睿” “怎么了芹扭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)澈蚌。 經(jīng)常有香客問(wèn)我灼狰,道長(zhǎng)交胚,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任杯活,我火速辦了婚禮熬词,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘歪今。我一直安慰自己寄猩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布替废。 她就那樣靜靜地躺著椎镣,像睡著了一般彬呻。 火紅的嫁衣襯著肌膚如雪柄瑰。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音授翻,去河邊找鬼堪唐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛淮菠,可吹牛的內(nèi)容都是我干的合陵。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼踏拜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼速梗!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起峦嗤,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤屋摔,失蹤者是張志新(化名)和其女友劉穎钓试,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體恋谭,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疚颊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年信认,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嫁赏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡款熬,死狀恐怖攘乒,靈堂內(nèi)的尸體忽然破棺而出则酝,到底是詐尸還是另有隱情,我是刑警寧澤堤魁,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布妥泉,位于F島的核電站,受9級(jí)特大地震影響蝇率,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜排拷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一监氢、第九天 我趴在偏房一處隱蔽的房頂上張望藤违。 院中可真熱鬧,春花似錦议街、人聲如沸璧榄。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)访得。三九已至陕凹,卻和暖如春杜耙,著一層夾襖步出監(jiān)牢的瞬間拂盯,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工团驱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嚎花,地道東北人呀洲。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像兵罢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巩那,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容