Oracle データベース復旧手順書とフルバックアップスクリプト

最近は業務の関係上、Oracle データベースの復旧手順書を作成していました。

Oracle のエンタープライズ分野の主流は RAC 構成になりますが、小規模システムではまだまだシングルインスタンス構成も多いことかと思います。実際システム構成的にはシングルインスタンスの方が遙かにシンプルで運用も楽です。

業務では RAC 構成のシステムを見ていますが、教育という側面からはシングルインスタンスをまずは教えるのが吉です。また部下に DBA の立場を担って貰うことを考えると、最低限知っておいて欲しいのはバックアップ&リカバリ。システムダウン時に活躍するスキルを身につけて欲しいと願います。せっかくいろいろ資料を作ってきたので汎用化できる部分のみ公開しようと思います。

バックアップ方式について言えば最近の主流はもちろん Oracle が提供している Recovery Manager を使ったバックアップ。10g あたりから RMAN が相当使いやすくなってきているので、今から構築なら間違いなく RMAN を使うことをおすすめします。

でも旧来のシステムを使い続けている場合や、小規模なシステムでは、まだまだファイルベースのバックアップ方式をお使いのケースも多いかと思います。これから説明する方法はファイルベースのバックアップを元にリカバリを行う方法になります。RMAN なら書籍でばっちり学ぶことができるので当ブログでは今のところ扱いません。

- スポンサーリンク -

さて、バックアップについては、いろいろ書籍で学んだりネットの情報で勉強をしてきましたが、いまいちコレというフローチャート的なものが見つかりませんでした。いざマニュアルを書くことになっていろいろ調べてみたら、こんなページを見つけました。ページ自体はずいぶん昔からあったみたいなので、今まで見落としていただけのようです。

Oracle データベースの復旧手順 : http://srgia.com/docs/RecoveringOracle-j.html

この手順書は Oracle 7 時代のもので Server manager 使っていたりするので、今時な Oracle 10g/11g 版に書き直しました。また実際考えられるケースを絞り込んでフローチャートも簡略化しました。

Oracle 10g single instance (アーカイブログモード運用)の復旧フローチャート

各ステップの詳細については別エントリにて記述しますが、下記フローチャートから読み取って欲しい重要なポイントは次の通りです。

  • バックアップ&リカバリを考えればアーカイブログ運用は必須。
  • 制御ファイルが全損するとデータベースは基本的に復旧不可能な状態になる。
  • カレント状態(もしくはアーカイブされていないアクティブ状態)のオンラインREDOロググループが全損するとデータベースは最新の状態まで復旧することができない。
  • それ以外の障害であれば、基本的に最新の状態まで復旧することができる。

ora_recovery01.jpg

次に今回のリカバリの元となるバックアップスクリプトの雛形はこちら。※右クリックで DL もできます。

#!/bin/bash 
## oracle ユーザでスクリプトを実行して下さい

##=============================================================================
## 各種変数の定義をココで行います。ご自分の環境にあわせて変更下さい。
source /etc/bashrc
NLS_LANG=American_America.JA16EUC
ORACLE_TNS=testdb                                   ## tnsnames.ora で記述したサービス名を指定する
ORACLE_SID=testdb                                   ## SID を指定する
SysIDPW='sys/パスワード as sysdba'                  ## sqlplus に DBA 権限で接続する際の ID/PW 設定
Mailaddress='your@mail.address.jp'                  ## メール通知先のアドレスを設定
BackupPoint=(/db/ora)                               ## アーカイブログ、データファイル(.arc, .dbf)が存在するディレクトリ名を指定。
                                                    ## 複数指定の場合はスペースを入れて記述する
Tools_dir=/db/tools/backup                          ## このスクリプトを設置する場所
Log_file=$Tools_dir/fullbackup.log                  ## ログファイル
Backup_dir=/db/tools/backup                         ## バックアップファイルを保存する場所
MachineId=`hostname`                                ## Machine name
##=============================================================================

sleeptime=5
cd $Tools_dir


