Mysql 数据库迁移

一、数据库全量备份

bash 复制代码
#!/bin/bash

# 配置参数
DB_HOST="数据库IP地址"
DB_USER="数据库用户名"
DB_PASS="数据库密码"
BACKUP_DIR="/usr/local/mysqldump"
DATE=$(date +"%Y%m%d_%H%M%S")
LOG_FILE="$BACKUP_DIR/backup_$DATE.log"

# 创建备份目录
mkdir -p $BACKUP_DIR/$DATE

# 开始日志
echo "$(date): 开始MySQL全库备份" | tee -a $LOG_FILE

# 获取数据库列表(排除系统库)
echo "$(date): 获取数据库列表..." | tee -a $LOG_FILE
DATABASES=$(mysql -h $DB_HOST -u $DB_USER -p$DB_PASS -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "(Database|information_schema|performance_schema|sys)")

if [ $? -ne 0 ]; then
    echo "$(date): 错误:无法连接MySQL服务器" | tee -a $LOG_FILE
    exit 1
fi

echo "找到数据库: $DATABASES" | tee -a $LOG_FILE

# 备份每个数据库
for DB in $DATABASES; do
    echo "$(date): 备份数据库: $DB" | tee -a $LOG_FILE
    
    # 备份命令
    mysqldump -h $DB_HOST -u $DB_USER -p$DB_PASS \
              --single-transaction \
              --routines \
              --events \
              --triggers \
              --add-drop-database \
              $DB 2>> $LOG_FILE | gzip > $BACKUP_DIR/$DATE/${DB}_${DATE}.sql.gz
    
    # 检查备份是否成功
    if [ ${PIPESTATUS[0]} -eq 0 ]; then
        echo "$(date): ✓ 成功备份: $DB" | tee -a $LOG_FILE
    else
        echo "$(date): ✗ 备份失败: $DB" | tee -a $LOG_FILE
    fi
done

echo "$(date): 备份完成!文件保存在: $BACKUP_DIR/$DATE/" | tee -a $LOG_FILE

# 显示备份文件信息
echo "备份文件列表:" | tee -a $LOG_FILE
ls -lh $BACKUP_DIR/$DATE/ | tee -a $LOG_FILE

二、数据库备份恢复

bash 复制代码
#!/bin/bash

# 配置参数
NEW_DB_HOST="数据库IP地址"
NEW_DB_USER="数据库用户名"
NEW_DB_PASS="数据库密码"
# 数据库端口,默认3306
NEW_DB_PORT="3306"
BACKUP_DIR="数据库备份地址"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 日志文件
LOG_FILE="$BACKUP_DIR/import_$(date +%Y%m%d_%H%M%S).log"

