加油
努力

如何在单台服务器上部署多个PostgreSQL数据库实例?

在单台服务器上部署多个 PostgreSQL 实例是常见且完全可行的做法,通常用于隔离不同项目、测试环境或数据库版本。以下是完整、安全的部署步骤:


✅ 核心思路

每个 PostgreSQL 实例使用:

  • 独立的 data 目录(存放数据文件)
  • 独立的监听端口(如 5432, 5433, 5434…)
  • 独立的 Unix socket 路径(可选但推荐)
  • 独立的系统用户(可选但增强安全性)

🛠️ 步骤详解(以 Ubuntu/Debian 为例)

1️⃣ 安装 PostgreSQL

sudo apt update
sudo apt install postgresql postgresql-contrib
# 默认会安装一个实例(data_dir: /var/lib/postgresql/16/main),监听 5432

💡 若需特定版本(如 14、15、17),可从官方源安装对应包:
apt install postgresql-14 postgresql-15


2️⃣ 创建第二个实例(示例:端口 5433)

方法 A:使用 pg_ctlcluster(推荐,适用于 Debian/Ubuntu)

# 创建新集群(指定端口和数据目录)
sudo pg_createcluster 16 secondary --port=5433 --datadir=/var/lib/postgresql/16/secondary

# 启动实例
sudo pg_ctlcluster 16 secondary start

# 设置开机自启
sudo systemctl enable postgresql@16-secondary.service

✅ 验证:

sudo -u postgres psql -p 5433 -c "SELECT version();"

方法 B:手动初始化(更灵活,适合非标准路径或自定义配置)

# 创建专用用户(可选但安全)
sudo useradd -r -s /bin/false postgres_sec

# 创建数据目录
sudo mkdir -p /opt/pg_data/instance2
sudo chown postgres:postgres /opt/pg_data/instance2
sudo chmod 700 /opt/pg_data/instance2

# 初始化数据库(使用与主实例相同的 PG_VERSION)
sudo -u postgres initdb -D /opt/pg_data/instance2

# 修改配置文件
cat > /opt/pg_data/instance2/postgresql.conf <<EOF
listen_addresses = 'localhost'
port = 5433
unix_socket_directories = '/tmp'
data_directory = '/opt/pg_data/instance2'
log_destination = 'stderr'
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'instance2-%Y-%m-%d.log'
max_connections = 100
shared_buffers = 256MB
EOF

# 配置权限(pg_hba.conf)
cat > /opt/pg_data/instance2/pg_hba.conf <<EOF
local   all             all                                     peer
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256
EOF

# 启动实例
sudo -u postgres /usr/lib/postgresql/16/bin/pg_ctl 
  -D /opt/pg_data/instance2 
  -l /var/log/postgresql/instance2.log 
  start

# 设置开机启动(systemd 服务)
sudo tee /etc/systemd/system/postgresql-instance2.service > /dev/null <<EOF
[Unit]
Description=PostgreSQL Instance 2
After=network.target

[Service]
Type=forking
User=postgres
Group=postgres
ExecStart=/usr/lib/postgresql/16/bin/pg_ctl -D /opt/pg_data/instance2 start
ExecStop=/usr/lib/postgresql/16/bin/pg_ctl -D /opt/pg_data/instance2 stop
PIDFile=/opt/pg_data/instance2/postmaster.pid
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable postgresql-instance2
sudo systemctl start postgresql-instance2

3️⃣ 管理多个实例

操作 命令
查看状态 pg_lsclusters(Debian)或 systemctl status postgresql@*
启动实例 pg_ctlcluster 16 secondary startsystemctl start postgresql-instance2
停止实例 pg_ctlcluster 16 secondary stop
重启实例 pg_ctlcluster 16 secondary restart
连接实例 psql -h localhost -p 5433 -U youruser
备份单个实例 pg_dumpall -p 5433 > backup_5433.sql
恢复单个实例 psql -p 5433 < restore_5433.sql

🔐 安全建议

  • 为每个实例创建独立 OS 用户(避免共享 postgres 权限)
  • 限制 pg_hba.conf 的访问来源(仅允许必要 IP)
  • 启用 SSL(在 postgresql.conf 中配置 ssl = on + 证书)
  • 定期监控磁盘空间(多实例易占满 /var/opt
  • 使用 pg_rewind 或流复制实现高可用(跨实例容灾)

📊 扩展提示

  • 可结合 Docker 容器化部署(每个实例一个容器,通过 docker-compose 编排)
  • 使用 pgbouncer 做连接池,统一暴露端口给应用
  • 监控工具:Prometheus + postgres_exporter(支持多实例指标采集)

需要我提供 Docker 版多实例方案CentOS/RHEL 下的 systemd 配置模板 吗?

云服务器