diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
new file mode 100644
index 94e748e..cd684af
*** a/src/backend/postmaster/autovacuum.c
--- b/src/backend/postmaster/autovacuum.c
*************** do_autovacuum(void)
*** 2247,2252 ****
--- 2247,2261 ----
  		}
  
  		/*
+ 		 * Store the table in shared memory before releasing
+ 		 * the lock so that other workers don't vacuum it concurrently.
+ 		 * Claim the table now so that we don't hold the lock
+ 		 * over a potentially expensive recheck.
+ 		 */
+ 		MyWorkerInfo->wi_tableoid = relid;
+ 		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)
*** 2262,2279 ****
  		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;
- 		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().
--- 2271,2283 ----
  		if (tab == NULL)
  		{
  			/* someone else vacuumed the table, or it went away */
+ 			LWLockAcquire(AutovacuumScheduleLock, LW_EXCLUSIVE);
+ 			MyWorkerInfo->wi_tableoid = InvalidOid;
  			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().
