自动化单mysql多实例库的全量迁移脚本

一 核心功能

1.1 自动化迁移流程

  • 全自动完成 导出→传输→导入 流程,无需人工干预
  • 通过唯一迁移ID(MIGRATION_ID)管理整个迁移生命周期

1.2 多线程并行处理

  • 支持自定义并发线程数(THREADS变量)
  • 同时处理多个数据库的导出/导入(通过xargs -P实现)

1.3 大数据库优化

  • 使用pigz进行并行压缩/解压(比gzip快5倍以上)

  • 关键参数优化:

    bash 复制代码
    --max-allowed-packet=1G       # 支持大字段数据
    --net-buffer-length=16384     # 提升网络传输效率
    --skip-lock-tables            # 避免锁表阻塞业务

1.4 智能数据校验

  • 自动过滤系统库(mysql/sys/information_schema/performance_schema)
  • 目标端自动创建缺失数据库(CREATE DATABASE IF NOT EXISTS)

1.5 完整日志追踪

  • 记录每个操作的精确耗时(导出/导入时间精确到秒)
  • 记录文件大小、错误详情(failed_dbs.txt/failed_imports.txt)

1.6 安全与隔离

  • 通过MIGRATION_ID隔离不同迁移任务
  • 迁移后自动清理临时文件(*_${MIGRATION_ID}.sql.gz)

二 典型使用场景

2.1 跨服务器迁移

  • 适用于迁移源库和目标库在不同IP的场景(如:本地机房→云数据库)

  • 示例配置:

    bash 复制代码
    export SRC_HOST="10.0.0.1"     # 旧服务器IP
    export DEST_HOST="10.0.0.2"    # 新服务器IP

2.2 大规模数据迁移

  • 专为700G+级数据库设计,通过:
    • 分库并行处理(避免单库过大导致OOM)
    • 流式压缩传输(减少磁盘I/O瓶颈)

2.3多实例库迁移

  • 自动识别并迁移所有非系统数据库
  • 支持数百个库的批量迁移(通过线程池控制资源)

2.4 数据库升级/重构

  • 迁移时保留存储过程/触发器(--routines --triggers)
  • 二进制数据安全传输(--hex-blob)

2.5 容灾备份

  • 通过--single-transaction确保数据一致性
  • 日志可审计(migration_*.log)

三 性能优化亮点

优化项 作用 适用场景
pigz -9 多线程压缩(比gzip快5-10倍) 节省磁盘空间和传输时间
SET foreign_key_checks=0 禁用外键约束检查 加速导入过程
分库并行处理 避免单库过大导致超时 100GB+单库迁移
进度与耗时统计 精确预估迁移时间 运维排期参考

💡 实际案例:测试环境中,500G数据库迁移仅需约15分钟

四 使用限制

4.1 环境要求:

  • 需安装mysql/mysqldump/pigz
  • 执行机需同时访问源库和目标库
    4.2 安全建议:
  • 密码明文存储,生产环境建议使用Vault或环境变量注入
  • 敏感操作建议通过nohup ... &后台执行

这通过此脚本,可高效完成从GB到TB级数据库的迁移,尤其适合数据中心迁移、云迁移、数据库版本升级等场景。

五 脚本全内容:

bash 复制代码
#!/bin/bash
# 多线程MySQL迁移脚本 (v3.0 - 性能优化版)
# ===== 配置区 =====
export THREADS=4                             # 并发线程数(建议设为CPU核心数1.5-2倍)
export SRC_HOST="source-db.example.com"      # 源数据库地址
export SRC_PORT=3306                         # 源数据库端口
export SRC_USER="admin"                      # 源数据库用户
export SRC_PASS="secure_password"            # 源数据库密码
export DEST_HOST="target-db.example.com"     # 目标数据库地址
export DEST_PORT=3306                        # 目标数据库端口
export DEST_USER="admin"                     # 目标数据库用户
export DEST_PASS="secure_password"           # 目标数据库密码
export LOG_FILE="migration_$(date +%s).log"  # 日志文件路径

# 生成唯一迁移ID
MIGRATION_ID=$(date +%s%N | sha1sum | head -c 8)
export MIGRATION_ID

# ===== 函数定义 =====

# 日志记录函数
log() {
  local level=$1 msg=$2
  echo "[$(date '+%F %T')] [$level] $msg" | tee -a "$LOG_FILE"
}

# 命令检查函数
check_commands() {
  for cmd in mysql mysqldump pigz; do
    if ! command -v $cmd &>/dev/null; then
      log "ERROR" "必需命令缺失: $cmd"
      exit 1
    fi
  done
}

# 优化导出函数
optimized_dump() {
  set -o pipefail
  local db=$1
  local start_time=$(date +%s)
  
  log "INFO" "开始导出: $db (迁移ID:${MIGRATION_ID})"
  export MYSQL_PWD="$SRC_PASS"
  
  # 添加性能优化参数
  if ! mysqldump -h"$SRC_HOST" -P"$SRC_PORT" -u"$SRC_USER" \
      --single-transaction --quick --skip-lock-tables \
      --max-allowed-packet=1G --net-buffer-length=16384 \
      --routines --triggers --events --hex-blob \
      "$db" | pigz -9 > "${db}_${MIGRATION_ID}.sql.gz"; then
      
    log "ERROR" "导出失败: $db"
    echo "$db" >> failed_dbs.txt
    return 1
  fi
  
  local end_time=$(date +%s)
  local duration=$((end_time - start_time))
  log "INFO" "导出完成: $db (大小: $(du -h ${db}_${MIGRATION_ID}.sql.gz | awk '{print $1}'), 耗时: ${duration}秒)"
}

