Skip to content

PostgreSQL 在 Linux 上安装

安装方式选择

PostgreSQL 在 Linux 上有多种安装方式,每种方式适用于不同的场景和需求。以下是主要安装方式的比较:

安装方式适用场景优势劣势
包管理器安装快速部署、生产环境、标准配置简单快捷、自动依赖管理、便于更新、官方支持版本可能滞后、定制化程度低
编译安装自定义配置、特定版本需求、性能优化完全定制、最新版本、优化编译选项、适合特殊硬件复杂耗时、需手动管理依赖和更新
Docker 安装开发测试、容器化环境、快速部署隔离性好、部署快速、环境一致性、便于迁移性能开销、管理复杂度增加、不适合所有生产场景
二进制安装特定环境、无需编译、版本可控快速部署、版本可控、无需编译环境手动管理、更新复杂、缺乏系统集成

包管理器安装

Debian/Ubuntu 系统

安装步骤

bash
# 1. 更新包列表
apt update

# 2. 安装 PostgreSQL 及相关工具
# 安装最新稳定版本
apt install -y postgresql postgresql-contrib postgresql-client

# 或安装特定版本(如 PostgreSQL 15)
apt install -y postgresql-15 postgresql-client-15 postgresql-contrib-15

# 3. 验证安装
ps aux | grep postgres  # 查看 PostgreSQL 进程
pg_isready              # 检查数据库是否就绪
psql --version          # 查看 psql 客户端版本

服务管理

bash
# 启动服务
systemctl start postgresql
# 或针对特定版本
systemctl start postgresql@15-main

# 停止服务
systemctl stop postgresql

# 重启服务
systemctl restart postgresql

# 设置开机自启
systemctl enable postgresql

# 查看服务状态
systemctl status postgresql

初始访问

bash
# 切换到 postgres 系统用户
su - postgres

# 进入 PostgreSQL 命令行
psql

# 或直接访问(无需切换用户)
sudo -u postgres psql

# 退出 PostgreSQL 命令行
\q

CentOS/RHEL 系统

安装步骤

bash
# 1. 安装 PostgreSQL 官方仓库
# CentOS/RHEL 8
dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# CentOS/RHEL 7
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# 2. 禁用默认 PostgreSQL 模块(仅 RHEL 8+)
dnf -qy module disable postgresql

# 3. 安装 PostgreSQL
# 安装 PostgreSQL 15
dnf install -y postgresql15-server postgresql15-contrib postgresql15

# 4. 初始化数据库
/usr/pgsql-15/bin/postgresql-15-setup initdb

服务管理

bash
# 启动服务
systemctl start postgresql-15

# 停止服务
systemctl stop postgresql-15

# 重启服务
systemctl restart postgresql-15

# 设置开机自启
systemctl enable postgresql-15

# 查看服务状态
systemctl status postgresql-15

初始访问

bash
# 切换到 postgres 系统用户
su - postgres

# 进入 PostgreSQL 命令行
psql

# 或直接访问
sudo -u postgres psql

openSUSE/SUSE Linux Enterprise

安装步骤

bash
# 1. 添加 PostgreSQL 官方仓库
zypper addrepo -f https://download.postgresql.org/pub/repos/zypp/repo/pgdg-sles15-postgresql-15.repo

# 2. 安装 PostgreSQL
zypper install -y postgresql15 postgresql15-server postgresql15-contrib

# 3. 初始化数据库
/usr/pgsql-15/bin/postgresql-15-setup initdb

服务管理

bash
# 启动服务
systemctl start postgresql-15

# 停止服务
systemctl stop postgresql-15

# 重启服务
systemctl restart postgresql-15

# 设置开机自启
systemctl enable postgresql-15

编译安装

编译前准备

安装依赖

Debian/Ubuntu:

bash
apt install -y build-essential libreadline-dev zlib1g-dev libssl-dev \
libxml2-dev libxslt1-dev libxmlsec1-dev liblz4-dev libzstd-dev \
libbz2-dev krb5-multidev libcurl4-openssl-dev libicu-dev

CentOS/RHEL:

bash
dnf groupinstall -y "Development Tools"
dnf install -y readline-devel zlib-devel openssl-devel \
libxml2-devel libxslt-devel libxmlsec1-devel lz4-devel zstd-devel \
bzip2-devel krb5-devel curl-devel libicu-devel

下载并解压源码

