文章目录
前言
工作中遇到一个新的需求,需要通过shell脚本实现expdp,impdp自动化作业任务,旨在自动生成dmp文件后通过shell脚本再次实现dmp文件的自动恢复。本次操作是在同一主机的不同实例下完成的功能。
提示:本功能分为两大部分:expdp导出部分,impdp导入部分
一、expdp导出部分
expdp导出部分比较简单,大家直接看代码理解下:
#!/bin/sh
# Oracle 环境变量设置
ORACLE_BASE=[ORACLE_BASE]; export ORACLE_BASE
ORACLE_HOME=$ORACLE_BASE/product/19.0.0.0/dbhome_1; export ORACLE_HOME
ORACLE_SID=[ORACLE_SID]; export ORACLE_SID
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$ORACLE_HOME/jdk/bin:$ORACLE_BASE/scripts:$PATH
#SQL>CREATE DIRECTORY [DIR_NAME] as '[/XXXX/XXXX/XXXX]';
#SQL>grant read,write on directory [DIR_NAME] to public;
DATA_DIR=[/XXXX/XXXX/XXXX]
DMP_FILE=bak[NAME]_expdp_$(date +%Y%m%d)_%U.dmp
DMP_FILE_BAK=bak[NAME]_expdp_$(date +%Y%m%d)
LOG_FILE=bak[NAME]_expdp_$(date +%Y%m%d).log
FILE_NAME=bak[NAME]_expdp_$(date +%Y%m%d)
#开始expdp导出hisdb数据
expdp SYS/[PASSWORD]@[TNSNAME] directory=[DIR_NAME] parallel=4 SCHEMAS=[USERNAME] cluster=N dumpfile=$DMP_FILE logfile=$LOG_FILE COMPRESSION=ALL
#删除备份3天以上的备份数据
cd $DATA_DIR
#tar czvf $FILE_NAME.tar.gz $DMP_FILE_BAK_*.dmp $LOG_FILE
find $DATA_DIR -mtime +3 -name "bak[NAME]_expdp_*" -exec rm -f {} \;
#以上
二、impdp导入部分
1.kill已连接会话的spid(生成txt文件执行)
由于在恢复数据前需要进行drop user的数据,但如果存在连接的话将无法drop user,遂我们要先kill掉已连接的会话。(前提和业务部门确认好执行时间段)
2.命令登录sqlplus后执行kill命令
3.完成kill后执行drop user操作
kill完成后建议等待一分钟左右再进行drop操作,在测试过程中发现kill掉后系统没有立马释放,需要等待一段时间,下面代码有注释。
4.最后完成impdp导入操作
#杀死会话gv\$process
#!/usr/bin/bash
sqlinfo1="alter user [USERNAME] account lock;" #先锁定用户防止应用自启连接
sqlinfo2="select '!kill -9 '||spid||';' from gv\$process where addr in (select paddr from gv\$session where SCHEMANAME='[USERNAME]');" #通过select语句生成kill执行脚本,rac模式使用gv$session,这里'\'为转义
start_time=`date +%Y%m%d%H%M%S` #时间记录
work_path=[/YYYY/XXXX/XXXX] #脚本执行目录
DbCon=SYS/[PASSWORD]@[TNSNAME]/[IP:PROT/SID] #连接数据库字符串
filename=${work_path}/kill_spid.txt; #生成spid号的txt文本名称
#以下为输出
echo "---------------- start to exec job $start_time "
echo "---------------- sqlinfo = $sqlinfo1"
echo "---------------- sqlinfo = $sqlinfo2"
#以上将生成
sqlplus -S $DbCon<< EndSql #登入sqlplus
#以下为oracle spool 缓冲池的设置,大家可自行学习
set line 1000
set pagesize 0
set feedback off
set heading off
set trimspool on
set trims on
set echo off
set colsep ','
set termout off
$sqlinfo1 #执行锁定用户
spool $filename #开始生成记录文件
$sqlinfo2 #执行查询
spool off #结束生成
@$filename #执行select结果文件kill_spid.txt
exit
EndSql
#去除文件开头的空格及中间的空白字符
#sed -i 's/ //g' ${work_path}/kill_spid.txt
end_time=`date +%Y%m%d%H%M%S` #时间记录
echo "---------------- cmd end , please check te result $end_time"
#等待系统释放
sleep 100 #shell设置等待时长为100秒
#这是导入测试库脚本
#1.先删除原有旧数据
# Oracle 环境变量设置
ORACLE_BASE=[ORACLE_BASE]; export ORACLE_BASE
ORACLE_HOME=$ORACLE_BASE/product/19.0.0.0/dbhome_1; export ORACLE_HOME
ORACLE_SID=[ORACLE_SID]; export ORACLE_SID
DATE=`date +%Y%m%d`
DATA_DIR=[/XXXX/XXXX/XXXX]
DMP_FILE=bak[NAME]_expdp_$(date +%Y%m%d)_%U.dmp
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$ORACLE_HOME/jdk/bin:$ORACLE_BASE/scripts:$PATH
if [ $USER = "oracle" ]
then
echo "当前用户是oracle,可以继续!"
else
echo "!!!当前用户不是oracle,请使用oracle用户执行本备份脚本,程序将退出!!!"
exit
fi
export ORACLE_SID=[ORACLE_SID]
sqlplus SYS/[PASSWORD]@[TNSNAME] <<EOF>>[[/YYYY/XXXX/XXXX]]/impdp_$ORACLE_SID.$DATE.log
drop user [USERNAME] cascade;
exit;
EOF
echo "原有数据删除:$ORACLE_SID 删除完成!"
#SQL>CREATE DIRECTORY [DIRNAME] as '/data/yhis/hisdb';
#SQL>grant read,write on directory [DIRNAME] to public;
#开始impdp导入hisdb数据
impdp SYS/[PASSWORD]@[TNSNAME] directory=[DIRNAME] parallel=4 SCHEMAS=[USERNAME] cluster=N dumpfile=$DMP_FILE
echo "impdp导入操作完成!"
总结
因为操作有可能是正式环境中,而且涉及到drop操作,童鞋们要注意导出和导入的实例名称,经过测试后再实施,生产无小事!