本站包含联盟链接——如果你通过链接注册,我们可能获得佣金。 Affiliate links.

DigitalOcean Droplet 上的 PostgreSQL 调优指南 2026

DigitalOcean Droplet 上的 PostgreSQL 调优指南 2026

通过 apt 包管理器用默认设置在 Droplet 上安装的 PostgreSQL 通常没有针对实际机器规格进行调优,因为 PostgreSQL 的默认值是为内存最小的机器设计的,而不是为拥有 2GB、4GB 或更多 RAM 的 Droplet 设计的。本文通过真实命令示例说明如何在 Droplet 上安装和调优 PostgreSQL 的主要参数,包括何时应该停止自我管理并改为迁移到托管数据库。

在 Droplet 上安装 PostgreSQL

在运行 Ubuntu 或 Debian 的 Droplet 上安装 PostgreSQL 可以直接通过 apt 完成。首先使用 sudo apt update 更新包列表,然后使用 sudo apt install postgresql postgresql-contrib 安装。系统将安装 PostgreSQL 服务器和随附的标准扩展(如 pg_stat_statements)的 contrib 扩展。安装完成后,服务会自动启动。您可以使用 sudo systemctl status postgresql 检查状态。 下一步是通过首先进入 psql shell 为 postgres 系统用户设置密码:sudo -u postgres psql,然后运行命令 ALTER USER postgres WITH PASSWORD 'set your password here';。在 shell 中,使用 \q 退出。您需要了解的两个主要配置文件是 postgresql.conf(控制所有实例参数)和 pg_hba.conf(控制哪些客户端可以连接以及使用哪种身份验证方法)。这两个文件都位于 Ubuntu 24.04 上的 /etc/postgresql/16/main/(路径中的版本号将根据 apt 安装的主版本而改变)。 对于打算认真运行 PostgreSQL 的 Droplet,您应该选择至少 2GB RAM 或更多的规格,因为 PostgreSQL 需要内存用于共享缓冲区、连接和复杂查询的工作内存。只有 512MiB RAM 的最小 Droplet 只适合用于实验或学习。如果您想允许外部客户端连接,您需要在 postgresql.conf 中编辑 listen_addresses = '*',并在 pg_hba.conf 中为特定 IP 添加授权行,同时仅从受信任的 IP 向端口 5432 打开云防火墙。永远不要在没有 IP 限制的情况下向互联网开放端口 5432,因为这是自动化扫描仪持续搜索的漏洞。

基本调优参数:shared_buffers、work_mem

根据我们的实测——PostgreSQL 全新安装后的默认值设置得非常保守,因为它们被设计为即使在内存有限的机器上也能运行。这意味着拥有几 GB RAM 的 Droplet 除非您手动调整,否则不会充分利用其资源。您应该调整的第一个参数是 shared_buffers,这是 PostgreSQL 用于在进程中缓存表/索引数据的内存。一般指导原则是将其设置为总 RAM 的约 25%。例如,4GB Droplet(根据 DigitalOcean 基本 Droplet 定价每月 $24)应该设置 shared_buffers = 1GB,而 2GB Droplet(每月 $12)可以设置为 shared_buffers = 512MB。 第二个参数是 effective_cache_size,它不会实际保留内存,但会告诉查询规划器系统有多少操作系统文件缓存(操作系统页面缓存)可用。这有助于规划器做出更好的决策,即使用索引而不是顺序扫描。建议值是 RAM 的 50-75%,例如在 4GB Droplet 上设置 effective_cache_size = 3GB。 第三个参数是 work_mem,这是每个查询中每个排序或哈希操作的内存。这个需要特别注意,因为单个查询可能同时多次使用 work_mem(例如排序 + 哈希连接),每个连接是分离的。如果您在有许多连接的服务器上设置得过高,RAM 将耗尽,OOM 杀手将终止 postgres 进程。对于典型 Droplet 的安全起始值是 work_mem = 16MBwork_mem = 32MB。同时,在创建索引或运行 VACUUM 时使用的 maintenance_work_mem 可以设置得更高,例如 maintenance_work_mem = 256MB,因为它运行不频繁且不影响每个连接。 在 postgresql.conf 文件中更改所有值后,您必须使用 sudo systemctl restart postgresql 重新加载或重新启动服务。某些参数更改(如 shared_buffers)需要完整重启;仅重新加载是不够的。您可以在进行更改后使用 psql 命令验证使用中的值:SHOW shared_buffers;

