Shell脚本实现条件刷库和幂等升级

直接改 SQL 加条件判断太麻烦,用 Shell 脚本先查库判断,满足条件再执行 SQL 更灵活。但原始代码有坑:明文密码、临时文件不清理、不幂等。安全做法是环境变量传密码、加事务、写日志、判断执行结果。

Shell 脚本实现条件刷库和幂等升级

在系统运维和自动化部署中,经常需要条件式地执行数据库操作,同时要保证操作的幂等性(可以安全地重复执行而不会出现异常)。

本文通过实战案例,展示如何使用 Shell 脚本实现这一需求。

什么是幂等升级

幂等升级指的是:无论执行多少次,最终的结果都是相同的。

例如:

  • 第一次执行:版本从 1.0 升级到 2.0(执行所有变更)
  • 第二次执行:检测到已是 2.0,直接跳过升级逻辑
  • 第三次执行:同样检测到已是 2.0,跳过升级

这样即使脚本被意外多次执行,系统状态也不会出现混乱。

基本思路

  1. 检查当前状态 - 查询数据库记录的当前版本或已执行的操作
  2. 条件判断 - 根据状态决定是否需要执行升级
  3. 执行变更 - 如果需要,执行 SQL 更新
  4. 记录状态 - 更新版本号或执行标记

脚本框架

#!/bin/bash

# 配置项
DB_HOST="localhost"
DB_USER="root"
DB_PASS="password"
DB_NAME="myapp"
CURRENT_VERSION="2.0"

# 查询当前版本
LATEST_VERSION=$(mysql -h $DB_HOST -u $DB_USER -p$DB_PASS -D $DB_NAME -N -e "SELECT version FROM migration_version ORDER BY id DESC LIMIT 1;")

# 条件判断
if [ "$LATEST_VERSION" = "$CURRENT_VERSION" ]; then
    echo "已是最新版本 $CURRENT_VERSION,跳过升级"
    exit 0
fi

echo "准备从 $LATEST_VERSION 升级到 $CURRENT_VERSION"

# 执行升级 SQL
mysql -h $DB_HOST -u $DB_USER -p$DB_PASS -D $DB_NAME << EOF
  ALTER TABLE users ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP;
  INSERT INTO migration_version (version, executed_at) VALUES ('$CURRENT_VERSION', NOW());
EOF

if [ $? -eq 0 ]; then
    echo "升级成功"
else
    echo "升级失败"
    exit 1
fi
​

关键技术点

1. 查询条件

使用 mysql 命令行工具的 -N 和 -e 参数实现无格式查询

2. 版本管理表

建议维护一个版本管理表,记录每次升级

3. 错误处理

通过检查 $? 获取上一条命令的退出码

4. 锁机制

防止多个脚本同时执行,使用文件锁

小结

  • 条件刷库的核心是先检查再执行
  • 使用版本管理表记录升级历史
  • 通过幂等设计确保脚本可以安全重复执行
  • 加入错误处理和锁机制提高脚本的健壮性

更多推荐

章节目录