PostgreSQL自动清理导致了显著的性能下降。

4
我们的Postgres数据库(托管在Google Cloud SQL上,具有1个CPU、3.7GB的RAM,见下文)主要由一个大约90GB的表格组成,其中包含约6000万行。使用模式几乎完全由追加和表格末尾的少量索引读取组成。偶尔会删除一些用户,从表中分散删除小比例的行。
这都运作良好,但每隔几个月就会对该表触发自动清理,这会显著影响我们服务的性能,持续约8小时:
- 存储使用率在自动清理期间(数小时)增加约1GB,然后缓慢返回到之前的值(可能会因自动清理释放页面而最终低于之前的值) - 数据库CPU利用率从<10%跳至约20% - 磁盘读写操作从接近零增加到约50/秒 - 数据库内存略微增加,但保持在2GB以下 - 如预期那样,每秒事务数和进出字节数也基本不受影响
这会导致我们服务的95th百分位延迟从约100ms增加到约0.5-1s,进而触发我们的监控。该服务每秒提供约十个请求,每个请求由几个简单的DB读/写组成,通常每个请求的延迟为2-3毫秒。
以下是说明问题的一些监控截图:
CPU使用情况:CPU usage 存储使用情况:Storage usage 内存使用情况:Memory usage 读/写操作情况:Read/Write operations 延迟情况:Latency 数据库配置相当基本: DB configuration 记录此自动清理过程的日志条目如下:
system usage: CPU 470.10s/358.74u sec elapsed 38004.58 sec
avg read rate: 2.491 MB/s, avg write rate: 2.247 MB/s
buffer usage: 8480213 hits, 12117505 misses, 10930449 dirtied
tuples: 5959839 removed, 57732135 remain, 4574 are dead but not yet removable
pages: 0 removed, 6482261 remain, 0 skipped due to pins, 0 skipped frozen
automatic vacuum of table "XXX": index scans: 1

有什么建议可以调整以减少未来自动清理对我们服务的影响吗?或者我们做错了什么吗?
1个回答

10
如果你增加了autovacuum_vacuum_cost_delay,你的自动清理会变慢且不会那么侵入性。
然而,通常最好的解决方案是通过将autovacuum_vacuum_cost_limit设置为2000或者更高速度,使其运行更快。然后它会更快地完成。
你也可以尝试在对操作影响最小的时候自己调度表格的VACUUM
但是坦率地说,如果一个单独的无害的自动清理足以干扰你的操作,那么你需要更多的I/O带宽。

谢谢,增加autovacuum_vacuum_cost_delay减少autovacuum_vacuum_cost_limit有助于提高服务性能,但当然会使autovacuum需要更长时间(但这没关系)。我怀疑谷歌对100 GB持久磁盘的~3k IOPS和50 MB/s吞吐量限制(请参见https://cloud.google.com/compute/docs/disks/performance)在这里有问题。 - MrMage
将自动清理进程的延迟再次增加是一条危险的道路。你已经被警告了!我会为更多的存储带宽付出代价。 - Laurenz Albe
我实际上增加了自动清理的频率(将比例因子从0.2减少到0.01),同时降低了它们的速度。因此,每个单独的自动清理应该有更少的工作要做。 - MrMage
这将使自动清理一直运行。您应该监视它是否完成,以及膨胀是否增加。 - Laurenz Albe
如何在GCP上安排VACUUM @LaurenzAlbe? - Tobias
没什么主意。通常你可以让自动清理(autovacuum)来完成这项工作 - 它会自动安排操作。 - Laurenz Albe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接