我们的Postgres数据库(托管在具有1个CPU,3.7 GB RAM的Google Cloud SQL上,请参见下文)主要由一个约90GB的大表组成,约有6000万行。使用模式几乎完全由追加和表末尾附近的一些索引读取组成。有时会删除一些用户,从而删除分散在表中的一小部分行。
这一切都很好,但是每隔几个月就会在该表上触发一次自动清理,这会在大约8个小时内严重影响我们的服务性能:
这会在自动真空期间将我们服务的第95个延迟百分位数从〜100ms增加到〜0.5-1s,这反过来又触发了我们的监视。该服务每秒可处理大约十个请求,每个请求由几个简单的DB读/写组成,通常每个读/写的等待时间为2-3ms。
以下是一些监控屏幕截图,说明了此问题:
数据库配置相当原始:
记录此自动清理过程的日志条目如下:
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
有什么建议我们可以调整以减少未来自动真空对我们服务的影响?还是我们做错了什么?
答案 0 :(得分:2)
如果您可以增加autovacuum_vacuum_cost_delay
,则您的自吸速度会变慢,并且侵入性较小。
但是,通常最好的方法是将autovacuum_vacuum_cost_limit
设置为2000左右以使其更快。然后它完成得更快。
您也可以尝试自己安排时间表中VACUUM
的时间,以免受到最大的伤害。
但是坦率地说,如果一个无害的自动真空足以干扰您的操作,则您需要更多的I / O带宽。