配置 PostgreSQL 以提高写入性能

Dan*_*ons 30 postgresql performance

我的一台 PostgreSQL 服务器托管了几个 (1-3) 数据库,这些数据库接收恒定的数据流。数据不是特别结构化,它相当于当前时间和特定时刻的各种观察数据。数据速率相当高;一个数据库每天大约可以计算出 1 GB 的数据,而另一个数据库则大约是每天 1 GB 的数据。我不希望这个比率会增加。读取性能的优先级要低得多,目前是可以接受的。

在日志中,我有这条消息:

LOG:  checkpoints are occurring too frequently (15 seconds apart)
HINT:  Consider increasing the configuration parameter "checkpoint_segments".
Run Code Online (Sandbox Code Playgroud)

该值当前设置为 16,这是由 提供的pgtune

我应该考虑哪些设置来提高写入性能?我宁愿保持尽可能多的安全。考虑到传入的数据量,只要大部分数据完好无损,我可以接受在故障中丢失一些最近的数据。

编辑:我现在使用 PostgreSQL 9.0,但我计划升级到 9.1。我不会发布硬件细节,因为虽然我承认它们的重要性,但我最终将需要在具有非常不同硬件的几台机器上进行这种优化。如果硬件对答案至关重要,请给我一般信息,以便我可以将答案应用于具有不同硬件配置的机器。

Sco*_*owe 25

每天 1 GB 的写入负载并不高。全天分布,每秒大约 50kbytes。一个慢速的 USB 拇指驱动器可以解决这个问题。不过,我假设它更突发。正如 a_horse_with_no_name 建议的那样,增加检查点段。100个左右也不算特别。

然后将您的时间checkpoint_timeout增加到 1 小时,并考虑将您的时间checkpoint_completion_target增加到接近 1.0 (100%) 的程度。完成目标告诉 PostgreSQL 如何积极地在后台写入,以便在运行检查点之前完成 x%,这会强制从 WAL 一次写出所有数据,并在它发生时将系统减慢到爬行。

您通常不将其设置为 100% 的原因是多次写入同一个块是很常见的,并且通过延迟 WAL 写出到主存储,您可以防止同一个块被无故写入两次。

如果您不太可能在超时发生之前多次写入同一个块,即您所做的就是插入,然后将其设置得相当高,将其提高到 0.9 左右是有意义的。最糟糕的情况是,您编写的次数会比原本需要的次数多一点,但检查点的影响将大大减少。


Jac*_*las 10

在一个非常“写重”的系统中,您可能会受到高峰活动期间可以写入 WAL 的速率的限制。

如果你真的可以“接受在失败中丢失一些最近的数据”,你可以关闭同步提交

当性能比事务持久性的确切确定性更重要时,它可能是一个有用的替代方案

如果您能够更改硬件,则可以考虑以下任何一种来优化写入:

  • RAID10 优于 RAID5
  • 许多主轴(例如可能意味着 2.5" 而不是 3.5")
  • SAS 超过 SATA
  • 15K 超过 10K 驱动器
  • 固态硬盘

- 编辑

根据您对@Scott出色回答的评论:“写入量实际上几乎完全一致”,以及“每秒 50kbytes”的隐含数据速率,我怀疑您是否需要做任何有数据丢失风险的事情。也许了解其他一些配置参数的设置会有所帮助。

  • 如果写入性能很重要,操作系统和旋转硬盘驱动器之间的电池支持控制器可以产生巨大的差异。 (3认同)

小智 6

您还可以检查提交的频率/大小:我最近遇到了一个问题,我试图在单个事务中更新 > 100 万条记录。我收到了类似于 OP 描述的日志消息,但即使在几个小时后交易也无法完成。当我将写入分成几个较小的事务(大约 10,000 条记录)时,所需的总时间减少到大约 15 分钟。

认为发生的事情是 Postgres 花了太多时间写日志,而checkpoint_timeout在它可以取得实质性进展之前已经过去了。我不确定这个解释是否成立。我仍然收到警告,但最终会处理所有写入。但是,我需要(并找到)一种程序化的解决方法,而不是需要重新配置数据库的方法。

另见http://www.postgresql.org/docs/9.3/static/wal-configuration.html