bash
# 下载最新稳定版本
wget https://ftp.postgresql.org/pub/source/v16.1/postgresql-16.1.tar.bz2

# 或选择特定版本
wget https://ftp.postgresql.org/pub/source/v15.6/postgresql-15.6.tar.bz2

# 解压源码包
tar -xjf postgresql-16.1.tar.bz2
cd postgresql-16.1

配置编译选项

bash
# 查看所有可用配置选项
./configure --help

# 基本配置示例(适合大多数生产环境)
./configure \
  --prefix=/usr/local/pgsql \
  --with-pgport=5432 \
  --with-segsize=1 \
  --with-blocksize=8 \
  --with-wal-blocksize=8 \
  --enable-nls \
  --with-openssl \
  --with-libxml \
  --with-libxslt \
  --with-lz4 \
  --with-zstd \
  --with-bz2 \
  --with-curl \
  --with-icu \
  --enable-thread-safety \
  --with-systemd

# 高性能配置示例(适合内存充足的服务器)
./configure \
  --prefix=/usr/local/pgsql \
  --with-pgport=5432 \
  --with-segsize=1 \
  --with-blocksize=8 \
  --with-wal-blocksize=16 \
  --enable-nls \
  --with-openssl \
  --with-libxml \
  --with-libxslt \
  --with-lz4 \
  --with-zstd \
  --with-bz2 \
  --with-icu \
  --enable-thread-safety \
  --with-systemd \
  --with-tcl \
  --with-perl \
  --with-python

编译与安装

bash
# 编译(使用多核加速,-j 后接 CPU 核心数)
make -j $(nproc)

# 安装核心组件
make install

# 安装扩展模块
make -C contrib install

# 安装文档(可选)
make install-docs

# 安装手册页(可选)
make install-man

初始化与配置

创建用户和目录

bash
# 创建 postgres 系统用户
useradd -m -s /bin/bash postgres

# 设置密码
passwd postgres

# 创建数据目录
mkdir -p /data/pgdata
chown -R postgres:postgres /data/pgdata
chmod 700 /data/pgdata  # 数据目录必须是 700 权限

# 创建日志目录
mkdir -p /var/log/postgresql
chown -R postgres:postgres /var/log/postgresql

# 创建归档目录(如果启用 WAL 归档)
mkdir -p /data/pgarchive
chown -R postgres:postgres /data/pgarchive
chmod 700 /data/pgarchive

初始化数据库

bash
# 切换到 postgres 用户
su - postgres

# 设置环境变量(建议添加到 ~/.bashrc)
export PATH=/usr/local/pgsql/bin:$PATH
export PGDATA=/data/pgdata
export PGLOG=/var/log/postgresql/postgresql.log

# 初始化数据库
# 基本初始化
initdb -D $PGDATA -E UTF8 --locale=en_US.UTF-8 -W

# 生产环境初始化建议
initdb \
  -D $PGDATA \
  -E UTF8 \
  --locale=en_US.UTF-8 \
  --lc-collate=C \
  --lc-ctype=en_US.UTF-8 \
  --auth-local=peer \
  --auth-host=scram-sha-256 \
  -W

配置 postgresql.conf

bash
# 编辑配置文件
vi $PGDATA/postgresql.conf

# 基本生产环境配置建议
listen_addresses = '*'          # 允许所有IP访问(生产环境建议指定IP)
port = 5432                     # 端口号
max_connections = 200           # 最大连接数(根据实际需求调整)
shared_buffers = 4GB            # 共享缓冲区(建议系统内存的 25%)
work_mem = 8MB                  # 每个查询操作可使用的内存
maintenance_work_mem = 512MB    # 维护操作使用的内存

effective_cache_size = 12GB     # 系统缓存建议值(建议系统内存的 75%)
wal_level = replica             # WAL 级别(流复制需要 replica 或 higher)
archive_mode = on               # 启用 WAL 归档
archive_command = 'cp %p /data/pgarchive/%f'  # 归档命令
max_wal_size = 4GB             # 最大 WAL 大小
min_wal_size = 2GB             # 最小 WAL 大小
checkpoint_completion_target = 0.9  # 检查点完成目标(平滑 I/O)

