數據庫在運行過程當中,可能會處於某種原因導致控制文件丟失或者損壞,數據庫文件記錄着數據庫的結構信息,包括數據文件,歸檔日誌文件等數據庫的重要信息,控制文件丟失,直接會導致數據庫宕機。這篇博客會模擬各種控制文件丟失的情況,來恢復數據庫的正常使用。
丟失部分控制文件
控制文件在數據庫中佔據着非常主要的地位,通常會採用多路複用的原則對數據庫控制文件進行保護,即使丟失了部分控制文件,數據庫可以通過多路複用中的其他控制文件,恢復控制文件。
假設數據庫中我們控制文件存放在兩個位置
位置1:/u01/app/oracle/oradata/XE/control.ctl
位置2:/u02/app/oracle/oradata/XE/control.ctl
SQL> select name from v$controlfile;
NAME
--------------------------------------------------
/u01/app/oracle/oradata/XE/control.ctl
/u02/app/oracle/oradata/XE/control.ctl
SQL>
恢復控制文件到默認的目錄下
數據庫在運行的某個階段,突然導致/u01目錄下的控制文件丟失了,我們希望通過/u02目錄下的控制文件來恢復/u01下的控制文件,下面模擬恢復的過程:
rm -rf /u01/app/oracle/oradata/XE/control.ctl
強制停止數據庫
SQL> shutdown abort;
拷貝/u02下的控制文件到/u01下控制文件的存放位置
oracle@oracledb:~$ cp /u02/app/oracle/oradata/XE/control.ctl /u01/app/oracle/oradata/XE/
啓動數據庫
SQL> startup nomount;
ORACLE instance started.
Total System Global Area 601272320 bytes
Fixed Size 2228848 bytes
Variable Size 180358544 bytes
Database Buffers 415236096 bytes
Redo Buffers 3448832 bytes
SQL> alter database mount;
Database altered.
SQL> alter database open;
Database altered.
恢復控制文件到其他的目錄
假設系統咋運行的過程當中導致存放多路複用的一個控制文件的目錄丟失,我們需要把控制文件恢復到別的目錄下,這就需要我們修改參數文件中控制文件的路徑。下面演示過程:
rm -rf /u01/app/oracle/oradata/XE
強制停止數據庫
SQL> shutdown abort;
ORACLE instance shut down.
創建控制文件的恢復目錄,並拷貝控制文件
root@oracledb:~# mkdir -p /u03/app/oracle/oradata/XE/
root@oracledb:~# chown -R oracle:dba /u03
root@oracledb:~# chmod -R 755 /u03
root@oracledb:~# su - oracle
oracle@oracledb:~$ cp /u01/app/oracle/oradata/XE/control.ctl /u03/app/oracle/oradata/XE/
修改參數文件中控制文件的路徑
SQL> create pfile from spfile;
File created.
SQL> host vi $/dbs/initXE.ora
SQL> host vi $ORACLE_HOME/dbs/initXE.ora
*.control_files='/u01/app/oracle/oradata/XE/control.ctl','/u03/app/oracle/oradata/XE/control.ctl'
重啓數據庫
SQL> startup nomount pfile=?/dbs/initXE.ora
ORACLE instance started.
Total System Global Area 601272320 bytes
Fixed Size 2228848 bytes
Variable Size 180358544 bytes
Database Buffers 415236096 bytes
Redo Buffers 3448832 bytes
SQL> create spfile from pfile;
SQL> alter database mount;
Database altered.
SQL> alter database open;
Database altered.
控制文件全部丟失,但是有一個曾經備份過的二進制控制文件
這種情景是數據庫在運行的過程當中,控制文件丟失,但以前冷備過一個控制文件,oracle的一致性狀態,控制文件的頭部和數據庫文件的頭部有SCN號,來保證數據庫文件的一致性。我們使用以前備份過的控制文件需要一些額外的恢復操作,下面演示恢復步驟。
oracle@oracledb:~$ rm -rf /u01/app/oracle/oradata/XE/control.ctl
oracle@oracledb:~$ rm -rf /u02/app/oracle/oradata/XE/control.ctl
強制關閉數據庫
SQL> shutdown abort;
ORACLE instance shut down.
拷貝老的備份的控制文件
oracle@oracledb:~$ cp /upload/control.ctl /u01/app/oracle/oradata/XE/
oracle@oracledb:~$ cp /upload/control.ctl /u02/app/oracle/oradata/XE/
數據庫打開到mount狀態
SQL> startup mount;
ORACLE instance started.
Total System Global Area 601272320 bytes
Fixed Size 2228848 bytes
Variable Size 180358544 bytes
Database Buffers 415236096 bytes
Redo Buffers 3448832 bytes
Database mounted.
數據庫在mount時,並不會提示什麼錯誤信息,接下來我們嘗試打開數據庫,會提示錯誤。
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01190: control file or data file 1 is from before the last RESETLOGS
ORA-01110: data file 1: '/u01/app/oracle/oradata/XE/system.dbf'
恢復數據庫
我們使用的是一個老的控制文件,在恢復數據庫時需要使用using backup controlfile子句。
恢復的過程當中,數據庫會提示我們使用歸檔日誌文件來恢復數據庫。如果數據庫處於非歸檔模式的情況下,我們只能使用在線重做日誌文件來恢復數據庫
SQL> recover database using backup controlfile until cancel;
ORA-00279: change 458993 generated at 03/31/2018 06:52:10 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/fast_recovery_area/XE/archivelog/2018_03_31/o1_mf_1_5_%u_.arc
ORA-00280: change 458993 for thread 1 is in sequence #5
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u01/app/oracle/oradata/XE/redo1.log
Log applied.
Media recovery complete.
打開數據庫
SQL> alter database open resetlogs;
Database altered.
控制文件全部丟失,重建控制文件
如果控制文件沒有多慮複用,存在單點故障的問題,控制文件一旦丟失,沒有備份,我們需要重建控制文件.重建控制文件的sql語句,我們可以通過alert_sid日誌中找到。但可能存在一些問題,需要我們注意的:如果找到一個最古老的的控制文件,在這個控制文件創建之後,又新建了表空間,我們需要找到這些表空間,並把表空間的信息加入到重建控制文件中的sql語句中。
oracle@oracledb:~$ rm -rf /u01/app/oracle/oradata/XE/control.ctl
oracle@oracledb:~$ rm -rf /u03/app/oracle/oradata/XE/control.ctl
強制停止數據庫
SQL> shutdown abort;
ORACLE instance shut down.
將數據庫打開到nomount狀態
SQL> startup nomount
ORACLE instance started.
Total System Global Area 601272320 bytes
Fixed Size 2228848 bytes
Variable Size 180358544 bytes
Database Buffers 415236096 bytes
Redo Buffers 3448832 bytes
create controlfile語句可以在數據庫的alert日誌文件中找到,我的日誌文件位於: /u01/app/oracle/diag/rdbms/xe/XE/trace/alert_XE.log.
或者以前以文本形式備份過的控制文件:
SQL> alter database backup controlfile to trace as '/upload/control1.bak';
下面這個語句是在線重做日誌文件和歸檔日誌文件都可用的情況下使用,注意參數NORESETLOGS NOARCHIVELOG和DATAFILE,需要補充後來新建的表空間文件.
CREATE CONTROLFILE REUSE DATABASE "XE" NORESETLOGS NOARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 '/u01/app/oracle/oradata/XE/redo1.log' SIZE 50M BLOCKSIZE 512,
GROUP 2 '/u01/app/oracle/oradata/XE/redo2.log' SIZE 50M BLOCKSIZE 512
-- STANDBY LOGFILE
DATAFILE
'/u01/app/oracle/oradata/XE/system.dbf',
'/u01/app/oracle/oradata/XE/sysaux.dbf',
'/u01/app/oracle/oradata/XE/undotbs1.dbf',
'/u01/app/oracle/oradata/XE/users.dbf',
'/u01/app/oracle/oradata/XE/itreasury1.dbf'
CHARACTER SET AL32UTF8;
recover數據庫
SQL> recover database;
Media recovery complete.
啓動數據庫
SQL> alter database open;
Database altered.