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:
@@ -4,16 +4,46 @@
|
|||||||
|
|
||||||
本文档提供 CCDI 纪检初核系统数据库迁移的详细操作步骤,包括从开发环境导出数据库和导入到生产/测试环境。
|
本文档提供 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 命令)
|
- MySQL 客户端工具(包含 mysqldump 和 mysql 命令)
|
||||||
- Bash shell 环境
|
- Bash shell 环境(Windows 用户可使用 Git Bash)
|
||||||
- 网络访问权限(能连接源数据库和目标数据库)
|
- 网络访问权限(能连接源数据库和目标数据库)
|
||||||
|
|
||||||
### 检查 mysqldump 是否安装
|
### 检查工具是否安装
|
||||||
```bash
|
```bash
|
||||||
mysqldump --version
|
mysqldump --version
|
||||||
|
mysql --version
|
||||||
```
|
```
|
||||||
|
|
||||||
如果未安装,请根据操作系统安装 MySQL 客户端:
|
如果未安装,请根据操作系统安装 MySQL 客户端:
|
||||||
@@ -73,6 +103,10 @@ cat db_config.conf | grep -E "^[A-Z]"
|
|||||||
### 执行导出
|
### 执行导出
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# 方式1: 使用默认命令
|
||||||
|
./export_database.sh
|
||||||
|
|
||||||
|
# 方式2: 显式指定命令
|
||||||
./export_database.sh export
|
./export_database.sh export
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -84,15 +118,16 @@ cat db_config.conf | grep -E "^[A-Z]"
|
|||||||
[INFO] mysqldump 命令检查通过
|
[INFO] mysqldump 命令检查通过
|
||||||
[INFO] 开始导出表结构...
|
[INFO] 开始导出表结构...
|
||||||
[INFO] 表结构导出成功: doc/database/backup/ccdi_structure.sql
|
[INFO] 表结构导出成功: doc/database/backup/ccdi_structure.sql
|
||||||
[INFO] 文件大小: XXX
|
[INFO] 文件大小: 60K
|
||||||
[INFO] 开始导出数据...
|
[INFO] 开始导出数据...
|
||||||
[INFO] 数据导出成功: doc/database/backup/ccdi_data.sql
|
[INFO] 数据导出成功: doc/database/backup/ccdi_data.sql
|
||||||
[INFO] 文件大小: XXX
|
[INFO] 文件大小: 5.7M
|
||||||
[INFO] 验证导出文件...
|
[INFO] 验证导出文件...
|
||||||
[INFO] 导出文件验证通过
|
[INFO] 导出文件验证通过
|
||||||
[INFO] 表结构文件: doc/database/backup/ccdi_structure.sql (XXX)
|
[INFO] 表结构文件: doc/database/backup/ccdi_structure.sql (60K)
|
||||||
[INFO] 数据文件: doc/database/backup/ccdi_data.sql (XXX)
|
[INFO] 数据文件: doc/database/backup/ccdi_data.sql (5.7M)
|
||||||
[INFO] ========== 数据库导出完成 ==========
|
[INFO] ========== 数据库导出完成 ==========
|
||||||
|
[INFO] 使用 ./import_database.sh <env> 导入到目标环境
|
||||||
```
|
```
|
||||||
|
|
||||||
### 验证导出文件
|
### 验证导出文件
|
||||||
@@ -103,8 +138,8 @@ ls -lh doc/database/backup/
|
|||||||
```
|
```
|
||||||
|
|
||||||
应该看到:
|
应该看到:
|
||||||
- `ccdi_structure.sql` - 表结构文件
|
- `ccdi_structure.sql` - 表结构文件(~60KB)
|
||||||
- `ccdi_data.sql` - 数据文件
|
- `ccdi_data.sql` - 数据文件(~5.7MB)
|
||||||
|
|
||||||
**2. 检查字符集声明**
|
**2. 检查字符集声明**
|
||||||
```bash
|
```bash
|
||||||
@@ -119,7 +154,7 @@ SET CHARACTER SET utf8mb4;
|
|||||||
|
|
||||||
**3. 检查文件内容**
|
**3. 检查文件内容**
|
||||||
```bash
|
```bash
|
||||||
# 查看表结构
|
# 查看表数量
|
||||||
grep "CREATE TABLE" doc/database/backup/ccdi_structure.sql | wc -l
|
grep "CREATE TABLE" doc/database/backup/ccdi_structure.sql | wc -l
|
||||||
|
|
||||||
# 查看数据量(INSERT 语句数量)
|
# 查看数据量(INSERT 语句数量)
|
||||||
@@ -153,30 +188,42 @@ CREATE DATABASE ccdi CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
|||||||
### 导入到测试环境
|
### 导入到测试环境
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./export_database.sh import test
|
./import_database.sh test
|
||||||
```
|
```
|
||||||
|
|
||||||
### 导入到生产环境
|
### 导入到生产环境
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./export_database.sh import production
|
./import_database.sh production
|
||||||
```
|
```
|
||||||
|
|
||||||
或简写:
|
或简写:
|
||||||
```bash
|
```bash
|
||||||
./export_database.sh import prod
|
./import_database.sh prod
|
||||||
|
```
|
||||||
|
|
||||||
|
### 导入到开发环境
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./import_database.sh dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### 预期输出
|
### 预期输出
|
||||||
|
|
||||||
```
|
```
|
||||||
[INFO] ========== 开始导入数据库到 test 环境 ==========
|
[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] 导入表结构到 test 环境: XXX:3306/ccdi
|
||||||
[INFO] 表结构导入成功
|
[INFO] 表结构导入成功
|
||||||
[INFO] 导入数据到 test 环境: XXX:3306/ccdi
|
[INFO] 导入数据到 test 环境: XXX:3306/ccdi
|
||||||
[INFO] 数据导入成功
|
[INFO] 数据导入成功
|
||||||
[INFO] 验证导入结果...
|
[INFO] 验证导入结果...
|
||||||
[INFO] 目标数据库表数量: XX
|
[INFO] 目标数据库表数量: 42
|
||||||
[INFO] sys_user 表数据行数: XX
|
[INFO] sys_user 表数据行数: XX
|
||||||
[INFO] 数据库字符集: utf8mb4
|
[INFO] 数据库字符集: utf8mb4
|
||||||
[INFO] ========== 数据库导入完成 ==========
|
[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 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. 导出数据库**
|
**2. 导出数据库**
|
||||||
```bash
|
```bash
|
||||||
./export_database.sh export
|
./export_database.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
**3. 验证导出文件**
|
**3. 验证导出文件**
|
||||||
@@ -269,7 +319,7 @@ head -20 doc/database/backup/ccdi_structure.sql
|
|||||||
|
|
||||||
**4. 先在测试环境验证**
|
**4. 先在测试环境验证**
|
||||||
```bash
|
```bash
|
||||||
./export_database.sh import test
|
./import_database.sh test
|
||||||
```
|
```
|
||||||
|
|
||||||
**5. 验证测试环境**
|
**5. 验证测试环境**
|
||||||
@@ -278,7 +328,7 @@ head -20 doc/database/backup/ccdi_structure.sql
|
|||||||
|
|
||||||
**6. 导入到生产环境**
|
**6. 导入到生产环境**
|
||||||
```bash
|
```bash
|
||||||
./export_database.sh import production
|
./import_database.sh prod
|
||||||
```
|
```
|
||||||
|
|
||||||
**7. 验证生产环境**
|
**7. 验证生产环境**
|
||||||
@@ -352,6 +402,14 @@ cp db_config.conf.template db_config.conf
|
|||||||
- 使用具有足够权限的用户(如 root)
|
- 使用具有足够权限的用户(如 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. **字符集**:
|
4. **字符集**:
|
||||||
- 确保所有步骤都使用 utf8mb4 字符集
|
- 确保所有步骤都使用 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.template`
|
||||||
- 实际配置: `db_config.conf`
|
- 实际配置: `db_config.conf`
|
||||||
- 表结构文件: `doc/database/backup/ccdi_structure.sql`
|
- 表结构文件: `doc/database/backup/ccdi_structure.sql`
|
||||||
- 数据文件: `doc/database/backup/ccdi_data.sql`
|
- 数据文件: `doc/database/backup/ccdi_data.sql`
|
||||||
|
- 排序规则修改脚本: `doc/database/alter_collation_to_general_ci.sql`
|
||||||
- 设计文档: `docs/plans/2026-02-28-database-migration-design.md`
|
- 设计文档: `docs/plans/2026-02-28-database-migration-design.md`
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# CCDI 数据库迁移自动化脚本
|
# CCDI 数据库导出脚本
|
||||||
# 功能:数据库导出和导入自动化
|
# 功能:从开发环境导出数据库到 backup 文件夹
|
||||||
|
|
||||||
set -e # 遇到错误立即退出
|
set -e # 遇到错误立即退出
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ export_structure() {
|
|||||||
--no-data \
|
--no-data \
|
||||||
--skip-triggers \
|
--skip-triggers \
|
||||||
--skip-add-drop-table \
|
--skip-add-drop-table \
|
||||||
--default-character-set=$CHARACTER_SET \
|
--default-character-set=utf8mb4 \
|
||||||
--single-transaction \
|
--single-transaction \
|
||||||
--max_allowed_packet=$MAX_ALLOWED_PACKET \
|
--max_allowed_packet=$MAX_ALLOWED_PACKET \
|
||||||
"$SOURCE_DB_NAME" > "$temp_file" 2>/dev/null
|
"$SOURCE_DB_NAME" > "$temp_file" 2>/dev/null
|
||||||
@@ -88,7 +88,7 @@ export_structure() {
|
|||||||
echo "-- CCDI 数据库表结构"
|
echo "-- CCDI 数据库表结构"
|
||||||
echo "-- 导出时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
echo "-- 导出时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
echo "-- 源数据库: ${SOURCE_DB_HOST}:${SOURCE_DB_PORT}/${SOURCE_DB_NAME}"
|
echo "-- 源数据库: ${SOURCE_DB_HOST}:${SOURCE_DB_PORT}/${SOURCE_DB_NAME}"
|
||||||
echo "-- 字符集: ${CHARACTER_SET}"
|
echo "-- 字符集: utf8mb4"
|
||||||
echo ""
|
echo ""
|
||||||
echo "SET NAMES utf8mb4;"
|
echo "SET NAMES utf8mb4;"
|
||||||
echo "SET CHARACTER SET utf8mb4;"
|
echo "SET CHARACTER SET utf8mb4;"
|
||||||
@@ -125,7 +125,7 @@ export_data() {
|
|||||||
-p"$SOURCE_DB_PASS" \
|
-p"$SOURCE_DB_PASS" \
|
||||||
--no-create-info \
|
--no-create-info \
|
||||||
--skip-triggers \
|
--skip-triggers \
|
||||||
--default-character-set=$CHARACTER_SET \
|
--default-character-set=utf8mb4 \
|
||||||
--single-transaction \
|
--single-transaction \
|
||||||
--complete-insert \
|
--complete-insert \
|
||||||
--extended-insert \
|
--extended-insert \
|
||||||
@@ -138,7 +138,7 @@ export_data() {
|
|||||||
echo "-- CCDI 数据库数据"
|
echo "-- CCDI 数据库数据"
|
||||||
echo "-- 导出时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
echo "-- 导出时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
echo "-- 源数据库: ${SOURCE_DB_HOST}:${SOURCE_DB_PORT}/${SOURCE_DB_NAME}"
|
echo "-- 源数据库: ${SOURCE_DB_HOST}:${SOURCE_DB_PORT}/${SOURCE_DB_NAME}"
|
||||||
echo "-- 字符集: ${CHARACTER_SET}"
|
echo "-- 字符集: utf8mb4"
|
||||||
echo ""
|
echo ""
|
||||||
echo "SET NAMES utf8mb4;"
|
echo "SET NAMES utf8mb4;"
|
||||||
echo "SET CHARACTER SET utf8mb4;"
|
echo "SET CHARACTER SET utf8mb4;"
|
||||||
@@ -196,189 +196,6 @@ verify_export() {
|
|||||||
log_info "数据文件: $data_file ($(du -h "$data_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"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
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() {
|
export_database() {
|
||||||
log_info "========== 开始导出数据库 =========="
|
log_info "========== 开始导出数据库 =========="
|
||||||
@@ -391,36 +208,41 @@ export_database() {
|
|||||||
verify_export
|
verify_export
|
||||||
|
|
||||||
log_info "========== 数据库导出完成 =========="
|
log_info "========== 数据库导出完成 =========="
|
||||||
|
log_info "使用 ./import_database.sh <env> 导入到目标环境"
|
||||||
}
|
}
|
||||||
|
|
||||||
# 使用帮助
|
# 使用帮助
|
||||||
show_usage() {
|
show_usage() {
|
||||||
echo "用法: $0 <command> [options]"
|
echo "用法: $0 [command]"
|
||||||
echo ""
|
echo ""
|
||||||
echo "命令:"
|
echo "命令:"
|
||||||
echo " export 导出数据库"
|
echo " export 导出数据库(默认命令)"
|
||||||
echo " import <env> 导入数据库到指定环境"
|
|
||||||
echo " help 显示帮助信息"
|
echo " help 显示帮助信息"
|
||||||
echo ""
|
echo ""
|
||||||
echo "环境:"
|
echo "说明:"
|
||||||
echo " production, prod 生产环境"
|
echo " 此脚本从开发环境导出数据库到 doc/database/backup/ 文件夹"
|
||||||
echo " test 测试环境"
|
echo " 生成文件:"
|
||||||
|
echo " - ccdi_structure.sql (表结构)"
|
||||||
|
echo " - ccdi_data.sql (数据)"
|
||||||
|
echo ""
|
||||||
|
echo "前置条件:"
|
||||||
|
echo " 1. 已配置 db_config.conf 文件"
|
||||||
|
echo " 2. 已安装 MySQL 客户端工具(mysqldump)"
|
||||||
echo ""
|
echo ""
|
||||||
echo "示例:"
|
echo "示例:"
|
||||||
echo " $0 export # 导出数据库到 doc/database/backup/ 目录"
|
echo " $0 # 导出数据库(默认)"
|
||||||
echo " $0 import test # 导入数据库到测试环境"
|
echo " $0 export # 导出数据库"
|
||||||
echo " $0 import prod # 导入数据库到生产环境"
|
echo ""
|
||||||
|
echo "后续操作:"
|
||||||
|
echo " 使用 ./import_database.sh <env> 导入到目标环境"
|
||||||
}
|
}
|
||||||
|
|
||||||
# 主函数
|
# 主函数
|
||||||
main() {
|
main() {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
export)
|
export|"")
|
||||||
export_database
|
export_database
|
||||||
;;
|
;;
|
||||||
import)
|
|
||||||
import_database "$2"
|
|
||||||
;;
|
|
||||||
help|--help|-h)
|
help|--help|-h)
|
||||||
show_usage
|
show_usage
|
||||||
;;
|
;;
|
||||||
|
|||||||
329
import_database.sh
Normal file
329
import_database.sh
Normal file
@@ -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 <env>"
|
||||||
|
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 <environment>"
|
||||||
|
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 "$@"
|
||||||
Reference in New Issue
Block a user