批量执行 SQL 脚本的 Shell 脚本及注意事项

批量执行 SQL 脚本的 Shell 脚本及注意事项

脚本示例

bash 复制代码
#!/bin/bash

# 配置数据库和用户信息
DATABASES=("Database1" "Database2" "Database3" "Database4" "Database5")
USERS=("user1" "user2" "user3" "user4" "user5" "user6")
PASSWORD="your_password" # 假设所有用户使用同一个密码
SQL_SCRIPT="upgrade_script.sql" # SQL 脚本路径

# 数据库执行函数
execute_sql() {
    local db=$1
    local user=$2
    local sql=$3
    echo "Executing script on database: $db, user: $user..."
    mysql -h localhost -u "$user" -p"$PASSWORD" "$db" < "$sql"
    if [[ $? -ne 0 ]]; then
        echo "Error: Execution failed on $db for user $user" >&2
        return 1
    fi
    echo "Success: Executed script on $db for user $user"
}

# 主循环:对每个数据库和用户执行 SQL
for db in "${DATABASES[@]}"; do
    for user in "${USERS[@]}"; do
        execute_sql "$db" "$user" "$SQL_SCRIPT"
    done
done

echo "All scripts executed successfully!"

工作流程

  1. 配置部分

    • DATABASES 列出所有目标数据库。
    • USERS 列出所有需要执行 SQL 脚本的用户。
    • PASSWORD 是用户的统一密码,脚本使用 -p 参数传递密码。
    • SQL_SCRIPT 是 SQL 脚本的文件路径。
  2. 函数定义

    • execute_sql 函数通过 mysql 命令连接数据库并执行脚本。
    • 检查命令返回值 $?,如有错误会输出失败信息到标准错误。
  3. 主循环

    • 外层循环遍历每个数据库。
    • 内层循环遍历每个用户。
    • 对每个 数据库-用户 执行 execute_sql 函数。
  4. 日志记录

    • 在执行脚本时打印执行进度。
    • 成功和失败的信息分别输出到标准输出和标准错误。

注意事项

  1. SQL 脚本的幂等性

    • 确保 SQL 脚本是幂等的(多次执行不会产生重复影响)。
    • 如果需要,可以在 SQL 脚本中添加 IF NOT EXISTS 等判断条件。
  2. 数据库和用户权限

    • 确保所有用户对目标数据库有执行权限,否则会出现权限错误。
  3. MySQL 密码管理

    • 脚本中密码明文存储可能存在安全风险,可以改用 .my.cnf 文件来管理凭据:

      plaintext 复制代码
      [client]
      user=user1
      password=your_password

      然后调用时简化为:

      bash 复制代码
      mysql Database1 < upgrade_script.sql
  4. 脚本执行路径

    • 确保脚本执行时,SQL_SCRIPT 文件路径正确。如果脚本运行在不同目录,建议使用绝对路径。
  5. 执行错误处理

    • 如果一个数据库或用户执行失败,建议脚本继续运行,记录失败的数据库和用户,以便后续重试。
  6. 多线程优化(可选)

    • 如果数据库和服务器性能允许,可以使用 & 并发执行以提高效率:

      bash 复制代码
      for db in "${DATABASES[@]}"; do
          for user in "${USERS[@]}"; do
              execute_sql "$db" "$user" "$SQL_SCRIPT" &
          done
      done
      wait

可能遇到的问题

  1. 脚本执行失败

    • 原因:脚本内容不正确、数据库用户无权限、网络问题等。
    • 解决:查看失败日志,修正 SQL 脚本或用户权限。
  2. MySQL 执行超时

    • 如果脚本非常大或查询耗时长,可能会出现超时问题。
    • 解决:在 MySQL 中调整 max_allowed_packetwait_timeout 参数。
  3. 密码泄露风险

    • 密码明文存储在脚本中存在安全隐患。
    • 建议改用 .my.cnf 或环境变量存储密码。
  4. 并发执行的冲突

    • 并发运行可能导致锁表或资源竞争。
    • 解决:控制并发数量,或按顺序逐一执行。

为所有用户授予数据库执行权限的操作指南

步骤 1:明确权限需求

  • 确认需要授予的权限类型。对于执行 SQL 脚本的需求,通常需要 EXECUTE 或其他相关权限(如 SELECT, UPDATE, INSERT, DELETE)。
  • 确认哪些用户需要权限。

步骤 2:SQL 语法示例