# 数据库大小预估函数(用于pv进度条)
estimate_db_size() {
  local db=$1
  export MYSQL_PWD="$SRC_PASS"
  mysql -h"$SRC_HOST" -P"$SRC_PORT" -u"$SRC_USER" -Nse \
    "SELECT SUM(data_length + index_length) \
     FROM information_schema.TABLES \
     WHERE table_schema = '$db'" || echo "0"
}

# 优化导入函数
optimized_import() {
  set -o pipefail
  local db=$1
  local start_time=$(date +%s)
  
  log "INFO" "开始导入: $db (迁移ID:${MIGRATION_ID})"
  export MYSQL_PWD="$DEST_PASS"
  
  # 创建目标数据库
  if ! mysql -h"$DEST_HOST" -P"$DEST_PORT" -u"$DEST_USER" \
    -e "CREATE DATABASE IF NOT EXISTS \`$db\`"; then
    log "ERROR" "数据库创建失败: $db"
    return 1
  fi
  
  # 添加性能优化参数
  if ! pigz -dc "${db}_${MIGRATION_ID}.sql.gz" | \
      mysql -h"$DEST_HOST" -P"$DEST_PORT" -u"$DEST_USER" \
      --init-command="SET SESSION foreign_key_checks=0; SET SESSION unique_checks=0;" \
      --max-allowed-packet=1G --net-buffer-length=16384 \
      "$db"; then
      
    log "ERROR" "导入失败: $db"
    echo "$db" >> failed_imports.txt
    return 1
  fi
  
  local end_time=$(date +%s)
  local duration=$((end_time - start_time))
  log "INFO" "导入完成: $db (耗时: ${duration}秒)"
}

# 多线程导出函数
parallel_export() {
  local db_list=($(mysql -h"$SRC_HOST" -P"$SRC_PORT" -u"$SRC_USER" -p"$SRC_PASS" \
    -Ne "SHOW DATABASES" | grep -Ev "^(mysql|sys|information_schema|performance_schema)$"))
  log "INFO" "启动多线程导出 (线程数: $THREADS, 数据库数: ${#db_list[@]}, 迁移ID: ${MIGRATION_ID})"
  
  printf "%s\n" "${db_list[@]}" | xargs -P $THREADS -I {} bash -c '
    source_db="{}"
    optimized_dump "$source_db"
  '
}

# 多线程导入函数
parallel_import() {
  log "INFO" "启动多线程导入 (线程数: $THREADS, 迁移ID: ${MIGRATION_ID})"
  find . -maxdepth 1 -name "*_${MIGRATION_ID}.sql.gz" | while read -r file; do
    db_name="${file%_${MIGRATION_ID}.sql.gz}"
    db_name="${db_name#./}"
    echo "$db_name"
  done | xargs -P $THREADS -I {} bash -c '
    db_name="{}"
    optimized_import "$db_name"
  '
}

# ===== 主流程 =====
check_commands
export -f log optimized_dump optimized_import estimate_db_size
log "INFO" "===== 开始迁移任务 (迁移ID: ${MIGRATION_ID}) ====="

# 1. 并行导出所有非系统数据库
parallel_export

# 2. 并行导入所有数据库文件
parallel_import

# 3. 清理临时文件
find . -name "*_${MIGRATION_ID}.sql.gz" -exec rm -f {} \;

# 4. 错误检查
if [ -f failed_dbs.txt ] || [ -f failed_imports.txt ]; then
  log "WARNING" "部分任务失败,请检查 failed_dbs.txt 和 failed_imports.txt"
  exit 1
fi

log "INFO" "===== 迁移成功完成 (迁移ID: ${MIGRATION_ID}) ====="
相关推荐
王不忘.3 小时前
MySQL 数据库核心知识点详解
数据库·mysql
xhbh6665 小时前
MySQL分库分表详解:从原理、策略到ShardingSphere中间件选型,避坑指南一篇就够了
数据库·mysql·mysql分库分表
Sadsvit5 小时前
HAProxy 完整指南:简介、负载均衡原理与安装配置
linux·运维·服务器·负载均衡
xx.ii5 小时前
52.haproxy负载均衡
运维·负载均衡
silence2505 小时前
CentOS 下使用 LVM 扩展根分区空间的完整流程
linux·运维·centos
toooooop85 小时前
linux centos 脚本批量启动宝塔服务(二)
linux·运维·centos
9毫米的幻想6 小时前
【Linux系统】—— 进程切换&&进程优先级&&进程调度
linux·运维·服务器·c++·学习·算法
wuyunhang1234566 小时前
MySQL----MVCC机制
数据库·mysql
CIb0la6 小时前
介绍一套体系化的工作流程或学习方法:标准化输出
运维·笔记·学习·学习方法