#!/bin/bash # 表结构对齐脚本 - 准生产 → VPS # 支持单表模式,避免全量同步 # 不使用 set -e,手动处理错误 # 连接信息 SOURCE_HOST="100.115.195.188" SOURCE_PORT="50036" SOURCE_USER="witsoftd" TARGET_HOST="101.34.227.188" TARGET_PORT="3306" TARGET_USER="root" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } usage() { echo "用法:$0 " echo " $0 # 同步整个库" echo "" echo "示例:" echo " $0 dmp_serp idb_pub_basic_item_info # 单表同步" echo " $0 dmp_serp # 全库同步" exit 1 } [ -z "$1" ] && usage SOURCE_DB="$1" TABLE="$2" TARGET_DB="${3:-$SOURCE_DB}" # 可选第三个参数指定目标库名,默认同源库名 # 检查环境变量 if [ -z "$MYSQL_PWD_WIT" ]; then log_error "缺少环境变量 MYSQL_PWD_WIT" exit 1 fi if [ -z "$MYSQL_PWD_SQL" ]; then log_error "缺少环境变量 MYSQL_PWD_SQL" exit 1 fi # 输出目录 DATE=$(date +%Y%m%d) OUTPUT_DIR="/home/yangxuan/codes/xuan-sql/scripts/${DATE}" mkdir -p "$OUTPUT_DIR" log_info "同步方向:准生产 (${SOURCE_HOST}:${SOURCE_PORT}) → VPS (${TARGET_HOST}:${TARGET_PORT})" log_info "数据库:${SOURCE_DB}" [ -n "$TABLE" ] && log_info "表:${TABLE} (单表模式)" # 获取表列表 if [ -n "$TABLE" ]; then # 单表模式 log_info "单表模式:只同步 ${TABLE}" TABLES="$TABLE" else # 全库模式 log_info "全库模式:获取表列表..." TABLES=$(mysql -h "$SOURCE_HOST" -P "$SOURCE_PORT" -u "$SOURCE_USER" -p"${MYSQL_PWD_WIT}" -D "$SOURCE_DB" -N -e "SHOW TABLES;") TABLE_COUNT=$(echo "$TABLES" | wc -l) log_info "共 ${TABLE_COUNT} 张表" if [ "$TABLE_COUNT" -gt 50 ]; then log_warn "表数量超过 50,确认继续?(y/n)" read -r CONFIRM [ "$CONFIRM" != "y" ] && exit 0 fi fi # 同步单表函数 sync_single_table() { local TABLE_NAME="$1" local SCRIPT_FILE="${OUTPUT_DIR}/${SOURCE_DB}__${TABLE_NAME}__struct.sql" log_info "处理:${TABLE_NAME}" # 检查源表是否存在 SOURCE_EXISTS=$(mysql -h "$SOURCE_HOST" -P "$SOURCE_PORT" -u "$SOURCE_USER" -p"${MYSQL_PWD_WIT}" -D "$SOURCE_DB" -N -e \ "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$SOURCE_DB' AND TABLE_NAME='$TABLE_NAME';") if [ "$SOURCE_EXISTS" -eq 0 ]; then log_error "源表 ${SOURCE_DB}.${TABLE_NAME} 不存在" return 1 fi # 检查目标表是否存在 TARGET_EXISTS=$(mysql -h "$TARGET_HOST" -P "$TARGET_PORT" -u "$TARGET_USER" -p"${MYSQL_PWD_SQL}" -D "$TARGET_DB" -N -e \ "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$TARGET_DB' AND TABLE_NAME='$TABLE_NAME';") # 获取源表结构(去除字面量 \n,转换为真实换行;cut -f2 取 CREATE 语句列) SOURCE_CREATE=$(mysql -h "$SOURCE_HOST" -P "$SOURCE_PORT" -u "$SOURCE_USER" -p"${MYSQL_PWD_WIT}" -D "$SOURCE_DB" -N -e "SHOW CREATE TABLE \`${TABLE_NAME}\`;" | cut -f2 | sed 's/\\n/\n/g') if [ "$TARGET_EXISTS" -eq 0 ]; then # 表不存在 → CREATE log_info " 目标表不存在,使用 CREATE TABLE" # 提取 CREATE TABLE 语句的主体部分(删除第一行和最后一行) TABLE_BODY=$(echo "$SOURCE_CREATE" | sed '1d;$d') cat > "$SCRIPT_FILE" </dev/null | tail -1 || echo "无法获取") TARGET_STRUCT=$(mysql -h "$TARGET_HOST" -P "$TARGET_PORT" -u "$TARGET_USER" -p"${MYSQL_PWD_SQL}" -D "$TARGET_DB" -N -e "SHOW CREATE TABLE \`$TABLE_NAME\`;" 2>/dev/null | tail -1 || echo "无法获取") cat > "$SCRIPT_FILE" <&1; then log_info " ✅ 成功" else log_error " ❌ 失败,查看脚本:${SCRIPT_FILE}" fi fi } # 执行同步 FAILED=0 SUCCESS=0 for TABLE_NAME in $TABLES; do if sync_single_table "$TABLE_NAME"; then ((SUCCESS++)) else ((FAILED++)) fi done log_info "完成!成功:${SUCCESS}, 失败:${FAILED}" log_info "脚本目录:${OUTPUT_DIR}"