Just wanted to record a quick idea in case its useful in the future.
VACUUM reads all blocks in sequence and waits on each one to acquire a
cleanup lock.
If VACUUM is running with vacuum_delay enabled then we might take a
slightly different approach:
Read the heap blocks in sequence, but make a conditional lock for
cleanup on each block. If we don't get it, sleep, then try again when we
wake up. If we fail the second time, just skip the block completely.
As long as we skip no more than 1% of the blocks we should be able to do
a very good job of cleanup, yet with reduced block contention as the
VACUUM proceeds.
-- Simon Riggs EnterpriseDB http://www.enterprisedb.com