## BEGIN BLOCK 1 : MODULES=====================================================
## BEGIN BLOCK 1.1 : MailOnErr()-----------------------------------------------
MailOnErr ()
{
    Today=`date '+%Y/%m/%d'`
    Time=`date '+%T'`
    MailTo=$Mailaddress
    echo "===================
$0
$Today
$Time

$MachineId has had an error.
Database: ${ORACLE_TNS}
Massage : $message
===================" | mail -s "Error Mail fullbackup_tool" $MailTo
}
## END BLOCK 1.1---------------------------------------------------------------


## BEGIN BLOCK 1.2 : MailOnGood()----------------------------------------------
MailOnGood ()
{
    Today=`date '+%Y/%m/%d'`
    Time=`date '+%T'`
    MailTo=$Mailaddress
    echo "===================
$0
$Today
$Time

$MachineId backup has completed.
Database: ${ORACLE_TNS}
===================" | mail -s "Oracle full_backup completed" $MailTo
}
## ENDBLOCK 1.2----------------------------------------------------------------


## BEGIN BLOCK 1.3 : log_write()-----------------------------------------------
log_write ()
{
    Today=`date '+%Y/%m/%d'`
    Time=`date '+%T'`
    echo "$Today-$Time              $message" >>$Log_file
}
## ENDBLOCK 1.3----------------------------------------------------------------
## END BLOCK 1 : MODULES=======================================================


message='Begin fullbackup tool'
log_write


## BEGIN BLOCK 2 : ORACLE CHECK================================================
## BEGIN BLOCK 2.1 : Oracle Usable Check---------------------------------------
message='- Oracle Usable Check'
log_write
sqlplus -s <<Eof
    $SysIDPW
    exit
Eof

if [ $? -ne 0 ]
then
    message="Sqlplus could not connect to Oracle. Oracle could not Use!!"
    log_write
    MailOnErr
    exit 1
fi
## END BLOCK 2.1---------------------------------------------------------------


## BEGIN BLOCK 2.2 : The newest Archive redo log is generated------------------
message='- The newest Archive redo log is generated'
log_write
sqlplus -s <<Eof
    $SysIDPW
    alter system switch logfile;
    exit
Eof

if [ $? -ne 0 ]
then
    message="could not switch logfile. Oracle could not Use!!"
    log_write
    MailOnErr
    exit 1
fi
## END BLOCK 2.2---------------------------------------------------------------


## BEGIN BLOCK 2.3 : Get Oracle SID Environmental Variable---------------------
message='- Get Oracle SID Environmental Variable'
log_write
if [ -z "$ORACLE_TNS" ]
then
    message='ERROR occured!
    Can not find $ORACLE_TNS definition - EXITING SCRIPT!'
    log_write
    MailOnErr
    exit 1
fi
## END BLOCK 2.3---------------------------------------------------------------
## END BLOCK 2 : ORACLE CHECK==================================================


## BEGIN BLOCK 3 : Check Database in Archivelog mode and is enabled============
message='- Check Database in Archivelog mode and is enabled'
log_write
sqlplus -s << Eof 2>&1
    $SysIDPW
    spool archiveloglist.txt;
    archive log list
    spool off;
    exit
Eof

if [ ! -s "archiveloglist.txt" ]
then
    message='ERROR occured!
    Failed to produce archive log list.'
    log_write
    MailOnErr
    exit 1
fi

DbLogMode=`awk ' /log mode/ {print $4}' archiveloglist.txt`
if [ -z $DbLogMode ]
then
    message='ERROR occured!
    Can not get Database log mode.'
    log_write
    MailOnErr
    exit 1
fi

if [ "$DbLogMode" != Archive ]
then
    message='ERROR occured!
    Oracle database is not in Database log Mode.
    Please inform your Oracle DBA that the ARCHIVELOG mode must
    be set   - EXIT SCRIPT!'
    log_write
    MailOnErr
    exit 1
fi

AutoArc=`awk ' /Automatic/ {print $3}' archiveloglist.txt`
if [ -z $AutoArc ]
then
    message='ERROR occured!
    Can not get Database archival mode.'
    log_write
    MailOnErr
    exit 1
fi

if [ "$AutoArc" != Enabled ]
then
    message='ERROR occured!
    Oracle database is not in Automatic Archival Mode.
    Please inform your Oracle DBA that the ARCHIVELOG mode must
    be set  - EXIT SCRIPT!'
    log_write
    MailOnErr
    exit 1
