在单台服务器上部署多个 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 start 或 systemctl 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 配置模板 吗?
云小栈