Skip to content

Commit 745c1b2

Browse files
committed
Rearrange vacuum-related bits in PGPROC as a bitmask, to better support
having several of them. Add two more flags: whether the process is executing an ANALYZE, and whether a vacuum is for Xid wraparound (which is obviously only set by autovacuum). Sneakily move the worker's recently-acquired PostAuthDelay to a more useful place.
1 parent 3ef1879 commit 745c1b2

File tree

7 files changed

+97
-41
lines changed

7 files changed

+97
-41
lines changed

src/backend/access/transam/twophase.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.36 2007/09/21 16:32:19 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.37 2007/10/24 20:55:36 alvherre Exp $
1111
*
1212
* NOTES
1313
* Each global transaction is associated with a global transaction
@@ -283,8 +283,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
283283
gxact->proc.databaseId = databaseid;
284284
gxact->proc.roleId = owner;
285285
gxact->proc.inCommit = false;
286-
gxact->proc.inVacuum = false;
287-
gxact->proc.isAutovacuum = false;
286+
gxact->proc.vacuumFlags = 0;
288287
gxact->proc.lwWaiting = false;
289288
gxact->proc.lwExclusive = false;
290289
gxact->proc.lwWaitLink = NULL;

src/backend/commands/analyze.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.109 2007/09/24 03:12:23 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.110 2007/10/24 20:55:36 alvherre Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -31,6 +31,7 @@
3131
#include "parser/parse_relation.h"
3232
#include "pgstat.h"
3333
#include "postmaster/autovacuum.h"
34+
#include "storage/proc.h"
3435
#include "utils/acl.h"
3536
#include "utils/datum.h"
3637
#include "utils/lsyscache.h"
@@ -201,6 +202,11 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
201202
return;
202203
}
203204

205+
/* let others know what I'm doing */
206+
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
207+
MyProc->vacuumFlags |= PROC_IN_ANALYZE;
208+
LWLockRelease(ProcArrayLock);
209+
204210
/* measure elapsed time iff autovacuum logging requires it */
205211
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
206212
{
@@ -484,6 +490,14 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
484490
RelationGetRelationName(onerel),
485491
pg_rusage_show(&ru0))));
486492
}
493+
494+
/*
495+
* Reset my PGPROC flag. Note: we need this here, and not in vacuum_rel,
496+
* because the vacuum flag is cleared by the end-of-xact code.
497+
*/
498+
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
499+
MyProc->vacuumFlags &= ~PROC_IN_ANALYZE;
500+
LWLockRelease(ProcArrayLock);
487501
}
488502

489503
/*

src/backend/commands/vacuum.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.359 2007/09/20 17:56:31 tgl Exp $
16+
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.360 2007/10/24 20:55:36 alvherre Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -660,9 +660,9 @@ vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
660660
* fixed-size never-null columns, but these are.
661661
*
662662
* Another reason for doing it this way is that when we are in a lazy
663-
* VACUUM and have inVacuum set, we mustn't do any updates --- somebody
664-
* vacuuming pg_class might think they could delete a tuple marked with
665-
* xmin = our xid.
663+
* VACUUM and have PROC_IN_VACUUM set, we mustn't do any updates ---
664+
* somebody vacuuming pg_class might think they could delete a tuple
665+
* marked with xmin = our xid.
666666
*
667667
* This routine is shared by full VACUUM, lazy VACUUM, and stand-alone
668668
* ANALYZE.
@@ -987,22 +987,24 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
987987
* During a lazy VACUUM we do not run any user-supplied functions, and
988988
* so it should be safe to not create a transaction snapshot.
989989
*
990-
* We can furthermore set the inVacuum flag, which lets other
990+
* We can furthermore set the PROC_IN_VACUUM flag, which lets other
991991
* concurrent VACUUMs know that they can ignore this one while
992-
* determining their OldestXmin. (The reason we don't set inVacuum
992+
* determining their OldestXmin. (The reason we don't set it
993993
* during a full VACUUM is exactly that we may have to run user-
994994
* defined functions for functional indexes, and we want to make sure
995995
* that if they use the snapshot set above, any tuples it requires
996996
* can't get removed from other tables. An index function that
997997
* depends on the contents of other tables is arguably broken, but we
998998
* won't break it here by violating transaction semantics.)
999999
*
1000-
* Note: the inVacuum flag remains set until CommitTransaction or
1000+
* Note: this flag remains set until CommitTransaction or
10011001
* AbortTransaction. We don't want to clear it until we reset
10021002
* MyProc->xid/xmin, else OldestXmin might appear to go backwards,
10031003
* which is probably Not Good.
10041004
*/
1005-
MyProc->inVacuum = true;
1005+
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1006+
MyProc->vacuumFlags |= PROC_IN_VACUUM;
1007+
LWLockRelease(ProcArrayLock);
10061008
}
10071009

