#!/bin/bash

# ==============================================================================
# 数据库备份脚本
# 功能：
#   1. 备份指定数据库中的多个表。
#   2. 每天定时运行时，支持滚动备份：
#      - 删除前两天的备份表（后缀 _bak）。
#      - 将前一天的备份表更名为带着 _bak 后缀的表。
#      - 备份今天的表。
#   3. 表名列表从文件中读取。
# ==============================================================================

# --- 配置区 START ---

# 源数据库连接信息 (mysql5.7)
DUMP_HOST="172.16.20.39"
DUMP_PORT="23306"
DUMP_USER="iflyreadonly"
DUMP_PASSWORD="davwXJk8_m5mWUNg"

# 目标数据库连接信息 (mysql8)
RESTORE_HOST="localhost"
RESTORE_PORT="3306"
RESTORE_USER="root"
RESTORE_PASSWORD="1qaz@WSX"

DATABASE="exchange_data_local" # 数据库名称，源和目标数据库相同

# 备份的where条件，所有表都使用这个条件
WHERE_CONDITION="school_id='1010000001000020417'"

# !!! 新增配置 !!!
# 存储表名的文件路径，每行一个表名
TABLE_LIST_FILE="./table_list.txt" 

# 日志文件路径
LOG_FILE=".db_backup_$(date +%Y%m%d).log" 

# 其他 mysqldump 选项
MYSQLDUMP_OPTIONS="--single-transaction --set-gtid-purged=OFF --column-statistics=0 --databases ${DATABASE}"

# --- 配置区 END ---

# 检查表列表文件是否存在
if [ ! -f "$TABLE_LIST_FILE" ]; then
    echo "错误：表列表文件 '${TABLE_LIST_FILE}' 不存在！"
    echo "请创建该文件并在其中列出要备份的表名，每行一个。"
    exit 1
fi

# 将STDOUT和STDERR重定向到日志文件
exec > >(tee -a "$LOG_FILE") 2>&1

echo "================================================================================="
echo "数据库备份脚本开始运行于：$(date '+%Y-%m-%d %H:%M:%S')"
echo "================================================================================="

# 获取当前日期（YYYYMMDD）
TODAY=$(date +%Y%m%d)
# 获取昨天日期（YYYYMMDD）
YESTERDAY=$(date -d "yesterday" +%Y%m%d)
# 获取前天日期（YYYYMMDD）
DAY_BEFORE_YESTERDAY=$(date -d "2 days ago" +%Y%m%d)

echo "当前日期：${TODAY}"
echo "昨天日期：${YESTERDAY}"
echo "前天日期：${DAY_BEFORE_YESTERDAY}"

# 从文件中读取表名列表
# 使用 IFS 和 while read 循环来处理每行，跳过空行和注释行
echo "正在从文件 '${TABLE_LIST_FILE}' 读取表名..."
TABLES=()
while IFS= read -r line || [[ -n "$line" ]]; do
    # 移除行首尾空格
    line=$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    # 跳过空行和以 # 开头的注释行
    if [[ -n "$line" && ! "$line" =~ ^# ]]; then
        TABLES+=("$line")
    fi
done < "$TABLE_LIST_FILE"

if [ ${#TABLES[@]} -eq 0 ]; then
    echo "警告：表列表文件 '${TABLE_LIST_FILE}' 中没有找到有效的表名。"
    echo "请确保文件中有表名，并且每行一个。"
    exit 0 # 没有表可备份，直接退出
fi
echo "=====找到了 ${#TABLES[@]} 个表等待备份。====="
echo "=====开始备份作业====="
sleep 2

# 遍历每个表进行备份
for TABLE in "${TABLES[@]}"; do
    echo "---------------------------------------------------------------------------------"
    echo "开始处理表：${TABLE}"

    # 定义目标表名
    TARGET_TABLE="${TABLE}"
    YESTERDAY_BACKUP_TABLE="${TABLE}_bak"

    # 0. 删除_bak表;

    echo "删除之前备份的表: ${TABLE}_bak"
    mysql -u${RESTORE_USER} -p${RESTORE_PASSWORD} ${DATABASE} -e "DROP TABLE IF EXISTS \`${TABLE}_bak\`;"
    if [ $? -eq 0 ]; then
        echo "成功删除表：${YESTERDAY_BACKUP_TABLE}"
    else
        echo "删除表失败或表不存在：${YESTERDAY_BACKUP_TABLE}"
    fi
    # 1. 将昨天的备份表重命名为带有 _bak 后缀的表
    echo "尝试将昨天的备份表更名为：${TABLE}_bak"

    count=$(mysql -u${RESTORE_USER} -p${RESTORE_PASSWORD} ${DATABASE} -sN -e "SELECT count(*) FROM information_schema.TABLES WHERE TABLE_NAME = '${TABLE}';")

   if [ "$count" -gt 0 ]; then
    mysql -u${RESTORE_USER} -p${RESTORE_PASSWORD} ${DATABASE} -e "RENAME TABLE  \`${TABLE}\` TO \`${YESTERDAY_BACKUP_TABLE}\`;"
    if [ $? -eq 0 ]; then
        echo "成功重命名表：${TABLE} 为 ${YESTERDAY_BACKUP_TABLE}"
    else
        echo "重命名表失败或昨天备份表不存在：${TABLE}"
    fi
else
    echo "Table ${TABLE} does not exist or count is 0."
fi

    # 3. 执行 mysqldump 备份今天的表
    echo "尝试备份表：${TABLE} 到 ${TARGET_TABLE}"

    DUMP_COMMAND="mysqldump -h${DUMP_HOST} -P${DUMP_PORT} -u${DUMP_USER} -p${DUMP_PASSWORD} ${MYSQLDUMP_OPTIONS} --tables ${TABLE} --where=${WHERE_CONDITION}"
    RESTORE_COMMAND="mysql  -u${RESTORE_USER} -p${RESTORE_PASSWORD} ${DATABASE}"

    # 先删除目标表（如果存在），确保清空
    echo "删除旧的今日目标表 (如果存在)：${TABLE}"
    mysql  -u${RESTORE_USER} -p${RESTORE_PASSWORD} ${DATABASE} -e "DROP TABLE IF EXISTS \`${TABLE}\`;"
    if [ $? -ne 0 ]; then
        echo "警告：删除旧的今日目标表 ${TABLE} 失败！继续备份，但可能存在问题。"
    fi

    # 执行备份和导入，并捕获错误
    echo "导出到本地文件 ${TABLE}.sql "
   # ${DUMP_COMMAND} | ${RESTORE_COMMAND}
    ${DUMP_COMMAND} > ${TABLE}.sql # 先导出到文件

    sleep 1
    echo "从本地文件 ${TABLE}.sql 导入。"
    ${RESTORE_COMMAND} < ${TABLE}.sql # 再把文件导入
    if [ $? -eq 0 ]; then
        echo "成功备份表：${TABLE}"
    else
        echo "备份表失败：${TABLE}"
        echo "请检查错误信息，可能是 mysqldump 或 mysql 命令执行失败。"
        # 可以选择在这里退出脚本，或者继续处理下一个表
        # exit 1 
    fi

    echo "完成处理表：${TABLE}"
    sleep 1
done

echo "================================================================================="
echo "所有表备份完成于：$(date '+%Y-%m-%d %H:%M:%S')"
echo "================================================================================="

exit 0