代码改变世界

db_expdp_data_v1.sh导数脚本分享

2025-08-06 22:44  潇湘隐者  阅读(35)  评论(0)    收藏  举报

脚本介绍

在日常运维工作中,经常会有使用数据泵导数的需求.遇到这种需求,经常需要手写一个导数的脚本或者去找一个导数脚本的例子进行修改. 这样重复的工作,虽然没有很复杂,突然有一天意识到应该避免这样重复、琐碎、繁杂的工作. 工作就要提升效率与自动化,可以优化的流程和方法,尽量优化,能简单的尽量简单.哪怕简洁一点点。于是有了这样一个脚本.

脚本变量

DUMP_DIR        设置数据泵的导出的路径. 根据实际情况调整                                          
DB_USER         访问数据库的账号,可以不设置(如果启用操作系统认证方式),默认不设置
DB_PASSWORD     DB_USER指定账户的密码,可以不设置(如果启用操作系统认证方式),默认不设置                                          
PARALLEL_NUM    expdp的并行度                                                   
LOG_FILE        此变量赋值在usage函数的后面进行重新赋值..      

上面变量除了DUMP_DIR需要设置外,其它变量几乎不用设置.当然每个人的实际环境可能有所不同.根据实际情况进行调整.

脚本参数

脚本有三个参数:

./db_expdp_data_v1.sh <ORACLE_SID>|<PDB_NAME>   <DUMP_DIR>  [<SCHEMA_NAME>]  
  1. 第一个参数指定<ORACLE_SID>或<PDB_NAME>.
    因为在笔者手头维护的环境绝大部分是ORACLE 19c的多租户环境,有些环境甚至是多实例环境. 有些是非多租户环境. 当你使用<PDB_NAME>时就导出PDB的数据.

  2. 第二个参数指定<DIR_NAME>

    指定DIRECTORY_NAME, 如下所示,脚本中会在指定的数据库或PDB_NAME中创建一个名字为<DIR_NAME>的目录

# 创建DUMP DIRECTORY目录
# sqlplus -s "${DB_USER}/${DB_PASSWORD}@DB_NAME" << EOF
sqlplus -s "/ as sysdba" <<EOF
CREATE OR REPLACE DIRECTORY ${DIR_NAME} AS '${DUMP_DIR}';
EOF
  1. 第三个参数为可选参数, 如果未指定的话,则导出整个数据库,而不是按SCHEMA_NAME导数.

脚本源码

#!/sbin/sh
####!/bin/bash

#########################################################################################
#                                                                                       #
# This script uses expdp to export the whole database or pdb database                   #
#                                                                                       #
#########################################################################################
#                                                                                       #
# ScriptName            :    db_expdp_data_v1.sh                                        #
# Author                :    潇湘隐者                                                      #
# CreateDate            :    2025-01-27                                                 #
# Email                 :    kerry2008code@qq.com                                       #
#***************************************************************************************#
# 变量配置                                                                              #
#---------------------------------------------------------------------------------------#
# DUMP_DIR        设置数据泵的导出的路径                                                #
# DB_USER         访问数据库的账号,可以不设置(如果启用操作系统认证方式),默认不设置      #
# DB_PASSWORD     DB_USER指定账户的密码                                                 #
# PARALLEL_NUM    expdp的并行度                                                         #
# LOG_FILE        此变量赋值在usage函数的后面进行赋值.                                  #
# COMPRESSION_WAY 导出压缩的方式                                                        #
#---------------------------------------------------------------------------------------#
# 参数说明                                                                              #
#---------------------------------------------------------------------------------------#
#  $1  <ORACLE_SID>|<PDB_NAME>                                                          #
#  $2  <DIR_NAME>  mandatory parameter                                                  #
#  $3  <SCHEME_ANME,SCHEME_ANME>  可选参数                                              #
#                                                                                       #
#---------------------------------------------------------------------------------------#
#   Usage:                                                                              #
#       ./db_expdp_data_v1.sh <ORACLE_SID>   <DUMP_DIR>  <SCHEMA_NAME>                  #
#   Example:                                                                            #
#       ./db_expdp_data_v1.sh gsp DP                                                    #
#   多租户环境, 可以这么做:                                                             #
#   例如,需要导出gspprod这个PDB数据库,那么可以执行下面命令:                             #
#       ./db_expdp_data_v1.sh gspprod DP                                                #
#   导出gspprod这个数据库下的gspdata这个SCHEMA下的数据                                  #
#       ./db_expdp_data_v1.sh gspprod DP gspdata                                        #
#***************************************************************************************#
# Version        Modified Date            Description                                   #
#***************************************************************************************#
# V.1.0          2025-01-27              创建此脚本                                     #
# V.1.1          2025-02-10              增加变量判断数据库版本                         #
# V.1.2          2025-04-06              增加按SCHEMA_NAME导出数据                      #
#---------------------------------------------------------------------------------------#
#注意事项:                                                                             #
#    1. 此脚本适用于多实例环境,第一个参数可以指定ORACLE_SID或PDB NAME                   #
#    2. 在使用前,请检查/设定变量ORACLE_HOME,DUMP_DIR, 如果数据库使用系统认证方式登录    #
#       则无须设置变量DB_USER,DB_PASSWORD                                               #
#    3. 注意根据实际情况调整函数create_dump_dir中登录数据库的方式                       #
#    4. 注意根据实际情况调整函数expdp_dump_file中链接数据库的方式                       #
#    5. 此脚本在HP-UX和Linx(RHEL)是适用的,但是不能保证所有平台都OK,使用前请测试验证     #
#########################################################################################