索引和查询性能基础

服务器级参数调优在一定程度上有帮助,但大多数真实生产性能问题来自于没有适当索引支持的查询。您需要的必要工具是 EXPLAIN ANALYZE,您可以将其放在 SELECT 语句之前以查看实际执行计划以及每个步骤花费的时间。例如,EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 42;。如果结果显示 Seq Scan on orders 而不是在有数十万行的表上进行 Index Scan,这是您需要创建索引的迹象。 创建索引很简单,使用 CREATE INDEX idx_orders_customer_id ON orders (customer_id);,但在具有大量数据和持续流量的表上,普通索引创建将在创建期间锁定表反对写入。您应该改用 CREATE INDEX CONCURRENTLY 以在不阻止写入的情况下构建索引,即使花费的时间稍长。 另一个非常有用的工具是随 postgresql-contrib 附带的 pg_stat_statements 扩展。通过在 postgresql.conf 中添加行 shared_preload_libraries = 'pg_stat_statements' 然后重新启动来启用它。之后,使用 CREATE EXTENSION pg_stat_statements; 创建扩展。启用后,您可以查询 pg_stat_statements 表以查看哪些查询调用最频繁并花费最多总时间,帮助您将优化工作集中在真正重要的查询上,而不是随意猜测。 除了索引,表统计维护同样重要。PostgreSQL 使用 ANALYZE 的统计信息来决定查询计划。如果统计信息过时或与实际数据不匹配,规划器可能会选择一个糟糕的计划。通常 autovacuum 会自动运行 ANALYZE,但在一次性加载大量数据(批量导入)后,您应该立即自己运行 ANALYZE table_name; 以更新统计信息,而不是等待下一个 autovacuum 周期。

  1. 使用 EXPLAIN ANALYZE 查看执行计划,然后再猜测问题是什么
  2. 大表上的 Seq Scan = 需要创建索引的迹象
  3. 在实时表上使用 CREATE INDEX CONCURRENTLY 创建索引
  4. 启用 pg_stat_statements 查找消耗最多总时间的查询

何时迁移到托管数据库

在 Droplet 上自己运行 PostgreSQL 最初提供最大的灵活性和最低成本,但当您的团队开始花费更多时间于备份、版本补丁和监控而不是您希望的时候,您应该考虑改为迁移到 DigitalOcean 托管数据库。DigitalOcean 的托管 PostgreSQL 从基本计划开始,具有 1vCPU/1GiB RAM 和 10-30GiB 存储空间,每月 $15.15(2026 年 7 月的价格,请查看提供商的网站了解当前定价),这比规格相似的裸 Droplet 更昂贵,但它包括每日自动备份、时间点恢复、自动安全补丁更新,以及添加备用节点以实现高可用性的选项,这在 Droplet 上自己设置会很复杂。 三个主要信号表示迁移的时候到了。首先,当数据库停机开始对业务产生真实影响时,例如在连续接收订单的电子商务系统上。托管数据库中具有自动故障转移的备用节点显著降低了这种风险。其次,当您的团队缺少有数据库管理经验的人来一致地处理 vacuuming、索引膨胀和安全补丁时。托管数据库会自动处理这些。第三,当您需要在难以在自托管 Droplet 上配置的级别进行合规或审计日志记录时。 反之,如果您的项目仍在开发中、预算有限或您的团队已经拥有 PostgreSQL 知识并需要对扩展/配置进行细粒度控制(如使用托管数据库不支持的扩展),在 Droplet 上自己管理 PostgreSQL 仍然有意义。许多团队选择混合方法:开发/暂存在 Droplet 上运行,而生产在系统有真实用户后迁移到托管数据库。

要点总结: 托管 PostgreSQL 从 $15.15/月 起(1vCPU/1GiB RAM、10-30GiB 存储)— 2026 年 7 月定价

使用 pg_dump 和卷快照备份

