Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1573939

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 8ee29a1 commit 1573939

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

src/backend/postmaster/autovacuum.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ typedef struct autovac_table
190190
int at_vacuum_cost_delay;
191191
int at_vacuum_cost_limit;
192192
bool at_dobalance;
193+
bool at_sharedrel;
193194
char *at_relname;
194195
char *at_nspname;
195196
char *at_datname;
@@ -203,6 +204,7 @@ typedef struct autovac_table
203204
* wi_links entry into free list or running list
204205
* wi_dboid OID of the database this worker is supposed to work on
205206
* wi_tableoid OID of the table currently being vacuumed, if any
207+
* wi_sharedrel flag indicating whether table is marked relisshared
206208
* wi_proc pointer to PGPROC of the running worker, NULL if not started
207209
* wi_launchtime Time at which this worker was launched
208210
* wi_cost_* Vacuum cost-based delay parameters current in this worker
@@ -220,6 +222,7 @@ typedef struct WorkerInfoData
220222
PGPROC *wi_proc;
221223
TimestampTz wi_launchtime;
222224
bool wi_dobalance;
225+
bool wi_sharedrel;
223226
int wi_cost_delay;
224227
int wi_cost_limit;
225228
int wi_cost_limit_base;
@@ -717,6 +720,7 @@ AutoVacLauncherMain(int argc, char *argv[])
717720
worker = AutoVacuumShmem->av_startingWorker;
718721
worker->wi_dboid = InvalidOid;
719722
worker->wi_tableoid = InvalidOid;
723+
worker->wi_sharedrel = false;
720724
worker->wi_proc = NULL;
721725
worker->wi_launchtime = 0;
722726
dlist_push_head(&AutoVacuumShmem->av_freeWorkers,
@@ -1683,6 +1687,7 @@ FreeWorkerInfo(int code, Datum arg)
16831687
dlist_delete(&MyWorkerInfo->wi_links);
16841688
MyWorkerInfo->wi_dboid = InvalidOid;
16851689
MyWorkerInfo->wi_tableoid = InvalidOid;
1690+
MyWorkerInfo->wi_sharedrel = false;
16861691
MyWorkerInfo->wi_proc = NULL;
16871692
MyWorkerInfo->wi_launchtime = 0;
16881693
MyWorkerInfo->wi_dobalance = false;
@@ -2229,8 +2234,8 @@ do_autovacuum(void)
22292234
if (worker == MyWorkerInfo)
22302235
continue;
22312236

2232-
/* ignore workers in other databases */
2233-
if (worker->wi_dboid != MyDatabaseId)
2237+
/* ignore workers in other databases (unless table is shared) */
2238+
if (!worker->wi_sharedrel && worker->wi_dboid != MyDatabaseId)
22342239
continue;
22352240

22362241
if (worker->wi_tableoid == relid)
@@ -2271,6 +2276,7 @@ do_autovacuum(void)
22712276
* the lock so that other workers don't vacuum it concurrently.
22722277
*/
22732278
MyWorkerInfo->wi_tableoid = relid;
2279+
MyWorkerInfo->wi_sharedrel = tab->at_sharedrel;
22742280
LWLockRelease(AutovacuumScheduleLock);
22752281

22762282
/*
@@ -2382,6 +2388,7 @@ do_autovacuum(void)
23822388
*/
23832389
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
23842390
MyWorkerInfo->wi_tableoid = InvalidOid;
2391+
MyWorkerInfo->wi_sharedrel = false;
23852392
LWLockRelease(AutovacuumLock);
23862393

23872394
/* restore vacuum cost GUCs for the next iteration */
@@ -2577,6 +2584,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
25772584

25782585
tab = palloc(sizeof(autovac_table));
25792586
tab->at_relid = relid;
2587+
tab->at_sharedrel = classForm->relisshared;
25802588
tab->at_vacoptions = VACOPT_SKIPTOAST |
25812589
(dovacuum ? VACOPT_VACUUM : 0) |
25822590
(doanalyze ? VACOPT_ANALYZE : 0) |

0 commit comments

Comments
 (0)