642 lines
19 KiB
Bash
Executable File
642 lines
19 KiB
Bash
Executable File
#!/bin/bash
|
||
# ============================================
|
||
# LJWX 数据库迁移管理脚本
|
||
# ============================================
|
||
# 功能:
|
||
# - 导出宿主数据库作为基线
|
||
# - 应用版本化迁移脚本
|
||
# - 迁移历史跟踪
|
||
# - 支持回滚
|
||
# ============================================
|
||
|
||
set -e
|
||
|
||
# 加载配置
|
||
if [ -f .env ]; then
|
||
source .env
|
||
else
|
||
echo "❌ 错误: .env 文件不存在"
|
||
echo "💡 请先复制: cp .env.unified .env"
|
||
exit 1
|
||
fi
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# 配置
|
||
MIGRATION_DIR="${DB_MIGRATION_DIR:-./docker/mysql/migrations}"
|
||
BACKUP_DIR="./backups/mysql"
|
||
CONTAINER_NAME="ljwx-mysql"
|
||
|
||
# 创建必要目录
|
||
mkdir -p "$MIGRATION_DIR/rollback"
|
||
mkdir -p "$BACKUP_DIR"
|
||
|
||
# ============================================
|
||
# 工具函数
|
||
# ============================================
|
||
|
||
print_header() {
|
||
echo -e "\n${BLUE}========================================${NC}"
|
||
echo -e "${BLUE}$1${NC}"
|
||
echo -e "${BLUE}========================================${NC}\n"
|
||
}
|
||
|
||
print_success() {
|
||
echo -e "${GREEN}✅ $1${NC}"
|
||
}
|
||
|
||
print_error() {
|
||
echo -e "${RED}❌ $1${NC}"
|
||
}
|
||
|
||
print_warning() {
|
||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||
}
|
||
|
||
print_info() {
|
||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||
}
|
||
|
||
# 检查MySQL连接(宿主机)
|
||
check_host_mysql() {
|
||
if mysql -h ${HOST_MYSQL_HOST} -P ${HOST_MYSQL_PORT} -u${HOST_MYSQL_USER} -p${HOST_MYSQL_PASSWORD} -e "SELECT 1" >/dev/null 2>&1; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# 检查MySQL连接(容器)
|
||
check_container_mysql() {
|
||
if docker exec $CONTAINER_NAME mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} ${MYSQL_DATABASE} -e "SELECT 1" >/dev/null 2>&1; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# 创建迁移历史表
|
||
create_migration_table() {
|
||
local target=$1 # host 或 container
|
||
|
||
local sql="CREATE TABLE IF NOT EXISTS \`schema_migrations\` (
|
||
\`version\` VARCHAR(50) NOT NULL PRIMARY KEY,
|
||
\`description\` VARCHAR(255),
|
||
\`type\` VARCHAR(20) DEFAULT 'migration',
|
||
\`script\` VARCHAR(255),
|
||
\`checksum\` VARCHAR(64),
|
||
\`installed_by\` VARCHAR(100) DEFAULT 'db-migrate.sh',
|
||
\`installed_on\` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
\`execution_time\` INT,
|
||
\`success\` BOOLEAN DEFAULT TRUE,
|
||
INDEX idx_installed_on (installed_on),
|
||
INDEX idx_success (success)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据库迁移历史记录';"
|
||
|
||
if [ "$target" = "host" ]; then
|
||
mysql -h ${HOST_MYSQL_HOST} -P ${HOST_MYSQL_PORT} \
|
||
-u${HOST_MYSQL_USER} -p${HOST_MYSQL_PASSWORD} \
|
||
${HOST_MYSQL_DATABASE} -e "$sql" 2>/dev/null
|
||
else
|
||
docker exec $CONTAINER_NAME mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
|
||
${MYSQL_DATABASE} -e "$sql" 2>/dev/null
|
||
fi
|
||
}
|
||
|
||
# 获取已应用的迁移版本
|
||
get_applied_migrations() {
|
||
local target=$1
|
||
|
||
if [ "$target" = "host" ]; then
|
||
mysql -h ${HOST_MYSQL_HOST} -P ${HOST_MYSQL_PORT} \
|
||
-u${HOST_MYSQL_USER} -p${HOST_MYSQL_PASSWORD} \
|
||
${HOST_MYSQL_DATABASE} \
|
||
-Nse "SELECT version FROM schema_migrations WHERE success = TRUE ORDER BY version" 2>/dev/null || echo ""
|
||
else
|
||
docker exec $CONTAINER_NAME mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
|
||
${MYSQL_DATABASE} \
|
||
-Nse "SELECT version FROM schema_migrations WHERE success = TRUE ORDER BY version" 2>/dev/null || echo ""
|
||
fi
|
||
}
|
||
|
||
# 计算文件MD5
|
||
calc_checksum() {
|
||
local file=$1
|
||
if [ "$(uname)" = "Darwin" ]; then
|
||
md5 -q "$file"
|
||
else
|
||
md5sum "$file" | awk '{print $1}'
|
||
fi
|
||
}
|
||
|
||
# ============================================
|
||
# 主要功能
|
||
# ============================================
|
||
|
||
# 导出宿主数据库作为基线
|
||
export_baseline() {
|
||
print_header "导出宿主数据库作为基线"
|
||
|
||
if ! check_host_mysql; then
|
||
print_error "无法连接到宿主数据库"
|
||
exit 1
|
||
fi
|
||
|
||
local version=${1:-${LJWX_VERSION}}
|
||
local timestamp=$(date +%Y%m%d_%H%M%S)
|
||
local baseline_file="${MIGRATION_DIR}/V${version}__baseline.sql"
|
||
local backup_file="${BACKUP_DIR}/baseline_${version}_${timestamp}.sql"
|
||
|
||
print_info "正在导出数据库: ${HOST_MYSQL_DATABASE}"
|
||
print_info "目标版本: V${version}"
|
||
|
||
# 导出完整数据库
|
||
mysqldump -h ${HOST_MYSQL_HOST} -P ${HOST_MYSQL_PORT} \
|
||
-u${HOST_MYSQL_USER} -p${HOST_MYSQL_PASSWORD} \
|
||
--single-transaction \
|
||
--quick \
|
||
--lock-tables=false \
|
||
--routines \
|
||
--triggers \
|
||
--events \
|
||
--complete-insert \
|
||
--add-drop-table \
|
||
--databases ${HOST_MYSQL_DATABASE} \
|
||
2>/dev/null > "$baseline_file"
|
||
|
||
# 备份一份
|
||
cp "$baseline_file" "$backup_file"
|
||
|
||
# 添加文件头
|
||
local header="-- ============================================
|
||
-- 迁移版本: V${version}
|
||
-- 创建时间: $(date +'%Y-%m-%d %H:%M:%S')
|
||
-- 描述: 数据库基线 - 从宿主机导出
|
||
-- 数据库: ${HOST_MYSQL_DATABASE}
|
||
-- 表数量: $(mysql -h ${HOST_MYSQL_HOST} -P ${HOST_MYSQL_PORT} -u${HOST_MYSQL_USER} -p${HOST_MYSQL_PASSWORD} ${HOST_MYSQL_DATABASE} -Nse "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${HOST_MYSQL_DATABASE}'" 2>/dev/null)
|
||
-- ============================================
|
||
|
||
"
|
||
echo "$header" | cat - "$baseline_file" > temp && mv temp "$baseline_file"
|
||
|
||
local file_size=$(du -h "$baseline_file" | awk '{print $1}')
|
||
|
||
print_success "基线导出完成"
|
||
print_info "基线文件: $baseline_file ($file_size)"
|
||
print_info "备份文件: $backup_file"
|
||
|
||
# 更新data.sql(用于Docker镜像构建)
|
||
cp "$baseline_file" "./docker/mysql/data.sql"
|
||
print_success "已更新 docker/mysql/data.sql"
|
||
}
|
||
|
||
# 创建新的迁移脚本模板
|
||
create_migration() {
|
||
local version=${1:-${LJWX_VERSION}}
|
||
local description=$2
|
||
|
||
if [ -z "$description" ]; then
|
||
print_error "请提供迁移描述"
|
||
echo "用法: $0 create <版本号> <描述>"
|
||
echo "示例: $0 create 2.0.4 add_health_features"
|
||
exit 1
|
||
fi
|
||
|
||
print_header "创建迁移脚本"
|
||
|
||
local migration_file="${MIGRATION_DIR}/V${version}__${description}.sql"
|
||
local rollback_file="${MIGRATION_DIR}/rollback/R${version}__rollback.sql"
|
||
|
||
if [ -f "$migration_file" ]; then
|
||
print_error "迁移文件已存在: $migration_file"
|
||
exit 1
|
||
fi
|
||
|
||
# 创建迁移脚本模板
|
||
cat > "$migration_file" <<EOF
|
||
-- ============================================
|
||
-- 迁移版本: V${version}
|
||
-- 创建时间: $(date +'%Y-%m-%d %H:%M:%S')
|
||
-- 描述: ${description}
|
||
-- 依赖版本: (请填写依赖的前一个版本)
|
||
-- ============================================
|
||
|
||
-- 开始事务
|
||
START TRANSACTION;
|
||
|
||
-- ============================================
|
||
-- 在这里编写迁移SQL
|
||
-- ============================================
|
||
|
||
-- 示例1: 创建新表
|
||
CREATE TABLE IF NOT EXISTS \`t_example_new_table\` (
|
||
\`id\` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||
\`name\` varchar(100) NOT NULL COMMENT '名称',
|
||
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
PRIMARY KEY (\`id\`),
|
||
KEY \`idx_name\` (\`name\`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='示例新表';
|
||
|
||
-- 示例2: 添加字段(幂等性)
|
||
SET @col_exists = 0;
|
||
SELECT COUNT(*) INTO @col_exists
|
||
FROM information_schema.columns
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = 't_user'
|
||
AND column_name = 'new_field';
|
||
|
||
SET @sql = IF(@col_exists = 0,
|
||
'ALTER TABLE t_user ADD COLUMN new_field VARCHAR(100) COMMENT ''新字段''',
|
||
'SELECT ''Column new_field already exists'' AS message');
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
-- 示例3: 创建索引(幂等性)
|
||
SET @index_exists = 0;
|
||
SELECT COUNT(*) INTO @index_exists
|
||
FROM information_schema.statistics
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = 't_user'
|
||
AND index_name = 'idx_new_field';
|
||
|
||
SET @sql = IF(@index_exists = 0,
|
||
'ALTER TABLE t_user ADD INDEX idx_new_field (new_field)',
|
||
'SELECT ''Index idx_new_field already exists'' AS message');
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
-- ============================================
|
||
-- 验证迁移结果
|
||
-- ============================================
|
||
-- 在这里添加验证SQL,确保迁移正确执行
|
||
|
||
-- 提交事务
|
||
COMMIT;
|
||
|
||
-- 记录迁移成功
|
||
-- (此记录由迁移系统自动添加)
|
||
EOF
|
||
|
||
# 创建回滚脚本模板
|
||
cat > "$rollback_file" <<EOF
|
||
-- ============================================
|
||
-- 回滚版本: R${version}
|
||
-- 创建时间: $(date +'%Y-%m-%d %H:%M:%S')
|
||
-- 描述: 回滚 ${description}
|
||
-- 目标版本: (请填写回滚后的版本)
|
||
-- ============================================
|
||
|
||
-- 开始事务
|
||
START TRANSACTION;
|
||
|
||
-- ============================================
|
||
-- 在这里编写回滚SQL(与迁移脚本相反的操作)
|
||
-- ============================================
|
||
|
||
-- 示例: 删除添加的表
|
||
DROP TABLE IF EXISTS \`t_example_new_table\`;
|
||
|
||
-- 示例: 删除添加的字段
|
||
ALTER TABLE t_user DROP COLUMN IF EXISTS new_field;
|
||
|
||
-- 示例: 删除添加的索引
|
||
ALTER TABLE t_user DROP INDEX IF EXISTS idx_new_field;
|
||
|
||
-- ============================================
|
||
-- 验证回滚结果
|
||
-- ============================================
|
||
|
||
-- 提交事务
|
||
COMMIT;
|
||
|
||
-- 删除迁移记录
|
||
DELETE FROM schema_migrations WHERE version = '${version}';
|
||
EOF
|
||
|
||
print_success "迁移脚本已创建: $migration_file"
|
||
print_success "回滚脚本已创建: $rollback_file"
|
||
print_info "请编辑脚本文件,完成实际的迁移SQL"
|
||
}
|
||
|
||
# 应用迁移
|
||
apply_migration() {
|
||
local version=$1
|
||
local force=${2:-false}
|
||
|
||
if [ -z "$version" ]; then
|
||
print_error "请指定要应用的版本"
|
||
echo "用法: $0 apply <版本号> [--force]"
|
||
exit 1
|
||
fi
|
||
|
||
print_header "应用迁移: V${version}"
|
||
|
||
# 查找迁移文件
|
||
local migration_file=$(find "$MIGRATION_DIR" -maxdepth 1 -name "V${version}__*.sql" | head -1)
|
||
|
||
if [ -z "$migration_file" ]; then
|
||
print_error "找不到迁移文件: V${version}__*.sql"
|
||
exit 1
|
||
fi
|
||
|
||
print_info "迁移文件: $migration_file"
|
||
|
||
# 检查容器是否运行
|
||
if ! docker ps | grep -q $CONTAINER_NAME; then
|
||
print_error "MySQL容器未运行: $CONTAINER_NAME"
|
||
print_info "请先启动容器: docker-compose -f docker-compose.prod.yml up -d ljwx-mysql"
|
||
exit 1
|
||
fi
|
||
|
||
# 创建迁移历史表
|
||
create_migration_table "container"
|
||
|
||
# 检查是否已应用
|
||
local applied=$(docker exec $CONTAINER_NAME mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
|
||
${MYSQL_DATABASE} -Nse \
|
||
"SELECT COUNT(*) FROM schema_migrations WHERE version='${version}' AND success=TRUE" 2>/dev/null || echo "0")
|
||
|
||
if [ "$applied" -gt 0 ] && [ "$force" != "--force" ]; then
|
||
print_warning "迁移 V${version} 已经应用过"
|
||
print_info "如需重新应用,使用: $0 apply ${version} --force"
|
||
return 0
|
||
fi
|
||
|
||
# 备份当前数据库
|
||
local backup_file="${BACKUP_DIR}/before_${version}_$(date +%Y%m%d_%H%M%S).sql"
|
||
print_info "备份当前数据库..."
|
||
docker exec $CONTAINER_NAME mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
|
||
--single-transaction --routines --triggers --events \
|
||
${MYSQL_DATABASE} > "$backup_file" 2>/dev/null
|
||
print_success "备份完成: $backup_file"
|
||
|
||
# 应用迁移
|
||
print_info "应用迁移..."
|
||
local start_time=$(date +%s)
|
||
|
||
if docker exec -i $CONTAINER_NAME mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
|
||
${MYSQL_DATABASE} < "$migration_file" 2>&1 | tee /tmp/migration.log; then
|
||
local end_time=$(date +%s)
|
||
local execution_time=$((end_time - start_time))
|
||
|
||
# 记录迁移历史
|
||
local checksum=$(calc_checksum "$migration_file")
|
||
local script_name=$(basename "$migration_file")
|
||
local description=$(echo "$script_name" | sed 's/V[0-9.]*__//g' | sed 's/.sql//g')
|
||
|
||
docker exec $CONTAINER_NAME mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
|
||
${MYSQL_DATABASE} -e "INSERT INTO schema_migrations
|
||
(version, description, script, checksum, execution_time, success)
|
||
VALUES ('${version}', '${description}', '${script_name}', '${checksum}', ${execution_time}, TRUE)
|
||
ON DUPLICATE KEY UPDATE
|
||
execution_time = ${execution_time},
|
||
success = TRUE,
|
||
installed_on = CURRENT_TIMESTAMP" 2>/dev/null
|
||
|
||
print_success "迁移应用成功 (耗时: ${execution_time}秒)"
|
||
else
|
||
print_error "迁移应用失败"
|
||
print_info "错误日志: /tmp/migration.log"
|
||
print_info "备份文件: $backup_file"
|
||
print_warning "建议回滚到备份"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# 应用所有待执行迁移
|
||
apply_all() {
|
||
print_header "应用所有待执行迁移"
|
||
|
||
# 创建迁移历史表
|
||
create_migration_table "container"
|
||
|
||
# 获取已应用的版本
|
||
local applied_versions=$(get_applied_migrations "container")
|
||
|
||
# 获取所有迁移文件(按版本排序)
|
||
local migration_files=$(find "$MIGRATION_DIR" -maxdepth 1 -name "V*.sql" -type f | sort -V)
|
||
|
||
local pending_count=0
|
||
local applied_count=0
|
||
|
||
for file in $migration_files; do
|
||
local filename=$(basename "$file")
|
||
local version=$(echo "$filename" | sed 's/V\([0-9.]*\)__.*/\1/')
|
||
|
||
if echo "$applied_versions" | grep -q "^${version}$"; then
|
||
print_info "跳过已应用: V${version}"
|
||
((applied_count++))
|
||
else
|
||
print_info "待应用: V${version}"
|
||
apply_migration "$version"
|
||
((pending_count++))
|
||
fi
|
||
done
|
||
|
||
print_success "迁移应用完成"
|
||
print_info "已应用: ${applied_count} 个"
|
||
print_info "新应用: ${pending_count} 个"
|
||
}
|
||
|
||
# 查看迁移状态
|
||
show_status() {
|
||
print_header "迁移状态"
|
||
|
||
if ! docker ps | grep -q $CONTAINER_NAME; then
|
||
print_warning "MySQL容器未运行"
|
||
|
||
# 显示可用的迁移文件
|
||
print_info "可用的迁移脚本:"
|
||
find "$MIGRATION_DIR" -maxdepth 1 -name "V*.sql" -type f | sort -V | while read file; do
|
||
local filename=$(basename "$file")
|
||
local version=$(echo "$filename" | sed 's/V\([0-9.]*\)__.*/\1/')
|
||
local size=$(du -h "$file" | awk '{print $1}')
|
||
echo " - V${version} ($size)"
|
||
done
|
||
return 0
|
||
fi
|
||
|
||
# 创建迁移历史表
|
||
create_migration_table "container"
|
||
|
||
# 获取已应用的迁移
|
||
print_info "已应用的迁移:"
|
||
docker exec $CONTAINER_NAME mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
|
||
${MYSQL_DATABASE} -e \
|
||
"SELECT version, description, installed_on, execution_time, success
|
||
FROM schema_migrations
|
||
ORDER BY installed_on DESC
|
||
LIMIT 10" 2>/dev/null
|
||
|
||
echo ""
|
||
|
||
# 待应用的迁移
|
||
local applied_versions=$(get_applied_migrations "container")
|
||
print_info "待应用的迁移:"
|
||
|
||
local has_pending=false
|
||
find "$MIGRATION_DIR" -maxdepth 1 -name "V*.sql" -type f | sort -V | while read file; do
|
||
local filename=$(basename "$file")
|
||
local version=$(echo "$filename" | sed 's/V\([0-9.]*\)__.*/\1/')
|
||
|
||
if ! echo "$applied_versions" | grep -q "^${version}$"; then
|
||
echo " - V${version}"
|
||
has_pending=true
|
||
fi
|
||
done
|
||
|
||
if [ "$has_pending" != "true" ]; then
|
||
echo " (无待应用迁移)"
|
||
fi
|
||
}
|
||
|
||
# 回滚迁移
|
||
rollback_migration() {
|
||
local version=$1
|
||
|
||
if [ -z "$version" ]; then
|
||
print_error "请指定要回滚的版本"
|
||
echo "用法: $0 rollback <版本号>"
|
||
exit 1
|
||
fi
|
||
|
||
print_header "回滚迁移: V${version}"
|
||
|
||
# 查找回滚文件
|
||
local rollback_file="${MIGRATION_DIR}/rollback/R${version}__rollback.sql"
|
||
|
||
if [ ! -f "$rollback_file" ]; then
|
||
print_error "找不到回滚文件: $rollback_file"
|
||
exit 1
|
||
fi
|
||
|
||
print_warning "警告: 即将回滚迁移 V${version}"
|
||
print_info "回滚文件: $rollback_file"
|
||
read -p "确认继续? (yes/no): " confirm
|
||
|
||
if [ "$confirm" != "yes" ]; then
|
||
print_info "已取消回滚操作"
|
||
exit 0
|
||
fi
|
||
|
||
# 备份
|
||
local backup_file="${BACKUP_DIR}/before_rollback_${version}_$(date +%Y%m%d_%H%M%S).sql"
|
||
print_info "备份当前数据库..."
|
||
docker exec $CONTAINER_NAME mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
|
||
--single-transaction --routines --triggers --events \
|
||
${MYSQL_DATABASE} > "$backup_file" 2>/dev/null
|
||
print_success "备份完成: $backup_file"
|
||
|
||
# 执行回滚
|
||
print_info "执行回滚..."
|
||
if docker exec -i $CONTAINER_NAME mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
|
||
${MYSQL_DATABASE} < "$rollback_file" 2>&1; then
|
||
print_success "回滚成功"
|
||
else
|
||
print_error "回滚失败"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# ============================================
|
||
# 主程序
|
||
# ============================================
|
||
|
||
show_help() {
|
||
cat <<EOF
|
||
LJWX 数据库迁移管理工具
|
||
|
||
用法:
|
||
$0 <命令> [参数]
|
||
|
||
命令:
|
||
|
||
export [版本号] 导出宿主数据库作为基线
|
||
版本号默认为 .env 中的 LJWX_VERSION
|
||
示例: $0 export 2.0.3
|
||
|
||
create <版本号> <描述> 创建新的迁移脚本模板
|
||
示例: $0 create 2.0.4 add_health_features
|
||
|
||
apply <版本号> [--force] 应用指定版本的迁移
|
||
--force 强制重新应用
|
||
示例: $0 apply 2.0.3
|
||
|
||
apply-all 应用所有待执行的迁移
|
||
示例: $0 apply-all
|
||
|
||
status 查看迁移状态
|
||
示例: $0 status
|
||
|
||
rollback <版本号> 回滚到指定版本
|
||
示例: $0 rollback 2.0.2
|
||
|
||
help 显示此帮助信息
|
||
|
||
配置:
|
||
配置文件: .env
|
||
迁移目录: ${MIGRATION_DIR}
|
||
备份目录: ${BACKUP_DIR}
|
||
|
||
示例工作流:
|
||
|
||
1. 导出当前宿主数据库作为基线
|
||
$ $0 export 2.0.3
|
||
|
||
2. 创建新的迁移脚本
|
||
$ $0 create 2.0.4 add_new_features
|
||
|
||
3. 编辑迁移脚本(手动)
|
||
$ vim ${MIGRATION_DIR}/V2.0.4__add_new_features.sql
|
||
|
||
4. 测试应用迁移
|
||
$ $0 apply 2.0.4
|
||
|
||
5. 查看迁移状态
|
||
$ $0 status
|
||
|
||
6. 如有问题,执行回滚
|
||
$ $0 rollback 2.0.4
|
||
|
||
更多信息请查看: ${MIGRATION_DIR}/README.md
|
||
|
||
EOF
|
||
}
|
||
|
||
# 主命令分发
|
||
case "${1:-help}" in
|
||
export)
|
||
export_baseline "$2"
|
||
;;
|
||
create)
|
||
create_migration "$2" "$3"
|
||
;;
|
||
apply)
|
||
apply_migration "$2" "$3"
|
||
;;
|
||
apply-all)
|
||
apply_all
|
||
;;
|
||
status)
|
||
show_status
|
||
;;
|
||
rollback)
|
||
rollback_migration "$2"
|
||
;;
|
||
help|--help|-h)
|
||
show_help
|
||
;;
|
||
*)
|
||
print_error "未知命令: $1"
|
||
show_help
|
||
exit 1
|
||
;;
|
||
esac
|