note/work/AI/mpmysql.sql
2025-11-19 10:16:05 +08:00

164 lines
5.9 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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