本文最后更新于0 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
1.数据库备份
1)逻辑备份脚本参考
此脚本需要修改以下内容:
username="SYSDBA"
password="Hn@dameng123"
address="127.0.0.1:5136"
# 备份并发数
parallel=2
# 保存天数
retention=5
# 要备份的目录未知
base_path="/dm/bak/dexp"
脚本内容参考
#!/bin/bash
set -e
# 00 02 * * * /bin/bash /dm/bak/dexp/backup.sh
##### 公共配置 #####
username="SYSDBA"
password="Hn@dameng123"
address="127.0.0.1:5136"
# 备份并发数
parallel=2
# 保存天数
retention=5
# 要备份的目录未知
base_path="/dm/bak/dexp"
########################
format_time=`date +%Y%m%d%H`
backup_path="${base_path}/backup"
log_path="${base_path}/logs"
log_file="${log_path}/${format_time}.log"
test ! -d "${log_path}" && mkdir -p "${log_path}"
test ! -d "${backup_path}" && mkdir -p "${backup_path}"
log() {
local level=$1
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[${timestamp}] [${level}] ${message}" | tee -a "${log_file}"
}
error_exit() {
log "ERROR" "$1"
exit 1
}
set_env() {
log "INFO" "Setting up DM environment variables..."
dm_pid=`pgrep -f dmserver`
if [ -z "$dm_pid" ]; then
log "WARN" "dmserver is not running, try to find it by ps"
dp_pid=`ps -ef | grep dmserver | grep -v grep | awk '{print $2}'`
if [ -z "$dp_pid" ]; then
log "ERROR" "dmserver is not running"
error_exit "dmserver is not running"
fi
fi
log "INFO" "Found dmserver process: PID=$dm_pid"
dm_home=$(pwdx "$dm_pid" 2>/dev/null | awk '{print $2}')
if [ -z "$dm_home" ]; then
# 如果pwdx失败,尝试其他方法
dm_home=$(lsof -p "$dm_pid" 2>/dev/null | grep cwd | awk '{print $9}')
if [ -z "$dm_home" ]; then
error_exit "Cannot determine DM_HOME from process $dm_pid"
fi
fi
log "INFO" "DM_HOME determined as: $dm_home"
if [ `grep -c "$dm_home" /etc/profile` -eq 0 ]; then
echo "export DM_HOME=$dm_home" >> /etc/profile
echo "export PATH=\$DM_HOME:\$PATH" >> /etc/profile
echo "export LD_LIBRARY_PATH=\$DM_HOME:\$LD_LIBRARY_PATH" >> /etc/profile
source /etc/profile
else
log "INFO" "DM_HOME is already set in /etc/profile"
source /etc/profile
fi
}
validate_connection() {
log "INFO" "Validating database connection..."
id_code=`disql $username/'"'$password'"'@$address -e "select id_code;"`
if [[ $id_code == *"id_code"* ]]; then
log "INFO" "Connected to the database successfully."
else
log "ERROR" "Failed to connect to the database."
error_exit "Failed to connect to the database."
fi
}
# 按文件数量删除备份文件
delete_backup_by_num() {
# 备份文件目标目录
dst_dir=$1
# 目标保留天数
save_days=$2
c_num=0
# 获取当前保留的备份文件数量
current_save_days=$(ls -t "$dst_dir" | wc -l)
log "INFO" "目标目录: $dst_dir"
log "INFO" "当前保留的文件列表: "
ls -t "$dst_dir"
log "INFO" "目标保留天数: $save_days"
log "INFO" "当前保留的备份文件数量: $current_save_days"
if [ "$save_days" -lt "$current_save_days" ]; then
sort_backup_files=$(ls -t $dst_dir)
log "INFO" "$sort_backup_files"
for f in $sort_backup_files; do
if [ "$c_num" -lt "$save_days" ]; then
((c_num += 1))
else
rm -rf "${dst_dir}/${f}"
if [ $? -ne 0 ]; then
return
fi
log "INFO" "${dst_dir}/${f} 删除完成"
fi
done
else
log "INFO" "当前备份文件数为: $current_save_days, 目标保留文件数: $save_days, 不需要删除"
fi
}
# 获取所有的schema
get_schemas() {
echo `disql $username/'"'$password'"'@$address -e "select object_name from dba_objects where object_type='SCH';" | awk '/^object_name/ && !found {found=1} found' | awk 'NF' | grep -v -E "object_name|---" | grep -v SYS`
}
# 获取指定schema下的所有表
get_tables() {
local schema=$1
echo `disql $username/'"'$password'"'@$address -e "SELECT TABLE_NAME FROM DBA_TABLES WHERE OWNER = '$schema';" | awk '/^TABLE_NAME/ && !found {found=1} found' | awk 'NF' | grep -v -E "TABLE_NAME|---"`
}
# 备份
backup() {
set_env
validate_connection
schemas=$(get_schemas)
for schema in $schemas; do
backup_file="${backup_path}/${format_time}/${schema}.dmp"
test ! -d "${backup_path}/${format_time}" && mkdir -p "${backup_path}/${format_time}"
log "INFO" "backup $schema to $backup_file"
dexp USERID=$username/'"'$password'"'@$address FILE=${schema}.dmp SCHEMAS=${schema} DIRECTORY=${backup_path}/${format_time} NOLOG=Y PARALLEL=${parallel} TABLE_PARALLEL=${parallel} COMPRESS=Y COMPRESS_LEVEL=4
if [ $? -eq 0 ]; then
log "INFO" "backup $schema success"
rm -f ${backup_path}/${format_time}/dexp.log ${backup_path}/${format_time}/dexp_${schema}.log
else
mv ${backup_path}/${format_time}/dexp.log ${backup_path}/${format_time}/dexp_${schema}.log
log "ERROR" "backup $schema failed"
fi
done
}
main() {
# 设置环境变量
set_env
# 验证连接
validate_connection
# 清理历史备份
delete_backup_by_num "${backup_path}" "${retention}"
# 备份
backup
}
main
2)创建计划任务
将此脚本放到任意目录中执行,保存成backup.sh文件名
执行 crontab -e命令后,会进入编辑框,输入以下内容:
# 需要修改下备份脚本路径
00 02 * * * /bin/bash /dm/bak/dexp/backup.sh
2.数据库恢复
1)明确要恢复的库(schema)
直接去备份目录中,找到要恢复的库,位置在[基础目录]/backup/[年月日]/库名.dmp,例如:
/dm/bak/dexp/backup/2026020502/procurement_contract_gcbp.dmp
这里的procurement_contract_gcbp即为库名
2)恢复原库数据到其他库(重命名的新库)中
恢复之前,建议先把要恢复的库文件先拷贝到新的目录中
执行命令:
dimp USERID=SYSDBA/'"Hn@dameng123"':5136 FILE=implementation_engine_gcbp.dmp LOG=implementation_engine_gcbp.log REMAP_SCHEMA=implementation_engine_gcbp:import_20260107_implementation_engine_gcbp DIRECTORY=/dm/bak/dexp/recovery/260107
参数说明
- FILE 指定逻辑备份的备份文件,以dmp结尾
- LOG 指定恢复时的日志文件,随意设置即可
- REMAP_SCHEMA 设置要把原库恢复到目标库的规则,写法为:原库:新库
- DIRECTORY 指定备份文件的目录位置