log_destination = 'stderr'      # 日志输出目标
logging_collector = on          # 启用日志收集器
log_directory = '/var/log/postgresql'  # 日志目录
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'  # 日志文件名格式
log_rotation_age = '1d'         # 日志轮转时间
log_rotation_size = 0           # 按时间轮转,不按大小
log_min_duration_statement = 1000  # 记录执行时间超过 1 秒的语句
log_checkpoints = on            # 记录检查点信息
log_connections = on            # 记录连接信息
log_disconnections = on         # 记录断开连接信息

配置 pg_hba.conf

bash
# 编辑认证配置文件
vi $PGDATA/pg_hba.conf

# 添加以下规则(根据实际需求调整)
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             postgres                                peer
local   all             all                                     peer
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256

# 允许特定网段访问(生产环境建议限制 IP)
host    all             all             192.168.1.0/24          scram-sha-256

# 允许特定用户从任何 IP 访问特定数据库
host    mydb            myuser          0.0.0.0/0               scram-sha-256

创建 Systemd 服务文件

bash
# 创建服务文件
vi /etc/systemd/system/postgresql.service

# 服务文件内容
[Unit]
Description=PostgreSQL Database Server
After=network.target
After=syslog.target

[Service]
Type=forking
User=postgres
Group=postgres
Environment=PGDATA=/data/pgdata
Environment=PATH=/usr/local/pgsql/bin:$PATH
ExecStart=/usr/local/pgsql/bin/pg_ctl -D ${PGDATA} start -l /var/log/postgresql/postgresql.log
ExecStop=/usr/local/pgsql/bin/pg_ctl -D ${PGDATA} stop -m fast
ExecReload=/usr/local/pgsql/bin/pg_ctl -D ${PGDATA} reload
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

# 重新加载 systemd 配置
systemctl daemon-reload

# 启动服务
systemctl start postgresql

# 设置开机自启
systemctl enable postgresql

# 查看服务状态
systemctl status postgresql

Docker 安装

安装 Docker

bash
# 安装 Docker
curl -fsSL https://get.docker.com | bash

# 启动 Docker 服务
systemctl start docker

# 设置开机自启
systemctl enable docker

# 验证 Docker 安装
docker --version

运行 PostgreSQL 容器

bash
# 拉取官方镜像
# 拉取最新版本
docker pull postgres

# 或拉取特定版本
docker pull postgres:16

# 创建数据卷(持久化存储)
docker volume create pgdata

# 创建网络(可选,用于容器间通信)
docker network create pgnet

# 运行容器
# 基本运行
docker run -d \
  --name postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD=your_secure_password \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_DB=postgres \
  -v pgdata:/var/lib/postgresql/data \
  postgres:16

# 生产环境建议配置
docker run -d \
  --name postgres \
  --network pgnet \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD=your_secure_password \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_DB=postgres \
  -e PGDATA=/var/lib/postgresql/data/pgdata \
  -e POSTGRES_INITDB_ARGS="--encoding=UTF8 --lc-collate=C --lc-ctype=en_US.UTF-8" \
  -v pgdata:/var/lib/postgresql/data \
  -v /etc/localtime:/etc/localtime:ro \
  --restart=unless-stopped \
  --memory=8g \
  --cpus=4 \
  postgres:16

访问容器内的 PostgreSQL

bash
# 进入容器
docker exec -it postgres bash

# 在容器内访问 PostgreSQL
psql -U postgres

# 或直接执行命令(无需进入容器)
docker exec -it postgres psql -U postgres -c "SELECT version();"

# 备份容器内的数据库
docker exec -it postgres pg_dumpall -U postgres > /host/path/backup.sql

初始化配置

基本配置检查

bash
# 检查 PostgreSQL 版本
psql --version

# 检查数据库状态
pg_isready -h localhost -p 5432

# 查看服务器信息
psql -U postgres -c "SELECT version();"

# 查看当前数据库和用户
psql -U postgres -c "\l"  # 列出所有数据库
psql -U postgres -c "\du" # 列出所有用户/角色

初始数据库设置

sql
-- 更改 postgres 用户密码
ALTER USER postgres WITH PASSWORD 'new_secure_password';

-- 创建新数据库
CREATE DATABASE myapp;

-- 创建新用户并设置密码
CREATE USER myappuser WITH PASSWORD 'app_user_password';

-- 授予用户对数据库的权限
GRANT ALL PRIVILEGES ON DATABASE myapp TO myappuser;

-- 授予用户创建扩展的权限
ALTER USER myappuser CREATEDB CREATEROLE;

