From 79f00f30d846e0fa4ea3d8080f71fcecbea15b10 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Sat, 28 Feb 2026 15:18:01 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=88=86=E7=A6=BB=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E5=AF=BC=E5=87=BA=E5=92=8C=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=EF=BC=8C=E4=BC=98=E5=8C=96=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 改进内容: 1. 创建独立的 import_database.sh 导入脚本 - 从 doc/database/backup/ 读取 SQL 文件 - 支持导入到 dev/test/prod 环境 - 自动验证导入结果 2. 简化 export_database.sh 导出脚本 - 只负责导出数据库到 backup 文件夹 - 移除导入功能,职责单一 - 添加后续操作提示 3. 优化文件结构 - backup 文件夹只保留 SQL 备份文件 - 配置文件和脚本统一放在根目录 - 移动操作指南到 doc/database/ 目录 4. 更新操作指南 - 详细说明两个脚本的用法 - 完整的迁移流程示例 - 常见问题解答 文件变更: - 新增: import_database.sh (独立导入脚本) - 修改: export_database.sh (简化为导出专用) - 移动: export_guide.md -> doc/database/数据库迁移操作指南.md - 删除: doc/database/backup/ 中的非 SQL 文件 使用方法: - 导出: ./export_database.sh - 导入: ./import_database.sh --- .../export_guide.md => 数据库迁移操作指南.md} | 95 ++++- export_database.sh | 228 ++---------- import_database.sh | 329 ++++++++++++++++++ 3 files changed, 432 insertions(+), 220 deletions(-) rename doc/database/{backup/export_guide.md => 数据库迁移操作指南.md} (77%) create mode 100644 import_database.sh diff --git a/doc/database/backup/export_guide.md b/doc/database/数据库迁移操作指南.md similarity index 77% rename from doc/database/backup/export_guide.md rename to doc/database/数据库迁移操作指南.md index 3b46807..9824475 100644 --- a/doc/database/backup/export_guide.md +++ b/doc/database/数据库迁移操作指南.md @@ -4,16 +4,46 @@ 本文档提供 CCDI 纪检初核系统数据库迁移的详细操作步骤,包括从开发环境导出数据库和导入到生产/测试环境。 +## 脚本说明 + +项目提供两个独立的脚本: + +1. **export_database.sh** - 数据库导出脚本 + - 从开发环境导出数据库 + - 生成表结构和数据文件到 `doc/database/backup/` 文件夹 + +2. **import_database.sh** - 数据库导入脚本 + - 从 `doc/database/backup/` 文件夹读取备份文件 + - 导入到指定的目标环境(dev/test/prod) + +## 文件结构 + +``` +项目根目录/ +├── export_database.sh # 导出脚本 +├── import_database.sh # 导入脚本 +├── db_config.conf.template # 配置模板 +├── db_config.conf # 实际配置(不提交到 Git) +└── doc/ + └── database/ + ├── backup/ # 备份文件夹 + │ ├── .gitkeep + │ ├── ccdi_structure.sql # 表结构(~60KB) + │ └── ccdi_data.sql # 数据文件(~5.7MB) + └── alter_collation_to_general_ci.sql # 排序规则修改脚本 +``` + ## 前置条件 ### 必需工具 - MySQL 客户端工具(包含 mysqldump 和 mysql 命令) -- Bash shell 环境 +- Bash shell 环境(Windows 用户可使用 Git Bash) - 网络访问权限(能连接源数据库和目标数据库) -### 检查 mysqldump 是否安装 +### 检查工具是否安装 ```bash mysqldump --version +mysql --version ``` 如果未安装,请根据操作系统安装 MySQL 客户端: @@ -73,6 +103,10 @@ cat db_config.conf | grep -E "^[A-Z]" ### 执行导出 ```bash +# 方式1: 使用默认命令 +./export_database.sh + +# 方式2: 显式指定命令 ./export_database.sh export ``` @@ -84,15 +118,16 @@ cat db_config.conf | grep -E "^[A-Z]" [INFO] mysqldump 命令检查通过 [INFO] 开始导出表结构... [INFO] 表结构导出成功: doc/database/backup/ccdi_structure.sql -[INFO] 文件大小: XXX +[INFO] 文件大小: 60K [INFO] 开始导出数据... [INFO] 数据导出成功: doc/database/backup/ccdi_data.sql -[INFO] 文件大小: XXX +[INFO] 文件大小: 5.7M [INFO] 验证导出文件... [INFO] 导出文件验证通过 -[INFO] 表结构文件: doc/database/backup/ccdi_structure.sql (XXX) -[INFO] 数据文件: doc/database/backup/ccdi_data.sql (XXX) +[INFO] 表结构文件: doc/database/backup/ccdi_structure.sql (60K) +[INFO] 数据文件: doc/database/backup/ccdi_data.sql (5.7M) [INFO] ========== 数据库导出完成 ========== +[INFO] 使用 ./import_database.sh 导入到目标环境 ``` ### 验证导出文件 @@ -103,8 +138,8 @@ ls -lh doc/database/backup/ ``` 应该看到: -- `ccdi_structure.sql` - 表结构文件 -- `ccdi_data.sql` - 数据文件 +- `ccdi_structure.sql` - 表结构文件(~60KB) +- `ccdi_data.sql` - 数据文件(~5.7MB) **2. 检查字符集声明** ```bash @@ -119,7 +154,7 @@ SET CHARACTER SET utf8mb4; **3. 检查文件内容** ```bash -# 查看表结构 +# 查看表数量 grep "CREATE TABLE" doc/database/backup/ccdi_structure.sql | wc -l # 查看数据量(INSERT 语句数量) @@ -153,30 +188,42 @@ CREATE DATABASE ccdi CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; ### 导入到测试环境 ```bash -./export_database.sh import test +./import_database.sh test ``` ### 导入到生产环境 ```bash -./export_database.sh import production +./import_database.sh production ``` 或简写: ```bash -./export_database.sh import prod +./import_database.sh prod +``` + +### 导入到开发环境 + +```bash +./import_database.sh dev ``` ### 预期输出 ``` [INFO] ========== 开始导入数据库到 test 环境 ========== +[INFO] 配置文件加载成功 +[INFO] mysql 命令检查通过 +[INFO] 检查备份文件... +[INFO] 备份文件检查通过 +[INFO] 表结构文件: doc/database/backup/ccdi_structure.sql (60K) +[INFO] 数据文件: doc/database/backup/ccdi_data.sql (5.7M) [INFO] 导入表结构到 test 环境: XXX:3306/ccdi [INFO] 表结构导入成功 [INFO] 导入数据到 test 环境: XXX:3306/ccdi [INFO] 数据导入成功 [INFO] 验证导入结果... -[INFO] 目标数据库表数量: XX +[INFO] 目标数据库表数量: 42 [INFO] sys_user 表数据行数: XX [INFO] 数据库字符集: utf8mb4 [INFO] ========== 数据库导入完成 ========== @@ -237,6 +284,9 @@ SELECT user_name, nick_name FROM sys_user LIMIT 10; -- 查询字典数据 SELECT dict_label, dict_value FROM sys_dict_data LIMIT 10; + +-- 查询业务表 +SELECT name, person_type FROM ccdi_biz_intermediary LIMIT 10; ``` 确保中文字符显示正常,无乱码。 @@ -258,7 +308,7 @@ nano db_config.conf **2. 导出数据库** ```bash -./export_database.sh export +./export_database.sh ``` **3. 验证导出文件** @@ -269,7 +319,7 @@ head -20 doc/database/backup/ccdi_structure.sql **4. 先在测试环境验证** ```bash -./export_database.sh import test +./import_database.sh test ``` **5. 验证测试环境** @@ -278,7 +328,7 @@ head -20 doc/database/backup/ccdi_structure.sql **6. 导入到生产环境** ```bash -./export_database.sh import production +./import_database.sh prod ``` **7. 验证生产环境** @@ -352,6 +402,14 @@ cp db_config.conf.template db_config.conf - 使用具有足够权限的用户(如 root) - 或授予用户必要权限 +### 8. 备份文件不存在 + +**错误信息**: `表结构文件不存在: doc/database/backup/ccdi_structure.sql` + +**解决**: +- 先执行导出:`./export_database.sh` +- 检查 backup 文件夹中是否有 SQL 文件 + ## 回滚方案 如果迁移失败或出现问题: @@ -379,6 +437,7 @@ cp db_config.conf.template db_config.conf 4. **字符集**: - 确保所有步骤都使用 utf8mb4 字符集 - 验证阶段重点检查中文数据 + - 表结构文件不再包含显式的 COLLATE 配置(使用默认 utf8mb4_general_ci) ## 技术支持 @@ -390,9 +449,11 @@ cp db_config.conf.template db_config.conf ## 相关文件 -- 自动化脚本: `export_database.sh` +- 导出脚本: `export_database.sh` +- 导入脚本: `import_database.sh` - 配置模板: `db_config.conf.template` - 实际配置: `db_config.conf` - 表结构文件: `doc/database/backup/ccdi_structure.sql` - 数据文件: `doc/database/backup/ccdi_data.sql` +- 排序规则修改脚本: `doc/database/alter_collation_to_general_ci.sql` - 设计文档: `docs/plans/2026-02-28-database-migration-design.md` diff --git a/export_database.sh b/export_database.sh index 0efd7dc..4d8367a 100644 --- a/export_database.sh +++ b/export_database.sh @@ -1,7 +1,7 @@ #!/bin/bash -# CCDI 数据库迁移自动化脚本 -# 功能:数据库导出和导入自动化 +# CCDI 数据库导出脚本 +# 功能:从开发环境导出数据库到 backup 文件夹 set -e # 遇到错误立即退出 @@ -77,7 +77,7 @@ export_structure() { --no-data \ --skip-triggers \ --skip-add-drop-table \ - --default-character-set=$CHARACTER_SET \ + --default-character-set=utf8mb4 \ --single-transaction \ --max_allowed_packet=$MAX_ALLOWED_PACKET \ "$SOURCE_DB_NAME" > "$temp_file" 2>/dev/null @@ -88,7 +88,7 @@ export_structure() { echo "-- CCDI 数据库表结构" echo "-- 导出时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "-- 源数据库: ${SOURCE_DB_HOST}:${SOURCE_DB_PORT}/${SOURCE_DB_NAME}" - echo "-- 字符集: ${CHARACTER_SET}" + echo "-- 字符集: utf8mb4" echo "" echo "SET NAMES utf8mb4;" echo "SET CHARACTER SET utf8mb4;" @@ -125,7 +125,7 @@ export_data() { -p"$SOURCE_DB_PASS" \ --no-create-info \ --skip-triggers \ - --default-character-set=$CHARACTER_SET \ + --default-character-set=utf8mb4 \ --single-transaction \ --complete-insert \ --extended-insert \ @@ -138,7 +138,7 @@ export_data() { echo "-- CCDI 数据库数据" echo "-- 导出时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "-- 源数据库: ${SOURCE_DB_HOST}:${SOURCE_DB_PORT}/${SOURCE_DB_NAME}" - echo "-- 字符集: ${CHARACTER_SET}" + echo "-- 字符集: utf8mb4" echo "" echo "SET NAMES utf8mb4;" echo "SET CHARACTER SET utf8mb4;" @@ -196,189 +196,6 @@ verify_export() { log_info "数据文件: $data_file ($(du -h "$data_file" | cut -f1))" } -# 导入表结构 -import_structure() { - local env_type=$1 - local db_host db_port db_user db_pass db_name - - case "$env_type" in - production|prod) - db_host="$PROD_DB_HOST" - db_port="$PROD_DB_PORT" - db_user="$PROD_DB_USER" - db_pass="$PROD_DB_PASS" - db_name="$PROD_DB_NAME" - ;; - test) - db_host="$TEST_DB_HOST" - db_port="$TEST_DB_PORT" - db_user="$TEST_DB_USER" - db_pass="$TEST_DB_PASS" - db_name="$TEST_DB_NAME" - ;; - *) - log_error "未知的环境类型: $env_type" - exit 1 - ;; - esac - - log_info "导入表结构到 ${env_type} 环境: ${db_host}:${db_port}/${db_name}" - - local structure_file="${BACKUP_DIR}/${STRUCTURE_FILE}" - - if [ ! -f "$structure_file" ]; then - log_error "表结构文件不存在: $structure_file" - log_info "请先执行导出: ./export_database.sh export" - exit 1 - fi - - # 导入表结构 - mysql -h "$db_host" \ - -P "$db_port" \ - -u "$db_user" \ - -p"$db_pass" \ - --default-character-set=$CHARACTER_SET \ - "$db_name" < "$structure_file" 2>/dev/null - - if [ $? -eq 0 ]; then - log_info "表结构导入成功" - else - log_error "表结构导入失败" - exit 1 - fi -} - -# 导入数据 -import_data() { - local env_type=$1 - local db_host db_port db_user db_pass db_name - - case "$env_type" in - production|prod) - db_host="$PROD_DB_HOST" - db_port="$PROD_DB_PORT" - db_user="$PROD_DB_USER" - db_pass="$PROD_DB_PASS" - db_name="$PROD_DB_NAME" - ;; - test) - db_host="$TEST_DB_HOST" - db_port="$TEST_DB_PORT" - db_user="$TEST_DB_USER" - db_pass="$TEST_DB_PASS" - db_name="$TEST_DB_NAME" - ;; - *) - log_error "未知的环境类型: $env_type" - exit 1 - ;; - esac - - log_info "导入数据到 ${env_type} 环境: ${db_host}:${db_port}/${db_name}" - - local data_file="${BACKUP_DIR}/${DATA_FILE}" - - if [ ! -f "$data_file" ]; then - log_error "数据文件不存在: $data_file" - log_info "请先执行导出: ./export_database.sh export" - exit 1 - fi - - # 导入数据 - mysql -h "$db_host" \ - -P "$db_port" \ - -u "$db_user" \ - -p"$db_pass" \ - --default-character-set=$CHARACTER_SET \ - "$db_name" < "$data_file" 2>/dev/null - - if [ $? -eq 0 ]; then - log_info "数据导入成功" - else - log_error "数据导入失败" - exit 1 - fi -} - -# 验证导入结果 -verify_import() { - local env_type=$1 - local db_host db_port db_user db_pass db_name - - case "$env_type" in - production|prod) - db_host="$PROD_DB_HOST" - db_port="$PROD_DB_PORT" - db_user="$PROD_DB_USER" - db_pass="$PROD_DB_PASS" - db_name="$PROD_DB_NAME" - ;; - test) - db_host="$TEST_DB_HOST" - db_port="$TEST_DB_PORT" - db_user="$TEST_DB_USER" - db_pass="$TEST_DB_PASS" - db_name="$TEST_DB_NAME" - ;; - *) - log_error "未知的环境类型: $env_type" - exit 1 - ;; - esac - - log_info "验证导入结果..." - - # 查询表数量 - local table_count=$(mysql -h "$db_host" \ - -P "$db_port" \ - -u "$db_user" \ - -p"$db_pass" \ - --default-character-set=$CHARACTER_SET \ - -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$db_name';" "$db_name" 2>/dev/null) - - log_info "目标数据库表数量: $table_count" - - # 查询关键表行数(示例:sys_user 表) - local user_count=$(mysql -h "$db_host" \ - -P "$db_port" \ - -u "$db_user" \ - -p"$db_pass" \ - --default-character-set=$CHARACTER_SET \ - -N -e "SELECT COUNT(*) FROM sys_user;" "$db_name" 2>/dev/null) - - log_info "sys_user 表数据行数: $user_count" - - # 检查数据库字符集 - local db_charset=$(mysql -h "$db_host" \ - -P "$db_port" \ - -u "$db_user" \ - -p"$db_pass" \ - --default-character-set=$CHARACTER_SET \ - -N -e "SELECT DEFAULT_CHARACTER_SET_NAME FROM information_schema.schemata WHERE schema_name='$db_name';" 2>/dev/null) - - log_info "数据库字符集: $db_charset" -} - -# 导入数据库 -import_database() { - local env_type=$1 - - if [ -z "$env_type" ]; then - log_error "请指定目标环境: production 或 test" - log_info "用法: $0 import [production|test]" - exit 1 - fi - - log_info "========== 开始导入数据库到 ${env_type} 环境 ==========" - - check_config - import_structure "$env_type" - import_data "$env_type" - verify_import "$env_type" - - log_info "========== 数据库导入完成 ==========" -} - # 导出数据库 export_database() { log_info "========== 开始导出数据库 ==========" @@ -391,36 +208,41 @@ export_database() { verify_export log_info "========== 数据库导出完成 ==========" + log_info "使用 ./import_database.sh 导入到目标环境" } # 使用帮助 show_usage() { - echo "用法: $0 [options]" + echo "用法: $0 [command]" echo "" echo "命令:" - echo " export 导出数据库" - echo " import 导入数据库到指定环境" - echo " help 显示帮助信息" + echo " export 导出数据库(默认命令)" + echo " help 显示帮助信息" echo "" - echo "环境:" - echo " production, prod 生产环境" - echo " test 测试环境" + echo "说明:" + echo " 此脚本从开发环境导出数据库到 doc/database/backup/ 文件夹" + echo " 生成文件:" + echo " - ccdi_structure.sql (表结构)" + echo " - ccdi_data.sql (数据)" + echo "" + echo "前置条件:" + echo " 1. 已配置 db_config.conf 文件" + echo " 2. 已安装 MySQL 客户端工具(mysqldump)" echo "" echo "示例:" - echo " $0 export # 导出数据库到 doc/database/backup/ 目录" - echo " $0 import test # 导入数据库到测试环境" - echo " $0 import prod # 导入数据库到生产环境" + echo " $0 # 导出数据库(默认)" + echo " $0 export # 导出数据库" + echo "" + echo "后续操作:" + echo " 使用 ./import_database.sh 导入到目标环境" } # 主函数 main() { case "$1" in - export) + export|"") export_database ;; - import) - import_database "$2" - ;; help|--help|-h) show_usage ;; diff --git a/import_database.sh b/import_database.sh new file mode 100644 index 0000000..6ccf589 --- /dev/null +++ b/import_database.sh @@ -0,0 +1,329 @@ +#!/bin/bash + +# CCDI 数据库导入脚本 +# 功能:从 backup 文件夹导入数据库到目标环境 + +set -e # 遇到错误立即退出 + +# 颜色定义 +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" +} + +# 脚本目录 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONFIG_FILE="${SCRIPT_DIR}/db_config.conf" +BACKUP_DIR="${SCRIPT_DIR}/doc/database/backup" +STRUCTURE_FILE="ccdi_structure.sql" +DATA_FILE="ccdi_data.sql" + +# 检查配置文件 +check_config() { + if [ ! -f "$CONFIG_FILE" ]; then + log_error "配置文件不存在: $CONFIG_FILE" + log_info "请先复制配置模板: cp db_config.conf.template db_config.conf" + log_info "然后编辑 db_config.conf 填写目标数据库连接信息" + exit 1 + fi + + # 加载配置文件 + source "$CONFIG_FILE" + log_info "配置文件加载成功" +} + +# 检查 mysql 命令 +check_mysql() { + if ! command -v mysql &> /dev/null; then + log_error "mysql 命令未找到" + log_info "请安装 MySQL 客户端工具" + exit 1 + fi + log_info "mysql 命令检查通过" +} + +# 检查备份文件 +check_backup_files() { + log_info "检查备份文件..." + + local structure_file="${BACKUP_DIR}/${STRUCTURE_FILE}" + local data_file="${BACKUP_DIR}/${DATA_FILE}" + + if [ ! -f "$structure_file" ]; then + log_error "表结构文件不存在: $structure_file" + log_info "请先执行导出: ./export_database.sh export" + exit 1 + fi + + if [ ! -f "$data_file" ]; then + log_error "数据文件不存在: $data_file" + log_info "请先执行导出: ./export_database.sh export" + exit 1 + fi + + log_info "备份文件检查通过" + log_info "表结构文件: $structure_file ($(du -h "$structure_file" | cut -f1))" + log_info "数据文件: $data_file ($(du -h "$data_file" | cut -f1))" +} + +# 导入表结构 +import_structure() { + local env_type=$1 + local db_host db_port db_user db_pass db_name + + case "$env_type" in + production|prod) + db_host="$PROD_DB_HOST" + db_port="$PROD_DB_PORT" + db_user="$PROD_DB_USER" + db_pass="$PROD_DB_PASS" + db_name="$PROD_DB_NAME" + ;; + test) + db_host="$TEST_DB_HOST" + db_port="$TEST_DB_PORT" + db_user="$TEST_DB_USER" + db_pass="$TEST_DB_PASS" + db_name="$TEST_DB_NAME" + ;; + dev|development) + db_host="$SOURCE_DB_HOST" + db_port="$SOURCE_DB_PORT" + db_user="$SOURCE_DB_USER" + db_pass="$SOURCE_DB_PASS" + db_name="$SOURCE_DB_NAME" + ;; + *) + log_error "未知的环境类型: $env_type" + exit 1 + ;; + esac + + log_info "导入表结构到 ${env_type} 环境: ${db_host}:${db_port}/${db_name}" + + local structure_file="${BACKUP_DIR}/${STRUCTURE_FILE}" + + # 导入表结构 + mysql -h "$db_host" \ + -P "$db_port" \ + -u "$db_user" \ + -p"$db_pass" \ + --default-character-set=utf8mb4 \ + "$db_name" < "$structure_file" 2>/dev/null + + if [ $? -eq 0 ]; then + log_info "表结构导入成功" + else + log_error "表结构导入失败" + exit 1 + fi +} + +# 导入数据 +import_data() { + local env_type=$1 + local db_host db_port db_user db_pass db_name + + case "$env_type" in + production|prod) + db_host="$PROD_DB_HOST" + db_port="$PROD_DB_PORT" + db_user="$PROD_DB_USER" + db_pass="$PROD_DB_PASS" + db_name="$PROD_DB_NAME" + ;; + test) + db_host="$TEST_DB_HOST" + db_port="$TEST_DB_PORT" + db_user="$TEST_DB_USER" + db_pass="$TEST_DB_PASS" + db_name="$TEST_DB_NAME" + ;; + dev|development) + db_host="$SOURCE_DB_HOST" + db_port="$SOURCE_DB_PORT" + db_user="$SOURCE_DB_USER" + db_pass="$SOURCE_DB_PASS" + db_name="$SOURCE_DB_NAME" + ;; + *) + log_error "未知的环境类型: $env_type" + exit 1 + ;; + esac + + log_info "导入数据到 ${env_type} 环境: ${db_host}:${db_port}/${db_name}" + + local data_file="${BACKUP_DIR}/${DATA_FILE}" + + # 导入数据 + mysql -h "$db_host" \ + -P "$db_port" \ + -u "$db_user" \ + -p"$db_pass" \ + --default-character-set=utf8mb4 \ + "$db_name" < "$data_file" 2>/dev/null + + if [ $? -eq 0 ]; then + log_info "数据导入成功" + else + log_error "数据导入失败" + exit 1 + fi +} + +# 验证导入结果 +verify_import() { + local env_type=$1 + local db_host db_port db_user db_pass db_name + + case "$env_type" in + production|prod) + db_host="$PROD_DB_HOST" + db_port="$PROD_DB_PORT" + db_user="$PROD_DB_USER" + db_pass="$PROD_DB_PASS" + db_name="$PROD_DB_NAME" + ;; + test) + db_host="$TEST_DB_HOST" + db_port="$TEST_DB_PORT" + db_user="$TEST_DB_USER" + db_pass="$TEST_DB_PASS" + db_name="$TEST_DB_NAME" + ;; + dev|development) + db_host="$SOURCE_DB_HOST" + db_port="$SOURCE_DB_PORT" + db_user="$SOURCE_DB_USER" + db_pass="$SOURCE_DB_PASS" + db_name="$SOURCE_DB_NAME" + ;; + *) + log_error "未知的环境类型: $env_type" + exit 1 + ;; + esac + + log_info "验证导入结果..." + + # 查询表数量 + local table_count=$(mysql -h "$db_host" \ + -P "$db_port" \ + -u "$db_user" \ + -p"$db_pass" \ + --default-character-set=utf8mb4 \ + -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$db_name';" "$db_name" 2>/dev/null) + + log_info "目标数据库表数量: $table_count" + + # 查询关键表行数(示例:sys_user 表) + local user_count=$(mysql -h "$db_host" \ + -P "$db_port" \ + -u "$db_user" \ + -p"$db_pass" \ + --default-character-set=utf8mb4 \ + -N -e "SELECT COUNT(*) FROM sys_user;" "$db_name" 2>/dev/null) + + log_info "sys_user 表数据行数: $user_count" + + # 检查数据库字符集 + local db_charset=$(mysql -h "$db_host" \ + -P "$db_port" \ + -u "$db_user" \ + -p"$db_pass" \ + --default-character-set=utf8mb4 \ + -N -e "SELECT DEFAULT_CHARACTER_SET_NAME FROM information_schema.schemata WHERE schema_name='$db_name';" 2>/dev/null) + + log_info "数据库字符集: $db_charset" +} + +# 导入数据库 +import_database() { + local env_type=$1 + + if [ -z "$env_type" ]; then + log_error "请指定目标环境: dev, test 或 production" + log_info "用法: $0 " + exit 1 + fi + + log_info "========== 开始导入数据库到 ${env_type} 环境 ==========" + + check_config + check_mysql + check_backup_files + import_structure "$env_type" + import_data "$env_type" + verify_import "$env_type" + + log_info "========== 数据库导入完成 ==========" +} + +# 使用帮助 +show_usage() { + echo "用法: $0 " + echo "" + echo "环境:" + echo " dev, development 开发环境(源数据库)" + echo " test 测试环境" + echo " production, prod 生产环境" + echo "" + echo "说明:" + echo " 此脚本从 doc/database/backup/ 文件夹读取备份文件并导入到指定环境" + echo " 备份文件:" + echo " - ccdi_structure.sql (表结构)" + echo " - ccdi_data.sql (数据)" + echo "" + echo "前置条件:" + echo " 1. 已执行 ./export_database.sh export 导出数据库" + echo " 2. 已配置 db_config.conf 文件" + echo "" + echo "示例:" + echo " $0 test # 导入到测试环境" + echo " $0 prod # 导入到生产环境" + echo " $0 dev # 导入到开发环境" +} + +# 主函数 +main() { + case "$1" in + dev|development) + import_database "dev" + ;; + test) + import_database "test" + ;; + production|prod) + import_database "production" + ;; + help|--help|-h) + show_usage + ;; + *) + if [ -z "$1" ]; then + log_error "缺少环境参数" + else + log_error "未知的环境: $1" + fi + show_usage + exit 1 + ;; + esac +} + +# 执行主函数 +main "$@"