前言
常在河邊走西剥,哪能不濕鞋?
今天有客戶聯(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;
進(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;
注意:為了模擬客戶環(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');
四夫晌、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
新主機(jī)使用修改后的參數(shù)文件打開(kāi)數(shù)據(jù)庫(kù)實(shí)例到nomount狀態(tài)
sqlplus / as sysdba
startup nomount pfile='/tmp/pfile.ora';
主庫(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;
可以看到控制文件位置药有。
新主機(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;
}
新主機(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;
}
這里有一個(gè)小BUG:客戶環(huán)境是Windows扇单,執(zhí)行這一步最后報(bào)錯(cuò)蜘澜,手動(dòng)offline數(shù)據(jù)文件依然無(wú)法開(kāi)啟數(shù)據(jù)庫(kù)响疚。
解決方案:
--將恢復(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;
確認(rèn)新主機(jī)實(shí)例的表數(shù)據(jù)是否正確
select * from lucifer.lucifer;
注意:若不正確則重復(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;
至此吐限,整個(gè)RMAN恢復(fù)過(guò)程就結(jié)束了褂始。
總之崎苗,有備份什么都好說(shuō)。所以肌蜻,作為DBA必尼,備份一定要做好!6雇臁券盅!