From 6be0917ce4f89810a16883859a281ca73fc20eb8 Mon Sep 17 00:00:00 2001 From: yml Date: Fri, 5 Jun 2026 21:46:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=80=E9=94=AE=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/clean-old-migrations.sh | 94 +++++++++++++++++++++++++++++++++ scripts/deploy-prod.sh | 37 ++++++++----- scripts/dev.sh | 40 ++++++++++---- 3 files changed, 148 insertions(+), 23 deletions(-) create mode 100755 scripts/clean-old-migrations.sh diff --git a/scripts/clean-old-migrations.sh b/scripts/clean-old-migrations.sh new file mode 100755 index 0000000..e3bf6d2 --- /dev/null +++ b/scripts/clean-old-migrations.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +set -euo pipefail + +# 这个脚本用于删除已合并到 000001_init.sql 的旧迁移文件 +# 使用场景:迁移文件合并后,清理旧的分散文件 + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +MIGRATIONS_DIR="${ROOT_DIR}/backend/migrations" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[1;34m' +NC='\033[0m' + +log() { + printf "${BLUE}[clean]${NC} %s\n" "$*" +} + +log_success() { + printf "${GREEN}[clean]${NC} %s\n" "$*" +} + +log_warn() { + printf "${YELLOW}[clean]${NC} %s\n" "$*" +} + +log_error() { + printf "${RED}[clean]${NC} %s\n" "$*" >&2 +} + +# 要删除的旧迁移文件列表 +OLD_MIGRATIONS=( + "000002_payment_refund_schema.sql" + "000003_add_indexes.sql" + "000004_add_support_status.sql" + "000005_add_announcements.sql" + "000006_insert_sample_announcements.sql" + "000007_add_announcement_permissions.sql" + "000008_fix_announcement_charset.sql" +) + +main() { + cd "${MIGRATIONS_DIR}" + + log "检查旧迁移文件..." + + local found=0 + local file + for file in "${OLD_MIGRATIONS[@]}"; do + if [[ -f "${file}" ]]; then + found=$((found + 1)) + log_warn "发现旧文件:${file}" + fi + done + + if [[ "${found}" == "0" ]]; then + log_success "没有发现旧的迁移文件,无需清理" + exit 0 + fi + + log "" + log "即将删除 ${found} 个旧迁移文件" + log "这些文件的内容已经合并到 000001_init.sql 中" + log "" + + # 确认删除 + read -p "确认删除?(yes/no): " -r + echo + if [[ ! "${REPLY}" =~ ^[Yy][Ee][Ss]$ ]]; then + log "取消删除" + exit 0 + fi + + # 执行删除 + local deleted=0 + for file in "${OLD_MIGRATIONS[@]}"; do + if [[ -f "${file}" ]]; then + rm -f "${file}" + log_success "已删除:${file}" + deleted=$((deleted + 1)) + fi + done + + log "" + log_success "清理完成,已删除 ${deleted} 个文件" + log "" + log "注意事项:" + log "1. 如果是开发环境,建议执行:./scripts/dev.sh --clean-init" + log "2. 如果是生产环境,建议执行:./scripts/deploy-prod.sh --clean-init" + log "3. 这些命令会清理旧数据库并使用新的 000001_init.sql 初始化" +} + +main "$@" diff --git a/scripts/deploy-prod.sh b/scripts/deploy-prod.sh index 6d93846..bd152d0 100755 --- a/scripts/deploy-prod.sh +++ b/scripts/deploy-prod.sh @@ -62,7 +62,7 @@ show_help() { 选项: --no-build 不重新构建镜像,仅启动已有镜像 --no-migrate 不执行数据库迁移 - --reset-db 重置数据库(测试阶段使用,会删除并重建) + --reset-db 重置数据库(删除并重建,自动清理旧迁移记录) --logs 部署完成后跟随查看后端日志 -h, --help 显示帮助信息 @@ -217,20 +217,33 @@ CREATE TABLE IF NOT EXISTS schema_migrations ( SQL } +clean_legacy_migrations() { + local has_legacy + has_legacy="$(mysql_scalar "SELECT COUNT(*) FROM schema_migrations WHERE version IN ('000002_payment_refund_schema', '000003_add_indexes', '000004_add_support_status', '000005_add_announcements', '000006_insert_sample_announcements', '000007_add_announcement_permissions', '000008_fix_announcement_charset');")" + + if [[ "${has_legacy}" != "0" ]]; then + log_warn "检测到旧的迁移记录(000002-000008),正在清理..." + mysql_exec "$(require_env MYSQL_DATABASE)" -e \ + "DELETE FROM schema_migrations WHERE version IN ('000002_payment_refund_schema', '000003_add_indexes', '000004_add_support_status', '000005_add_announcements', '000006_insert_sample_announcements', '000007_add_announcement_permissions', '000008_fix_announcement_charset');" + log_success "已清理旧迁移记录" + fi +} + bootstrap_existing_schema_history() { - local migration_count users_exists system_configs_exists + local migration_count users_exists migration_count="$(mysql_scalar "SELECT COUNT(*) FROM schema_migrations;")" users_exists="$(mysql_scalar "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'users';")" - system_configs_exists="$(mysql_scalar "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'system_configs';")" - if [[ "${migration_count}" == "0" && "${users_exists}" != "0" && "${system_configs_exists}" != "0" ]]; then - log_warn "检测到已有表结构但没有迁移记录,将当前 migration 文件标记为已应用" + if [[ "${migration_count}" == "0" && "${users_exists}" != "0" ]]; then + log_warn "检测到已有表结构但没有迁移记录,补记当前所有迁移文件为已应用" local file version + shopt -s nullglob for file in "${MIGRATIONS_DIR}"/*.sql; do version="$(basename "${file}" .sql)" mysql_exec "$(require_env MYSQL_DATABASE)" -e \ "INSERT IGNORE INTO schema_migrations (version) VALUES ('${version}');" done + shopt -u nullglob fi } @@ -246,7 +259,7 @@ reset_database() { exit 1 fi - log_warn "重置数据库 ${database}..." + log_warn "重置数据库 ${database}(会清理旧迁移记录)..." mysql_root_exec -e \ "DROP DATABASE IF EXISTS \`${database}\`; CREATE DATABASE \`${database}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" log_success "数据库已重建" @@ -262,18 +275,18 @@ run_migrations() { ensure_migration_table bootstrap_existing_schema_history + # 只有在数据库未重置的情况下才需要清理旧迁移记录 + if [[ "${RESET_DB}" != "1" ]]; then + clean_legacy_migrations + fi + local file version applied shopt -s nullglob for file in "${MIGRATIONS_DIR}"/*.sql; do version="$(basename "${file}" .sql)" applied="$(mysql_scalar "SELECT COUNT(*) FROM schema_migrations WHERE version = '${version}';")" if [[ "${applied}" != "0" ]]; then - if [[ "${version}" == "000001_init" ]]; then - log "同步初始化脚本:${version}" - mysql_exec "$(require_env MYSQL_DATABASE)" < "${file}" - else - log "跳过已应用迁移:${version}" - fi + log "跳过已应用迁移:${version}" continue fi diff --git a/scripts/dev.sh b/scripts/dev.sh index f150656..39976d8 100755 --- a/scripts/dev.sh +++ b/scripts/dev.sh @@ -52,7 +52,7 @@ show_help() { 用法: ./scripts/dev.sh [选项] 选项: - --reset-db 重置数据库(删除并重建) + --reset-db 重置数据库(删除并重建,自动清理旧迁移记录) --seed-only 仅重新同步基础数据 --no-migrate 不执行数据库迁移 --no-frontend 不启动前端 @@ -76,7 +76,7 @@ show_help() { 示例: ./scripts/dev.sh # 正常启动 - ./scripts/dev.sh --reset-db # 重置数据库后启动 + ./scripts/dev.sh --reset-db # 重置数据库后启动(推荐迁移后使用) ./scripts/dev.sh --seed-only # 重新同步基础数据 EOF exit 0 @@ -248,15 +248,33 @@ CREATE TABLE IF NOT EXISTS schema_migrations ( SQL } +clean_legacy_migrations() { + local has_legacy + has_legacy="$(mysql_scalar "SELECT COUNT(*) FROM schema_migrations WHERE version IN ('000002_payment_refund_schema', '000003_add_indexes', '000004_add_support_status', '000005_add_announcements', '000006_insert_sample_announcements', '000007_add_announcement_permissions', '000008_fix_announcement_charset');")" + + if [[ "${has_legacy}" != "0" ]]; then + log_warn "检测到旧的迁移记录(000002-000008),正在清理..." + mysql_hfb --default-character-set=utf8mb4 -e \ + "DELETE FROM schema_migrations WHERE version IN ('000002_payment_refund_schema', '000003_add_indexes', '000004_add_support_status', '000005_add_announcements', '000006_insert_sample_announcements', '000007_add_announcement_permissions', '000008_fix_announcement_charset');" "${MYSQL_DATABASE}" + log_success "已清理旧迁移记录" + fi +} + bootstrap_existing_schema_history() { local migration_count users_exists migration_count="$(mysql_scalar "SELECT COUNT(*) FROM schema_migrations;")" users_exists="$(mysql_scalar "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'users';")" if [[ "${migration_count}" == "0" && "${users_exists}" != "0" ]]; then - log_warn "检测到已有表结构但没有迁移记录,补记 000001_init 并同步初始化脚本" - mysql_hfb --default-character-set=utf8mb4 -e \ - "INSERT IGNORE INTO schema_migrations (version) VALUES ('000001_init');" "${MYSQL_DATABASE}" + log_warn "检测到已有表结构但没有迁移记录,补记当前所有迁移文件为已应用" + local file version + shopt -s nullglob + for file in "${MIGRATIONS_DIR}"/*.sql; do + version="$(basename "${file}" .sql)" + mysql_hfb --default-character-set=utf8mb4 -e \ + "INSERT IGNORE INTO schema_migrations (version) VALUES ('${version}');" "${MYSQL_DATABASE}" + done + shopt -u nullglob fi } @@ -270,6 +288,11 @@ run_migrations() { ensure_migration_table bootstrap_existing_schema_history + # 只有在数据库未重置的情况下才需要清理旧迁移记录 + if [[ "${RESET_DB}" != "1" ]]; then + clean_legacy_migrations + fi + local file version applied local found=0 shopt -s nullglob @@ -278,12 +301,7 @@ run_migrations() { version="$(basename "${file}" .sql)" applied="$(mysql_scalar "SELECT COUNT(*) FROM schema_migrations WHERE version = '${version}';")" if [[ "${applied}" != "0" ]]; then - if [[ "${version}" == "000001_init" ]]; then - log "同步初始化脚本:${version}" - mysql_hfb --default-character-set=utf8mb4 "${MYSQL_DATABASE}" < "${file}" - else - log "跳过已应用迁移:${version}" - fi + log "跳过已应用迁移:${version}" continue fi