数据库自动连库执行增量脚本-Linux

目录标题

创建数据库连接密码加密文件

执行如下命令,可自动创建密文登录数据库连接文件,/usr/local/mysql 是服务器数据库安装目录,--login-path 是密文文件引用,host 是服务器数据库连接 IP,执行命令后会要求输入数据库密码,密码不显示,输入后回车即可;

bash 复制代码
/usr/local/mysql/bin/mysql_config_editor set --login-path=increment_import --host=127.0.0.1 --port=3306 --user=root --password

执行完成后,验证密码是否加密,执行如下命令,可以看到 increment_import 段落且密码显示为 ***** 就说明成功了。

bash 复制代码
/usr/local/mysql/bin/mysql_config_editor print --all

创建脚本文件

在服务器创建bash脚本文件 increment.sh,添加如下脚本内容,

bash 复制代码
#!/bin/bash
#=============================================================
#  增量 SQL 自动导入脚本   (麒麟 V10 + MySQL)
#  功能:把 increment.sql 一键导入 MySQL,自动登录,自动记日志
#  用法:./run_increment.sh              普通执行(命令行)
#        ./run_increment.sh --pause      执行完等按键(双击用)
#        ./run_increment.sh /path/x.sql  指定其它 SQL 文件
#=============================================================

set -o pipefail

#=================== ① 配置区(只改这里)=====================
MYSQL_BIN="/usr/local/mysql/bin/mysql"   # mysql 客户端完整路径
DB_NAME="my_db"                          # 要导入的数据库名
CHARSET="utf8mb4"                        # 字符集
SQL_FILE_NAME="increment.sql"            # 默认增量 SQL 文件名
LOG_KEEP_DAYS=30                         # 日志保留天数
#============================================================

#=================== ② 基础变量 =============================
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
LOG_DIR="${SCRIPT_DIR}/logs"
LOCK_FILE="/tmp/import_increment.lock"

# 颜色
RED=$'\033[31m'; GREEN=$'\033[32m'; YELLOW=$'\033[33m'; CYAN=$'\033[36m'; NC=$'\033[0m'

#=================== ③ 参数解析 =============================
PAUSE=0
SQL_FILE_ARG=""
for arg in "$@"; do
    case "$arg" in
        --pause) PAUSE=1 ;;
        *)       SQL_FILE_ARG="$arg" ;;
    esac
done

mkdir -p "$LOG_DIR"
LOG_FILE="${LOG_DIR}/import_$(date +%Y%m%d_%H%M%S).log"

if [ -n "$SQL_FILE_ARG" ]; then
    SQL_FILE="$(readlink -f "$SQL_FILE_ARG")"
else
    SQL_FILE="${SCRIPT_DIR}/${SQL_FILE_NAME}"
fi

#=================== ④ 日志函数 =============================
log()  { echo -e "$*" | tee -a "$LOG_FILE"; }
info() { log "${CYAN}[INFO]${NC} $*"; }
ok()   { log "${GREEN}[ OK ]${NC} $*"; }
warn() { log "${YELLOW}[WARN]${NC} $*"; }
err()  { log "${RED}[FAIL]${NC} $*"; }

#=================== ⑤ 主流程 ===============================
main() {
    log "============================================================"
    log " 增量 SQL 导入任务   开始时间: $(date '+%Y-%m-%d %H:%M:%S')"
    log "============================================================"

    # --- 0. 防重复执行(同一时刻只允许一个导入进程)---
    if command -v flock >/dev/null 2>&1; then
        exec 9>"$LOCK_FILE"
        if ! flock -n 9; then
            err "检测到上一次导入还在执行中,本次取消。"
            return 1
        fi
    fi

    # --- 1. 检查 mysql 客户端 ---
    if [ ! -x "$MYSQL_BIN" ]; then
        err "找不到 mysql 客户端:$MYSQL_BIN"
        err "请检查配置区 MYSQL_BIN 是否正确。"
        return 1
    fi

    # --- 2. 检查 SQL 文件 ---
    if [ ! -f "$SQL_FILE" ]; then
        err "找不到增量 SQL 文件:$SQL_FILE"
        return 1
    fi
    if [ ! -s "$SQL_FILE" ]; then
        err "SQL 文件是空的:$SQL_FILE"
        return 1
    fi

    local file_size
    file_size=$(du -h "$SQL_FILE" | cut -f1)
    info "待导入文件:$SQL_FILE  (大小: ${file_size})"

    # 检测 UTF-8 BOM(会导致第一条语句报错)
    if head -c 3 "$SQL_FILE" | grep -q $'\xEF\xBB\xBF'; then
        warn "检测到文件带 UTF-8 BOM 头,建议用 'sed -i '1s/^\xEF\xBB\xBF//' 文件' 去掉。"
    fi

    # --- 3. 生成临时登录配置(避免密码出现在命令行/进程列表)---
    LOGIN_PATH="increment_import"

    # --- 4. 测试连接 ---
    info "正在连接数据库 ${DB_USER}@${DB_HOST}:${DB_PORT} ..."
    if ! "$MYSQL_BIN" --login-path="$LOGIN_PATH" \
            -e "SELECT 1;" >/dev/null 2>>"$LOG_FILE"; then
        err "数据库连接失败!请检查:账号/密码/端口/MySQL 服务是否已启动。"
        return 1
    fi
    ok "数据库连接正常。"

    # 检查目标库是否存在
    if ! "$MYSQL_BIN" --login-path="$LOGIN_PATH" \
            -e "USE \`${DB_NAME}\`;" >/dev/null 2>>"$LOG_FILE"; then
        err "数据库 [${DB_NAME}] 不存在或无权访问。"
        return 1
    fi

    # --- 5. 执行导入 ---
    info "开始导入,请稍候 ..."
    local start_ts end_ts cost
    start_ts=$(date +%s)

    if "$MYSQL_BIN" --login-path="$LOGIN_PATH" \
            "$DB_NAME" < "$SQL_FILE" 2>>"$LOG_FILE"; then
        end_ts=$(date +%s); cost=$((end_ts - start_ts))
        log "------------------------------------------------------------"
        ok "导入成功!耗时 ${cost} 秒。"
        log " 日志文件:$LOG_FILE"
        log "------------------------------------------------------------"
        return 0
    else
        end_ts=$(date +%s); cost=$((end_ts - start_ts))
        log "------------------------------------------------------------"
        err "导入失败!耗时 ${cost} 秒。"
        err "错误详情请查看日志:$LOG_FILE"
        log "------------------------------------------------------------"
        return 1
    fi
}

