Ubuntu 22.04 安装配置 PostgreSQL 16 完整指南与最佳实践
1. 项目缘起:为什么是Ubuntu + PostgreSQL 16?
最近在给一个数据中台项目做技术选型,数据库这块,团队内部讨论了好几轮。MySQL 8.0固然成熟,但考虑到未来业务对复杂查询、GIS地理信息、JSONB原生支持以及更强大的并发事务处理能力的需求,我们最终还是把票投给了PostgreSQL。而版本选择上,直接上了最新的PostgreSQL 16。理由很简单:16版本在逻辑复制、并行查询、监控管理(比如pg_stat_io)方面有不少实用改进,对于新建项目,用新不用旧,能避免未来升级的麻烦。
操作系统环境我们统一用的是Ubuntu 22.04 LTS。LTS版本意味着长期稳定的支持,对于生产环境数据库来说,这是底线。但当你真正去Ubuntu的默认软件源里找postgresql-16时,会发现根本找不到。这是因为Ubuntu为了确保其仓库的稳定性,通常不会立即纳入上游软件的最新主版本。直接apt install postgresql装上的很可能是PostgreSQL 14。
所以,“在Ubuntu上安装PostgreSQL 16”这个看似简单的需求,背后其实涉及一个关键操作:配置PostgreSQL官方的APT软件仓库。这不仅仅是运行几条命令,更关乎后续能否顺畅地接收安全更新和bug修复。今天,我就把从仓库配置、软件安装、基础安全设置到连接测试的完整流程,以及我趟过的几个坑,详细拆解一遍。无论你是刚接触PostgreSQL的开发者,还是需要搭建新环境的运维,这篇都能让你一次搞定。
2. 核心准备:配置PostgreSQL官方APT仓库
这是整个安装过程的基石。用第三方仓库,首先要解决的是信任和来源问题。PostgreSQL全球开发组(PGDG)维护了针对各Linux发行版的官方仓库,这是最可靠的选择。
2.1 更新本地软件包索引并安装前置工具
在开始之前,确保你的系统是最新的,并安装一些必要的工具,其中curl和gnupg是关键。
sudo apt update sudo apt upgrade -y sudo apt install -y curl gnupg lsb-release这里解释一下为什么是这几个包:
curl:用于从网络下载仓库的签名密钥。gnupg:GNU Privacy Guard,用于验证下载的软件包签名,确保软件来源未被篡改。这是安全安装的必备。lsb-release:一个工具,可以方便地获取系统的LSB(Linux Standard Base)信息,比如发行版代号。我们稍后写仓库源地址时会用到它来动态获取系统版本,让脚本更具通用性。
2.2 导入PostgreSQL官方签名密钥
软件仓库的GPG密钥相当于一个官方的“印章”。APT在下载软件包时会用这个“印章”来验证包是否真的来自官方,而不是被恶意篡改过的。
sudo mkdir -p /etc/apt/keyrings curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/keyrings/postgresql.gpg让我们拆解这条命令:
sudo mkdir -p /etc/apt/keyrings:创建目录。-p参数确保如果目录已存在也不会报错。在较新的Ubuntu/Debian系统中,/etc/apt/keyrings是存放第三方仓库密钥的推荐位置。curl -fsSL https://...:-f表示静默失败,-s静默模式,-S在错误时显示错误信息,-L跟随重定向。组合使用让curl更健壮。| sudo gpg --dearmor -o /etc/apt/keyrings/postgresql.gpg:将curl下载的密钥流通过管道传递给gpg。--dearmor命令是将ASCII格式的密钥(.asc文件)转换为二进制格式(.gpg),这是APT能够识别的格式。-o指定输出文件路径。
注意:一定要确保最终生成的
postgresql.gpg文件权限正确(应该是644),并且所属用户和组是root。上面的命令通过sudo执行,通常没问题。如果手动操作,记得用sudo chmod 644 /etc/apt/keyrings/postgresql.gpg检查一下。
2.3 创建APT仓库源文件
接下来,我们需要告诉APT系统,去哪里寻找PostgreSQL 16的软件包。
echo "deb [signed-by=/etc/apt/keyrings/postgresql.gpg] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list这是最关键的一行命令,我们来逐部分解析:
deb:表示这是一个二进制软件包仓库。[signed-by=/etc/apt/keyrings/postgresql.gpg]:指定用于验证此仓库的GPG密钥路径。这是Ubuntu 22.04及以后版本推荐的做法,比之前将密钥添加到apt-key链更清晰、易于管理。https://apt.postgresql.org/pub/repos/apt:PostgreSQL官方APT仓库的地址。$(lsb_release -cs)-pgdg main:动态定义仓库的发行版和组件。$(lsb_release -cs):一个命令替换,会执行lsb_release -cs并输出结果。对于Ubuntu 22.04,这个结果是jammy。这样做的好处是,如果你的系统是Ubuntu 20.04 (focal),它会自动替换为focal,命令具有可移植性。-pgdg:PGDG仓库的命名约定。main:仓库的组件名。
| sudo tee /etc/apt/sources.list.d/pgdg.list:echo输出的内容通过管道传给tee命令,tee会同时将内容显示在屏幕(标准输出)并写入到/etc/apt/sources.list.d/pgdg.list文件中。/etc/apt/sources.list.d/目录下的.list文件都会被APT自动读取,这样做的目的是将第三方仓库的配置与系统默认的sources.list文件隔离,管理起来更清晰。
2.4 更新软件包列表
添加了新仓库之后,必须更新本地的软件包索引,让APT知道这个新仓库里有哪些可用的软件包。
sudo apt update执行这个命令后,你应该能在输出信息中看到类似于“命中:13 https://apt.postgresql.org/pub/repos/apt jammy-pgdg InRelease”的字样,这说明PGDG仓库已经成功添加并可用。
3. 安装与基础配置PostgreSQL 16
仓库配置妥当,安装就水到渠成了。但安装过程中的一些选择,会直接影响你后续的使用体验。
3.1 安装PostgreSQL 16服务器与客户端
sudo apt install -y postgresql-16 postgresql-client-16为什么指定版本-16?
- 明确指定版本可以确保安装的就是我们想要的PostgreSQL 16。如果不指定,
apt install postgresql可能会安装软件源里默认的旧版本。 - 同时安装
postgresql-client-16非常重要。它包含了像psql这样的核心客户端工具,让你能够连接和管理数据库。虽然服务器包可能依赖客户端包,但显式安装是个好习惯。
安装过程会自动完成以下事情:
- 创建名为
postgres的系统用户和用户组,用于运行数据库服务(安全最佳实践:服务以非root用户运行)。 - 在
/etc/postgresql/16/main/目录下生成主配置文件postgresql.conf和客户端认证配置文件pg_hba.conf。 - 在
/var/lib/postgresql/16/main/目录下初始化数据库集群(即主数据目录)。 - 创建并启动一个名为
postgresql@16-main的systemd服务。
安装完成后,立即检查服务状态是一个好习惯:
sudo systemctl status postgresql@16-main你应该看到服务状态为active (running)。如果处于inactive状态,使用sudo systemctl start postgresql@16-main启动它,并使用sudo systemctl enable postgresql@16-main设置开机自启。
3.2 修改postgres用户密码与初始连接
PostgreSQL安装后,会创建一个默认的数据库超级用户postgres。在本地,配置为使用“peer authentication”方式,允许同名的系统用户无需密码直接以postgres数据库用户身份登录。
方式一:使用sudo切换系统用户(推荐初学者)这是最直接的方式,利用了“peer authentication”。
sudo -u postgres psql这条命令的意思是:以系统用户postgres的身份执行psql命令。由于psql默认不指定参数会尝试连接与当前系统用户名同名的数据库和用户,所以它就以数据库用户postgres的身份连接到了postgres数据库,进入了交互式命令行。
进入psql后,提示符会变成postgres=#。我们可以修改postgres用户的密码:
ALTER USER postgres WITH PASSWORD 'YourStrongPassword123!';请务必将'YourStrongPassword123!'替换成一个高强度密码。完成后输入\q退出psql。
方式二:直接以postgres系统用户登录你也可以先切换到postgres系统用户,再执行psql。
sudo su - postgres psql # 执行ALTER USER命令... exit # 退出postgres系统用户回到原用户3.3 配置远程访问(按需)
默认情况下,PostgreSQL只监听本地回环地址127.0.0.1,且pg_hba.conf的配置只允许本地“peer”或“ident”认证。如果你需要从其他服务器连接(例如应用服务器连接数据库服务器),需要修改两个配置。
重要安全提示:仅在确实需要远程访问时才进行此操作,并务必结合防火墙(如UFW)限制访问源IP。生产环境强烈建议通过内网连接或使用SSH隧道。
1. 修改监听地址:编辑主配置文件postgresql.conf。
sudo nano /etc/postgresql/16/main/postgresql.conf找到listen_addresses这一行。默认可能是:
#listen_addresses = 'localhost'取消注释,并将值改为'*'(监听所有网络接口)或特定的IP地址(如'192.168.1.100')。
listen_addresses = '*'2. 修改客户端认证规则:编辑pg_hba.conf文件。
sudo nano /etc/postgresql/16/main/pg_hba.conf在文件末尾添加一行,允许特定网段或所有IP使用密码进行MD5加密认证。例如,允许所有IPv4连接:
# TYPE DATABASE USER ADDRESS METHOD host all all 0.0.0.0/0 md5或者,更安全地,只允许你的应用服务器网段(例如192.168.1.0/24):
host all all 192.168.1.0/24 md53. 重启PostgreSQL服务使配置生效:
sudo systemctl restart postgresql@16-main4. 配置防火墙(如果使用UFW):如果系统启用了UFW,需要开放PostgreSQL默认的5432端口。
sudo ufw allow from 192.168.1.0/24 to any port 5432 # 仅允许特定网段 # 或(谨慎使用) # sudo ufw allow 5432/tcp sudo ufw reload4. 基础操作、管理与问题排查
安装配置完成后,我们来看看日常最基本的管理操作和可能遇到的问题。
4.1 常用命令行操作
连接数据库:
# 本地连接,指定用户和数据库 psql -U postgres -d postgres # 远程连接 psql -h <服务器IP> -U postgres -d postgres系统会提示输入密码。
在psql中的常用元命令:
\l:列出所有数据库。\c <database_name>:切换到另一个数据库。\dt:列出当前数据库中的所有表。\du或\dg:列出所有数据库角色(用户和组)。\q:退出psql。
创建新数据库和用户:
-- 在psql中执行 CREATE DATABASE myappdb; CREATE USER myappuser WITH ENCRYPTED PASSWORD 'UserPassword123!'; GRANT ALL PRIVILEGES ON DATABASE myappdb TO myappuser; -- 更精细的权限控制通常还需要在连接到具体数据库后,对schema和表进行授权
4.2 服务管理命令
记住,服务名是postgresql@16-main,而不是简单的postgresql。
# 启动服务 sudo systemctl start postgresql@16-main # 停止服务 sudo systemctl stop postgresql@16-main # 重启服务(修改配置后常用) sudo systemctl restart postgresql@16-main # 查看服务状态 sudo systemctl status postgresql@16-main # 设置开机自启 sudo systemctl enable postgresql@16-main # 禁用开机自启 sudo systemctl disable postgresql@16-main4.3 常见问题与排查
问题1:安装时提示“无法定位软件包 postgresql-16”这几乎肯定是APT仓库没有正确配置。
- 检查:运行
sudo apt update,查看输出中是否有PGDG仓库的错误信息(如404 Not Found)。 - 解决:检查
/etc/apt/sources.list.d/pgdg.list文件内容是否正确,特别是$(lsb_release -cs)展开后的发行版代号(如jammy)是否正确。可以手动运行lsb_release -cs验证。也可以去浏览器打开https://apt.postgresql.org/pub/repos/apt/dists/,查看是否存在以你的发行版代号-pgdg命名的目录。
问题2:psql: could not connect to server: Connection refused连接被拒绝,通常是因为服务没启动,或者监听地址配置不正确。
- 检查服务状态:
sudo systemctl status postgresql@16-main。 - 检查监听地址:确认
postgresql.conf中的listen_addresses是否包含你正在连接的地址(本地localhost或远程IP)。 - 检查端口:默认是5432。使用
sudo ss -tlnp | grep 5432查看是否有进程在监听该端口。
问题3:password authentication failed for user “postgres”密码认证失败。
- 确认密码:你是否在用
ALTER USER设置的密码?注意密码中的大小写和特殊字符。 - 检查
pg_hba.conf:对于你的连接方式(本地socket还是TCP/IP),对应的METHOD是md5(密码)还是peer/ident?如果你从本地用psql -U postgres连接,对应的行很可能是local all postgres peer,它期望的是系统用户认证,而不是密码。这时你应该用sudo -u postgres psql。
问题4:日志文件在哪里?日志是排查问题的金矿。PostgreSQL 16的日志通常配置为写入系统日志(syslog),但也可以通过postgresql.conf中的log_destination和logging_collector配置为写入文件。默认情况下,你可以查看:
sudo journalctl -u postgresql@16-main -f # 查看实时日志 sudo tail -f /var/log/postgresql/postgresql-16-main.log # 如果配置了文件日志配置文件postgresql.conf中的log_line_prefix和log_statement等参数可以控制日志的详细程度。
5. 性能与安全初步调优(可选但重要)
对于刚安装的实例,有几个配置项值得在投入生产前根据硬件情况调整。编辑/etc/postgresql/16/main/postgresql.conf,以下是一些起点建议:
5.1 内存相关配置
shared_buffers:数据库服务器使用的共享内存缓冲区。通常设置为系统总内存的25%。对于4GB内存的机器,可以设置为1GB。shared_buffers = 1GBeffective_cache_size:PostgreSQL查询规划器假设操作系统可用于磁盘缓存的内存大小。通常设置为系统总内存的50%-75%。effective_cache_size = 2GBwork_mem:用于排序和哈希表操作的内存。设置过大可能导致内存溢出。可以保守地从4MB开始,对于复杂查询多的系统可以适当增加。work_mem = 4MBmaintenance_work_mem:用于维护操作(如VACUUM, CREATE INDEX)的内存。可以设置得比work_mem大,例如256MB。maintenance_work_mem = 256MB
5.2 连接与检查点
max_connections:最大并发连接数。默认通常是100。设置过高会消耗更多内存。需要根据应用实际并发量调整。如果应用使用连接池(如PgBouncer),这里可以设置得低一些。max_connections = 100checkpoint_completion_target:检查点完成的目标比例,默认0.9。这有助于平滑I/O,通常保持默认即可。random_page_cost:对于使用SSD的服务器,可以降低此值(如1.1),让优化器更倾向于使用索引扫描。random_page_cost = 1.1 # 如果使用SSD
修改任何配置后,都需要重启PostgreSQL服务才能生效:
sudo systemctl restart postgresql@16-main5.3 安全加固建议
- 更改默认端口:在
postgresql.conf中修改port = 5432为其他端口,可以减少自动化攻击脚本的扫描。 - 限制超级用户:除了
postgres,避免创建其他超级用户。为每个应用创建专属的普通用户,并仅授予其所需数据库的最小权限。 - 定期更新:由于我们使用了官方仓库,定期运行
sudo apt update && sudo apt upgrade可以及时获取安全更新。 - 备份
pg_hba.conf:在对pg_hba.conf进行重大修改前,先进行备份。一个错误的配置可能导致所有连接被拒绝,包括本地连接。
6. 验证安装与后续步骤
完成所有步骤后,进行一次完整的验证是个好习惯。
- 验证服务运行:
systemctl status显示为active (running)。 - 验证本地连接:使用
sudo -u postgres psql能成功进入命令行。 - 验证网络连接(如果配置了):从另一台机器使用
psql -h <你的服务器IP> -U postgres -d postgres进行连接,输入密码后应能成功。 - 执行一个简单查询:在
psql中运行SELECT version();,应该能正确返回PostgreSQL 16的版本信息。
至此,一个功能完整、基础安全的PostgreSQL 16数据库服务就在你的Ubuntu系统上搭建完成了。接下来的工作,就是根据你的具体业务需求,创建数据库、设计表结构、导入数据,并在此基础上进行更深入的性能监控和调优了。对于生产环境,务必制定完善的备份策略(如使用pg_dump逻辑备份或pg_basebackup物理备份),并考虑配置复制(Replication)以实现高可用。