生產環境 Oracle 資料庫需建立可靠的自動化備份策略。本文提供一個生產就緒的 Shell 腳本,整合 環境變數載入、Data Pump 導出 (expdp)、壓縮打包、舊備份清理、日誌記錄、錯誤通知,配合 crontab 實現每日零干預備份。
expdp 導出指定 Schema/全庫,支援平行度、壓縮tar.gz 壓縮,節省磁碟空間/backup/oracledata/oracle_backup.sh#!/bin/bash
# ============================================================
# Oracle Database Automated Backup Script
# Author: DBA Team
# Version: 2.0
# ============================================================
set -euo pipefail
# ----- 配置區 (請依環境修改) -----
export ORACLE_BASE=/data/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db_1
export ORACLE_SID=orcl
export ORACLE_TERM=xterm
export PATH=$ORACLE_HOME/bin:/usr/sbin:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export LANG=C
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
# 備份參數
BACKUP_DIR=/backup/oracledata
SCHEMA_LIST="OSYUNWEI" # 多 schema 用逗號分隔,或 FULL=Y
PARALLEL=4
COMPRESSION=ALL
RETENTION_DAYS=7
DATE_TAG=$(date +%Y%m%d_%H%M%S)
DUMP_PREFIX="${SCHEMA_LIST//,/_}_${DATE_TAG}"
LOG_FILE="${BACKUP_DIR}/logs/expdp_${DUMP_PREFIX}.log"
DUMP_DIR_OBJ=DPUMP_DIR # 預建的 Directory Object
NOTIFY_WEBHOOK="" # 企業微信/釘釘 Webhook URL
# --------------------------------
mkdir -p "${BACKUP_DIR}/dumps" "${BACKUP_DIR}/logs"
log() { echo "[$(date '+%F %T')] $*" | tee -a "${LOG_FILE}"; }
notify() {
local msg="$1"
[[ -n "${NOTIFY_WEBHOOK}" ]] && curl -s -X POST -H 'Content-Type: application/json' \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"[Oracle Backup] ${msg}\"}}" "${NOTIFY_WEBHOOK}"
}
log "=== 開始備份 ${ORACLE_SID} Schema: ${SCHEMA_LIST} ==="
START_SEC=$(date +%s)
# ----- 執行 expdp -----
if [[ "${SCHEMA_LIST^^}" == "FULL=Y" ]]; then
EXPDP_CMD="expdp \"/ as sysdba\" FULL=Y DIRECTORY=${DUMP_DIR_OBJ} DUMPFILE=${DUMP_PREFIX}_%U.dmp LOGFILE=expdp_${DUMP_PREFIX}.log PARALLEL=${PARALLEL} COMPRESSION=${COMPRESSION} METRICS=YES"
else
EXPDP_CMD="expdp \"/ as sysdba\" SCHEMAS=${SCHEMA_LIST} DIRECTORY=${DUMP_DIR_OBJ} DUMPFILE=${DUMP_PREFIX}_%U.dmp LOGFILE=expdp_${DUMP_PREFIX}.log PARALLEL=${PARALLEL} COMPRESSION=${COMPRESSION} METRICS=YES"
fi
log "執行命令: ${EXPDP_CMD}"
eval "${EXPDP_CMD}" >> "${LOG_FILE}" 2>&1
EXPDP_RC=$?
END_SEC=$(date +%s)
DURATION=$((END_SEC - START_SEC))
if [[ ${EXPDP_RC} -eq 0 ]]; then
log "expdp 成功,耗時 ${DURATION} 秒"
# 統計檔案大小
ls -lh "${BACKUP_DIR}/dumps/${DUMP_PREFIX}"_*.dmp 2>/dev/null | awk '{sum+=$5} END {print "總大小:", sum}' | while read line; do log "$line"; done
else
log "expdp 失敗,返回碼 ${EXPDP_RC}"
notify "❌ ${ORACLE_SID} 備份失敗,請檢查日誌: ${LOG_FILE}"
exit 1
fi
# ----- 壓縮打包 -----
log "開始壓縮..."
tar -czf "${BACKUP_DIR}/dumps/${DUMP_PREFIX}.tar.gz" -C "${BACKUP_DIR}/dumps" "${DUMP_PREFIX}"_*.dmp "${BACKUP_DIR}/logs/expdp_${DUMP_PREFIX}.log" 2>>"${LOG_FILE}"
log "壓縮完成: ${BACKUP_DIR}/dumps/${DUMP_PREFIX}.tar.gz"
# ----- 清理原始 dump/log (保留壓縮包) -----
find "${BACKUP_DIR}/dumps" -name "${DUMP_PREFIX/_*/}_*.dmp" -type f -delete
find "${BACKUP_DIR}/logs" -name "expdp_${DUMP_PREFIX/_*/}_*.log" -type f -delete
# ----- 刪除過期備份 -----
log "清理 ${RETENTION_DAYS} 天前備份..."
find "${BACKUP_DIR}/dumps" -name "*.tar.gz" -type f -mtime +${RETENTION_DAYS} -delete
find "${BACKUP_DIR}/logs" -name "*.log" -type f -mtime +${RETENTION_DAYS} -delete
log "=== 備份流程全部完成 ==="
notify "✅ ${ORACLE_SID} 備份成功,保留 ${RETENTION_DAYS} 天,壓縮包: ${DUMP_PREFIX}.tar.gz"
exit 0
mkdir -p /backup/oracledata/{dumps,logs}
chown -R oracle:oinstall /backup/oracledata
CREATE OR REPLACE DIRECTORY DPUMP_DIR AS '/backup/oracledata/dumps';
GRANT READ, WRITE ON DIRECTORY DPUMP_DIR TO SYSTEM;
/backup/oracledata/oracle_backup.sh,chmod +x。su - oracle -c /backup/oracledata/oracle_backup.sh。# crontab -e -u oracle
30 2 * * * /backup/oracledata/oracle_backup.sh >> /backup/oracledata/logs/cron_$(date +\%Y\%m).log 2>&1
rman target / 做 Level 0/1 增量備份,實現區塊級恢復 (PITR)。rsync -avz /backup/oracledata/dumps/ remote:/offsite/backup/ 推送至異地。impdp ... TABLE_EXISTS_ACTION=SKIP 驗證 dump 可用性。這支腳本解決了「環境變數缺失導致 crontab 失效」、「無壓縮佔滿磁碟」、「舊備份不清理」、「無通知不知成敗」四大常見痛點。直接複製、修改配置區、加入 crontab 即可投入生產。建議配合 RMAN 實體備份形成「邏輯 + 實體」雙重保障體系。