#=================== ⑥ 执行 & 收尾 ==========================
main
RET=$?

# 清理过期日志
if [ "$LOG_KEEP_DAYS" -gt 0 ] 2>/dev/null; then
    find "$LOG_DIR" -name 'import_*.log' -type f -mtime +"$LOG_KEEP_DAYS" -delete 2>/dev/null
fi

echo
if [ "$RET" -eq 0 ]; then
    echo -e "${GREEN}>>> 全部完成,可以关闭窗口了。${NC}"
else
    echo -e "${RED}>>> 执行出现问题,请查看上面的提示和日志文件。${NC}"
fi

# 双击运行时,等待按键,避免窗口一闪而过
if [ "$PAUSE" -eq 1 ]; then
    echo
    read -n 1 -s -r -p "按任意键退出..."
    echo
fi

exit $RET

创建导入SQL文件

创建SQL文件 increment.sql ,将需要导入的SQL脚本添加到SQL文件中即可,注意如果需要切换数据库以及关闭索引等,需要在SQL脚本中添加对应的SQL命令,SQL脚本是一次全部执行。

执行脚本导入数据

将 increment.sh 脚本和 increment.sql 脚本全部上传到服务器,放在同一个目录下,然后执行bash increment.sh脚本,查看执行结果,如果执行命令提示如下异常:

执行脚本提示行9: $'\r':为找到命令 第10行:set: pipefail 行 35未预期的符号 $'do\r' 附近语法错误 行35 for arg in "$@"; do

是因为脚本是在Windows系统中创建保存的,上传Linux服务器后需要转换,执行如下命令可对文件进行转换处理:

bash 复制代码
tr -d '\r' < increment.sh > increment_new.sh
mv increment_new.sh increment.sh
chmod +x increment.sh

转换后进行验证:file run_increment.sh执行命令验证:

显示 ASCII text 或 UTF-8 Unicode text → 正常;

显示 with CRLF line terminators → 还有 \r,需要再转一次

相关推荐
GeW1 小时前
新质生产力发展路线图来了,Linux和数据库人该怎么接
linux·数据库
用户125758524361 小时前
GoFrame Vue3开源后台管理系统推荐:数据库与Worker要求怎么验
数据库·后端·go
MaxHua1 小时前
达梦 DTS 迁移 MySQL 报错 - 3236:此列列表已索引 解决方案
数据库·后端
用户8662978480081 小时前
Oracle 迁 KingbaseES 全流程:从评估到割接,一个都不能少
数据库
用户8662978480082 小时前
从 MySQL 迁到 KingbaseES,KDTS 这些参数不调会吃亏
数据库
yunwei372 小时前
eBPF 示例:使用 CUPTI 构建 GPU 火焰图分析器
linux·后端·性能优化
库库的数据库笔记2 小时前
金融核心交易系统的数据库国产信创改造该如何做?
大数据·数据库·分布式·mysql·oracle·金融·数据库架构
这个DBA有点耶2 小时前
连接数没满,应用却连不上数据库——TCP backlog溢出与somaxconn的隐藏限制
数据库·mysql·代码规范
yunlaodacom2 小时前
华为云国际站服务代理商:BMS数据库延迟突然升高?磁盘I/O、网络与CPU排查方法
网络·数据库·华为云