fi
## END BLOCK 3=================================================================


## BEGIN BLOCK 4 : Get Oracle Home Environmental Variable======================
message='- Get Oracle Home Environmental Variable'
log_write
if [ -z "$ORACLE_HOME" ]
then
    message='ERROR occured!
    Can not find $ORACLE_HOME definition - EXITING SCRIPT!'
    log_write
    MailOnErr
    exit 1
fi
## END BLOCK 4=================================================================


## BEGIN BLOCK 5 : Get Oracle Initialisation File Path and File================
message='- Get Oracle Initialisation File Path and File'
log_write
sqlplus << Eof 2>&1
    $SysIDPW
    spool spfile.txt;
    select value from v\$system_parameter where name ='spfile';
    spool off;
    exit
Eof

if [ ! -s "spfile.txt" ]
then
    message='ERROR occured!
    Failed to produce spfile location.'
    log_write
    MailOnErr
    exit 1
fi

InitSpFile=`awk '/.ora/ {print $1}' spfile.txt`
if [ -z $DbLogMode ]
then
    message='ERROR occured!
    Can not get spfile location.'
    log_write
    MailOnErr
    exit 1
fi
InitFile=$Backup_dir/init${ORACLE_TNS}.ora
## END BLOCK 5=================================================================


## BEGIN BLOCK 6 : Database Backup=============================================
## BEGIN BLOCK 6.1 : Begin Backup----------------------------------------------
message='- Begin Backup'
log_write
sqlplus << Eof 2>&1
    $SysIDPW
    alter database begin backup;
    exit
Eof
## END BLOCK 6.1---------------------------------------------------------------


## BEGIN BLOCK 6.2 : Compress All Backup All files-----------------------------
message="- Compress all backup-files."
log_write
rm -f datafiles.txt
for dirname in ${BackupPoint[@]};
do
    find $dirname -name *.dbf >>datafiles.txt
    find $dirname -name *.arc >>datafiles.txt
done;

cat datafiles.txt | while read line
do
    compress_file=`echo $line | awk -F/ '{print $NF}'`
    data_file=`echo $line | awk '{print $1}'`

    message="  - compress_file : $compress_file"
    log_write
    tar cvzf $Backup_dir/$compress_file.tar.gz $data_file

    if [ $? -ne 0 ]
    then
        message="ERROR OCCURED!! when $TableSpace : $compress_file copy"
        log_write
        MailOnErr
        exit 1
    fi

    echo "   --> compressed!!"
done;

tar cvfz $Backup_dir/db0.tar.gz /db0/oradata
message="Compress all backup-files."
log_write
## END BLOCK 6.2---------------------------------------------------------------


## BEGIN BLOCK 6.3 : End Backup------------------------------------------------
message='- End Backup'
log_write
sqlplus << Eof 2>&1
    $SysIDPW
    alter database end backup;
    exit
Eof
## END BLOCK 6.3---------------------------------------------------------------
## END BLOCK 6 : End of Database Backup========================================


## BEGIN BLOCK 7 : Configuration File Backup===================================
message='- Configuration File Backup'
log_write
sqlplus << Eof 2>&1
    $SysIDPW
    create pfile='$InitFile' from spfile;
    exit
Eof
## END BLOCK 7=================================================================


## BEGIN BLOCK 8 : Controlfile Backup==========================================
message='- Controlfile Backup'
log_write
sqlplus << Eof 2>&1
    $SysIDPW
    alter database backup controlfile to '$Backup_dir/controlfile.arc' reuse;
    exit
Eof
message="Controlfile Backup Completed."
log_write
## END BLOCK 8=================================================================


## BEGIN BLOCK 9 : Lister & tnsname Backup=====================================
message='- Lister & tnsname Backup'
log_write
cp -f $ORACLE_HOME/network/admin/listener.ora $Backup_dir/listener.ora
cp -f $ORACLE_HOME/network/admin/tnsnames.ora $Backup_dir/tnsnames.ora
## END BLOCK 9=================================================================


MailOnGood
message='END fullbackup tool'
log_write

exit 0
- スポンサーリンク -