作为一名数据库管理员,定期备份关键数据是最基础也最重要的工作之一。金仓KingbaseES作为国产数据库的代表产品,在企业级应用中越来越常见。今天我要分享的是一个针对KingbaseES数据库的指定表备份脚本,这个脚本已经在生产环境稳定运行超过两年,每天自动备份5张关键业务表,累计完成超过700次备份任务。
这个脚本的核心功能是通过KingbaseES自带的sys_dump工具(部分版本可能是pg_dump),将指定的多张表以二进制.dmp格式备份到指定目录。相比全库备份,这种针对关键表的备份方式更加轻量,恢复时也更精准快速。脚本采用Bash编写,可以直接在Linux服务器上运行,特别适合作为定时任务执行。
脚本开头的配置区域需要根据实际环境进行调整,这是整个脚本的基础:
bash复制# 数据库连接信息
DB_HOST="10.xxx.xxx.xxx" # 数据库IP
DB_PORT="54321" # 金仓默认端口
DB_USER="system" # 数据库用户名
DB_PASS="*******" # 数据库密码
DB_NAME="rzkj_kc" # 数据库名
这里有几个关键点需要注意:
bash复制# 备份配置
BACKUP_DIR="/data/kingbase/backup/table_backup" # 备份根目录
TABLES=("kq_ckqsp_35" "kq_ckqsp_36" "kq_tkqsp" "KQ01_CKQ_CRHT" "KQ02_TKQSP") # 需要备份的表
RETENTION_DAYS=30 # 备份保留天数(超过自动删除)
备份策略配置决定了备份的存储和管理方式:
提示:如果表名包含特殊字符或空格,需要用引号包裹每个表名
脚本会按日期创建子目录存放当天的备份文件:
bash复制mkdir -p "${BACKUP_DIR}/tables/$(date +%Y%m%d)"
mkdir -p "${BACKUP_DIR}/backup_logs"
这种目录结构使得备份文件可以按日期组织,方便管理和查找。例如:
code复制/data/kingbase/backup/table_backup/
├── tables/
│ ├── 20230801/
│ ├── 20230802/
│ └── ...
└── backup_logs/
核心备份命令使用了KingbaseES的sys_dump工具:
bash复制${DUMP_CMD} -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} -d ${DB_NAME} \
-t ${TABLE} -F c -b -v -f "${BACKUP_FILE}"
关键参数说明:
-F c:指定自定义(二进制)格式输出,这种格式恢复时更快-b:包含大对象(如BLOB字段)-v:详细模式,输出更多信息到日志-t:指定要备份的表名每次备份后都会检查返回值判断是否成功:
bash复制if [ $? -eq 0 ]; then
log "表 ${TABLE} 备份成功(.dmp格式)"
else
log "表 ${TABLE} 备份失败!!!"
# 可选:备份失败告警(邮件/短信)
fi
在实际使用中,建议取消注释邮件告警部分,配置真实的告警接收邮箱,这样当备份失败时能及时通知DBA处理。
脚本会自动清理超过保留期限的备份文件和日志:
bash复制find "${BACKUP_DIR}/tables" -type f -name "*.dmp" -mtime +${RETENTION_DAYS} -delete
find "${BACKUP_DIR}/backup_logs" -type f -name "*.log" -mtime +${RETENTION_DAYS} -delete
这种自动清理机制避免了手动维护的麻烦,也防止备份文件无限增长占用磁盘空间。
脚本实现了完善的日志功能:
bash复制log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "${LOG_FILE}"
}
每次备份的详细过程都会记录到日志文件中,包括:
日志文件也按日期命名,方便排查问题时查找历史记录。
建议通过crontab设置定时执行,例如每天凌晨2点执行:
bash复制0 2 * * * /bin/bash /data/kingbase/backup/table_backup/table_backup.sh > /dev/null 2>&1
定时任务配置要点:
如果遇到"sys_dump: command not found"错误,可能是路径配置不正确。解决方法:
可以通过以下命令查找工具路径:
bash复制find / -name "sys_dump" 2>/dev/null
备份账号需要至少对目标表有SELECT权限。可以通过以下SQL检查权限:
sql复制SELECT * FROM information_schema.table_privileges
WHERE table_name IN ('kq_ckqsp_35','kq_ckqsp_36','kq_tkqsp','KQ01_CKQ_CRHT','KQ02_TKQSP');
如果权限不足,可以使用以下SQL授权:
sql复制GRANT SELECT ON TABLE kq_ckqsp_35 TO backup_user;
如果备份文件异常大,可以考虑:
可以通过以下SQL查询表大小:
sql复制SELECT table_name, pg_size_pretty(pg_total_relation_size(table_name))
FROM information_schema.tables
WHERE table_name IN ('kq_ckqsp_35','kq_ckqsp_36','kq_tkqsp','KQ01_CKQ_CRHT','KQ02_TKQSP');
可以在备份完成后增加校验步骤,例如:
bash复制# 检查备份文件是否有效
${DUMP_CMD} -l "${BACKUP_FILE}" >/dev/null 2>&1
if [ $? -ne 0 ]; then
log "备份文件 ${BACKUP_FILE} 校验失败,可能已损坏"
fi
备份前检查磁盘空间是否充足:
bash复制MIN_SPACE=10 # 最小需要10GB空间
available=$(df -BG "${BACKUP_DIR}" | awk 'NR==2 {print $4}' | tr -d 'G')
if [ "$available" -lt "$MIN_SPACE" ]; then
log "磁盘空间不足,当前剩余 ${available}GB,需要至少 ${MIN_SPACE}GB"
exit 1
fi
对于大表备份,可以考虑增加压缩:
bash复制gzip "${BACKUP_FILE}"
但要注意这会增加CPU负载,需要权衡压缩率和备份时间。
备份的目的是为了恢复,这里简要说明如何从.dmp文件恢复表:
bash复制# 恢复单张表
/home/kingbase/KingbaseES/Server/bin/sys_restore -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} -d ${DB_NAME} -t ${TABLE} -c ${BACKUP_FILE}
# 恢复所有表
/home/kingbase/KingbaseES/Server/bin/sys_restore -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} -d ${DB_NAME} -c ${BACKUP_FILE}
恢复时的注意事项:
bash复制chmod 700 /data/kingbase/backup/table_backup/table_backup.sh
定期检查备份文件是否可恢复,建议每季度至少做一次恢复演练
考虑将备份文件同步到异地存储,如通过rsync到另一台服务器
对备份目录设置适当的权限,防止未授权访问
可以通过以下方式监控备份性能:
bash复制start_time=$(date +%s)
# 备份操作...
end_time=$(date +%s)
log "备份耗时: $((end_time - start_time))秒"
监控备份文件大小变化,及时发现异常增长
在业务低峰期执行备份,减少对生产系统的影响
对大表考虑使用并行备份(如果KingbaseES版本支持):
bash复制${DUMP_CMD} ... -j 4 ... # 使用4个并行进程
这个脚本虽然只有100多行,但包含了数据库备份的完整流程和最佳实践。在实际使用中,建议先在小规模测试环境验证,确认无误后再部署到生产环境。根据我的经验,一个好的备份脚本应该像瑞士军刀一样可靠且多功能,这个脚本经过适当扩展完全可以满足大多数KingbaseES数据库的备份需求。