microservices/docker-gitlink/update_db.sh

182 lines
5.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# 获取当前路径
origin_path=$(pwd)
current_env=$1
server_name=$3
# 使用说明,用来提示输入参数
usage() {
echo -e "\e[91m错误必须传入环境参数 \e[0m"
echo "Usage: sh update_db.sh [dev|test|prod] [gen_time_string|exec_update_sql]"
exit 1
}
gen_time_string(){
local TIME_STRING=$(date +'%Y%m%d%H%M%S')
echo "$TIME_STRING"
}
update_sql_config(){
# 进入sql所在目录
cd "${origin_path}"/../sql/update
# 检查是否存在"replace_config"文件夹
if [ -d "replace_config" ]; then
cd ./replace_config
# 获取所有后缀为.replace的文件
REPLACE_FILES=$(find . -type f -name "*.replace")
# 遍历所有.replace文件
for REPLACE_FILE in $REPLACE_FILES; do
# 将.replace文件复制为.sql文件并替换其中的占位符
SQL_FILE=${REPLACE_FILE%.replace}.sql
cp "$REPLACE_FILE" "$SQL_FILE"
sed -i "s|#gateway_url|${gateway_url}|g" "$SQL_FILE"
# 检查.sql文件是否在update文件夹下存在
if [ -f "$SQL_FILE" ]; then
# 如果存在则删除update下该sql文件并将重命名后的.sql文件移动到update文件夹下
rm -f ../"$SQL_FILE"
mv "$SQL_FILE" ../
fi
done
fi
}
exec_update_sql(){
set -e
# 拉取最新代码
git pull
# 替换sql中变量
update_sql_config
cd "${origin_path}"/../sql/update
# 检查MySQL客户端是否已安装
if ! command -v mysql &> /dev/null; then
echo "错误未找到MySQL客户端。请先安装MySQL客户端并确保其在环境变量中可用。"
exit 1
fi
# MySQL连接信息
DB_HOST="${db_host}"
DB_PORT="${mapping_mysql_port}"
DB_USER="${db_username}"
DB_PASS="${db_password}"
DB_NAME="${db_name}"
# 版本表信息
VERSION_TABLE="sys_version"
VERSION_FIELD="current_version"
REMARKS_FIELD="remarks"
# 检查并过滤符合命名规则的SQL文件
validate_sql_file() {
local file="$1"
local filename=$(basename "$file")
local regex='^[0-9]{14}_.*\.sql$'
if [[ ! $filename =~ $regex ]]; then
echo "错误:$filename 不是有效的SQL文件。跳过执行。"
return 1
fi
}
# 获取所有未在版本库中记录的SQL文件名并按照从小到大的顺序排序
UNEXECUTED_SQL_FILES=$(comm -23 <(ls *.sql | sort) <(mysql -N --default-character-set=utf8mb4 -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -e "SELECT $VERSION_FIELD FROM $VERSION_TABLE;" | sort))
# 将未执行的SQL文件名按照日期和版本号的顺序排序
SORTED_SQL_FILES=$(echo "$UNEXECUTED_SQL_FILES" | sort)
# 创建已成功执行的SQL文件列表和未能执行的SQL文件列表
SUCCESSFUL_SQL_FILES=""
FAILED_SQL_FILES=""
# 开始事务
mysql --default-character-set=utf8mb4 -h "$DB_HOST" -P "$DB_PORT" -u "$DB_USER" -p"$DB_PASS" -D "$DB_NAME" -e "START TRANSACTION;"
# 循环执行排序后的未执行SQL文件
for SQL_FILE in $SORTED_SQL_FILES; do
# 检查SQL文件名是否符合规则
if ! validate_sql_file "$SQL_FILE"; then
FAILED_SQL_FILES+="\n$SQL_FILE"
continue
fi
# 提取日期和版本号
FILENAME=$(basename "$SQL_FILE")
DATE=$(echo "$FILENAME" | cut -c 1-14)
VERSION=$(echo "$FILENAME" | cut -c 16- | cut -d'_' -f1)
# 提取注释内容
FIRST_LINE=$(head -n 1 "$SQL_FILE")
REMARKS=$(echo "$FIRST_LINE" | sed 's/^--\s*//')
# 执行SQL文件捕获错误输出
if ! output=$(mysql --default-character-set=utf8mb4 -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME < $SQL_FILE 2>&1); then
# SQL文件执行失败打印错误信息并终止脚本
echo -e "\n错误SQL文件 $SQL_FILE 执行失败。错误原因如下:"
echo "$output"
# 回滚事务
mysql --default-character-set=utf8mb4 -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -e "ROLLBACK;"
exit 1
fi
# SQL文件执行成功将其添加到已成功执行的SQL文件列表中
SUCCESSFUL_SQL_FILES+="\n$SQL_FILE"
# 提取完整的SQL文件名包含时间戳和版本号
FULL_SQL_FILE_NAME=$(basename "$SQL_FILE")
# 在版本表中插入记录包括完整的SQL文件名和备注字段
mysql --default-character-set=utf8mb4 -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -e "INSERT INTO $VERSION_TABLE (execute_time, $VERSION_FIELD, $REMARKS_FIELD) VALUES (NOW(), '$FULL_SQL_FILE_NAME', '$REMARKS');"
done
# 所有SQL执行成功提交事务
mysql --default-character-set=utf8mb4 -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -e "COMMIT;"
# 打印已成功执行的SQL文件列表
if [ -n "$SUCCESSFUL_SQL_FILES" ]; then
echo -e "\n以下SQL文件已成功执行:"
echo -e "$SUCCESSFUL_SQL_FILES"
fi
# 打印未能执行的SQL文件列表
if [ -n "$FAILED_SQL_FILES" ]; then
echo -e "\n以下SQL文件未能执行:"
echo -e "$FAILED_SQL_FILES"
fi
}
case "$current_env" in
"test")
# 获取测试环境配置文件中的安装信息
. ./test_config.profile
;;
"dev")
# 获取测试环境配置文件中的安装信息
. ./dev_config.profile
;;
"prod")
. ./prod_config.profile
;;
*)
usage
;;
esac
# 根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$2" in
"gen_time_string")
gen_time_string
;;
"exec_update_sql")
exec_update_sql
;;
*)
usage
;;
esac