备份

#!/bin/bash
# Greenplum 6.25.3 专用备份脚本
# 修正路径和命令问题

# 加载正确的环境变量(关键修复)
source /usr/local/greenplum-db-6.25.3/greenplum_path.sh

BACKUP_ROOT="/data/gp_backup"
BACKUP_ROOT="/mnt/data1/gpdata/backup0320"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="${BACKUP_ROOT}/${TIMESTAMP}"
LOG_FILE="${BACKUP_DIR}/backup.log"

# 节点数据库配置(保持不变)
CURRENT_IP=$(hostname -I | awk '{print $1}')
case $CURRENT_IP in
    10.10.1.137)
        DB_LIST=(db_01,db_02,db_03)
        ;;
    10.10.1.143)
        DB_LIST=(db_01,db_02,db_03)
        ;;
    *)
        echo "无效的服务器IP:$CURRENT_IP"
        exit 1
        ;;
esac

mkdir -p ${BACKUP_DIR} || { echo "无法创建备份目录"; exit 1; }

echo "备份开始时间:$(date +'%Y-%m-%d %T')" | tee -a ${LOG_FILE}

# 使用pg_dumpall替代gp_dumpall(Greenplum 6特性)
echo "正在备份全局对象..." | tee -a ${LOG_FILE}
pg_dumpall --globals-only -f ${BACKUP_DIR}/globals.sql 2>>${LOG_FILE}

# 并行备份数据库(使用pg_dump)
for DB in ${DB_LIST[@]}; do
    {
        echo "开始备份数据库:${DB}" | tee -a ${LOG_FILE}
        pg_dump ${DB} \
            --schema-only \
            --exclude-schema=pg_catalog \
            --exclude-schema=gp_toolkit \
            --exclude-schema=information_schema \
            -f ${BACKUP_DIR}/${DB}_schema.sql \
            2>>${LOG_FILE}

        pg_dump ${DB} \
            --data-only \
            --exclude-schema=pg_catalog \
            --exclude-schema=gp_toolkit \
            --exclude-schema=information_schema \
            -f ${BACKUP_DIR}/${DB}_data.sql \
            2>>${LOG_FILE}
        echo "完成备份数据库:${DB}" | tee -a ${LOG_FILE}
    } &
done

wait

echo "备份完成时间:$(date +'%Y-%m-%d %T')" | tee -a ${LOG_FILE}
echo "备份文件存储路径:${BACKUP_DIR}" | tee -a ${LOG_FILE}

# 压缩备份文件
echo "正在压缩备份文件..." | tee -a ${LOG_FILE}
tar czf ${BACKUP_DIR}.tar.gz -C ${BACKUP_ROOT} ${TIMESTAMP} 2>>${LOG_FILE}

echo "备份操作全部完成!"

还原

#!/bin/bash
# Greenplum 6 数据库还原脚本
# 使用说明:./restore.sh
# 加载Greenplum环境
source /usr/local/greenplum-db-6.25.3/greenplum_path.sh

RESTORE_DIR="/mnt/data1/gpdata/backup/20250320_025115"
LOG_FILE="${RESTORE_DIR}/restore.log"


if [ ! -d "${RESTORE_DIR}" ]; then
    echo "备份目录不存在: ${RESTORE_DIR}"
    exit 1
fi

# 创建日志文件
exec > >(tee -a ${LOG_FILE}) 2>&1

echo "还原开始时间:$(date +'%Y-%m-%d %T')"

# 还原全局对象(需管理员权限)
echo "正在还原全局对象..." 
psql -d postgres -f "${RESTORE_DIR}/globals.sql" -v ON_ERROR_STOP=1

# 获取需要还原的数据库列表
DB_LIST=($(ls ${RESTORE_DIR} | grep '_schema.sql' | sed 's/_schema.sql//'))

# 并发还原数据库
for DB in "${DB_LIST[@]}"; do
{
    echo "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁"
    echo "开始还原数据库:${DB}"
    dropdb ${DB};
    
    # 创建数据库(如果不存在)
    createdb "${DB}" 2>/dev/null || echo "数据库已存在,直接使用:${DB}"
    
    # 还原Schema
    echo "还原表结构..."
    #psql -d "${DB}" -f "${RESTORE_DIR}/${DB}_schema.sql" -v ON_ERROR_STOP=1
    if ! psql -d "${DB}" -f "${RESTORE_DIR}/${DB}_schema.sql" -v ON_ERROR_STOP=1; then
        echo "[CRITICAL] Schema还原失败!立即终止" | tee -a ${LOG_FILE}
        exit 1
    fi
    
    # 还原数据
    echo "导入数据..."
    # psql -d "${DB}" -f "${RESTORE_DIR}/${DB}_data.sql" -v ON_ERROR_STOP=1
    psql -d "${DB}" --set=gp_enable_fast_sri=on --set=gp_autostats_mode=none -f "${RESTORE_DIR}/${DB}_data.sql" -v ON_ERROR_STOP=1
    
    echo "完成还原数据库:${DB}"
} &
done

