refactor: 分离数据库导出和导入脚本,优化文件结构

改进内容:
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 <dev|test|prod>
This commit is contained in:
wkc
2026-02-28 15:18:01 +08:00
parent 4d4076227f
commit 79f00f30d8
3 changed files with 432 additions and 220 deletions

View File

@@ -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 <env> 导入到目标环境"
}
# 使用帮助
show_usage() {
echo "用法: $0 <command> [options]"
echo "用法: $0 [command]"
echo ""
echo "命令:"
echo " export 导出数据库"
echo " import <env> 导入数据库到指定环境"
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 <env> 导入到目标环境"
}
# 主函数
main() {
case "$1" in
export)
export|"")
export_database
;;
import)
import_database "$2"
;;
help|--help|-h)
show_usage
;;