根据我们的实测——当您在 Droplet 上自己管理 PostgreSQL 时,备份责任完全落在您的团队上。没有像托管数据库提供的内置自动备份系统。最基本的方法是使用 pg_dump 在数据库级别进行备份,例如 pg_dump -U postgres mydb > mydb_backup.sql,或使用自定义格式,该格式压缩得更好,可以更灵活地使用 pg_dump -U postgres -Fc mydb > mydb_backup.dump 恢复。恢复使用 pg_restore -U postgres -d mydb mydb_backup.dump 完成。您应该设置 cron 作业以自动每天运行 pg_dump,例如,添加一行到 crontab -e0 2 * * * pg_dump -U postgres -Fc mydb > /backups/mydb_$(date +%F).dump,您还应该将备份文件复制到 Droplet 外,例如上传到 DigitalOcean Spaces,以便备份不会随 Droplet 一起消失。 您应该一起使用的另一层是 DigitalOcean 卷和卷快照。如果您将 PostgreSQL 的数据目录保存在单独的卷上(不同于 Droplet 的引导磁盘,价格为每月 $0.10/GiB),您可以直接创建该卷的快照。卷快照的成本为每月 $0.06/GiB,在某些情况下可能比存储原始备份文件便宜,快照对于大型数据库来说比 pg_dump 快得多,因为它们在块存储级别而不是逐行导出数据时工作。 需要注意的是卷快照是崩溃一致的,而不是应用程序一致的。如果在 PostgreSQL 正在写入数据时创建快照,您可能会得到一个在恢复时需要进行崩溃恢复的备份。更安全的方法是在创建快照之前运行 SELECT pg_start_backup('snapshot');,然后在创建完成后跟进 SELECT pg_stop_backup();(或对更全面的物理备份使用 pg_basebackup)。对于大多数团队来说,最安全和最容易验证的方法是使用 pg_dump 作为数据级备份的主要方法,并使用卷快照作为快速系统级恢复的额外层。

何时使用此功能(真实用例)

在 Droplet 上自己调优 PostgreSQL 适合某些特定情况,而不是每个项目的最佳选择。第一个明确的用例是小到中型应用程序,其中团队已经拥有 PostgreSQL 知识并想自己控制一切,例如一个刚开始的 SaaS,需要在早期阶段最小化基础设施成本。每月 $24 的 4GB Droplet,如果为 PostgreSQL 正确调优,通常可以处理数千到数万用户,成本低于从 $15.15/月 起的托管数据库(针对较小的规格)。 第二个用例是需要使用托管数据库不支持的 PostgreSQL 扩展的团队,或需要一起调整内核/文件系统参数的特殊配置,例如需要协调 PostgreSQL 与专门分析系统的工作,或需要直接控制 WAL 和复制插槽的团队进行自定义数据库复制。 第三个用例是将其用作不需要高 SLA 的开发/暂存环境。在同一 Droplet 上与应用程序一起运行 PostgreSQL,或单独的廉价 Droplet,与为每个环境创建单独的托管数据库相比可以省钱,也可以让您的团队比总是使用托管服务更深入地理解 PostgreSQL 行为。 同时,我们不推荐此方法的用例包括收入直接取决于数据库正常运行时间的系统,或没有时间一致地遵循安全补丁和 vacuuming 的团队。在这些情况下,自我管理的成本节省通常会被问题发生时的风险和时间损失所抵消。

常见错误和修复

基于真实使用经验,在 Droplet 上调优 PostgreSQL 时最常见的错误是设置 shared_bufferswork_mem 过高,同时忘记计算多个连接一起会消耗多少 RAM。结果是操作系统调用 OOM 杀手在请求中间终止 postgres 进程,导致数据库在没有警告的情况下崩溃。修复是仔细计算,将 max_connections 设置为您实际需要的值(对于典型 Droplet 不应超过 100-200),并使用诸如 PgBouncer 这样的连接池来处理许多应用程序连接,而无需提高 max_connections。 第二个错误是 RAM 较低的 Droplet(512MiB-1GiB)但没有启用交换。当 PostgreSQL 或其他进程超过 RAM 时,系统会立即崩溃,而不是优雅地降级。您应该使用 fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile 启用至少 1-2GB 的交换。虽然交换不是重工作负载的长期解决方案,但它有助于防止突然崩溃。 第三个错误是忘记监控数据目录所在的 Droplet 或卷磁盘空间。当磁盘填满时,PostgreSQL 立即拒绝写入,可能会损坏飞行中的事务。您应该通过 DigitalOcean Monitoring(免费)设置警报策略,以在磁盘实际填满之前的磁盘使用率超过 80% 时发出警告。 第四个错误是让 autovacuum 落后于数据变化的速率,导致表和索引膨胀累积,使查询逐渐变得更慢而没有明确的原因。您可以在 pg_stat_user_tables 表中检查 n_dead_tup 来检查这一点。如果该数字与 n_live_tup 相比异常高,请为经常更新的表向下调整 autovacuum_vacuum_scale_factor

