前言
常在河邊走,哪能不濕鞋?
今天有客戶聯系說誤更新資料表,導致資料錯亂了,希望將這張表恢復到 一周前 的指定時間點,
- 資料庫版本為
11.2.0.1 - 作業系統是
Windows64 - 資料已經被更改超過1周時間
- 資料庫已開啟歸檔模式
- 沒有DG容災
- 有RMAN備份
下面模擬一下問題的詳細解決程序!
一、分析
以下只列出常規恢復手段:
- 資料已經誤操作超過一周,所以排除使用UNDO快照來找回;
- 沒有DG容災環境,排除使用DG閃回;
- 主庫已開啟歸檔模式,并且存在RMAN備份,可使用RMAN異機恢復表對應表空間,使用DBLINK撈回資料表;
- Oracle 12C后支持單張表恢復;
結論:安全起見,使用RMAN異機恢復表空間來撈回資料表,
二、思路
客戶希望將表資料恢復到 <2021/06/08 17:00:00> 之前某個時間點,
大致操作步驟如下:
- 主庫查詢誤更新資料表對應的表空間和無需恢復的表空間,
- 新主機安裝Oracle 11.2.0.1資料庫軟體,無需建庫,目錄結構最好保持一致,
- 主庫拷貝引數檔案,密碼檔案至新主機,根據新主機修改引數檔案和創建新實體所需目錄,
- 新主機使用修改后的引數檔案打開資料庫實體到nomount狀態,
- 主庫拷貝備份的控制檔案至新主機,新主機使用RMAN恢復控制檔案,并且MOUNT新實體,
- 新主機RESTORE TABLESPACE恢復至時間點 <2021/06/08 16:00:00>,
- 新主機RECOVER DATABASE SKIP TABLESPACE恢復至時間點 <2021/06/08 16:00:00>,
- 新主機實體開啟到只讀模式,
- 確認新主機實體的表資料是否正確,若不正確則重復 第7步 調整時間點慢慢往 <2021/06/08 17:00:00> 推進恢復,
- 主庫創建連通新主機實體的DBLINK,通過DBLINK從新主機實體撈取表資料,
📢 注意: 選擇表空間恢復是因為主庫資料量比較大,如果全庫恢復需要大量時間,
三、測驗環境模擬
為了資料脫敏,因此以測驗環境模擬場景進行演示!
?? 測驗環境可以使用腳本安裝,可以使用博主撰寫的 Oracle 一鍵安裝腳本,同時支持單機和 RAC 集群模式!
開源專案:Install Oracle Database By Scripts!
更多更詳細的腳本使用方式可以訂閱專欄:Oracle一鍵安裝腳本,
1、環境準備
測驗環境資訊如下:
| 節點 | 主機版本 | 主機名 | 實體名 | Oracle版本 | IP地址 |
|---|---|---|---|---|---|
| 主庫 | rhel6.9 | orcl | orcl | 11.2.0.1 | 10.211.55.111 |
| 新主機 | rhel6.9 | orcl | 不創建實體 | 11.2.0.1 | 10.211.55.112 |
2、模擬測驗場景
主庫開啟歸檔模式:
sqlplus / as sysdba
## 設定歸檔路徑
alter system set log_archive_dest_1='LOCATION=/archivelog';
## 重啟開啟歸檔模式
shutdown immediate
startup mount
alter database archivelog;
## 打開資料庫
alter database open;
創建測驗資料:
sqlplus / as sysdba
## 創建表空間
create tablespace lucifer datafile '/oradata/orcl/lucifer01.dbf' size 10M autoextend off;
create tablespace ltest datafile '/oradata/orcl/ltest01.dbf' size 10M autoextend off;
## 創建用戶
create user lucifer identified by lucifer;
grant dba to lucifer;
## 創建表
conn lucifer/lucifer
create table lucifer(id number not null,name varchar2(20)) tablespace lucifer;
## 插入資料
insert into lucifer values(1,'lucifer');
insert into lucifer values(2,'test1');
insert into lucifer values(3,'test2');
commit;

進行資料庫全備:
rman target /
## 進入 rman 后執行以下命令
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;
}

模擬資料修改:
sqlplus / as sysdba
conn lucifer/lucifer
delete from lucifer where id=1;
update lucifer set name='lucifer' where id=2;
commit;