10081010
/*

src/backend/postmaster/autovacuum.c

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
*
5656
*
5757
* IDENTIFICATION
58-
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.62 2007/10/24 19:08:25 alvherre Exp $
58+
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.63 2007/10/24 20:55:36 alvherre Exp $
5959
*
6060
*-------------------------------------------------------------------------
6161
*/
@@ -172,6 +172,7 @@ typedef struct autovac_table
172172
int at_freeze_min_age;
173173
int at_vacuum_cost_delay;
174174
int at_vacuum_cost_limit;
175+
bool at_wraparound;
175176
} autovac_table;
176177

177178
/*-------------
@@ -280,7 +281,7 @@ static autovac_table *table_recheck_autovac(Oid relid);
280281
static void relation_needs_vacanalyze(Oid relid, Form_pg_autovacuum avForm,
281282
Form_pg_class classForm,
282283
PgStat_StatTabEntry *tabentry, bool *dovacuum,
283-
bool *doanalyze);
284+
bool *doanalyze, bool *wraparound);
284285

285286
static void autovacuum_do_vac_analyze(Oid relid, bool dovacuum,
286287
bool doanalyze, int freeze_min_age,
@@ -1440,9 +1441,6 @@ AutoVacWorkerMain(int argc, char *argv[])
14401441
/* Identify myself via ps */
14411442
init_ps_display("autovacuum worker process", "", "", "");
14421443

1443-
if (PostAuthDelay)
1444-
pg_usleep(PostAuthDelay * 1000000L);
1445-
14461444
SetProcessingMode(InitProcessing);
14471445

14481446
/*
@@ -1601,6 +1599,9 @@ AutoVacWorkerMain(int argc, char *argv[])
16011599
ereport(DEBUG1,
16021600
(errmsg("autovacuum: processing database \"%s\"", dbname)));
16031601

1602+
if (PostAuthDelay)
1603+
pg_usleep(PostAuthDelay * 1000000L);
1604+
16041605
/* And do an appropriate amount of work */
16051606
recentXid = ReadNewTransactionId();
16061607
do_autovacuum();
@@ -2085,6 +2086,14 @@ do_autovacuum(void)
20852086
/* clean up memory before each iteration */
20862087
MemoryContextResetAndDeleteChildren(PortalContext);
20872088

2089+
/* set the "vacuum for wraparound" flag in PGPROC */
2090+
if (tab->at_wraparound)
2091+
{
2092+
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
2093+
MyProc->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND;
2094+
LWLockRelease(ProcArrayLock);
2095+
}
2096+
20882097
/*
20892098
* We will abort vacuuming the current table if something errors out,
20902099
* and continue with the next one in schedule; in particular, this
@@ -2119,6 +2128,7 @@ do_autovacuum(void)
21192128
get_rel_name(tab->at_relid));
21202129
EmitErrorReport();
21212130

2131+
/* this resets the PGPROC flags too */
21222132
AbortOutOfAnyTransaction();
21232133
FlushErrorState();
21242134
MemoryContextResetAndDeleteChildren(PortalContext);
@@ -2129,6 +2139,14 @@ do_autovacuum(void)
21292139
}
21302140
PG_END_TRY();
21312141

2142+
/* reset my PGPROC flag */
2143+
if (tab->at_wraparound)
2144+
{
2145+
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
2146+
MyProc->vacuumFlags &= ~PROC_VACUUM_FOR_WRAPAROUND;
2147+
LWLockRelease(ProcArrayLock);
2148+
}
2149+
21322150
/* be tidy */
21332151
pfree(tab);
21342152

