182 lines
5.4 KiB
Bash
Executable File
182 lines
5.4 KiB
Bash
Executable File
#!/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 |