-- 或授予超级用户权限(谨慎使用)
-- ALTER USER myappuser WITH SUPERUSER;

生产环境配置建议

  1. 安全配置

    • 禁用远程 root 访问
    • 限制 PostgreSQL 监听地址
    • 使用强密码和加密认证
    • 配置防火墙限制访问
  2. 性能配置

    • 根据硬件资源调整 shared_bufferswork_mem 等参数
    • 配置适当的 WAL 级别和归档策略
    • 优化检查点参数减少 I/O 峰值
    • 配置日志记录级别和轮转策略
  3. 监控配置

    • 启用 PostgreSQL 统计收集
    • 配置日志监控和告警
    • 安装监控扩展(如 pg_stat_statementspg_stat_monitor

常见安装问题与解决方案

端口占用问题

症状:启动 PostgreSQL 时提示端口已被占用

解决方案

bash
# 查看端口占用情况
lsof -i :5432
# 或
ss -tulpn | grep 5432

# 终止占用端口的进程
kill -9 <PID>

# 或修改 PostgreSQL 端口
# 在 postgresql.conf 中修改
port = 5433

# 重启服务使配置生效
systemctl restart postgresql

权限问题

症状

  • FATAL: could not open directory "pg_tblspc": Permission denied
  • FATAL: data directory "/data/pgdata" has group or world access

解决方案

bash
# 检查数据目录权限
ls -ld /data/pgdata

# 修复数据目录权限
chown -R postgres:postgres /data/pgdata
chmod 700 /data/pgdata

# 检查日志目录权限
chown -R postgres:postgres /var/log/postgresql
chmod 750 /var/log/postgresql

依赖缺失问题

症状:编译时提示缺少依赖库

解决方案

bash
# Debian/Ubuntu:使用 apt-file 查找缺失的依赖包
apt install -y apt-file
apt-file update
apt-file search <missing-library.h>

# CentOS/RHEL:使用 dnf provides 查找缺失的依赖包
dnf provides */<missing-library.h>

# 安装找到的依赖包
apt install -y <package-name>
# 或
dnf install -y <package-name>

初始化失败

症状initdb 命令执行失败

解决方案

bash
# 检查错误日志
cat /var/log/postgresql/postgresql.log

# 常见原因及解决方法:
# 1. 数据目录非空
rm -rf /data/pgdata/*

# 2. 用户权限不足
chown -R postgres:postgres /data/pgdata

# 3. 环境变量问题
export PGDATA=/data/pgdata

# 4. 磁盘空间不足
df -h

# 5. 无效的编码或区域设置
initdb -D $PGDATA -E UTF8 --locale=C  # 使用安全的默认值

服务启动失败

症状systemctl start postgresql 失败

解决方案

bash
# 查看详细的服务状态
systemctl status postgresql -l

# 查看日志文件
journalctl -xeu postgresql

# 检查配置文件语法
/usr/local/pgsql/bin/pg_ctl -D /data/pgdata check

安装验证

功能验证

sql
-- 创建测试表
CREATE TABLE test (
  id SERIAL PRIMARY KEY,
  name VARCHAR(50) NOT NULL,
  value INTEGER,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入测试数据
INSERT INTO test (name, value) VALUES ('test1', 1), ('test2', 2), ('test3', 3);

-- 查询测试数据
SELECT * FROM test;

-- 更新测试数据
UPDATE test SET value = 100 WHERE name = 'test1';

-- 删除测试数据
DELETE FROM test WHERE name = 'test3';

-- 验证事务
BEGIN;
INSERT INTO test (name, value) VALUES ('test4', 4);
ROLLBACK;
-- 检查数据是否回滚
SELECT * FROM test;

-- 删除测试表
DROP TABLE test;

性能基准测试

bash
# 使用 pgbench 进行基准测试
# 初始化测试数据库
pgbench -i -U postgres -d postgres

# 运行测试(20 客户端,8 线程,运行 60 秒)
pgbench -c 20 -j 8 -T 60 -U postgres -d postgres

# 自定义测试(只读测试)
pgbench -c 20 -j 8 -T 60 -U postgres -d postgres -S

# 清理测试数据
dropdb -U postgres pgbenchdb
createdb -U postgres pgbenchdb

升级与迁移

包管理器安装的升级

Debian/Ubuntu:

bash
# 备份数据
pg_dumpall -U postgres > /backup/$(date +%Y%m%d)_fulldump.sql

# 更新包列表
apt update

# 升级 PostgreSQL
apt upgrade -y postgresql postgresql-contrib

# 验证升级
psql -U postgres -c "SELECT version();"

CentOS/RHEL:

bash
# 备份数据
pg_dumpall -U postgres > /backup/$(date +%Y%m%d)_fulldump.sql

# 升级 PostgreSQL
dnf update -y postgresql15-server postgresql15-contrib

# 验证升级
psql -U postgres -c "SELECT version();"

编译安装的升级

bash
# 1. 备份数据
pg_dumpall -U postgres > /backup/$(date +%Y%m%d)_fulldump.sql

# 2. 停止旧版本服务
systemctl stop postgresql

# 3. 安装新版本(按照编译安装步骤)
# 下载并编译新版本源码
# ...

# 4. 迁移数据
# 使用 pg_upgrade 迁移数据
pg_upgrade \
  --old-datadir=/data/pgdata_old \
  --new-datadir=/data/pgdata_new \
  --old-bindir=/usr/local/pgsql_old/bin \
  --new-bindir=/usr/local/pgsql_new/bin \
  --check  # 先检查迁移可行性

# 执行实际迁移
pg_upgrade \
  --old-datadir=/data/pgdata_old \
  --new-datadir=/data/pgdata_new \
  --old-bindir=/usr/local/pgsql_old/bin \
  --new-bindir=/usr/local/pgsql_new/bin

# 5. 启动新版本服务
systemctl start postgresql

# 6. 验证升级
psql -U postgres -c "SELECT version();"

# 7. 清理旧版本数据(可选)
# ./delete_old_cluster.sh

最佳实践

  1. 使用专用用户:始终使用 postgres 用户或专用的数据库用户运行 PostgreSQL,避免使用 root 用户

  2. 合理设置数据目录

    • 将数据目录与系统目录分离
    • 使用高性能存储(如 SSD/NVMe)
    • 确保足够的磁盘空间和 I/O 性能
  3. 配置合理的内存参数

    • shared_buffers:建议设置为系统内存的 25%
    • effective_cache_size:建议设置为系统内存的 75%
    • work_mem:根据查询复杂度和并发数调整
  4. 启用 WAL 归档

    • 配置 WAL 归档以支持时间点恢复
    • 将归档目录放在与数据目录不同的磁盘上
  5. 配置合理的日志策略

    • 启用日志收集器
    • 设置适当的日志级别和格式
    • 配置日志轮转和保留策略
  6. 配置防火墙

    • 限制 PostgreSQL 端口(5432)的访问
    • 只允许必要的 IP 地址访问
  7. 启用 SSL

    • 在生产环境中启用 SSL 加密
    • 使用有效的 SSL 证书
  8. 使用连接池

    • 对于高并发场景,使用 PgBouncer 或 Pgpool-II 等连接池
    • 合理配置连接池参数
  9. 定期备份

    • 建立定期备份策略(全量备份 + 增量备份)
    • 测试备份的可恢复性
    • 将备份存储在安全的位置
  10. 监控与告警

    • 安装监控工具(如 Prometheus + Grafana)
    • 监控关键指标(连接数、锁、慢查询等)
    • 配置告警机制

版本差异注意事项

PostgreSQL 版本重要变更
10统一 WAL 级别为 minimalreplicalogical
11支持并行查询、声明式分区
12引入 generated columns、改进查询优化
13改进索引性能、引入增量排序
14改进并发控制、引入并行 Vacuum
15增强安全特性、改进监控功能
16改进并行查询、增强统计信息

总结

PostgreSQL 在 Linux 上的安装方式多样,选择适合的安装方式取决于具体需求:

  • 快速部署:使用包管理器安装
  • 自定义配置:使用编译安装
  • 容器化环境:使用 Docker 安装
  • 特定版本需求:使用二进制安装或编译安装

无论使用哪种安装方式,都需要进行合理的配置和优化,以确保 PostgreSQL 数据库的性能和可靠性。在生产环境中,还需要建立完善的监控、备份和维护策略,定期进行性能调优和安全审计,以保证数据库的稳定运行。

通过遵循本文中的最佳实践和配置建议,DBA 可以快速、安全地在 Linux 系统上部署和配置 PostgreSQL 数据库,满足各种业务需求。