目录标题
创建数据库连接密码加密文件
执行如下命令,可自动创建密文登录数据库连接文件,/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,需要再转一次