We have PostgreSQL 12.9 running on Ubuntu 20.04.3 LTS in a streaming replication setup with 1 primary and 3 standbys where the following options have been configured on all servers:
- hot_standby=on
- hot_standby_feedback=on
- max_standby_archive_delay=30s
- max_standby_streaming_delay=30s
- wal_receiver_status_interval=10s
And on the primary only, we have configured:
- vacuum_defer_cleanup_age=1000
Our largest table is about 1TB in size (half for heap, half for index) with 6.5B rows, and is also the most active one with INSERTS/DELETES occurring frequently, so for that table, we have specified autovacuum_vacuum_scale_factor=0.001. Other server-level settings for autovacuum are:
- autovacuum_analyze_scale_factor=0.01
- autovacuum_analyze_threshold=40
- autovacuum_freeze_max_age=500000000
- autovacuum_max_workers=20
- autovacuum_multixact_freeze_max_age=400000000
- autovacuum_naptime=1s
- autovacuum_vacuum_cost_delay=10ms
- utovacuum_vacuum_cost_limit=10000
- autovacuum_vacuum_scale_factor=0.005
- autovacuum_vacuum_threshold=50
- autovacuum_work_mem=-1
- log_autovacuum_min_duration=100ms
Normally this works well and autovacuum kicks in without issue. However, now that we've seen an increase in TPS on our standby traffic, we are getting many 57014 errors on them "canceling statement due to user request" after about half hour, which is normally how long it takes when actual tuples are removed. This causes spikes in user connections making the clients unstable.
Also we see many of the SELECTs are being blocked, waiting for AccessShareLock from the autovacuum process.
We have traced each of these spikes to the primary which also has an associated 57014 error "canceling autovacuum task". When this occurs we can see no autovacuum is being done for quite some time (several hours).
Things we've tried:
- Rebuilding indexes to remove bloat. (There is no table bloat, only index bloat).
- Increasing vacuum_defer_cleanup_age. (Originally the value was 0, and we tried increasing it from 200->400->1000 with no noticeable impact).
In the end, we've had to suspend autovacuum on the table in order to stabilize the system. We still have a nightly job that kicks in to manually run VACUUM (ANALYZE) on the database, but we are hoping there's a better solution.