一键式做rman异机恢复脚本

写的一个小玩具

使用方法:

默认的环境变量启动该空壳实例

bak_dir下是所有备份+归档,有多少归档恢复到什么位置,自行保证一致性

restore_dir下展开的数据文件的地方

bak_ctl这个需要自己指定控制文件的备份片

#!/bin/sh

#user define var
restore_dir='/oradata'
bak_dir="'/home/oracle/rmanbak/'"
bak_ctl="'/home/oracle/rmanbak/control.bak'"
database="orcl"
parallelism=4

#prepare 
data_dir="${restore_dir}/${database}"
newname_path="'${restore_dir}/${database}/%b'"
logpath="/tmp/restore_${database}.log"









start_nomout(){
    # call startup with nomount

    sqlplus / as sysdba > ${logpath} << ABC
	startup nomount force;
	exit;
ABC
}


restore_ctl(){
    # call restore controle file and mount database

    rman target / log=${logpath} append << QWE
	run {
	allocate channel ch1 device type disk;
	restore controlfile from ${bak_ctl};
	RELEASE CHANNEL ch1;
	alter database mount;
	sql 'alter database flashback off';
	}
QWE
}

catalog_bak(){
    # call catalog
	
    rman target /  log=${logpath} append  << ZXC
	run {
	catalog start with ${bak_dir} noprompt;
	crosscheck backupset;
	delete noprompt expired backupset;
	}
ZXC
}


restore_db(){
    # call restore db

    rman target /  log=${logpath} append  << WSX
	run {
	CONFIGURE DEVICE TYPE DISK PARALLELISM ${parallelism};
	set newname for database to ${newname_path};
	catalog start with ${bak_dir} noprompt;
	restore database;
	switch datafile all;
	}
WSX
}


recover_db(){
	#recover db
    rman target /  log=${logpath} append  << QWE
	run {
	restore archivelog all;
	recover database;
	}
QWE
}

open_database(){
	#open database resetlogs
    sqlplus -s / as sysdba > /tmp/rename_redolog_${database}.sql << EOF
    set lines 500;
    set pages 500;
    set feedback off;
    set pagesize 0;
    set termout off;

    SELECT 'ALTER DATABASE RENAME FILE '''
    || old_redo.redo_files
    || ''' to '''
    || new_redo.new_redo_files
    || ''';' AS command
  FROM
    (SELECT group_number,
      redo_files
    FROM
      (SELECT group# AS group_number,
        listagg(member, ''',''') within GROUP (
      ORDER BY group#) AS redo_files
      FROM v\$logfile
      GROUP BY group#
      )
    ) old_redo,
    (SELECT group# AS group_number,
      listagg('${data_dir}/'
      || new_redologs, ''',''') within GROUP (
    ORDER BY group#) AS new_redo_files
    FROM
      (SELECT redologs.*,
        'redo0'
        || rownum
        || '.log' AS new_redologs
      FROM v\$logfile redologs
      )
    GROUP BY group#
    ) new_redo
  WHERE old_redo.group_number = new_redo.group_number;
EOF


    sqlplus / as sysdba >> ${logpath} << EDC
      @/tmp/rename_redolog_${database}.sql;
	  !sleep 3
      alter database open resetlogs;
      create spfile from pfile;
EDC
}


add_tempfile(){
    sqlplus -s / as sysdba > /tmp/add_tempfile_${database}.sql << POI
    set lines 500;
    set pages 500;
    set feedback off;
    set pagesize 0;
    set termout off;

	SELECT distinct 'alter tablespace '||temporary_tablespace||' add tempfile ''${datadir}/'||temporary_tablespace||'.dbf'' size 1g autoextend on;'
    from dba_users;
POI


    sqlplus / as sysdba >> ${logpath} << LKJ
      @/tmp/add_tempfile_${database}.sql;
LKJ
}




main(){
echo "log path: " ${logpath}
echo "data_dir" ${data_dir}
echo "newname_path" ${newname_path}
echo "bak_ctl" ${bak_ctl}
echo "bak_dir "${bak_dir}

mkdir ${data_dir}

####nomount judge
if [ (ps -ef|grep pmon|grep -v grep|grep ${database}|wc -l) < 1 ]; then
start_nomout
fi
sleep 3

####ctl judge
ctl_path=`sqlplus -silent "/ as sysdba" << END
set pagesize 0 feedback off verify off heading off echo off
select name from v\\\$controlfile;
exit;
END`
if [ ! -e "${ctl_path}" | awk 'BEGIN {RS="\\N"} {print $1}' ]; then
restore_ctl
fi
sleep 3

####restore judge
if [ ! find "${datadir}" -maxdepth 0 -type d -empty -exec false {} \; ]; then
restore_db 
fi
sleep 3

####recover judge
scn_smooth=`sqlplus -silent "/ as sysdba" << END
set pagesize 0 feedback off verify off heading off echo off
select distinct checkpoint_change# from v\\\$datafile_header;
exit;
END`
if [[ ! ${scn_smooth} =~ \s.+ ]]; then
recover_db
fi
sleep 3

####open judge
database_mode=`sqlplus -silent "/ as sysdba" << END
set pagesize 0 feedback off verify off heading off echo off
select open_mode from v\\\$database ;
exit;
END`
if [[ ! ${database_mode} == *'READ WRITE'* ]]; then
open_database
fi
sleep 3


####add temp judge
if [ -e ${data_dir}/temp.dbf ]; then
add_tempfile
fi


}

main

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值