vac_move_lock-2.patch
text/x-diff
Filename: vac_move_lock-2.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/postmaster/autovacuum.c | 0 | 0 |
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 21f5e2c..639bd71 100644
*** a/src/backend/postmaster/autovacuum.c
--- b/src/backend/postmaster/autovacuum.c
*************** typedef struct autovac_table
*** 212,220 ****
* wi_launchtime Time at which this worker was launched
* wi_cost_* Vacuum cost-based delay parameters current in this worker
*
! * All fields are protected by AutovacuumLock, except for wi_tableoid which is
! * protected by AutovacuumScheduleLock (which is read-only for everyone except
! * that worker itself).
*-------------
*/
typedef struct WorkerInfoData
--- 212,220 ----
* wi_launchtime Time at which this worker was launched
* wi_cost_* Vacuum cost-based delay parameters current in this worker
*
! * All fields are protected by AutovacuumLock, except for wi_tableoid and
! * wi_sharedrel which are protected by AutovacuumScheduleLock (note these
! * two fields are read-only for everyone except that worker itself).
*-------------
*/
typedef struct WorkerInfoData
*************** do_autovacuum(void)
*** 2317,2323 ****
--- 2317,2325 ----
foreach(cell, table_oids)
{
Oid relid = lfirst_oid(cell);
+ HeapTuple classTup;
autovac_table *tab;
+ bool isshared;
bool skipit;
int stdVacuumCostDelay;
int stdVacuumCostLimit;
*************** do_autovacuum(void)
*** 2342,2350 ****
}
/*
! * hold schedule lock from here until we're sure that this table still
! * needs vacuuming. We also need the AutovacuumLock to walk the
! * worker array, but we'll let go of that one quickly.
*/
LWLockAcquire(AutovacuumScheduleLock, LW_EXCLUSIVE);
LWLockAcquire(AutovacuumLock, LW_SHARED);
--- 2344,2366 ----
}
/*
! * Find out whether the table is shared or not. (It's slightly
! * annoying to fetch the syscache entry just for this, but in typical
! * cases it adds little cost because table_recheck_autovac would
! * refetch the entry anyway. We could buy that back by copying the
! * tuple here and passing it to table_recheck_autovac, but that
! * increases the odds of that function working with stale data.)
! */
! classTup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
! if (!HeapTupleIsValid(classTup))
! continue; /* somebody deleted the rel, forget it */
! isshared = ((Form_pg_class) GETSTRUCT(classTup))->relisshared;
! ReleaseSysCache(classTup);
!
! /*
! * Hold schedule lock from here until we've claimed the table. We
! * also need the AutovacuumLock to walk the worker array, but that one
! * can just be a shared lock.
*/
LWLockAcquire(AutovacuumScheduleLock, LW_EXCLUSIVE);
LWLockAcquire(AutovacuumLock, LW_SHARED);
*************** do_autovacuum(void)
*** 2381,2386 ****
--- 2397,2412 ----
}
/*
+ * Store the table's OID in shared memory before releasing the
+ * schedule lock, so that other workers don't try to vacuum it
+ * concurrently. (We claim it here so as not to hold
+ * AutovacuumScheduleLock while rechecking the stats.)
+ */
+ MyWorkerInfo->wi_tableoid = relid;
+ MyWorkerInfo->wi_sharedrel = isshared;
+ LWLockRelease(AutovacuumScheduleLock);
+
+ /*
* Check whether pgstat data still says we need to vacuum this table.
* It could have changed if something else processed the table while
* we weren't looking.
*************** do_autovacuum(void)
*** 2396,2414 ****
if (tab == NULL)
{
/* someone else vacuumed the table, or it went away */
LWLockRelease(AutovacuumScheduleLock);
continue;
}
/*
- * Ok, good to go. Store the table in shared memory before releasing
- * the lock so that other workers don't vacuum it concurrently.
- */
- MyWorkerInfo->wi_tableoid = relid;
- MyWorkerInfo->wi_sharedrel = tab->at_sharedrel;
- LWLockRelease(AutovacuumScheduleLock);
-
- /*
* Remember the prevailing values of the vacuum cost GUCs. We have to
* restore these at the bottom of the loop, else we'll compute wrong
* values in the next iteration of autovac_balance_cost().
--- 2422,2435 ----
if (tab == NULL)
{
/* someone else vacuumed the table, or it went away */
+ LWLockAcquire(AutovacuumScheduleLock, LW_EXCLUSIVE);
+ MyWorkerInfo->wi_tableoid = InvalidOid;
+ MyWorkerInfo->wi_sharedrel = false;
LWLockRelease(AutovacuumScheduleLock);
continue;
}
/*
* Remember the prevailing values of the vacuum cost GUCs. We have to
* restore these at the bottom of the loop, else we'll compute wrong
* values in the next iteration of autovac_balance_cost().
*************** deleted:
*** 2522,2531 ****
* settings, so we don't want to give up our share of I/O for a very
* short interval and thereby thrash the global balance.
*/
! LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
MyWorkerInfo->wi_tableoid = InvalidOid;
MyWorkerInfo->wi_sharedrel = false;
! LWLockRelease(AutovacuumLock);
/* restore vacuum cost GUCs for the next iteration */
VacuumCostDelay = stdVacuumCostDelay;
--- 2543,2552 ----
* settings, so we don't want to give up our share of I/O for a very
* short interval and thereby thrash the global balance.
*/
! LWLockAcquire(AutovacuumScheduleLock, LW_EXCLUSIVE);
MyWorkerInfo->wi_tableoid = InvalidOid;
MyWorkerInfo->wi_sharedrel = false;
! LWLockRelease(AutovacuumScheduleLock);
/* restore vacuum cost GUCs for the next iteration */
VacuumCostDelay = stdVacuumCostDelay;