# 注意,如果环境变量有设置ORACLE_HOME,此处可以不用指定ORACLE_HOME.在多实例,多数据库环境最好指定.
#export ORACLE_HOME=/opt/oracle19c/product/19.3.0/db_1

DUMP_DIR=/db_backup/dp_dump
DB_USER="*****"
DB_PASSWORD="*****"
DB_NAME="******"
PARALLEL_NUM=4
EXP_DATE=$(date +%Y%m%d_%H%M)
COMPRESSION_WAY='DATA_ONLY' # DATA_ONLY,METADATA_ONLY,ALL,NONE
DB_VERSION='E'  # E表示企业版, S表示标准版 O表示其它
LOG_FILE='${DUMP_DIR}/expdp_${DB_NAME}_${EXP_DATE}.log'
SCHEMA_NAME=''

usage()
{
    echo "Usage: `basename $0` <ORACLE_SID>|<PDB_NAME> [<SCHEMA_NAME>] "
    echo "eg: `basename $0` gsp dp  test1,test2,test3"
    echo "eg:  `basename $0` gsp dp"
    exit 1
}

if [ $# -eq 2 ]; then 
    DB_NAME=$1
    DIR_NAME=$2
    LOG_FILE=${DUMP_DIR}/expdp_${DB_NAME}_${EXP_DATE}.log
elif [ $# -eq 3 ]; then
    DB_NAME=$1
    DIR_NAME=$2
    SCHEMA_NAME=$3
    LOG_FILE=${DUMP_DIR}/expdp_${DB_NAME}_${EXP_DATE}.log
else 
   echo "The number of script parameters is incorrect"
   usage
fi 

check_env()
{
    if [ ! -d "${DUMP_DIR}" ];then
      echo "the path ${DUMP_DIR} did not exist, please check it"
      exit 1
    fi

    DB_EXIST=`ps -ef | grep ora_pmon_${DB_NAME} | grep -v grep | wc -l` 

    if [ $DB_EXIST = 1 ];then
        #多实例环境下,有些环境,需要指定ORACLE_SID
         export ORACLE_SID=${DB_NAME}
    else
        #如果多租户环境,这个是PDB
         #IS_PDB_EXIST=`sqlplus -s ${DB_USER}/${DB_PASSWORD} <<EOF
         IS_PDB_EXIST=`sqlplus  -s "/ as sysdba" <<EOF
SET HEADING OFF 
SELECT COUNT(*) VALUE FROM CDB_PDBS WHERE PDB_NAME=UPPER('${DB_NAME}');
EOF`
        if [ $IS_PDB_EXIST -eq 1 ];then
          export ORACLE_PDB_SID=${DB_NAME}
        else
          echo "the pdb ${DB_NAME} does not exist, please check it"
          exit 1
        fi
    fi 

   # 查询数据库版本信息
   #VERSION_INFO=$(sqlplus -silent $ORA_USER/$ORA_PASSWORD as sysdba <<EOF
   VERSION_INFO=$(sqlplus -s " / as sysdba " <<EOF
   SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
   SELECT banner FROM v\$version WHERE rownum = 1;
   EXIT;
EOF
)

   # 检查是否为企业版
   if [[ $VERSION_INFO =~ "Enterprise Edition" ]]; then
     DB_VERSION='E'
   elif [[ $VERSION_INFO =~ "Standard Edition" ]]; then
     DB_VERSION='S'
   else
     DB_VERSION='O'
   fi
   
   #判断schema是否存在,此处暂不实现,由执行脚本的人控制.
}


create_dump_dir()
{
 
# 创建DUMP DIRECTORY目录
# sqlplus -s "${DB_USER}/${DB_PASSWORD}@DB_NAME" << EOF
sqlplus -s "/ as sysdba" <<EOF
CREATE OR REPLACE DIRECTORY ${DIR_NAME} AS '${DUMP_DIR}';
EOF

SQL_STATUS=$?

if [ $SQL_STATUS -ne 0 ]; then
  echo "create dump directory failed, please check it!"
  exit 1
else 
  echo "create dump directory succesful."
fi
}

expdp_dump_file()
{

if [ ${DB_VERSION} == "E" ]; then
    if  [ -z $SCHEMA_NAME ]; then
        #系统认证方式
        EXP_CMD=`$ORACLE_HOME/bin/expdp \'/ as  sysdba \'  directory=${DIR_NAME}  full=y  dumpfile=${DB_NAME}_${EXP_DATE}_%U.dmp filesize=8G parallel=${PARALLEL_NUM} logfile=${DB_NAME}_${EXP_DATE}.log COMPRESSION=${COMPRESSION_WAY}`
        #非系统认证方式
        #EXP_CMD=`$ORACLE_HOME/bin/expdp ${DB_USER}/${DB_PASSWORD}@${DB_NAME}  directory=${DIR_NAME}  full=y  dumpfile=${DB_NAME}_${EXP_DATE}_%U.dmp filesize=8G parallel=${PARALLEL_NUM} logfile=${DB_NAME}_${EXP_DATE}.log COMPRESSION=ALL`
    else
        #系统认证方式
        EXP_CMD=`$ORACLE_HOME/bin/expdp \'/ as  sysdba \'  directory=${DIR_NAME}  schemas=${SCHEMA_NAME}  dumpfile=${DB_NAME}_${EXP_DATE}_%U.dmp filesize=8G parallel=${PARALLEL_NUM} logfile=${DB_NAME}_SCHEMA_${EXP_DATE}.log COMPRESSION=${COMPRESSION_WAY}`
        #非系统认证方式
        #EXP_CMD=`$ORACLE_HOME/bin/expdp ${DB_USER}/${DB_PASSWORD}@${DB_NAME}  directory=${DIR_NAME}  schema=${SCHEMA_NAME}  dumpfile=${DB_NAME}_${EXP_DATE}_%U.dmp filesize=8G parallel=${PARALLEL_NUM} logfile=${DB_NAME}_SCHEMA_${EXP_DATE}.log COMPRESSION=${COMPRESSION_WAY}`
    fi
else
    if  [ -z $SCHEMA_NAME ]; then
        #系统认证方式
        EXP_CMD=`$ORACLE_HOME/bin/expdp \'/ as  sysdba \'  directory=${DIR_NAME}  full=y  dumpfile=${DB_NAME}_${EXP_DATE}.dmp filesize=8G  logfile=${DB_NAME}_${EXP_DATE}.log`
        #非系统认证方式
        #EXP_CMD=`$ORACLE_HOME/bin/expdp ${DB_USER}/${DB_PASSWORD}@${DB_NAME}  directory=${DIR_NAME}  full=y  dumpfile=${DB_NAME}_${EXP_DATE}.dmp filesize=8G  logfile=${DB_NAME}_${EXP_DATE}.log`
    else
        #系统认证方式
        EXP_CMD=`$ORACLE_HOME/bin/expdp \'/ as  sysdba \'  directory=${DIR_NAME}  schemas=${SCHEMA_NAME}  dumpfile=${DB_NAME}_${EXP_DATE}.dmp filesize=8G  logfile=${DB_NAME}_SCHEMA_${EXP_DATE}.log `
        #非系统认证方式
        #EXP_CMD=`$ORACLE_HOME/bin/expdp ${DB_USER}/${DB_PASSWORD}@${DB_NAME}  directory=${DIR_NAME}  schema=${SCHEMA_NAME}  dumpfile=${DB_NAME}_${EXP_DATE}.dmp filesize=8G  logfile=${DB_NAME}_SCHEMA_${EXP_DATE}.log`
    fi
fi 
echo "The export command:\n"

$EXP_CMD


if [ $? -eq 0 ]; then
    echo "The data export was successful using expdp!"
else
    echo "The data export was failed using expdp"
fi
}

main()
{
  check_env
  create_dump_dir
  expdp_dump_file
}

# 执行主函数
main 2>&1 | tee ${LOG_FILE}  

PS:有个让人头痛的问题,微信公众号展示的代码在格式上会部分乱掉,本人的代码其实并没有这么凌乱(如下部分截图所示)。