本文目录导读:

我来为您编写一个完整的单表备份还原脚本,包含 MySQL 和 PostgreSQL 两个版本。
MySQL 版本单表备份还原脚本
#!/bin/bash
# MySQL单表备份还原脚本
# 作者:AI助手
# 版本:1.0
# 数据库配置
DB_HOST="localhost"
DB_PORT="3306"
DB_USER="root"
DB_PASSWORD="your_password"
DB_NAME="your_database"
TABLE_NAME="your_table"
# 备份目录配置
BACKUP_DIR="/data/backup/mysql"
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TABLE_NAME}_$(date +%Y%m%d_%H%M%S).sql"
LOG_FILE="${BACKUP_DIR}/backup.log"
# 创建备份目录
mkdir -p ${BACKUP_DIR}
# 日志函数
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a ${LOG_FILE}
}
# 备份函数
backup_table() {
log_message "开始备份表 ${DB_NAME}.${TABLE_NAME}"
# 使用mysqldump备份单表
mysqldump -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD} \
${DB_NAME} ${TABLE_NAME} \
--single-transaction \
--routines \
--triggers \
--events \
--set-gtid-purged=OFF \
> ${BACKUP_FILE} 2>> ${LOG_FILE}
if [ $? -eq 0 ]; then
# 压缩备份文件
gzip ${BACKUP_FILE}
log_message "备份成功: ${BACKUP_FILE}.gz"
# 显示备份文件信息
ls -lh ${BACKUP_FILE}.gz
else
log_message "备份失败: ${DB_NAME}.${TABLE_NAME}"
return 1
fi
}
# 还原函数
restore_table() {
local backup_file=$1
if [ ! -f "${backup_file}" ]; then
log_message "备份文件不存在: ${backup_file}"
return 1
fi
log_message "开始还原表 ${DB_NAME}.${TABLE_NAME}"
log_message "还原文件: ${backup_file}"
# 解压并还原
if [[ "${backup_file}" == *.gz ]]; then
gunzip -c ${backup_file} | mysql -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} 2>> ${LOG_FILE}
else
mysql -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} < ${backup_file} 2>> ${LOG_FILE}
fi
if [ $? -eq 0 ]; then
log_message "还原成功!"
else
log_message "还原失败!"
return 1
fi
}
# 列出所有备份文件
list_backups() {
echo "可用的备份文件:"
ls -lh ${BACKUP_DIR}/*${TABLE_NAME}*.sql* 2>/dev/null || echo "没有找到备份文件"
}
# 删除旧备份
cleanup_old_backups() {
local days=${1:-30} # 默认保留30天
log_message "清理${days}天前的旧备份"
find ${BACKUP_DIR} -name "*.sql*" -type f -mtime +${days} -delete 2>> ${LOG_FILE}
log_message "清理完成"
}
# 主函数
main() {
case "$1" in
backup)
backup_table
;;
restore)
if [ -n "$2" ]; then
restore_table "$2"
else
list_backups
echo "请指定要还原的备份文件: $0 restore <backup_file>"
fi
;;
list)
list_backups
;;
cleanup)
days=${2:-30}
cleanup_old_backups ${days}
;;
*)
echo "用法:"
echo " $0 backup - 备份单表"
echo " $0 restore <file> - 还原单表"
echo " $0 list - 列出备份文件"
echo " $0 cleanup [days] - 清理旧备份"
;;
esac
}
# 执行主函数
main "$@"
PostgreSQL 版本单表备份还原脚本
#!/bin/bash
# PostgreSQL单表备份还原脚本
# 作者:AI助手
# 版本:1.0
# 数据库配置
DB_HOST="localhost"
DB_PORT="5432"
DB_USER="postgres"
DB_PASSWORD="your_password" # 推荐使用.pgpass文件
DB_NAME="your_database"
TABLE_NAME="your_table"
PGPASS_FILE="~/.pgpass"
# 备份目录配置
BACKUP_DIR="/data/backup/postgresql"
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TABLE_NAME}_$(date +%Y%m%d_%H%M%S).sql"
LOG_FILE="${BACKUP_DIR}/backup.log"
# 创建备份目录
mkdir -p ${BACKUP_DIR}
# 设置PostgreSQL密码(推荐使用.pgpass文件)
export PGPASSWORD="${DB_PASSWORD}"
# 日志函数
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a ${LOG_FILE}
}
# 备份函数
backup_table() {
log_message "开始备份表 ${DB_NAME}.${TABLE_NAME}"
# 使用pg_dump备份单表
pg_dump -h${DB_HOST} -p${DB_PORT} -U${DB_USER} \
-t ${TABLE_NAME} \
--data-only \
--inserts \
--column-inserts \
--no-owner \
--no-acl \
${DB_NAME} > ${BACKUP_FILE} 2>> ${LOG_FILE}
if [ $? -eq 0 ]; then
# 压缩备份文件
gzip ${BACKUP_FILE}
log_message "备份成功: ${BACKUP_FILE}.gz"
# 显示备份文件信息
ls -lh ${BACKUP_FILE}.gz
else
log_message "备份失败: ${DB_NAME}.${TABLE_NAME}"
return 1
fi
}
# 备份带结构
backup_table_with_structure() {
log_message "开始备份表结构和数据 ${DB_NAME}.${TABLE_NAME}"
pg_dump -h${DB_HOST} -p${DB_PORT} -U${DB_USER} \
-t ${TABLE_NAME} \
--no-owner \
--no-acl \
${DB_NAME} > ${BACKUP_FILE} 2>> ${LOG_FILE}
if [ $? -eq 0 ]; then
gzip ${BACKUP_FILE}
log_message "备份成功: ${BACKUP_FILE}.gz"
else
log_message "备份失败"
return 1
fi
}
# 还原函数
restore_table() {
local backup_file=$1
if [ ! -f "${backup_file}" ]; then
log_message "备份文件不存在: ${backup_file}"
return 1
fi
log_message "开始还原表 ${DB_NAME}.${TABLE_NAME}"
log_message "还原文件: ${backup_file}"
# 解压并还原
if [[ "${backup_file}" == *.gz ]]; then
gunzip -c ${backup_file} | psql -h${DB_HOST} -p${DB_PORT} -U${DB_USER} -d${DB_NAME} 2>> ${LOG_FILE}
else
psql -h${DB_HOST} -p${DB_PORT} -U${DB_USER} -d${DB_NAME} -f ${backup_file} 2>> ${LOG_FILE}
fi
if [ $? -eq 0 ]; then
log_message "还原成功!"
else
log_message "还原失败!"
return 1
fi
}
# 清空表数据
truncate_table() {
log_message "清空表 ${DB_NAME}.${TABLE_NAME}"
psql -h${DB_HOST} -p${DB_PORT} -U${DB_USER} -d${DB_NAME} \
-c "TRUNCATE TABLE ${TABLE_NAME} CASCADE;" 2>> ${LOG_FILE}
if [ $? -eq 0 ]; then
log_message "清空成功"
else
log_message "清空失败"
return 1
fi
}
# 列出备份文件
list_backups() {
echo "可用的备份文件:"
ls -lh ${BACKUP_DIR}/*${TABLE_NAME}*.sql* 2>/dev/null || echo "没有找到备份文件"
}
# 删除旧备份
cleanup_old_backups() {
local days=${1:-30}
log_message "清理${days}天前的旧备份"
find ${BACKUP_DIR} -name "*.sql*" -type f -mtime +${days} -delete 2>> ${LOG_FILE}
log_message "清理完成"
}
# 主函数
main() {
case "$1" in
backup)
backup_table
;;
backup-structure)
backup_table_with_structure
;;
restore)
if [ -n "$2" ]; then
restore_table "$2"
else
list_backups
echo "请指定要还原的备份文件: $0 restore <backup_file>"
fi
;;
truncate)
truncate_table
;;
list)
list_backups
;;
cleanup)
days=${2:-30}
cleanup_old_backups ${days}
;;
*)
echo "用法:"
echo " $0 backup - 备份单表数据"
echo " $0 backup-structure - 备份表结构和数据"
echo " $0 restore <file> - 还原单表"
echo " $0 truncate - 清空表数据"
echo " $0 list - 列出备份文件"
echo " $0 cleanup [days] - 清理旧备份"
;;
esac
}
# 清理密码环境变量
cleanup() {
unset PGPASSWORD
}
trap cleanup EXIT
# 执行主函数
main "$@"
使用说明
配置脚本
# 修改数据库配置信息 DB_HOST="localhost" DB_PORT="3306" # 或 5432 (PostgreSQL) DB_USER="root" # 或 postgres DB_PASSWORD="your_password" DB_NAME="your_database" TABLE_NAME="your_table"
设置权限
chmod +x backup_script.sh
使用示例
MySQL版本:
# 备份表 ./backup_mysql.sh backup # 列出备份文件 ./backup_mysql.sh list # 还原表 ./backup_mysql.sh restore /data/backup/mysql/database_table_20230101_120000.sql.gz # 清理30天前的备份 ./backup_mysql.sh cleanup 30
PostgreSQL版本:
# 备份表数据 ./backup_postgres.sh backup # 备份表结构和数据 ./backup_postgres.sh backup-structure # 清空表数据 ./backup_postgres.sh truncate # 还原表 ./backup_postgres.sh restore /data/backup/postgresql/database_table_20230101_120000.sql.gz
设置定时任务(cron)
# 每天凌晨2点备份 0 2 * * * /path/to/backup_mysql.sh backup # 每周一清理30天前的备份 0 3 * * 1 /path/to/backup_mysql.sh cleanup 30
注意事项
- 安全性:不要将密码直接写在脚本中,建议使用配置文件或环境变量
- 测试:在生产环境使用前,先在测试环境验证
- 磁盘空间:定期检查备份目录的磁盘使用情况
- 备份验证:定期测试备份文件的可恢复性
- 大表处理:对于大表,考虑使用分片备份或增量备份策略
这个脚本提供了完整的单表备份和还原功能,您可以根据实际需求进行调整和扩展。