@@ -2223,9 +2241,10 @@ relation_check_autovac(Oid relid, Form_pg_class classForm,
22232241
{
22242242
bool dovacuum;
22252243
bool doanalyze;
2244+
bool dummy;
22262245

22272246
relation_needs_vacanalyze(relid, avForm, classForm, tabentry,
2228-
&dovacuum, &doanalyze);
2247+
&dovacuum, &doanalyze, &dummy);
22292248

22302249
if (classForm->relkind == RELKIND_TOASTVALUE)
22312250
{
@@ -2272,6 +2291,8 @@ table_recheck_autovac(Oid relid)
22722291
bool doit = false;
22732292
PgStat_StatDBEntry *shared;
22742293
PgStat_StatDBEntry *dbentry;
2294+
bool wraparound,
2295+
toast_wraparound = false;
22752296

22762297
/* use fresh stats */
22772298
autovac_refresh_stats();
@@ -2298,7 +2319,7 @@ table_recheck_autovac(Oid relid)
22982319
shared, dbentry);
22992320

23002321
relation_needs_vacanalyze(relid, avForm, classForm, tabentry,
2301-
&dovacuum, &doanalyze);
2322+
&dovacuum, &doanalyze, &wraparound);
23022323

23032324
/* OK, it needs vacuum by itself */
23042325
if (dovacuum)
@@ -2316,6 +2337,7 @@ table_recheck_autovac(Oid relid)
23162337
{
23172338
bool toast_dovacuum;
23182339
bool toast_doanalyze;
2340+
bool toast_wraparound;
23192341
Form_pg_class toastClassForm;
23202342
PgStat_StatTabEntry *toasttabentry;
23212343

@@ -2325,9 +2347,10 @@ table_recheck_autovac(Oid relid)
23252347
shared, dbentry);
23262348

23272349
/* note we use the pg_autovacuum entry for the main table */
2328-
relation_needs_vacanalyze(toastrelid, avForm, toastClassForm,
2329-
toasttabentry, &toast_dovacuum,
2330-
&toast_doanalyze);
2350+
relation_needs_vacanalyze(toastrelid, avForm,
2351+
toastClassForm, toasttabentry,
2352+
&toast_dovacuum, &toast_doanalyze,
2353+
&toast_wraparound);
23312354
/* we only consider VACUUM for toast tables */
23322355
if (toast_dovacuum)
23332356
{
@@ -2389,6 +2412,7 @@ table_recheck_autovac(Oid relid)
23892412
tab->at_freeze_min_age = freeze_min_age;
23902413
tab->at_vacuum_cost_limit = vac_cost_limit;
23912414
tab->at_vacuum_cost_delay = vac_cost_delay;
2415+
tab->at_wraparound = wraparound || toast_wraparound;
23922416
}
23932417