最佳实践

良好的调优必须从之前和之后的测量开始,而不是凭感觉。使用 postgresql-contrib 随附的 pgbench 工具使用 pgbench -i mydb 创建基准基线,然后运行使用 pgbench -c 10 -j 2 -T 60 mydb 的测试并记录每秒事务数。然后在每次参数调整后重新运行以进行比较。这样您可以确定调整是否有帮助,而不是猜测。 您应该一次调整一个参数,并在您的配置文件或提交消息中记录推理,特别是如果您将 postgresql.conf 保存在版本控制中。同时更改多个参数会使得很难找到问题所在,如果性能变差而不是变好。也要在将更改应用于生产之前在暂存 Droplet 上测试更改。 启用 DigitalOcean Monitoring(免费,无额外费用)以持续监控您的 Droplet 的 CPU、内存和磁盘 I/O。提前为内存和磁盘使用率设置警报策略,因为调优错误通常表现为实际崩溃前内存使用率逐渐上升。及早捕捉信号有助于在造成真正停机之前解决问题。 最后,您应该提前规划增长路径。您不必永远在 Droplet 上管理 PostgreSQL。提前设置清晰的指标:当流量超过某个水平或您的团队开始花费更多时间于数据库维护而不是功能开发时,切换到托管数据库。以这种方式规划可以根据真实数据而不是问题后的反应来做出迁移决定。

领取 $200 免费额度 →

常见问题(FAQ)

我应该为 4GB RAM Droplet 将 shared_buffers 设置为多少?
一般指导原则是总 RAM 的约 25%。对于 4GB RAM Droplet(根据 DigitalOcean 基本 Droplet 定价每月 $24),设置 shared_buffers = 1GB 是合适的,然后在使用 pgbench 测试后根据实际工作负载向上或向下调整。
在 Droplet 上自托管 PostgreSQL 真的比托管数据库便宜吗?
从原始成本来看,与从 $15.15/月 起的托管 PostgreSQL(2026 年 7 月定价)相比,Droplet 的成本更低,但您必须考虑您的团队花在备份、补丁和监控上自己的时间,这是账单中不反映的隐性成本。
我每次编辑 postgresql.conf 时都需要重启 PostgreSQL 吗?
不一定。某些参数(如 work_mem 和 effective_cache_size)可以使用 SELECT pg_reload_conf();sudo systemctl reload postgresql。但影响共享内存的参数(如 shared_buffers 和 max_connections)需要完整的服务重启。
卷快照和 pg_dump 之间的区别是什么?我应该使用哪个?
pg_dump 在数据库级别导出,花费时间更长但便携并且灵活地恢复。卷快照($0.06/GiB/月)在块存储级别工作,对于大型数据库快得多,但是崩溃一致的。我建议将两者一起使用以获得最大安全性。
我应该将 max_connections 设置得多高?
不要将其设置得高于必要,因为每个连接即使在空闲时也会消耗内存开销。对于典型 Droplet,100-200 就足够了。使用诸如 PgBouncer 之类的连接池来处理许多应用程序连接,而无需提高 max_connections。
我如何知道何时应该从自托管迁移到托管数据库?
关键信号包括停机影响业务时、您的团队无法一致地跟上安全补丁/vacuuming 时,或您需要高可用性备用节点(自己设置很复杂)时。那时,从 $15.15/月 起的托管数据库的价值通常超过自我管理的时间成本。