編寫目的
使用 exp 對人大金倉 資料庫進行線上備份,并指定輪轉次數
說明
因為個人原因,有點強迫症, 喜歡編寫能夠複用且使用簡單的腳本,提供簡單的功能, 先是寫的oracle備份腳本, 後來陸續寫了其他資料庫和作業系統的腳本
MySQL 備份也有類似腳本,請看我以前些的文章。
分享(1)一個 MySQL Shell 備份MySQL資料庫的腳本
分享(2)一個 mysqldump 備份 MySQL 資料庫的腳本
分享(3)一個使用 xtrabackup 備份 MySQL 資料庫的腳本
分享(4)一個使用 mysqlbackup 備份 MySQL 資料庫的腳本
分享(5) 一個windows平台 mysqldump 備份MySQL資料庫的腳本
能看懂腳本的花幾分鐘基本上也就明白了, 也都在測試環境和生産環境用過,但還是建議根據你的環境測試一下 也許有bug我沒測出來,哈哈
為了節省大家時間,也能放心使用,把大概功能略述一下
一 使用時隻需要提供備份目的地和輪轉次數
1. 備份目的地就不說了
2. 輪轉次數. 有點像 logrotate,每次備份會在備份目的地生成一個序号命名的子檔案夾, 到指定的輪轉次數再從頭開始
二 臨時檔案
記錄上次備份狀态的檔案, 主要用于防止上一次備份未結束,定時任務又啟動了下一次任務。
記錄輪轉序号的隐藏檔案, 決定下次備份到哪兒,每次備份結束+1, 到最大了再從0開始
日志檔案,記錄了備份的開始時間,每個庫的開始備份時間,結束時間
資料庫清單檔案,先查詢資料庫名稱并記錄于這個檔案, 然後挨個備份。 不喜歡整個執行個體一起備份, 還是分資料庫一個一個的好, 個人習慣。
當然,不需要備份的資料庫可以加入自定義名單,備份時會跳過不備份
三 執行順序
先查詢資料庫, 再挨個備份資料庫, 如果目錄已經有上一次輪轉時的備份檔案, 會覆寫。
四 備份時間
背景備份的話可以看日志檔案減一下, 前台執行的話腳本運作結束也會計算運作了多久(開始,結束時間減了一下)
速度比較
測試資料庫 12G :備份花了 6 分鐘
人大金倉備份腳本
#!/bin/bash
# =========================================================================
# (C) Copyright 2003-2033 hoplite([email protected])
# =========================================================================
# Script Purpose : exp kingbase v8 user data by exp
# -------------------------------------------------------------------------
# Version Date Description
# -------------------------------------------------------------------------
# V1.0 2023-04-26 Initial version
# =========================================================================
[ -f ~/.bash_profile ] && . ~/.bash_profile
set -Eeuo pipefail
show_usage ()
{
echo "usage: `basename $0` connstr TARGETDIR ROTATE"
echo "eg. `basename $0` system/[email protected]:54321/test /backup/kb_exp 7"
}
if [ $# -lt 3 ] || [ $# -gt 3 ]; then
show_usage
exit 1
fi
start_time=$(date +%F' '%T)
p_connstr=$1
p_targetdir=$2
p_rotate=$3
v_user=`echo ${p_connstr}|cut -f1 -d\/`
v_pwd=`echo ${p_connstr}|cut -f2 -d\/|cut -f1 -d@`
v_ip=`echo ${p_connstr}|cut -f2 -d@|cut -f1 -d:`
v_port=`echo ${p_connstr}|cut -f2 -d:|cut -f1 -d\/`
v_default_db=`echo ${p_connstr}|cut -f3 -d\/`
if [ ${p_connstr} != "${v_user}/${v_pwd}@${v_ip}:${v_port}/${v_default_db}" ]; then
show_usage
exit 1
fi
v_id=$(date +%Y%m%d%H%M%S)
v_hash=`echo -n ${p_connstr}|md5sum|cut -f1 -d" "`
stusfile=${p_targetdir}/.status.${v_hash}.9de7bb31d0644e7393039222babfed10 #file to record last backup status
rotafile=${p_targetdir}/.rotate.${v_hash}.9de7bb31d0644e7393039222babfed10 #file to record rotate number
log_file=${p_targetdir}/backup.log
err_file=${p_targetdir}/error.log
#file to record databases
vdbsfile1=$(mktemp -t .tmp.9de7bb31d0644e7393039222babfed10.XXXXXXXXXX.vdbs) || exit 1
vdbsfile2=$(mktemp -t .tmp.9de7bb31d0644e7393039222babfed10.XXXXXXXXXX.vdbs) || exit 1
#record last backup result,if fail, exit, must fix it manully, then reset the status
if [ -f ${stusfile} ]; then
if [ `cat ${stusfile}` = "running" ]; then
loginfo="$(date +%F' '%T) ...ERROR:last backup fail, check it,then drop status file and rerun." ; echo ${loginfo} ; echo ${loginfo} >> ${log_file}
exit 1
else
echo "running" > ${stusfile}
fi
else
echo "running" > ${stusfile}
fi
#rotate number,+1 every time
if [ -f ${rotafile} ]; then
v_last_id=`cat ${rotafile}`
v_incr_id=`expr ${v_last_id} + 1`
v_curr_id=$(( ${v_incr_id} % ${p_rotate} ))
else
v_curr_id=0
fi
echo ${v_curr_id} > ${rotafile}
v_targetdir=${p_targetdir}/${v_curr_id}
[ -d ${v_targetdir} ] || mkdir -p ${v_targetdir}
cd ${v_targetdir}
loginfo="$(date +%F' '%T) ...start backup to ${v_targetdir}" ; echo ${loginfo} ; echo ${loginfo} >> ${log_file}
ksql "host=${v_ip} port=${v_port} user=${v_user} password=${v_pwd} dbname=${v_default_db}" -c "select concat('9de7bb31d0644e7393039222babfed10 ',usename) username from sys_user where usename not in ('system','sao','sso');" -o ${vdbsfile1}
cat ${vdbsfile1} |grep 9de7bb31d0644e7393039222babfed10|grep -v 'SQL>'|awk '{print $2;}' > ${vdbsfile2}
filtered_dbs=("user_you_do_not_want_to_exp" "IDADMIN")
while read v_db
do
is_in_filtered_db="N"
for fd in ${filtered_dbs[*]} ; do
if [ "${fd}" == "${v_db}" ]; then
is_in_filtered_db="Y"
break
fi
done
if [[ "${is_in_filtered_db}" == "N" ]]; then
loginfo="$(date +%F' '%T) ...backup database ${v_db}" ; echo ${loginfo} ; echo ${loginfo} >> ${log_file}
exp host=${v_ip} port=${v_port} user=${v_user} password=${v_pwd} dbname=${v_db} file=${v_db}.dmp log=${v_db}.exp.log owner=${v_db} 2>${err_file}
fi
done < ${vdbsfile2}
loginfo="$(date +%F' '%T) ...end backup to ${v_targetdir}" ; echo ${loginfo} ; echo ${loginfo} >> ${log_file}
rm "${vdbsfile1:-unset}"
rm "${vdbsfile2:-unset}"
echo "completed" > ${stusfile}
end_time=$(date +%F' '%T)
t_start_time=`date -d "${start_time}" +%s`
t_end_time=`date -d "${end_time}" +%s`
t_diff_secs=$((${t_end_time} - ${t_start_time}))
t_hours=$((${t_diff_secs}/3600))
t_mins=$(($((${t_diff_secs}-${t_hours}*3600))/60))
t_secs=$((${t_diff_secs}%60))
echo
echo ==================================================
echo "File Name:`basename $0` Start Time:${start_time} End Time:${end_time} Total Cost:${t_hours}:${t_mins}:${t_secs}"
echo ==================================================
echo