# 等待所有后台任务
wait

# --------------------------
# 新增后处理步骤
# --------------------------
echo "开始后处理操作:$(date +'%Y-%m-%d %T')"

# 为每个数据库生成统计信息
for DB in "${DB_LIST[@]}"; do
{
    echo "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁"
    echo "处理数据库:${DB}"
    
    # 生成统计信息(数据库级别)
    echo "执行ANALYZE..."
    psql -d "${DB}" -c "ANALYZE;" -v ON_ERROR_STOP=1
    
    # 设置安全参数(会话级生效)
    echo "恢复安全参数..."
    psql -d "${DB}" <<-EOSQL
    SET gp_enable_fast_sri=off;
    SET gp_autostats_mode=on_change;
EOSQL
    
    echo "完成数据库后处理:${DB}"
} &
done

wait
echo "还原完成时间:$(date +'%Y-%m-%d %T')"
echo "详细日志查看:${LOG_FILE}"

其他相关: 合并segment

背景

-- 查询数据分布
SELECT content,
       role,
       preferred_role,
       mode,
       status,
       hostname,
       address,
       datadir
FROM gp_segment_configuration
ORDER BY content, role;
-1	p	p	n	u	dev-gp-01	dev-gp-01	/mnt/data1/gpdata/master/gpseg-1
    0	p	p	n	u	dev-gp-01	dev-gp-01	/mnt/data1/gpdata/data/primary/gpseg0
    1	p	p	n	u	dev-gp-01	dev-gp-01	/mnt/data1/gpdata/data/primary/gpseg1
    2	p	p	n	u	dev-gp-02	dev-gp-02	/mnt/data1/gpdata/data/primary/gpseg2
    3	p	p	n	u	dev-gp-02	dev-gp-02	/mnt/data1/gpdata/data/primary/gpseg3

目标

把dev-gp-02上的gpseg2gpseg3迁移到dev-gp-01

操作

## 在 dev-gp-01 上执行以下命令,从 dev-gp-02 复制数据
rsync -avz gpadmin@dev-gp-02:/mnt/data1/gpdata/data/primary/gpseg2/ /mnt/data1/gpdata/data/primary/gpseg2/
rsync -avz gpadmin@dev-gp-02:/mnt/data1/gpdata/data/primary/gpseg3/ /mnt/data1/gpdata/data/primary/gpseg3/
## 在 dev-gp-01 上执行以下命令,进入维护模式
gpstop -af && gpstart -m
## 执行工具模式且开启系统表修改配置
PGOPTIONS="-c gp_session_role=utility -c allow_system_table_mods=on" psql -d template1
## 执行以下sql
BEGIN;
-- 修改content=2的端口为6002
UPDATE gp_segment_configuration 
SET port = 6002 
WHERE content = 2;

-- 修改content=3的端口为6003
UPDATE gp_segment_configuration 
SET port = 6003 
WHERE content = 3;

-- 提交修改
COMMIT;
\q
## 修改Segment物理配置文件
### 修改gpseg2的端口配置
sed -i "s/^port=6000/port=6002/" /mnt/data1/gpdata/data/primary/gpseg2/postgresql.conf
### 修改gpseg3的端口配置
sed -i "s/^port=6001/port=6003/" /mnt/data1/gpdata/data/primary/gpseg3/postgresql.conf
## 检查新端口是否被占用
netstat -tuln | grep -E '6002|6003'
## 重启数据库
gpstop -m && gpstart -a

-- 确认端口配置已更新
SELECT content, port, datadir 
FROM gp_segment_configuration 
ORDER BY content;
## 验证结果
-- 预期输出:
 content | port |                datadir                
---------+------+---------------------------------------
      -1 | 5432 | /mnt/data1/gpdata/master/gpseg-1
       0 | 6000 | /mnt/data1/gpdata/data/primary/gpseg0
       1 | 6001 | /mnt/data1/gpdata/data/primary/gpseg1
       2 | 6002 | /mnt/data1/gpdata/data/primary/gpseg2
       3 | 6003 | /mnt/data1/gpdata/data/primary/gpseg3