pg数据库一键迁移脚本

pg数据库的一键迁移脚本,废话不多说,直接上脚本:

bash 复制代码
#!/bin/bash

# =============== 配置区域 =============== #
#原数据库信息
SOURCE_HOST="127.0.0.1"
SOURCE_PORT=1111
SOURCE_USER="username"
SOURCE_PASS='password'
#目标数据库信息
TARGET_HOST="127.0.0.2"
TARGET_PORT=2222
TARGET_USER="username"
TARGET_PASS='password'
#数据库库名
DB_NAME="base"
#数据库模式名称
SCHEMA="schema_test"

DUMP_DIR="dump_dir"

# 自动检测系统资源
TOTAL_CORES=$(nproc)
MEM_GB=$(free -g | awk '/Mem:/ {print $2}')

# 根据资源动态配置
THREADS=$(($TOTAL_CORES * 3)) 

# 内存优化(预留2GB给系统)
if [ $MEM_GB -gt 16 ]; then
  MAINT_MEM="$((MEM_GB / 2))GB"
  WORK_MEM="128MB"
  BUFFER_SIZE="128MB"
elif [ $MEM_GB -gt 8 ]; then
  MAINT_MEM="4GB"
  WORK_MEM="64MB"
  BUFFER_SIZE="64MB"
else
  MAINT_MEM="1GB"
  WORK_MEM="32MB"
  BUFFER_SIZE="32MB"
fi

LOG_FILE="db_migration_$(date +%Y%m%d_%H%M%S).log"
# ======================================== #

# 函数:带时间戳的日志记录
log() {
    local log_type=$1
    local message=$2
    local timestamp
    timestamp=$(date +"%Y-%m-%d %H:%M:%S")
    echo "[$timestamp] [$log_type] $message" | tee -a "$LOG_FILE"
}

# 函数:安全执行命令并记录输出
execute_with_log() {
    local command=$1
    local step_name=$2
    local password=$3
    
    log "START" "开始步骤: $step_name"
    
    # 安全记录命令(不显示密码)
    local safe_command=$(echo "$command" | sed "s/$password/*****/g")
    log "CMD" "执行命令: $safe_command"
    
    # 设置密码环境变量
    export PGPASSWORD=$password
    
    # 执行命令并捕获输出和错误
    eval "$command" 2>&1 | while IFS= read -r line; do
        log "PROGRESS" "$line"
    done
    
    local exit_code=${PIPESTATUS[0]}
    if [ $exit_code -ne 0 ]; then
        log "ERROR" "$step_name 失败, 退出码: $exit_code"
        exit $exit_code
    fi
    
    log "COMPLETE" "$step_name 成功完成"
}

# 创建日志文件
touch "$LOG_FILE"
log "INFO" "===== 极速数据库迁移开始 ====="
log "CONFIG" "源数据库: $SOURCE_HOST:$SOURCE_PORT"
log "CONFIG" "目标数据库: $TARGET_HOST:$TARGET_PORT"
log "CONFIG" "数据库: $DB_NAME, 模式: $SCHEMA"
log "CONFIG" "自动线程数: $THREADS"
log "CONFIG" "内存配置: 维护内存=$MAINT_MEM, 工作内存=$WORK_MEM"
log "CONFIG" "缓冲区: $BUFFER_SIZE"
log "CONFIG" "日志文件: $LOG_FILE"

# ================== 导出阶段 ================== #
log "INFO" "---- 阶段1: 并行数据导出 ----"
log "INFO" "优化策略:零压缩 + 大表优先"

export_command="pg_dump -h $SOURCE_HOST -p $SOURCE_PORT -U $SOURCE_USER -Fd \
  -j $THREADS --compress=0 -f $DUMP_DIR -n $SCHEMA $DB_NAME \
  --load-via-partition-root"

execute_with_log "$export_command" "源数据导出" "$SOURCE_PASS"

# 获取导出目录大小
dump_size=$(du -sh "$DUMP_DIR" 2>/dev/null | cut -f1)
log "INFO" "导出数据大小: ${dump_size:-未知}"

# ================== 导入准备 ================== #
log "INFO" "---- 阶段2: 目标数据库极限优化 ----"
log "INFO" "启用写入性能模式 (临时牺牲ACID特性)"

(
export PGPASSWORD=$TARGET_PASS
psql -h $TARGET_HOST -p $TARGET_PORT -U $TARGET_USER -d $DB_NAME <<EOF >> "$LOG_FILE" 2>&1
-- 禁用ACID特性 (导入期间临时关闭)
ALTER SYSTEM SET fsync = off;
ALTER SYSTEM SET full_page_writes = off;
ALTER SYSTEM SET synchronous_commit = off;
ALTER SYSTEM SET wal_level = minimal;

-- 内存优化
ALTER SYSTEM SET max_wal_size = '8GB';
ALTER SYSTEM SET checkpoint_timeout = '2h';
ALTER SYSTEM SET maintenance_work_mem = '$MAINT_MEM';
ALTER SYSTEM SET work_mem = '$WORK_MEM';
ALTER SYSTEM SET shared_buffers = '$BUFFER_SIZE';

-- 并行度优化
ALTER SYSTEM SET max_parallel_maintenance_workers = $THREADS;
ALTER SYSTEM SET max_parallel_workers = $THREADS;
ALTER SYSTEM SET max_parallel_workers_per_gather = $THREADS;

-- 立即生效
SELECT pg_reload_conf();
EOF
)

log "INFO" "目标数据库已进入极限性能模式"

# ================== 导入阶段 ================== #
log "INFO" "---- 阶段3: 分阶段并行恢复 ----"

# 第一阶段:仅恢复表结构 (加速DDL)
log "INFO" "步骤3.1: 恢复表结构 (并行)"
import_structure_command="pg_restore -h $TARGET_HOST -p $TARGET_PORT -U $TARGET_USER -d $DB_NAME \
  --schema=$SCHEMA --clean --if-exists --no-owner --no-acl \
  -j $THREADS --section=pre-data $DUMP_DIR"

execute_with_log "$import_structure_command" "表结构恢复" "$TARGET_PASS"

# 第二阶段:并行导入数据 (禁用所有约束)
log "INFO" "步骤3.2: 并行数据导入 (禁用所有约束)"
import_data_command="pg_restore -h $TARGET_HOST -p $TARGET_PORT -U $TARGET_USER -d $DB_NAME \
  --schema=$SCHEMA --no-owner --no-acl \
  -j $THREADS --section=data --disable-triggers --data-only $DUMP_DIR"

execute_with_log "$import_data_command" "数据导入" "$TARGET_PASS"

# 第三阶段:并行重建索引
log "INFO" "步骤3.3: 并行重建索引"
import_index_command="pg_restore -h $TARGET_HOST -p $TARGET_PORT -U $TARGET_USER -d $DB_NAME \
  --schema=$SCHEMA --no-owner --no-acl \
  -j $THREADS --section=post-data $DUMP_DIR"

execute_with_log "$import_index_command" "索引重建" "$TARGET_PASS"

# =============== 后期优化 ================ #
log "INFO" "---- 阶段4: 后期优化 ----"
log "INFO" "重建统计信息并恢复ACID特性"

(
export PGPASSWORD=$TARGET_PASS
psql -h $TARGET_HOST -p $TARGET_PORT -U $TARGET_USER -d $DB_NAME <<EOF >> "$LOG_FILE" 2>&1
-- 重建统计信息 (使用并行)
SET maintenance_work_mem = '$MAINT_MEM';
ANALYZE VERBOSE;

-- 恢复ACID特性
ALTER SYSTEM SET fsync = on;
ALTER SYSTEM SET full_page_writes = on;
ALTER SYSTEM SET synchronous_commit = on;
ALTER SYSTEM SET wal_level = replica;

-- 恢复默认并行设置
ALTER SYSTEM RESET max_parallel_maintenance_workers;
ALTER SYSTEM RESET max_parallel_workers;
ALTER SYSTEM RESET max_parallel_workers_per_gather;

-- 恢复内存设置
ALTER SYSTEM RESET maintenance_work_mem;
ALTER SYSTEM RESET work_mem;
ALTER SYSTEM RESET shared_buffers;

-- 刷新配置
SELECT pg_reload_conf();

-- 强制检查点确保数据持久化
CHECKPOINT;
EOF
)

# 清理敏感信息
unset SOURCE_PASS
unset TARGET_PASS
unset PGPASSWORD

# =============== 迁移完成 ================== #
log "SUCCESS" "===== 数据库迁移成功完成! ====="
log "PERF" "总耗时: $SECONDS 秒"
if [ -n "$dump_size" ]; then
  dump_bytes=$(du -sb "$DUMP_DIR" 2>/dev/null | awk '{print $1}')
  if [ -n "$dump_bytes" ] && [ "$dump_bytes" -gt 0 ]; then
    rate_kbs=$((dump_bytes / SECONDS / 1024))
    rate_mbs=$((dump_bytes / SECONDS / 1048576))
    log "PERF" "平均速率: $rate_kbs KB/s ($rate_mbs MB/s)"
  else
    log "PERF" "速率计算: 无法确定导出大小"
  fi
else
  log "PERF" "速率计算: 无法确定导出大小"
fi
log "INFO" "详细日志请查看: $LOG_FILE"
log "INFO" "导出目录: $DUMP_DIR (可手动删除以释放空间)"

上述就是脚本的具体信息,改一下目标数据库和原数据的信息就OK。

使用如下命令执行脚本:

bash 复制代码
nohup sh postgre.sh > migration.log 2>&1 &

然后就可以在migration.log中查看整个迁移过程的日志。

完事,收工。

相关推荐
Savvy..2 小时前
Day16若依-帝可得
数据库
Java后端的Ai之路2 小时前
【AI大模型开发】-Embedding 与向量数据库:从基础概念到实战应用
数据库·人工智能·embedding·向量数据库·ai应用开发工程师
2501_948194982 小时前
RN for OpenHarmony AnimeHub项目实战:关于页面开发
数据库·react native
松涛和鸣2 小时前
DAY55 Getting Started with ARM and IMX6ULL
linux·服务器·网络·arm开发·数据库·html
huahualaly3 小时前
重建oracle测试库步骤
数据库·oracle·ffmpeg
墨香幽梦客3 小时前
数据库选型对比:MySQL、Oracle与PostgreSQL的企业应用场景分析
数据库·mysql·oracle
wei_shuo4 小时前
多模一体破局:金仓数据库引领文档数据库国产化新征程
数据库·金仓数据库
Coder_Boy_4 小时前
基于SpringAI的在线考试系统-数据库 表结构 & 完整外键依赖关系梳理
java·数据库·人工智能·软件工程
清风拂山岗 明月照大江4 小时前
MySQL进阶
数据库·sql·mysql