📢 注意: 為了模擬客戶環境,假設無法通過UNDO快照找回,當前洗掉時間點為:<2021/06/17 18:10:00>,
如果使用UNDO快照,比較方便:
sqlplus / as sysdba
## 查找UNDO快照資料是否正確
select * from lucifer.lucifer as of timestamp to_timestamp('2021-06-17 18:05:00','YYYY-MM-DD HH24:MI:SS');
## 將UNDO快照資料撈至新建表中
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完整恢復程序
主庫查詢誤更新資料表對應的表空間和無需恢復的表空間:
sqlplus / as sysdba
## 查詢誤更新資料表對應表空間
select owner,tablespace_name from dba_segments where segment_name='LUCIFER';
## 查詢所有表空間
select tablespace_name from dba_tablespaces;


主庫拷貝引數檔案,密碼檔案至新主機,根據新主機修改引數檔案和創建新實體所需目錄:
## 生成pfile引數檔案
sqlplus / as sysdba
create pfile='/home/oracle/pfile.ora' from spfile;
exit;
## 拷貝至新主機
su - oracle
scp /home/oracle/pfile.ora 10.211.55.112:/tmp
scp $ORACLE_HOME/dbs/orapworcl 10.211.55.112:$ORACLE_HOME/dbs
## 新主機根據實際情況修改引數檔案并且創建目錄
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

新主機使用修改后的引數檔案打開資料庫實體到nomount狀態:
sqlplus / as sysdba
startup nomount pfile='/tmp/pfile.ora';

主庫拷貝備份的控制檔案至新主機,新主機使用RMAN恢復控制檔案,并且MOUNT新實體:
rman target /
list backup of controlfile;
exit;
## 拷貝備份檔案至新主機
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
## 新主機恢復控制檔案并開啟到mount狀態
rman target /
restore controlfile from '/tmp/backlv0_ORCL_20210617_1075485924_9_1';
alter database mount;
通過 list backup of controlfile; 可以看到控制檔案位置:



新主機RESTORE TABLESPACE恢復至時間點 <2021/06/17 18:06:00> :
## 新主機注冊備份集
rman target /
catalog start with '/tmp/backlv0_ORCL_20210617_107548592';
crosscheck backup;
delete noprompt expired backup;
delete noprompt obsolete device type disk;
## 恢復表空間LUCIFER和系統表空間,指定時間點 `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;
}

新主機RECOVER DATABASE SKIP TABLESPACE恢復至時間點 <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;
}

這里有一個小BUG: 客戶環境是Windows,執行這一步最后報錯,手動offline資料檔案依然無法開啟資料庫,

解決方案:
sqlplus / as sysdba
## 將恢復跳過的表空間都offline drop掉,執行以下查詢結果
select 'alter database datafile '|| file_id ||' offline drop;' from dba_data_files where tablespace_name in ('LTEST','EXAMPLE');
## 再次開啟資料庫
alter database open read only;
📢 注意: 如果顯示缺歸檔日志,可以參考如下步驟:
sqlplus / as sysdba
## 查詢恢復需要的歸檔日志號時間
alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss";
select first_time,sequence# from v$archived_log where sequence#='7';
exit;
## 通過備份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進行恢復至指定時間點 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;
}
新主機實體開啟到只讀模式:
sqlplus / as sysdba
alter database open read only;

確認新主機實體的表資料是否正確:
sqlplus / as sysdba
select * from lucifer.lucifer;

📢 注意: 若不正確則重復 第7步 調整時間點慢慢往 2021/06/17 18:10:00 推進恢復:
## 關閉資料庫
sqlplus / as sysdba
shutdown immediate;
## 開啟資料庫到mount狀態
startup mount pfile='/tmp/pfile.ora';
## 重復 第7步,往前推進1分鐘,調整時間點為 `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;
}
主庫創建連通新主機實體的DBLINK,通過DBLINK從新主機實體撈取表資料:
sqlplus / as sysdba
## 創建dblinnk
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)
)
)
)';
## 通過dblink撈取資料
create table lucifer.lucifer_0618 as select /*+full(lucifer)*/ * from lucifer.lucifer@ORCL112;
select * from lucifer.lucifer_0618;


至此,整個RMAN恢復程序就結束了!
寫在最后
備份永遠是最后一道防線,所以備份一定要做好!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/356118.html
標籤:其他
上一篇:(Java)資料結構之堆疊(Stack) ,附有三個堆疊相關OJ題目和對應做法(括號匹配,逆波蘭運算式求值,出堆疊入堆疊次序匹配)
下一篇:資料結構之二叉樹詳解
