diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 251b9fe..46fe94d 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -1898,6 +1898,8 @@ do_autovacuum(void) ScanKeyData key; TupleDesc pg_class_desc; int effective_multixact_freeze_max_age; + bool did_vacuum = false; + bool found_concurrent_worker = false; /* * StartTransactionCommand and CommitTransactionCommand will automatically @@ -2307,6 +2309,7 @@ do_autovacuum(void) if (worker->wi_tableoid == relid) { skipit = true; + found_concurrent_worker = true; break; } } @@ -2433,6 +2436,8 @@ do_autovacuum(void) } PG_END_TRY(); + did_vacuum = true; + /* the PGXACT flags are reset at the next end of transaction */ /* be tidy */ @@ -2470,8 +2475,20 @@ deleted: /* * Update pg_database.datfrozenxid, and truncate pg_clog if possible. We * only need to do this once, not after each table. + * + * This action effectively causes launch of another auto-vacuum iteration, + * hoping to choose another database. Now if this worker hasn't vaccuumed + * anything because of another working already having taken one or more + * tables, then there's no point going through another auto-vacuum + * iteration: the other worker will do that job. In fact, if we do create + * another iteration, we might keep spawning useless autovacuum iterations + * on the same database, until the other worker has finished with its + * tables and updated datfrozenxid. */ - vac_update_datfrozenxid(); + if (!did_vacuum && found_concurrent_worker) + ; /* Don't do anything */ + else + vac_update_datfrozenxid(); /* Finally close out the last transaction. */ CommitTransactionCommand();