#!/usr/bin/env bash # 夜间停机:仅在数据库服务器(或能连库的跳板机)执行 # 依赖:mysql 客户端 # # export BMS_DB_HOST=127.0.0.1 # export BMS_DB_PORT=3306 # export BMS_DB_NAME=bms # export BMS_DB_USER=root # export BMS_DB_PASS='******' # chmod +x 20261113_uuid_to_bigint_run.sh # ./20261113_uuid_to_bigint_run.sh # # CONFIRM=YES ./20261113_uuid_to_bigint_run.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SQL_FILE="${SQL_FILE:-${SCRIPT_DIR}/20261113_uuid_to_bigint_order_bill.sql}" LOG_DIR="${LOG_DIR:-${SCRIPT_DIR}/logs}" TS="$(date +%Y%m%d_%H%M%S)" LOG_FILE="${LOG_DIR}/uuid_to_bigint_${TS}.log" BMS_DB_HOST="${BMS_DB_HOST:-127.0.0.1}" BMS_DB_PORT="${BMS_DB_PORT:-3306}" BMS_DB_NAME="${BMS_DB_NAME:-bms}" BMS_DB_USER="${BMS_DB_USER:-root}" if [[ -z "${BMS_DB_PASS:-}" ]]; then echo "请先设置环境变量 BMS_DB_PASS(不要把密码写进脚本)" exit 1 fi if [[ ! -f "${SQL_FILE}" ]]; then echo "找不到 SQL 文件: ${SQL_FILE}" exit 1 fi if ! command -v mysql >/dev/null 2>&1; then echo "未找到 mysql 客户端,请先安装" exit 1 fi mkdir -p "${LOG_DIR}" echo "========================================" echo " UUID -> bigint 迁移" echo " host=${BMS_DB_HOST} port=${BMS_DB_PORT} db=${BMS_DB_NAME} user=${BMS_DB_USER}" echo " sql=${SQL_FILE}" echo " log=${LOG_FILE}" echo "========================================" echo echo "【必须】先停 Java / BMS,再执行本脚本。" echo "执行前请确认:" echo " 1) Java / BMS 应用与异步 worker 已全部停掉(不要边跑边迁)" echo " 2) 已做全库/关键表备份" echo " 3) 磅盘空间足够(建议 >= 订单+ext+费用表 2~3 倍)" echo " 4) SQL 成功后,再部署 Long 版后端并启动" echo if [[ "${CONFIRM:-}" != "YES" ]]; then read -r -p "已停 Java?输入 YES 开始执行 SQL: " ans if [[ "${ans}" != "YES" ]]; then echo "已取消(请先停 Java 再来)" exit 1 fi else echo "CONFIRM=YES:假定你已停 Java,直接开始 SQL..." fi MYSQL_OPTS=( -h "${BMS_DB_HOST}" -P "${BMS_DB_PORT}" -u "${BMS_DB_USER}" "-p${BMS_DB_PASS}" --default-character-set=utf8mb4 --comments "${BMS_DB_NAME}" ) echo echo "[$(date '+%F %T')] 连接检查..." | tee -a "${LOG_FILE}" mysql "${MYSQL_OPTS[@]}" -e "SELECT DATABASE() AS db, NOW() AS now_ts;" | tee -a "${LOG_FILE}" echo "[$(date '+%F %T')] 行数预览..." | tee -a "${LOG_FILE}" mysql "${MYSQL_OPTS[@]}" -e " SELECT 'prc_order_bill' AS tbl, COUNT(*) AS cnt FROM prc_order_bill UNION ALL SELECT 'prc_order_bill_ext', COUNT(*) FROM prc_order_bill_ext UNION ALL SELECT 'prc_income_bill', COUNT(*) FROM prc_income_bill UNION ALL SELECT 'prc_income_bill_fee', COUNT(*) FROM prc_income_bill_fee UNION ALL SELECT 'prc_pay_bill', COUNT(*) FROM prc_pay_bill UNION ALL SELECT 'prc_pay_bill_fee', COUNT(*) FROM prc_pay_bill_fee; " | tee -a "${LOG_FILE}" START_TS="$(date +%s)" echo "[$(date '+%F %T')] 开始执行迁移 SQL..." | tee -a "${LOG_FILE}" set +e mysql "${MYSQL_OPTS[@]}" < "${SQL_FILE}" 2>&1 | tee -a "${LOG_FILE}" RC=${PIPESTATUS[0]} set -e END_TS="$(date +%s)" ELAPSED=$((END_TS - START_TS)) if [[ "${RC}" -ne 0 ]]; then echo "[$(date '+%F %T')] 失败 exit=${RC} 耗时=${ELAPSED}s,请查日志: ${LOG_FILE}" | tee -a "${LOG_FILE}" echo "若已换表中途失败:优先整库备份恢复,不要部署新后端" exit "${RC}" fi echo "[$(date '+%F %T')] 成功耗时=${ELAPSED}s (约 $((ELAPSED/60)) 分钟)" | tee -a "${LOG_FILE}" echo echo "下一步:" echo " 1) 抽查日志中校验/抽查结果" echo " 2) 部署 Long 版后端并启应用" echo " 3) 按 20261113_uuid_to_bigint_runbook.md 做冒烟" echo "日志: ${LOG_FILE}"