23942418
heap_close(avRel, AccessShareLock);
@@ -2403,7 +2427,8 @@ table_recheck_autovac(Oid relid)
24032427
* relation_needs_vacanalyze
24042428
*
24052429
* Check whether a relation needs to be vacuumed or analyzed; return each into
2406-
* "dovacuum" and "doanalyze", respectively. avForm and tabentry can be NULL,
2430+
* "dovacuum" and "doanalyze", respectively. Also return whether the vacuum is
2431+
* being forced because of Xid wraparound. avForm and tabentry can be NULL,
24072432
* classForm shouldn't.
24082433
*
24092434
* A table needs to be vacuumed if the number of dead tuples exceeds a
@@ -2437,7 +2462,8 @@ relation_needs_vacanalyze(Oid relid,
24372462
PgStat_StatTabEntry *tabentry,
24382463
/* output params below */
24392464
bool *dovacuum,
2440-
bool *doanalyze)
2465+
bool *doanalyze,
2466+
bool *wraparound)
24412467
{
24422468
bool force_vacuum;
24432469
float4 reltuples; /* pg_class.reltuples */
@@ -2499,6 +2525,7 @@ relation_needs_vacanalyze(Oid relid,
24992525
force_vacuum = (TransactionIdIsNormal(classForm->relfrozenxid) &&
25002526
TransactionIdPrecedes(classForm->relfrozenxid,
25012527
xidForceLimit));
2528+
*wraparound = force_vacuum;
25022529

25032530
/* User disabled it in pg_autovacuum? (But ignore if at risk) */
25042531
if (avForm && !avForm->enabled && !force_vacuum)

src/backend/storage/ipc/procarray.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*
2424
*
2525
* IDENTIFICATION
26-
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.35 2007/09/23 18:50:38 tgl Exp $
26+
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.36 2007/10/24 20:55:36 alvherre Exp $
2727
*
2828
*-------------------------------------------------------------------------
2929
*/
@@ -242,7 +242,8 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
242242
proc->xid = InvalidTransactionId;
243243
proc->lxid = InvalidLocalTransactionId;
244244
proc->xmin = InvalidTransactionId;
245-
proc->inVacuum = false; /* must be cleared with xid/xmin */
245+
/* must be cleared with xid/xmin: */
246+
proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
246247
proc->inCommit = false; /* be sure this is cleared in abort */
247248

248249
/* Clear the subtransaction-XID cache too while holding the lock */
@@ -267,7 +268,8 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
267268

268269
proc->lxid = InvalidLocalTransactionId;
269270
proc->xmin = InvalidTransactionId;
270-
proc->inVacuum = false; /* must be cleared with xid/xmin */
271+
/* must be cleared with xid/xmin: */
272+
proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
271273
proc->inCommit = false; /* be sure this is cleared in abort */
272274

273275
Assert(proc->subxids.nxids == 0);
@@ -296,8 +298,10 @@ ProcArrayClearTransaction(PGPROC *proc)
296298
proc->xid = InvalidTransactionId;
297299
proc->lxid = InvalidLocalTransactionId;
298300
proc->xmin = InvalidTransactionId;
299-
proc->inVacuum = false; /* redundant, but just in case */
300-
proc->inCommit = false; /* ditto */
301+
302+
/* redundant, but just in case */
303+
proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
304+
proc->inCommit = false;
301305

302306
/* Clear the subtransaction-XID cache too */
303307
proc->subxids.nxids = 0;
@@ -546,7 +550,8 @@ TransactionIdIsActive(TransactionId xid)
546550
* If allDbs is TRUE then all backends are considered; if allDbs is FALSE
547551
* then only backends running in my own database are considered.
548552
*
549-
* If ignoreVacuum is TRUE then backends with inVacuum set are ignored.
553+
* If ignoreVacuum is TRUE then backends with the PROC_IN_VACUUM flag set are
554+
* ignored.
550555
*
551556
* This is used by VACUUM to decide which deleted tuples must be preserved
552557
* in a table. allDbs = TRUE is needed for shared relations, but allDbs =
@@ -586,7 +591,7 @@ GetOldestXmin(bool allDbs, bool ignoreVacuum)
586591
{
587592
volatile PGPROC *proc = arrayP->procs[index];
588593

589-
if (ignoreVacuum && proc->inVacuum)
594+
if (ignoreVacuum && (proc->vacuumFlags & PROC_IN_VACUUM))
590595
continue;
591596

592597
if (allDbs || proc->databaseId == MyDatabaseId)
@@ -723,7 +728,7 @@ GetSnapshotData(Snapshot snapshot, bool serializable)
723728
TransactionId xid;
724729

725730
/* Ignore procs running LAZY VACUUM */
726-
if (proc->inVacuum)
731+
if (proc->vacuumFlags & PROC_IN_VACUUM)
727732
continue;
728733

729734
/* Update globalxmin to be the smallest valid xmin */
@@ -1193,7 +1198,7 @@ CheckOtherDBBackends(Oid databaseId)
11931198

11941199
found = true;
11951200

1196-
if (proc->isAutovacuum)
1201+
if (proc->vacuumFlags & PROC_IS_AUTOVACUUM)
11971202
{
11981203
/* an autovacuum --- send it SIGTERM before sleeping */
11991204
int autopid = proc->pid;

src/backend/storage/lmgr/proc.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.194 2007/09/08 20:31:15 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.195 2007/10/24 20:55:36 alvherre Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -291,8 +291,9 @@ InitProcess(void)
291291
MyProc->databaseId = InvalidOid;
292292
MyProc->roleId = InvalidOid;
293293
MyProc->inCommit = false;
294-
MyProc->inVacuum = false;
295-
MyProc->isAutovacuum = IsAutoVacuumWorkerProcess();
294+
MyProc->vacuumFlags = 0;
295+
if (IsAutoVacuumWorkerProcess())
296+
MyProc->vacuumFlags |= PROC_IS_AUTOVACUUM;
296297
MyProc->lwWaiting = false;
297298
MyProc->lwExclusive = false;
298299
MyProc->lwWaitLink = NULL;
@@ -429,8 +430,8 @@ InitAuxiliaryProcess(void)
429430
MyProc->databaseId = InvalidOid;
430431
MyProc->roleId = InvalidOid;
431432
MyProc->inCommit = false;
432-
MyProc->inVacuum = false;
433-
MyProc->isAutovacuum = IsAutoVacuumLauncherProcess(); /* is this needed? */
433+
/* we don't set the "is autovacuum" flag in the launcher */
434+
MyProc->vacuumFlags = 0;
434435
MyProc->lwWaiting = false;
435436
MyProc->lwExclusive = false;
436437
MyProc->lwWaitLink = NULL;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy