Skip to content

Commit 92ebe50

Browse files
committed
Fix autovacuum for shared relations
The table-skipping logic in autovacuum would fail to consider that multiple workers could be processing the same shared catalog in different databases. This normally wouldn't be a problem: firstly because autovacuum workers not for wraparound would simply ignore tables in which they cannot acquire lock, and secondly because most of the time these tables are small enough that even if multiple for-wraparound workers are stuck in the same catalog, they would be over pretty quickly. But in cases where the catalogs are severely bloated it could become a problem. Backpatch all the way back, because the problem has been there since the beginning. Reported by Ondřej Světlík Discussion: https://www.postgresql.org/message-id/572B63B1.3030603%40flexibee.eu https://www.postgresql.org/message-id/572A1072.5080308%40flexibee.eu
1 parent cd5a652 commit 92ebe50

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

src/backend/postmaster/autovacuum.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ typedef struct autovac_table
195195
int at_vacuum_cost_limit;
196196
bool at_dobalance;
197197
bool at_wraparound;
198+
bool at_sharedrel;
198199
char *at_relname;
199200
char *at_nspname;
200201
char *at_datname;
@@ -208,6 +209,7 @@ typedef struct autovac_table
208209
* wi_links entry into free list or running list
209210
* wi_dboid OID of the database this worker is supposed to work on
210211
* wi_tableoid OID of the table currently being vacuumed, if any
212+
* wi_sharedrel flag indicating whether table is marked relisshared
211213
* wi_proc pointer to PGPROC of the running worker, NULL if not started
212214
* wi_launchtime Time at which this worker was launched
213215
* wi_cost_* Vacuum cost-based delay parameters current in this worker
@@ -225,6 +227,7 @@ typedef struct WorkerInfoData
225227
PGPROC *wi_proc;
226228
TimestampTz wi_launchtime;
227229
bool wi_dobalance;
230+
bool wi_sharedrel;
228231
int wi_cost_delay;
229232
int wi_cost_limit;
230233
int wi_cost_limit_base;
@@ -746,6 +749,7 @@ AutoVacLauncherMain(int argc, char *argv[])
746749
worker = AutoVacuumShmem->av_startingWorker;
747750
worker->wi_dboid = InvalidOid;
748751
worker->wi_tableoid = InvalidOid;
752+
worker->wi_sharedrel = false;
749753
worker->wi_proc = NULL;
750754
worker->wi_launchtime = 0;
751755
dlist_push_head(&AutoVacuumShmem->av_freeWorkers,
@@ -1739,6 +1743,7 @@ FreeWorkerInfo(int code, Datum arg)
17391743
dlist_delete(&MyWorkerInfo->wi_links);
17401744
MyWorkerInfo->wi_dboid = InvalidOid;
17411745
MyWorkerInfo->wi_tableoid = InvalidOid;
1746+
MyWorkerInfo->wi_sharedrel = false;
17421747
MyWorkerInfo->wi_proc = NULL;
17431748
MyWorkerInfo->wi_launchtime = 0;
17441749
MyWorkerInfo->wi_dobalance = false;
@@ -2272,8 +2277,8 @@ do_autovacuum(void)
22722277
if (worker == MyWorkerInfo)
22732278
continue;
22742279

2275-
/* ignore workers in other databases */
2276-
if (worker->wi_dboid != MyDatabaseId)
2280+
/* ignore workers in other databases (unless table is shared) */
2281+
if (!worker->wi_sharedrel && worker->wi_dboid != MyDatabaseId)
22772282
continue;
22782283

22792284
if (worker->wi_tableoid == relid)
@@ -2314,6 +2319,7 @@ do_autovacuum(void)
23142319
* the lock so that other workers don't vacuum it concurrently.
23152320
*/
23162321
MyWorkerInfo->wi_tableoid = relid;
2322+
MyWorkerInfo->wi_sharedrel = tab->at_sharedrel;
23172323
LWLockRelease(AutovacuumScheduleLock);
23182324

23192325
/*
@@ -2425,6 +2431,7 @@ do_autovacuum(void)
24252431
*/
24262432
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
24272433
MyWorkerInfo->wi_tableoid = InvalidOid;
2434+
MyWorkerInfo->wi_sharedrel = false;
24282435
LWLockRelease(AutovacuumLock);
24292436

24302437
/* restore vacuum cost GUCs for the next iteration */
@@ -2625,6 +2632,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
26252632

26262633
tab = palloc(sizeof(autovac_table));
26272634
tab->at_relid = relid;
2635+
tab->at_sharedrel = classForm->relisshared;
26282636
tab->at_dovacuum = dovacuum;
26292637
tab->at_doanalyze = doanalyze;
26302638
tab->at_freeze_min_age = freeze_min_age;

0 commit comments

Comments
 (0)