openeuler系统pgsql不宕机迁移

安装docker

查看当前操作系统架构

bash 复制代码
uname -a

Linux ecs-346a-0001.novalocal 5.10.0-106.18.0.68.oe2209.x86_64 #1 SMP

Wed Sep 28 07:03:00 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

在本机下载对应版本的

bash 复制代码
tar xzvf docker-28.3.0.tgz
cp docker/* /usr/bin/

创建 systemd 服务

bash 复制代码
sudo tee /etc/systemd/system/docker.service > /dev/null <<'EOF'
[Unit]
Description=Docker Application Container Engine
After=network.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
KillMode=process

[Install]
WantedBy=multi-user.target
EOF

设置权限和启动服务

bash 复制代码
chmod +x /usr/bin/docker /usr/bin/dockerd /usr/bin/docker-init /usr/bin/docker-proxy
sudo systemctl daemon-reload
sudo systemctl start docker
sudo systemctl enable docker

验证安装

bash 复制代码
docker --version
sudo systemctl status docker
sudo docker info

配置局域网yum源

  1. 备份现有repo文件
bash 复制代码
cd /etc/yum.repos.d/
mkdir backup
mv *.repo backup/
  1. 创建新的repo文件
bash 复制代码
cat > /etc/yum.repos.d/local_ftp.repo << EOF
[OS]
name=OS
baseurl=ftp://172.21.137.250:2209
enabled=1
gpgcheck=0
#gpgkey=http://repo.openeuler.org/openEuler-22.09/OS/$basearch/RPM-GPG-KEY-openEuler
EOF
  1. 清理缓存并安装
bash 复制代码
yum clean all
yum makecache
yum install -y telnet

配置互联网yum源

全局替换openeuler域名

bash 复制代码
sed -i 's/repo.openeuler.org/archives.openeuler.openatom.cn/g' /etc/yum.repos.d/openEuler.repo

baseurl=http://archives.openeuler.openatom.cn/openEuler-22.09/EPOL/$basearch/

改为

baseurl=http://archives.openeuler.openatom.cn/openEuler-22.09/EPOL/main/$basearch/

多加了一级main

配置ntp时间服务器

bash 复制代码
yum install chrony
vim /etc/chrony.conf

添加以下

bash 复制代码
server 172.21.137.117 iburst
allow 172.21.137.117

重启chrony服务

bash 复制代码
systemctl restart chronyd
systemctl status chronyd
systemctl enable chronyd

查看同步状态

bash 复制代码
chronyc sources -v
date

pgsql容器创建

  1. 将旧服务器的镜像保存到本地
bash 复制代码
docker save -o /zfw/dockerimages/redis.tar redis:4.0.11-alpine
  1. 在新服务器上加载镜像
bash 复制代码
docker load -i redis.tar
  1. 分析旧pgsql容器启动命令
    安装分析工具
bash 复制代码
docker pull assaflavie/runlike
bash 复制代码
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
    assaflavie/runlike tomcat3
  1. 上传镜像到新服务器
bash 复制代码
docker load -i postgis.tar
  1. 启动pgsql
    创建空数据目录
bash 复制代码
sudo mkdir -p /home/data/postgres/{data,conf,logs}

使用临时容器做基础备份

bash 复制代码
docker run --rm \
  -v /home/data/postgres/data:/var/lib/postgresql/data \
  -v /home/data/postgres/conf:/etc/postgresql \
  -v /home/data/postgres/logs:/var/log/postgresql \
  postgis/postgis:13-3.1-alpine \
  pg_basebackup \
  -h 192.168.41.17 -p 15432 -U replica -D /var/lib/postgresql/data \
  -P -R -X stream -C -S new_slave2

设置正确的权限

bash 复制代码
sudo chown -R 999:999 /home/data/postgres/data
sudo chmod -R 700 /home/data/postgres/data

启动从节点容器

bash 复制代码
docker run -d \
  --name postgres-slave-new2 \
  --restart unless-stopped \
  -p 15432:5432 \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=zjfsW2ffvewfacrQs \
  -v /home/data/postgres/data:/var/lib/postgresql/data \
  -v /home/data/postgres/conf:/etc/postgresql \
  -v /home/data/postgres/logs:/var/log/postgresql \
  postgis/postgis:13-3.1-alpine

新服务器同步

  1. 在已经存在的从节点上添加 replica 用户的复制权限,进入从节点容器
bash 复制代码
docker exec -it postgres-slave bash
  1. 在 pg_hba.conf 中添加 replica 用户的复制权限
    将新的两台数据库服务器IP加入
bash 复制代码
echo "host replication replica 192.168.41.230/32 trust" >> /var/lib/postgresql/data/pg_hba.conf
echo "host replication replica 192.168.41.138/32 trust" >> /var/lib/postgresql/data/pg_hba.conf
  1. 重新加载配置
bash 复制代码
psql -U postgres -c "SELECT pg_reload_conf();"

同步状态确认

  1. 检查当前复制状态
    在主节点查看所有复制连接
bash 复制代码
docker exec postgres-master psql -U postgres -c "
SELECT 
    application_name,
    client_addr,
    state,
    sync_state,
    pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn)) as send_lag,
    pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), write_lsn)) as write_lag,
    pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), flush_lsn)) as flush_lag,
    pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) as replay_lag
FROM pg_stat_replication;"

2.进入现有从节点容器

bash 复制代码
docker exec -it postgres-slave psql -U postgres

查看复制状态

bash 复制代码
SELECT application_name, client_addr, state, sync_state, write_lag, replay_lag 
FROM pg_stat_replication;

3.在新的从节点上查看接收状态

bash 复制代码
docker exec postgres-slave-new2 psql -U postgres -c "
SELECT 
    pg_is_in_recovery() as in_recovery,
    pg_last_wal_receive_lsn() as last_receive_lsn,
    pg_last_wal_replay_lsn() as last_replay_lsn,
    pg_last_xact_replay_timestamp() as last_replay_time;
"

pgsql迁移

  1. 停止应用写入
    在主节点设置为只读,防止新数据写入
bash 复制代码
docker exec postgres-master psql -U postgres -c "ALTER SYSTEM SET default_transaction_read_only = on;"

docker exec postgres-master psql -U postgres -c "SELECT pg_reload_conf();"
  1. 验证只读设置
bash 复制代码
docker exec postgres-master psql -U postgres -c "SHOW default_transaction_read_only;"
  1. 提升新服务器为主节点
    在新服务器1上执行:
bash 复制代码
docker exec --user postgres postgres-slave-new1 pg_ctl -D /var/lib/postgresql/data promote
docker restart postgres-slave-new1
  1. 检查是否已提升为主节点
bash 复制代码
docker exec postgres-slave-new1 psql -U postgres -c "SELECT pg_is_in_recovery();"

应该返回 f (false)

  1. 检查 WAL 位置
bash 复制代码
docker exec postgres-slave-new1 psql -U postgres -c "SELECT pg_current_wal_lsn();"
  1. 重新配置新服务器2连接到新的主节点
    在新服务器2上执行,停止容器
bash 复制代码
docker stop postgres-slave-new2
  1. 备份原有数据(可选)
bash 复制代码
cp -r /home/data/postgres/data /home/data/postgres/data_backup

清理数据目录

bash 复制代码
sudo rm -rf /home/data/postgres/data/*
  1. 重新配置从新的主节点同步
bash 复制代码
docker run --rm \
  -v /home/data/postgres/data:/var/lib/postgresql/data \
  postgis/postgis:13-3.1-alpine \
  pg_basebackup \
  -h 192.168.41.230 -p 15432 -U replica -D /var/lib/postgresql/data \
  -P -R -X stream -C -S new_slave2

重新启动容器

bash 复制代码
docker start postgres-slave-new2
  1. 配置新的主节点(新服务器1)
    进入新主节点容器
bash 复制代码
docker exec -it postgres-slave-new1 bash

创建复制用户(如果不存在)

bash 复制代码
psql -U postgres -c "CREATE USER replica WITH REPLICATION PASSWORD 'replica';"

配置 pg_hba.conf(如果不存在)

bash 复制代码
echo "host replication replica 192.168.41.138/32 trust" >> /var/lib/postgresql/data/pg_hba.conf

配置 postgresql.conf(对比一下先前的主服务器配置,再做修改)

bash 复制代码
echo "wal_level = replica" >> /var/lib/postgresql/data/postgresql.conf
echo "max_wal_senders = 100" >> /var/lib/postgresql/data/postgresql.conf
echo "max_replication_slots = 10" >> /var/lib/postgresql/data/postgresql.conf

创建复制槽

bash 复制代码
psql -U postgres -c "SELECT pg_create_physical_replication_slot('new_slave1');"

如果插槽存在,查看插槽对应的客户端信息

bash 复制代码
psql -U postgres -c "SELECT 
    s.slot_name,
    s.slot_type,
    s.active,
    s.active_pid,
    a.client_addr,
    a.client_hostname,
    a.application_name,
    a.state,
    s.restart_lsn,
    s.confirmed_flush_lsn,
    pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), s.restart_lsn)) as lag_size
FROM pg_replication_slots s
LEFT JOIN pg_stat_activity a ON s.active_pid = a.pid
ORDER BY s.slot_name;"

重新加载配置

bash 复制代码
psql -U postgres -c "SELECT pg_reload_conf();"

移除只读模式(如果之前设置了)

查看是否为只读模式

bash 复制代码
psql -U postgres -c "SHOW default_transaction_read_only;"

如果显示只读模式则关闭

bash 复制代码
psql -U postgres -c "ALTER SYSTEM SET default_transaction_read_only = off;"
psql -U postgres -c "SELECT pg_reload_conf();"

在新主节点(新服务器1)检查复制状态

bash 复制代码
docker exec postgres-slave-new1 psql -U postgres -c "
SELECT application_name, client_addr, state, sync_state, write_lag 
FROM pg_stat_replication;"

在新从节点(新服务器2)检查状态

bash 复制代码
docker exec postgres-slave-new2 psql -U postgres -c "SELECT pg_is_in_recovery(), 
       (SELECT sender_host  FROM pg_stat_wal_receiver) as primary_addr;"
相关推荐
古城小栈4 小时前
PostgreSQL 【vs】 MySQL
数据库·mysql·postgresql
Misnice5 小时前
MySQL 和 PostgreSQL 的区别
数据库·mysql·postgresql
q***016517 小时前
PostgreSQL 17 发布了!非常稳定的版本
数据库·postgresql
IvorySQL1 天前
Postgres 18:Skip Scan - 摆脱最左索引限制
数据库·postgresql·开源
g***72701 天前
从MySQL迁移到PostgreSQL的完整指南
数据库·mysql·postgresql
o***11141 天前
PostgreSQL的备份方式
数据库·postgresql
低头不见1 天前
CTE聚合查询,性能优化不止10几倍
java·sql·postgresql
菜萝卜子1 天前
k8s 启动 postgresql 数据库
数据库·postgresql·kubernetes
热爱跑步的恒川1 天前
OpenEuler上Docker Compose部署PostgreSQL数据库
数据库·docker·postgresql