假设目标数据库名为 target_db,需要为 5 个数据库中的每个数据库的 6 个用户授予权限,以下是通用的 GRANT 语法:

sql 复制代码
USE target_db;

-- 示例:为用户 user1 授予 EXECUTE 权限
GRANT EXECUTE ON DATABASE target_db TO user1;

-- 示例:如果还需要 SELECT、INSERT 权限:
GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE target_db TO user1;

步骤 3:为所有用户批量授予权限

假设有多个用户和多个数据库,可以用脚本循环处理,以下是手动 SQL 示例:

sql 复制代码
-- 在目标数据库下为每个用户循环授予权限
USE target_db;

GRANT EXECUTE ON DATABASE target_db TO user1;
GRANT EXECUTE ON DATABASE target_db TO user2;
GRANT EXECUTE ON DATABASE target_db TO user3;
GRANT EXECUTE ON DATABASE target_db TO user4;
GRANT EXECUTE ON DATABASE target_db TO user5;
GRANT EXECUTE ON DATABASE target_db TO user6;

步骤 4:使用 Shell 脚本批量执行 GRANT

脚本内容

假设我们使用 mysql 客户端登录来批量执行这些 SQL 授权操作:

bash 复制代码
#!/bin/bash

# 数据库配置
HOST="localhost"
USER="root"
PASSWORD="your_password"

# 数据库和用户列表
DATABASES=("db1" "db2" "db3" "db4" "db5")
USERS=("user1" "user2" "user3" "user4" "user5" "user6")

# 授权脚本
for DB in "${DATABASES[@]}"; do
    for USER in "${USERS[@]}"; do
        echo "Granting EXECUTE privilege on $DB to $USER..."
        mysql -h "$HOST" -u "$USER" -p"$PASSWORD" -e "GRANT EXECUTE ON $DB.* TO '$USER';"
    done
done

echo "All privileges granted!"

注意事项

  1. 权限验证:

    • 确保目标用户在数据库中已经存在。如果用户不存在,需要先通过 CREATE USER 创建用户。
    sql 复制代码
    CREATE USER 'user1'@'localhost' IDENTIFIED BY 'password';
  2. FLUSH PRIVILEGES

    • 有些数据库需要在权限更新后运行 FLUSH PRIVILEGES 来刷新权限表。
    sql 复制代码
    FLUSH PRIVILEGES;
  3. 权限范围:

    • 如果只需要对特定表授予权限,可以用 GRANT EXECUTE ON db_name.table_name
  4. 错误处理:

    • 如果脚本中出现 Access Denied 错误,可能是当前执行脚本的用户权限不足。请确保脚本运行用户拥有足够权限(如 GRANT OPTION 权限)。
  5. 重复授权:

    • MySQL 和其他数据库通常不会因为重复执行 GRANT 而出错,因此可以放心批量执行脚本。

常见问题

  1. 用户不存在错误:

    • 需要确保所有用户已被创建。如果需要自动创建用户,可以扩展 Shell 脚本,添加 CREATE USER
  2. 权限不足:

    • 确保运行脚本的用户(如 root)具有 GRANT OPTION 权限。
  3. 多数据库环境:

    • 如果存在多个数据库,确保用户被授予所有需要的数据库权限。

相关推荐
鹏说大数据21 分钟前
MySQL连接较慢原因分析及解决措施
数据库·mysql
极限实验室2 小时前
使用 INFINI Gateway 保护 Elasticsearch 集群之修改查询不合理参数(二)
数据库
竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生。2 小时前
etcd客户化工具
数据库·etcd
谷晓光2 小时前
python中print函数的flush如何使用
linux·服务器·数据库
OceanBase数据库官方博客2 小时前
自然语言秒转SQL—— 免费体验 OB Cloud Text2SQL 数据查询
数据库·sql·ai·oceanbase·分布式数据库·向量·text2sql
Stark、2 小时前
【MySQL】多表查询(笛卡尔积现象,联合查询、内连接、左外连接、右外连接、子查询)-通过练习快速掌握法
数据库·后端·sql·mysql
yqcoder3 小时前
Redis 的应用场景
数据库·redis·缓存
kngines3 小时前
【实战ES】实战 Elasticsearch:快速上手与深度实践-8.2.2成本优化与冷热数据分离
大数据·数据库·elasticsearch·搜索引擎
多多*4 小时前
浅谈Mysql数据库事务操作 用mybatis操作mysql事务 再在Springboot中使用Spring事务控制mysql事务回滚
java·数据库·windows·github·mybatis