如何编写单表备份还原脚本

wen 实用脚本 27

本文目录导读:

如何编写单表备份还原脚本

  1. MySQL 版本单表备份还原脚本
  2. PostgreSQL 版本单表备份还原脚本
  3. 使用说明
  4. 注意事项

我来为您编写一个完整的单表备份还原脚本,包含 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

注意事项

  1. 安全性:不要将密码直接写在脚本中,建议使用配置文件或环境变量
  2. 测试:在生产环境使用前,先在测试环境验证
  3. 磁盘空间:定期检查备份目录的磁盘使用情况
  4. 备份验证:定期测试备份文件的可恢复性
  5. 大表处理:对于大表,考虑使用分片备份或增量备份策略

这个脚本提供了完整的单表备份和还原功能,您可以根据实际需求进行调整和扩展。

抱歉,评论功能暂时关闭!