>
> Well, I diked out the code in vacuum.c that creates/deletes the pg_vlock
> lockfile, and tried it out. Turns out it's not quite such a no-brainer
> as I'd hoped. Several problems emerged:
>
> 1. You can run concurrent "VACUUM" this way, but concurrent "VACUUM
> ANALYZE" blows up. The problem seems to be that "VACUUM ANALYZE"'s
> first move is to delete all available rows in pg_statistic. That
> generates a conflict against other vacuums that might be inserting new
> rows in pg_statistic. The newly started VACUUM will almost always hang
> up on a not-yet-committed pg_statistic row, waiting to see whether that
> row commits so that it can delete it. Even more interesting, the older
> VACUUM generally hangs up shortly after that; I'm not perfectly clear on
> what *it's* waiting on, but it's obviously a mutual deadlock situation.
> The two VACUUMs don't fail with a nice "deadlock detected" message,
> either ... it's more like a 60-second spinlock timeout, followed by
> abort() coredumps in both backends, followed by the postmaster killing
> every other backend in sight. That's clearly not acceptable behavior
> for production databases.
>
The following stuff in vc_vacuum() may be a cause.
/* get list of relations */ vrl = vc_getrels(VacRelP);
if (analyze && VacRelP == NULL && vrl != NULL) vc_delhilowstats(InvalidOid, 0, NULL);
/* vacuum each heap relation */
CommitTransactionCommand() is executed at the end of vc_getrels()
and vc_delhilowstats() is executed without StartTransactionCommand().
Regards.
Hiroshi Inoue
Inoue@tpf.co.jp