第十三章:高可用与复制
最后更新: 2024-01-01
作者: PostgreSQL Team
页面目录
第十三章:高可用与复制
13.1 复制概述
┌─────────────────────────────────────────────────────────────┐
│ PostgreSQL 复制架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Primary ─────► Standby 1 (同步) │
│ │ ─────► Standby 2 (异步) │
│ │ ─────► Standby 3 (异步) │
│ │ │
│ ┌──┴──┐ │
│ │ │ │
│ sync async │
│ │
└─────────────────────────────────────────────────────────────┘
13.2 流复制配置
13.2.1 主库配置
# postgresql.conf
# 启用 WAL
wal_level = replica
# 最大复制连接数
max_wal_senders = 10
# WAL 保留
wal_keep_size = 1GB
max_replication_slots = 10
# 复制相关参数
synchronous_commit = on
synchronous_standby_names = 'standby1,standby2'
13.2.2 pg_hba.conf 配置
# TYPE DATABASE USER ADDRESS METHOD
# 允许复制连接
host replication replicator 192.168.1.0/24 scram-sha-256
host all postgres 192.168.1.0/24 scram-sha-256
13.2.3 创建复制用户
-- 创建复制用户
CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'replicator_password';
-- 授予必要权限
GRANT CONNECT ON DATABASE mydb TO replicator;
GRANT USAGE ON SCHEMA public TO replicator;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO replicator;
13.2.4 从库配置
# 方法 1:使用 pg_basebackup
pg_basebackup -h primary_ip -U replicator -D /var/lib/postgresql/16/main -P -Xs -R
# 参数说明:
# -h: 主库地址
# -U: 复制用户名
# -D: 从库数据目录
# -P: 显示进度
# -Xs: 包含 WAL 文件
# -R: 创建 standby.signal 文件
# 方法 2:手动配置
# 1. 从主库复制数据
rsync -av --exclude=pg_wal primary_server:/var/lib/postgresql/data/ /var/lib/postgresql/data/
# 2. 创建 standby.signal
touch /var/lib/postgresql/data/standby.signal
# 3. 配置连接信息
cat >> /var/lib/postgresql/data/postgresql.auto.conf << 'EOF'
primary_conninfo = 'host=primary_ip port=5432 user=replicator password=replicator_password application_name=standby1'
EOF
13.3 同步与异步复制
13.3.1 配置同步复制
# 主库 postgresql.conf
synchronous_commit = on
synchronous_standby_names = 'standby1,standby2'
# 同步复制优先级
synchronous_standby_names = 'standby1 (priority=2), standby2 (priority=1)'
13.3.2 复制状态查询
-- 在主库查看复制状态
SELECT * FROM pg_stat_replication;
-- 详细复制信息
SELECT
client_addr,
state,
sent_lsn,
write_lsn,
flush_lsn,
replay_lsn,
sync_state,
sync_priority
FROM pg_stat_replication;
-- 查看复制槽
SELECT * FROM pg_replication_slots;
-- 在从库查看复制状态
SELECT * FROM pg_stat_wal_receiver;
13.3.3 复制延迟监控
-- 主库监控复制延迟
SELECT
client_hostname,
state,
pg_size_pretty(
pg_wal_lsn_diff(sent_lsn, replay_lsn)
) AS replication_delay
FROM pg_stat_replication;
-- 从库查看延迟
SELECT
now() - pg_last_xact_replay_timestamp() AS replay_delay;
13.4 故障转移
13.4.1 手动故障转移
# 在主库查看复制状态
psql -U postgres -c "SELECT * FROM pg_stat_replication;"
# 停止主库
sudo systemctl stop postgresql
# 在新主库执行提升
sudo -u postgres pg_ctl promote -D /var/lib/postgresql/data
# 验证新主库
psql -U postgres -c "SELECT pg_is_in_recovery();"
# 应返回 f (false)
# 更新其他从库指向新主库
# 在其他从库执行:
psql -U postgres -c "SELECT pg_reload_conf();"
13.4.2 自动故障转移 - Patroni
# patroni.yml 配置示例
patroni:
name: node1
scope: postgres-cluster
namespace: /service
restapi:
listen: 0.0.0.0:8008
connect_address: node1:8008
etcd:
host: etcd:2379
postgresql:
listen: 0.0.0.0:5432
connect_address: node1:5432
data_dir: /data/postgresql
parameters:
wal_level: replica
max_wal_senders: 10
max_replication_slots: 10
hot_standby: on
slots:
persistent_slots:
node2:
type: physical
node3:
type: physical
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
synchronous_node_count: 1
members:
- node1
- node2
- node3
13.5 逻辑复制
13.5.1 配置逻辑复制
# postgresql.conf
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10
13.5.2 创建逻辑复制
-- 1. 创建发布
CREATE PUBLICATION my_publication FOR TABLE users, orders;
-- 2. 创建订阅
CREATE SUBSCRIPTION my_subscription
CONNECTION 'host=primary_ip port=5432 dbname=mydb user=replicator'
PUBLICATION my_publication;
-- 3. 查看订阅状态
SELECT * FROM pg_stat_subscription;
-- 4. 查看复制表
SELECT * FROM pg_publication_tables;
13.5.3 逻辑复制示例
-- 只复制特定行
CREATE PUBLICATION active_users_pub FOR TABLE users
WHERE (status = 'active');
-- 复制所有表的变更
CREATE PUBLICATION full_db_pub FOR ALL TABLES;
-- 添加表到发布
ALTER PUBLICATION my_publication ADD TABLE products;
-- 删除表
ALTER PUBLICATION my_publication DROP TABLE products;
-- 禁用表同步
ALTER SUBSCRIPTION my_subscription ALTER TABLE users SET (copy_data = false);
13.6 负载均衡
13.6.1 PgBouncer 配置
# pgbouncer.ini
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20
min_pool_size = 5
reserve_pool_size = 5
reserve_pool_timeout = 5
log_connections = 1
log_disconnections = 1
log_pooler_errors = 1
13.6.2 HAProxy 配置
# haproxy.cfg
listen postgres
bind 0.0.0.0:5432
mode tcp
balance roundrobin
# 主库(读写)
server primary primary_ip:5432 check port 5432 inter 2000 rise 2 fall 3
# 从库(只读)
server replica1 replica1_ip:5432 check port 5432 inter 2000 rise 2 fall 3
server replica2 replica2_ip:5432 check port 5432 inter 2000 rise 2 fall 3
listen pgbouncer
bind 0.0.0.0:6432
mode tcp
balance leastconn
server pgbouncer1 127.0.0.1:6432
13.7 高可用架构方案
| 方案 | 说明 | 复杂度 |
|---|---|---|
| 原生流复制 | 主从流复制 | 低 |
| Patroni + etcd | 自动故障转移 | 中 |
| Patroni + Consul | 自动故障转移 | 中 |
| pgpool-II | 读写分离 + 连接池 | 中 |
| Citus | 分布式 PostgreSQL | 高 |
13.8 本章小结
高可用与复制关键概念:
| 主题 | 说明 |
|---|---|
| 流复制 | WAL 流式传输到从库 |
| 同步复制 | 确保数据写入从库后提交 |
| 异步复制 | 可能有延迟 |
| 逻辑复制 | 表级别复制 |
| 故障转移 | 手动或自动 |
📌 下一章预告
下一章将介绍 PostgreSQL 的安全配置和管理。