三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Ubuntu 22.04 安装配置 PostgreSQL 16 完整指南与最佳实践

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 更新本地软件包索引并安装前置工具

在开始之前,确保你的系统是最新的,并安装一些必要的工具,其中curlgnupg是关键。

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

让我们拆解这条命令:

  1. sudo mkdir -p /etc/apt/keyrings:创建目录。-p参数确保如果目录已存在也不会报错。在较新的Ubuntu/Debian系统中,/etc/apt/keyrings是存放第三方仓库密钥的推荐位置。
  2. curl -fsSL https://...-f表示静默失败,-s静默模式,-S在错误时显示错误信息,-L跟随重定向。组合使用让curl更健壮。
  3. | 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.listecho输出的内容通过管道传给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这样的核心客户端工具,让你能够连接和管理数据库。虽然服务器包可能依赖客户端包,但显式安装是个好习惯。

安装过程会自动完成以下事情:

  1. 创建名为postgres的系统用户和用户组,用于运行数据库服务(安全最佳实践:服务以非root用户运行)。
  2. /etc/postgresql/16/main/目录下生成主配置文件postgresql.conf和客户端认证配置文件pg_hba.conf
  3. /var/lib/postgresql/16/main/目录下初始化数据库集群(即主数据目录)。
  4. 创建并启动一个名为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 md5

3. 重启PostgreSQL服务使配置生效:

sudo systemctl restart postgresql@16-main

4. 配置防火墙(如果使用UFW):如果系统启用了UFW,需要开放PostgreSQL默认的5432端口。

sudo ufw allow from 192.168.1.0/24 to any port 5432 # 仅允许特定网段 # 或(谨慎使用) # sudo ufw allow 5432/tcp sudo ufw reload

4. 基础操作、管理与问题排查

安装配置完成后,我们来看看日常最基本的管理操作和可能遇到的问题。

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-main

4.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),对应的METHODmd5(密码)还是peer/ident?如果你从本地用psql -U postgres连接,对应的行很可能是local all postgres peer,它期望的是系统用户认证,而不是密码。这时你应该用sudo -u postgres psql

问题4:日志文件在哪里?日志是排查问题的金矿。PostgreSQL 16的日志通常配置为写入系统日志(syslog),但也可以通过postgresql.conf中的log_destinationlogging_collector配置为写入文件。默认情况下,你可以查看:

sudo journalctl -u postgresql@16-main -f # 查看实时日志 sudo tail -f /var/log/postgresql/postgresql-16-main.log # 如果配置了文件日志

配置文件postgresql.conf中的log_line_prefixlog_statement等参数可以控制日志的详细程度。

5. 性能与安全初步调优(可选但重要)

对于刚安装的实例,有几个配置项值得在投入生产前根据硬件情况调整。编辑/etc/postgresql/16/main/postgresql.conf,以下是一些起点建议:

5.1 内存相关配置

  • shared_buffers:数据库服务器使用的共享内存缓冲区。通常设置为系统总内存的25%。对于4GB内存的机器,可以设置为1GB
    shared_buffers = 1GB
  • effective_cache_size:PostgreSQL查询规划器假设操作系统可用于磁盘缓存的内存大小。通常设置为系统总内存的50%-75%。
    effective_cache_size = 2GB
  • work_mem:用于排序和哈希表操作的内存。设置过大可能导致内存溢出。可以保守地从4MB开始,对于复杂查询多的系统可以适当增加。
    work_mem = 4MB
  • maintenance_work_mem:用于维护操作(如VACUUM, CREATE INDEX)的内存。可以设置得比work_mem大,例如256MB
    maintenance_work_mem = 256MB

5.2 连接与检查点

  • max_connections:最大并发连接数。默认通常是100。设置过高会消耗更多内存。需要根据应用实际并发量调整。如果应用使用连接池(如PgBouncer),这里可以设置得低一些。
    max_connections = 100
  • checkpoint_completion_target:检查点完成的目标比例,默认0.9。这有助于平滑I/O,通常保持默认即可。
  • random_page_cost:对于使用SSD的服务器,可以降低此值(如1.1),让优化器更倾向于使用索引扫描。
    random_page_cost = 1.1 # 如果使用SSD

修改任何配置后,都需要重启PostgreSQL服务才能生效:

sudo systemctl restart postgresql@16-main

5.3 安全加固建议

  1. 更改默认端口:在postgresql.conf中修改port = 5432为其他端口,可以减少自动化攻击脚本的扫描。
  2. 限制超级用户:除了postgres,避免创建其他超级用户。为每个应用创建专属的普通用户,并仅授予其所需数据库的最小权限。
  3. 定期更新:由于我们使用了官方仓库,定期运行sudo apt update && sudo apt upgrade可以及时获取安全更新。
  4. 备份pg_hba.conf:在对pg_hba.conf进行重大修改前,先进行备份。一个错误的配置可能导致所有连接被拒绝,包括本地连接。

6. 验证安装与后续步骤

完成所有步骤后,进行一次完整的验证是个好习惯。

  1. 验证服务运行systemctl status显示为active (running)
  2. 验证本地连接:使用sudo -u postgres psql能成功进入命令行。
  3. 验证网络连接(如果配置了):从另一台机器使用psql -h <你的服务器IP> -U postgres -d postgres进行连接,输入密码后应能成功。
  4. 执行一个简单查询:在psql中运行SELECT version();,应该能正确返回PostgreSQL 16的版本信息。

至此,一个功能完整、基础安全的PostgreSQL 16数据库服务就在你的Ubuntu系统上搭建完成了。接下来的工作,就是根据你的具体业务需求,创建数据库、设计表结构、导入数据,并在此基础上进行更深入的性能监控和调优了。对于生产环境,务必制定完善的备份策略(如使用pg_dump逻辑备份或pg_basebackup物理备份),并考虑配置复制(Replication)以实现高可用。

← 返回列表