# 显示带颜色的消息
log_info() { echo -e "${GREEN}[INFO]${NC} $(date): $1" | tee -a $LOG_FILE; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $(date): $1" | tee -a $LOG_FILE; }
log_error() { echo -e "${RED}[ERROR]${NC} $(date): $1" | tee -a $LOG_FILE; }

# 测试数据库连接
test_db_connection() {
    log_info "测试数据库连接..."
    mysql -h $NEW_DB_HOST -P $NEW_DB_PORT -u $NEW_DB_USER -p$NEW_DB_PASS -e "SELECT 1;" > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        log_error "无法连接到目标MySQL服务器"
        exit 1
    fi
    log_info "数据库连接测试成功"
}

# 获取备份文件列表
get_backup_files() {
    find $BACKUP_DIR -name "*.sql.gz" -type f | sort
}

# 从文件名提取数据库名
extract_db_name() {
    local filename=$(basename "$1") 
    # 使用sed去掉日期时间部分和扩展名
    echo "$filename" | sed 's/_[0-9]\{8\}_[0-9]\{6\}\.sql\.gz$//'
    #echo $filename | cut -d'_' -f1
}

# 创建数据库
create_database() {
    local db_name=$1
    log_info "创建数据库: $db_name"
    
    mysql -h $NEW_DB_HOST -P $NEW_DB_PORT -u $NEW_DB_USER -p$NEW_DB_PASS \
          -e "CREATE DATABASE IF NOT EXISTS \`$db_name\` 
              CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>> $LOG_FILE
    
    if [ $? -eq 0 ]; then
        log_info "✓ 数据库创建成功: $db_name"
        return 0
    else
        log_error "创建数据库失败: $db_name"
        return 1
    fi
}

# 导入数据库
import_database() {
    local db_name=$1
    local backup_file=$2
    
    log_info "开始导入: $db_name"
    
    # 显示进度(估算)
    total_size=$(gunzip -c "$backup_file" | wc -c 2>/dev/null)
    if [ -n "$total_size" ]; then
        log_info "预计导入数据量: $(($total_size/1024/1024)) MB"
    fi
    
    # 导入数据
    start_time=$(date +%s)
    gunzip -c "$backup_file" | mysql -h $NEW_DB_HOST -P $NEW_DB_PORT -u $NEW_DB_USER -p$NEW_DB_PASS $db_name 2>> $LOG_FILE
    
    local import_status=$?
    end_time=$(date +%s)
    duration=$((end_time - start_time))
    
    if [ $import_status -eq 0 ]; then
        log_info "✓ 导入成功: $db_name (耗时: ${duration}秒)"
        return 0
    else
        log_error "导入失败: $db_name"
        return 1
    fi
}

# 主函数
main() {
    log_info "开始数据库导入过程"
    
    # 测试连接
    test_db_connection
    
    # 获取备份文件列表
    backup_files=$(get_backup_files)
    total_files=$(echo "$backup_files" | wc -l)
    current_file=0
    
    log_info "找到 $total_files 个备份文件需要导入"
    
    # 导入每个数据库
    success_count=0
    fail_count=0
    
    for backup_file in $backup_files; do
        current_file=$((current_file + 1))
        db_name=$(extract_db_name "$backup_file")
        
        log_info "处理文件 [$current_file/$total_files]: $db_name"
        
        # 创建数据库
        if create_database "$db_name"; then
            # 导入数据
            if import_database "$db_name" "$backup_file"; then
                success_count=$((success_count + 1))
            else
                fail_count=$((fail_count + 1))
            fi
        else
            fail_count=$((fail_count + 1))
        fi
        
        echo "----------------------------------------" | tee -a $LOG_FILE
    done
    
    # 显示总结
    log_info "导入完成!"
    log_info "成功: $success_count 个数据库"
    if [ $fail_count -gt 0 ]; then
        log_warn "失败: $fail_count 个数据库"
    fi
    
    # 显示所有导入的数据库
    log_info "新服务器上的数据库列表:"
    mysql -h $NEW_DB_HOST -P $NEW_DB_PORT -u $NEW_DB_USER -p$NEW_DB_PASS -e "SHOW DATABASES;" | tee -a $LOG_FILE
}

# 执行主函数
main

三、按表备份

bash 复制代码
#!/bin/bash
# 远程MySQL数据库同步(导出+导入)
# 源数据库(要导出的数据库)
SRC_HOST="源数据库ip地址"
SRC_USER="源数据库用户名"
SRC_PASS="源数据库密码"
SRC_DB="源数据库表名称"

# 目标数据库(要导入的数据库)
DST_HOST="目标数据库ip地址"
DST_USER="目标数据库用户名"
DST_PASS="目标数据库密码"
DST_DB="目标数据库表名称"

# 临时目录
TEMP_DIR="./temp_backup_$(date +%Y%m%d_%H%M%S)"
mkdir -p $TEMP_DIR

echo "=== 开始数据库同步 ==="
echo "从: $SRC_HOST.$SRC_DB"
echo "到: $DST_HOST.$DST_DB"

# 从源数据库导出
echo "正在从源数据库导出..."
TABLES=$(mysql -h $SRC_HOST -u $SRC_USER -p$SRC_PASS $SRC_DB -N -e "SHOW TABLES;")
for TABLE in $TABLES; do
    echo "导出: $TABLE"
    mysqldump -h $SRC_HOST -u $SRC_USER -p$SRC_PASS $SRC_DB $TABLE > $TEMP_DIR/$TABLE.sql
done

# 导入到目标数据库
echo "正在导入到目标数据库..."
for SQL_FILE in $TEMP_DIR/*.sql; do
    TABLE_NAME=$(basename $SQL_FILE .sql)
    echo "导入: $TABLE_NAME"
    mysql -h $DST_HOST -u $DST_USER -p$DST_PASS $DST_DB < $SQL_FILE
done

# 清理临时文件
rm -rf $TEMP_DIR

echo "同步完成! 共处理 $(echo "$TABLES" | wc -l) 个表"

四、大SQL按表拆分为小SQL文件

bash 复制代码
#!/bin/bash

# SQL文件拆分脚本 - 按表拆分
# 用法: ./split_sql.sh <sql文件> [输出目录]

split_sql_by_tables() {
    local sql_file="$1"
    local output_dir="${2:-split_tables}"
    local current_table=""
    local output_file=""
    
    # 检查文件是否存在
    if [[ ! -f "$sql_file" ]]; then
        echo "错误: 文件 $sql_file 不存在"
        return 1
    fi
    
    # 创建输出目录
    mkdir -p "$output_dir"
    
    echo "开始拆分SQL文件: $sql_file"
    echo "输出目录: $output_dir"
    
    # 计数器
    local table_count=0
    
    # 逐行读取SQL文件
    while IFS= read -r line; do
        # 检测表创建语句
        if [[ "$line" =~ ^CREATE\ TABLE\ \`([^\`]+)\` ]]; then
            current_table="${BASH_REMATCH[1]}"
            output_file="$output_dir/${current_table}.sql"
            
            echo "创建表文件: ${current_table}.sql"
            table_count=$((table_count + 1))
            
            # 如果文件已存在,先删除(避免重复内容)
            if [[ -f "$output_file" ]]; then
                rm "$output_file"
            fi
        fi
        
        # 写入到当前表文件
        if [[ -n "$output_file" && -n "$current_table" ]]; then
            echo "$line" >> "$output_file"
        fi
        
    done < "$sql_file"
    
    echo "拆分完成!共处理 $table_count 个表"
    echo "文件保存在: $output_dir"
}

# 显示帮助信息
show_help() {
    echo "用法: $0 <SQL文件> [输出目录]"
    echo ""
    echo "示例:"
    echo "  $0 database.sql                  # 输出到 split_tables 目录"
    echo "  $0 database.sql table_files      # 输出到 table_files 目录"
    echo ""
    echo "功能: 将MySQL导出的SQL文件按表拆分成多个文件"
}

# 主程序
main() {
    # 检查参数
    if [[ $# -eq 0 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
        show_help
        exit 0
    fi
    
    local sql_file="$1"
    local output_dir="$2"
    
    # 执行拆分
    split_sql_by_tables "$sql_file" "$output_dir"
}

# 运行主程序
main "$@"
相关推荐
小陈工3 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
0xDevNull8 小时前
MySQL数据冷热分离详解
后端·mysql
科技小花8 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸8 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain8 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希8 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神9 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员9 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java9 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿9 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb