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.
This commit is contained in:
parent
3ef18797b8
commit
745c1b2c2a
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.36 2007/09/21 16:32:19 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.37 2007/10/24 20:55:36 alvherre Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Each global transaction is associated with a global transaction
|
* Each global transaction is associated with a global transaction
|
||||||
@ -283,8 +283,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
|
|||||||
gxact->proc.databaseId = databaseid;
|
gxact->proc.databaseId = databaseid;
|
||||||
gxact->proc.roleId = owner;
|
gxact->proc.roleId = owner;
|
||||||
gxact->proc.inCommit = false;
|
gxact->proc.inCommit = false;
|
||||||
gxact->proc.inVacuum = false;
|
gxact->proc.vacuumFlags = 0;
|
||||||
gxact->proc.isAutovacuum = false;
|
|
||||||
gxact->proc.lwWaiting = false;
|
gxact->proc.lwWaiting = false;
|
||||||
gxact->proc.lwExclusive = false;
|
gxact->proc.lwExclusive = false;
|
||||||
gxact->proc.lwWaitLink = NULL;
|
gxact->proc.lwWaitLink = NULL;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.109 2007/09/24 03:12:23 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.110 2007/10/24 20:55:36 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
#include "pgstat.h"
|
#include "pgstat.h"
|
||||||
#include "postmaster/autovacuum.h"
|
#include "postmaster/autovacuum.h"
|
||||||
|
#include "storage/proc.h"
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
#include "utils/datum.h"
|
#include "utils/datum.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
@ -201,6 +202,11 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* let others know what I'm doing */
|
||||||
|
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
|
||||||
|
MyProc->vacuumFlags |= PROC_IN_ANALYZE;
|
||||||
|
LWLockRelease(ProcArrayLock);
|
||||||
|
|
||||||
/* measure elapsed time iff autovacuum logging requires it */
|
/* measure elapsed time iff autovacuum logging requires it */
|
||||||
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
|
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
|
||||||
{
|
{
|
||||||
@ -484,6 +490,14 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
|
|||||||
RelationGetRelationName(onerel),
|
RelationGetRelationName(onerel),
|
||||||
pg_rusage_show(&ru0))));
|
pg_rusage_show(&ru0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset my PGPROC flag. Note: we need this here, and not in vacuum_rel,
|
||||||
|
* because the vacuum flag is cleared by the end-of-xact code.
|
||||||
|
*/
|
||||||
|
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
|
||||||
|
MyProc->vacuumFlags &= ~PROC_IN_ANALYZE;
|
||||||
|
LWLockRelease(ProcArrayLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.359 2007/09/20 17:56:31 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.360 2007/10/24 20:55:36 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -660,9 +660,9 @@ vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
|
|||||||
* fixed-size never-null columns, but these are.
|
* fixed-size never-null columns, but these are.
|
||||||
*
|
*
|
||||||
* Another reason for doing it this way is that when we are in a lazy
|
* Another reason for doing it this way is that when we are in a lazy
|
||||||
* VACUUM and have inVacuum set, we mustn't do any updates --- somebody
|
* VACUUM and have PROC_IN_VACUUM set, we mustn't do any updates ---
|
||||||
* vacuuming pg_class might think they could delete a tuple marked with
|
* somebody vacuuming pg_class might think they could delete a tuple
|
||||||
* xmin = our xid.
|
* marked with xmin = our xid.
|
||||||
*
|
*
|
||||||
* This routine is shared by full VACUUM, lazy VACUUM, and stand-alone
|
* This routine is shared by full VACUUM, lazy VACUUM, and stand-alone
|
||||||
* ANALYZE.
|
* ANALYZE.
|
||||||
@ -987,9 +987,9 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
|
|||||||
* During a lazy VACUUM we do not run any user-supplied functions, and
|
* During a lazy VACUUM we do not run any user-supplied functions, and
|
||||||
* so it should be safe to not create a transaction snapshot.
|
* so it should be safe to not create a transaction snapshot.
|
||||||
*
|
*
|
||||||
* We can furthermore set the inVacuum flag, which lets other
|
* We can furthermore set the PROC_IN_VACUUM flag, which lets other
|
||||||
* concurrent VACUUMs know that they can ignore this one while
|
* concurrent VACUUMs know that they can ignore this one while
|
||||||
* determining their OldestXmin. (The reason we don't set inVacuum
|
* determining their OldestXmin. (The reason we don't set it
|
||||||
* during a full VACUUM is exactly that we may have to run user-
|
* during a full VACUUM is exactly that we may have to run user-
|
||||||
* defined functions for functional indexes, and we want to make sure
|
* defined functions for functional indexes, and we want to make sure
|
||||||
* that if they use the snapshot set above, any tuples it requires
|
* that if they use the snapshot set above, any tuples it requires
|
||||||
@ -997,12 +997,14 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
|
|||||||
* depends on the contents of other tables is arguably broken, but we
|
* depends on the contents of other tables is arguably broken, but we
|
||||||
* won't break it here by violating transaction semantics.)
|
* won't break it here by violating transaction semantics.)
|
||||||
*
|
*
|
||||||
* Note: the inVacuum flag remains set until CommitTransaction or
|
* Note: this flag remains set until CommitTransaction or
|
||||||
* AbortTransaction. We don't want to clear it until we reset
|
* AbortTransaction. We don't want to clear it until we reset
|
||||||
* MyProc->xid/xmin, else OldestXmin might appear to go backwards,
|
* MyProc->xid/xmin, else OldestXmin might appear to go backwards,
|
||||||
* which is probably Not Good.
|
* which is probably Not Good.
|
||||||
*/
|
*/
|
||||||
MyProc->inVacuum = true;
|
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
|
||||||
|
MyProc->vacuumFlags |= PROC_IN_VACUUM;
|
||||||
|
LWLockRelease(ProcArrayLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.62 2007/10/24 19:08:25 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.63 2007/10/24 20:55:36 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -172,6 +172,7 @@ typedef struct autovac_table
|
|||||||
int at_freeze_min_age;
|
int at_freeze_min_age;
|
||||||
int at_vacuum_cost_delay;
|
int at_vacuum_cost_delay;
|
||||||
int at_vacuum_cost_limit;
|
int at_vacuum_cost_limit;
|
||||||
|
bool at_wraparound;
|
||||||
} autovac_table;
|
} autovac_table;
|
||||||
|
|
||||||
/*-------------
|
/*-------------
|
||||||
@ -280,7 +281,7 @@ static autovac_table *table_recheck_autovac(Oid relid);
|
|||||||
static void relation_needs_vacanalyze(Oid relid, Form_pg_autovacuum avForm,
|
static void relation_needs_vacanalyze(Oid relid, Form_pg_autovacuum avForm,
|
||||||
Form_pg_class classForm,
|
Form_pg_class classForm,
|
||||||
PgStat_StatTabEntry *tabentry, bool *dovacuum,
|
PgStat_StatTabEntry *tabentry, bool *dovacuum,
|
||||||
bool *doanalyze);
|
bool *doanalyze, bool *wraparound);
|
||||||
|
|
||||||
static void autovacuum_do_vac_analyze(Oid relid, bool dovacuum,
|
static void autovacuum_do_vac_analyze(Oid relid, bool dovacuum,
|
||||||
bool doanalyze, int freeze_min_age,
|
bool doanalyze, int freeze_min_age,
|
||||||
@ -1440,9 +1441,6 @@ AutoVacWorkerMain(int argc, char *argv[])
|
|||||||
/* Identify myself via ps */
|
/* Identify myself via ps */
|
||||||
init_ps_display("autovacuum worker process", "", "", "");
|
init_ps_display("autovacuum worker process", "", "", "");
|
||||||
|
|
||||||
if (PostAuthDelay)
|
|
||||||
pg_usleep(PostAuthDelay * 1000000L);
|
|
||||||
|
|
||||||
SetProcessingMode(InitProcessing);
|
SetProcessingMode(InitProcessing);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1601,6 +1599,9 @@ AutoVacWorkerMain(int argc, char *argv[])
|
|||||||
ereport(DEBUG1,
|
ereport(DEBUG1,
|
||||||
(errmsg("autovacuum: processing database \"%s\"", dbname)));
|
(errmsg("autovacuum: processing database \"%s\"", dbname)));
|
||||||
|
|
||||||
|
if (PostAuthDelay)
|
||||||
|
pg_usleep(PostAuthDelay * 1000000L);
|
||||||
|
|
||||||
/* And do an appropriate amount of work */
|
/* And do an appropriate amount of work */
|
||||||
recentXid = ReadNewTransactionId();
|
recentXid = ReadNewTransactionId();
|
||||||
do_autovacuum();
|
do_autovacuum();
|
||||||
@ -2085,6 +2086,14 @@ next_worker:
|
|||||||
/* clean up memory before each iteration */
|
/* clean up memory before each iteration */
|
||||||
MemoryContextResetAndDeleteChildren(PortalContext);
|
MemoryContextResetAndDeleteChildren(PortalContext);
|
||||||
|
|
||||||
|
/* set the "vacuum for wraparound" flag in PGPROC */
|
||||||
|
if (tab->at_wraparound)
|
||||||
|
{
|
||||||
|
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
|
||||||
|
MyProc->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND;
|
||||||
|
LWLockRelease(ProcArrayLock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We will abort vacuuming the current table if something errors out,
|
* We will abort vacuuming the current table if something errors out,
|
||||||
* and continue with the next one in schedule; in particular, this
|
* and continue with the next one in schedule; in particular, this
|
||||||
@ -2119,6 +2128,7 @@ next_worker:
|
|||||||
get_rel_name(tab->at_relid));
|
get_rel_name(tab->at_relid));
|
||||||
EmitErrorReport();
|
EmitErrorReport();
|
||||||
|
|
||||||
|
/* this resets the PGPROC flags too */
|
||||||
AbortOutOfAnyTransaction();
|
AbortOutOfAnyTransaction();
|
||||||
FlushErrorState();
|
FlushErrorState();
|
||||||
MemoryContextResetAndDeleteChildren(PortalContext);
|
MemoryContextResetAndDeleteChildren(PortalContext);
|
||||||
@ -2129,6 +2139,14 @@ next_worker:
|
|||||||
}
|
}
|
||||||
PG_END_TRY();
|
PG_END_TRY();
|
||||||
|
|
||||||
|
/* reset my PGPROC flag */
|
||||||
|
if (tab->at_wraparound)
|
||||||
|
{
|
||||||
|
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
|
||||||
|
MyProc->vacuumFlags &= ~PROC_VACUUM_FOR_WRAPAROUND;
|
||||||
|
LWLockRelease(ProcArrayLock);
|
||||||
|
}
|
||||||
|
|
||||||
/* be tidy */
|
/* be tidy */
|
||||||
pfree(tab);
|
pfree(tab);
|
||||||
|
|
||||||
@ -2223,9 +2241,10 @@ relation_check_autovac(Oid relid, Form_pg_class classForm,
|
|||||||
{
|
{
|
||||||
bool dovacuum;
|
bool dovacuum;
|
||||||
bool doanalyze;
|
bool doanalyze;
|
||||||
|
bool dummy;
|
||||||
|
|
||||||
relation_needs_vacanalyze(relid, avForm, classForm, tabentry,
|
relation_needs_vacanalyze(relid, avForm, classForm, tabentry,
|
||||||
&dovacuum, &doanalyze);
|
&dovacuum, &doanalyze, &dummy);
|
||||||
|
|
||||||
if (classForm->relkind == RELKIND_TOASTVALUE)
|
if (classForm->relkind == RELKIND_TOASTVALUE)
|
||||||
{
|
{
|
||||||
@ -2272,6 +2291,8 @@ table_recheck_autovac(Oid relid)
|
|||||||
bool doit = false;
|
bool doit = false;
|
||||||
PgStat_StatDBEntry *shared;
|
PgStat_StatDBEntry *shared;
|
||||||
PgStat_StatDBEntry *dbentry;
|
PgStat_StatDBEntry *dbentry;
|
||||||
|
bool wraparound,
|
||||||
|
toast_wraparound = false;
|
||||||
|
|
||||||
/* use fresh stats */
|
/* use fresh stats */
|
||||||
autovac_refresh_stats();
|
autovac_refresh_stats();
|
||||||
@ -2298,7 +2319,7 @@ table_recheck_autovac(Oid relid)
|
|||||||
shared, dbentry);
|
shared, dbentry);
|
||||||
|
|
||||||
relation_needs_vacanalyze(relid, avForm, classForm, tabentry,
|
relation_needs_vacanalyze(relid, avForm, classForm, tabentry,
|
||||||
&dovacuum, &doanalyze);
|
&dovacuum, &doanalyze, &wraparound);
|
||||||
|
|
||||||
/* OK, it needs vacuum by itself */
|
/* OK, it needs vacuum by itself */
|
||||||
if (dovacuum)
|
if (dovacuum)
|
||||||
@ -2316,6 +2337,7 @@ table_recheck_autovac(Oid relid)
|
|||||||
{
|
{
|
||||||
bool toast_dovacuum;
|
bool toast_dovacuum;
|
||||||
bool toast_doanalyze;
|
bool toast_doanalyze;
|
||||||
|
bool toast_wraparound;
|
||||||
Form_pg_class toastClassForm;
|
Form_pg_class toastClassForm;
|
||||||
PgStat_StatTabEntry *toasttabentry;
|
PgStat_StatTabEntry *toasttabentry;
|
||||||
|
|
||||||
@ -2325,9 +2347,10 @@ table_recheck_autovac(Oid relid)
|
|||||||
shared, dbentry);
|
shared, dbentry);
|
||||||
|
|
||||||
/* note we use the pg_autovacuum entry for the main table */
|
/* note we use the pg_autovacuum entry for the main table */
|
||||||
relation_needs_vacanalyze(toastrelid, avForm, toastClassForm,
|
relation_needs_vacanalyze(toastrelid, avForm,
|
||||||
toasttabentry, &toast_dovacuum,
|
toastClassForm, toasttabentry,
|
||||||
&toast_doanalyze);
|
&toast_dovacuum, &toast_doanalyze,
|
||||||
|
&toast_wraparound);
|
||||||
/* we only consider VACUUM for toast tables */
|
/* we only consider VACUUM for toast tables */
|
||||||
if (toast_dovacuum)
|
if (toast_dovacuum)
|
||||||
{
|
{
|
||||||
@ -2389,6 +2412,7 @@ table_recheck_autovac(Oid relid)
|
|||||||
tab->at_freeze_min_age = freeze_min_age;
|
tab->at_freeze_min_age = freeze_min_age;
|
||||||
tab->at_vacuum_cost_limit = vac_cost_limit;
|
tab->at_vacuum_cost_limit = vac_cost_limit;
|
||||||
tab->at_vacuum_cost_delay = vac_cost_delay;
|
tab->at_vacuum_cost_delay = vac_cost_delay;
|
||||||
|
tab->at_wraparound = wraparound || toast_wraparound;
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_close(avRel, AccessShareLock);
|
heap_close(avRel, AccessShareLock);
|
||||||
@ -2403,7 +2427,8 @@ table_recheck_autovac(Oid relid)
|
|||||||
* relation_needs_vacanalyze
|
* relation_needs_vacanalyze
|
||||||
*
|
*
|
||||||
* Check whether a relation needs to be vacuumed or analyzed; return each into
|
* Check whether a relation needs to be vacuumed or analyzed; return each into
|
||||||
* "dovacuum" and "doanalyze", respectively. avForm and tabentry can be NULL,
|
* "dovacuum" and "doanalyze", respectively. Also return whether the vacuum is
|
||||||
|
* being forced because of Xid wraparound. avForm and tabentry can be NULL,
|
||||||
* classForm shouldn't.
|
* classForm shouldn't.
|
||||||
*
|
*
|
||||||
* A table needs to be vacuumed if the number of dead tuples exceeds a
|
* A table needs to be vacuumed if the number of dead tuples exceeds a
|
||||||
@ -2437,7 +2462,8 @@ relation_needs_vacanalyze(Oid relid,
|
|||||||
PgStat_StatTabEntry *tabentry,
|
PgStat_StatTabEntry *tabentry,
|
||||||
/* output params below */
|
/* output params below */
|
||||||
bool *dovacuum,
|
bool *dovacuum,
|
||||||
bool *doanalyze)
|
bool *doanalyze,
|
||||||
|
bool *wraparound)
|
||||||
{
|
{
|
||||||
bool force_vacuum;
|
bool force_vacuum;
|
||||||
float4 reltuples; /* pg_class.reltuples */
|
float4 reltuples; /* pg_class.reltuples */
|
||||||
@ -2499,6 +2525,7 @@ relation_needs_vacanalyze(Oid relid,
|
|||||||
force_vacuum = (TransactionIdIsNormal(classForm->relfrozenxid) &&
|
force_vacuum = (TransactionIdIsNormal(classForm->relfrozenxid) &&
|
||||||
TransactionIdPrecedes(classForm->relfrozenxid,
|
TransactionIdPrecedes(classForm->relfrozenxid,
|
||||||
xidForceLimit));
|
xidForceLimit));
|
||||||
|
*wraparound = force_vacuum;
|
||||||
|
|
||||||
/* User disabled it in pg_autovacuum? (But ignore if at risk) */
|
/* User disabled it in pg_autovacuum? (But ignore if at risk) */
|
||||||
if (avForm && !avForm->enabled && !force_vacuum)
|
if (avForm && !avForm->enabled && !force_vacuum)
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.35 2007/09/23 18:50:38 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.36 2007/10/24 20:55:36 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -242,7 +242,8 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
|
|||||||
proc->xid = InvalidTransactionId;
|
proc->xid = InvalidTransactionId;
|
||||||
proc->lxid = InvalidLocalTransactionId;
|
proc->lxid = InvalidLocalTransactionId;
|
||||||
proc->xmin = InvalidTransactionId;
|
proc->xmin = InvalidTransactionId;
|
||||||
proc->inVacuum = false; /* must be cleared with xid/xmin */
|
/* must be cleared with xid/xmin: */
|
||||||
|
proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||||
proc->inCommit = false; /* be sure this is cleared in abort */
|
proc->inCommit = false; /* be sure this is cleared in abort */
|
||||||
|
|
||||||
/* Clear the subtransaction-XID cache too while holding the lock */
|
/* Clear the subtransaction-XID cache too while holding the lock */
|
||||||
@ -267,7 +268,8 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
|
|||||||
|
|
||||||
proc->lxid = InvalidLocalTransactionId;
|
proc->lxid = InvalidLocalTransactionId;
|
||||||
proc->xmin = InvalidTransactionId;
|
proc->xmin = InvalidTransactionId;
|
||||||
proc->inVacuum = false; /* must be cleared with xid/xmin */
|
/* must be cleared with xid/xmin: */
|
||||||
|
proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||||
proc->inCommit = false; /* be sure this is cleared in abort */
|
proc->inCommit = false; /* be sure this is cleared in abort */
|
||||||
|
|
||||||
Assert(proc->subxids.nxids == 0);
|
Assert(proc->subxids.nxids == 0);
|
||||||
@ -296,8 +298,10 @@ ProcArrayClearTransaction(PGPROC *proc)
|
|||||||
proc->xid = InvalidTransactionId;
|
proc->xid = InvalidTransactionId;
|
||||||
proc->lxid = InvalidLocalTransactionId;
|
proc->lxid = InvalidLocalTransactionId;
|
||||||
proc->xmin = InvalidTransactionId;
|
proc->xmin = InvalidTransactionId;
|
||||||
proc->inVacuum = false; /* redundant, but just in case */
|
|
||||||
proc->inCommit = false; /* ditto */
|
/* redundant, but just in case */
|
||||||
|
proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK;
|
||||||
|
proc->inCommit = false;
|
||||||
|
|
||||||
/* Clear the subtransaction-XID cache too */
|
/* Clear the subtransaction-XID cache too */
|
||||||
proc->subxids.nxids = 0;
|
proc->subxids.nxids = 0;
|
||||||
@ -546,7 +550,8 @@ TransactionIdIsActive(TransactionId xid)
|
|||||||
* If allDbs is TRUE then all backends are considered; if allDbs is FALSE
|
* If allDbs is TRUE then all backends are considered; if allDbs is FALSE
|
||||||
* then only backends running in my own database are considered.
|
* then only backends running in my own database are considered.
|
||||||
*
|
*
|
||||||
* If ignoreVacuum is TRUE then backends with inVacuum set are ignored.
|
* If ignoreVacuum is TRUE then backends with the PROC_IN_VACUUM flag set are
|
||||||
|
* ignored.
|
||||||
*
|
*
|
||||||
* This is used by VACUUM to decide which deleted tuples must be preserved
|
* This is used by VACUUM to decide which deleted tuples must be preserved
|
||||||
* in a table. allDbs = TRUE is needed for shared relations, but allDbs =
|
* in a table. allDbs = TRUE is needed for shared relations, but allDbs =
|
||||||
@ -586,7 +591,7 @@ GetOldestXmin(bool allDbs, bool ignoreVacuum)
|
|||||||
{
|
{
|
||||||
volatile PGPROC *proc = arrayP->procs[index];
|
volatile PGPROC *proc = arrayP->procs[index];
|
||||||
|
|
||||||
if (ignoreVacuum && proc->inVacuum)
|
if (ignoreVacuum && (proc->vacuumFlags & PROC_IN_VACUUM))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (allDbs || proc->databaseId == MyDatabaseId)
|
if (allDbs || proc->databaseId == MyDatabaseId)
|
||||||
@ -723,7 +728,7 @@ GetSnapshotData(Snapshot snapshot, bool serializable)
|
|||||||
TransactionId xid;
|
TransactionId xid;
|
||||||
|
|
||||||
/* Ignore procs running LAZY VACUUM */
|
/* Ignore procs running LAZY VACUUM */
|
||||||
if (proc->inVacuum)
|
if (proc->vacuumFlags & PROC_IN_VACUUM)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Update globalxmin to be the smallest valid xmin */
|
/* Update globalxmin to be the smallest valid xmin */
|
||||||
@ -1193,7 +1198,7 @@ CheckOtherDBBackends(Oid databaseId)
|
|||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
|
|
||||||
if (proc->isAutovacuum)
|
if (proc->vacuumFlags & PROC_IS_AUTOVACUUM)
|
||||||
{
|
{
|
||||||
/* an autovacuum --- send it SIGTERM before sleeping */
|
/* an autovacuum --- send it SIGTERM before sleeping */
|
||||||
int autopid = proc->pid;
|
int autopid = proc->pid;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.194 2007/09/08 20:31:15 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.195 2007/10/24 20:55:36 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -291,8 +291,9 @@ InitProcess(void)
|
|||||||
MyProc->databaseId = InvalidOid;
|
MyProc->databaseId = InvalidOid;
|
||||||
MyProc->roleId = InvalidOid;
|
MyProc->roleId = InvalidOid;
|
||||||
MyProc->inCommit = false;
|
MyProc->inCommit = false;
|
||||||
MyProc->inVacuum = false;
|
MyProc->vacuumFlags = 0;
|
||||||
MyProc->isAutovacuum = IsAutoVacuumWorkerProcess();
|
if (IsAutoVacuumWorkerProcess())
|
||||||
|
MyProc->vacuumFlags |= PROC_IS_AUTOVACUUM;
|
||||||
MyProc->lwWaiting = false;
|
MyProc->lwWaiting = false;
|
||||||
MyProc->lwExclusive = false;
|
MyProc->lwExclusive = false;
|
||||||
MyProc->lwWaitLink = NULL;
|
MyProc->lwWaitLink = NULL;
|
||||||
@ -429,8 +430,8 @@ InitAuxiliaryProcess(void)
|
|||||||
MyProc->databaseId = InvalidOid;
|
MyProc->databaseId = InvalidOid;
|
||||||
MyProc->roleId = InvalidOid;
|
MyProc->roleId = InvalidOid;
|
||||||
MyProc->inCommit = false;
|
MyProc->inCommit = false;
|
||||||
MyProc->inVacuum = false;
|
/* we don't set the "is autovacuum" flag in the launcher */
|
||||||
MyProc->isAutovacuum = IsAutoVacuumLauncherProcess(); /* is this needed? */
|
MyProc->vacuumFlags = 0;
|
||||||
MyProc->lwWaiting = false;
|
MyProc->lwWaiting = false;
|
||||||
MyProc->lwExclusive = false;
|
MyProc->lwExclusive = false;
|
||||||
MyProc->lwWaitLink = NULL;
|
MyProc->lwWaitLink = NULL;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.100 2007/09/05 18:10:48 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.101 2007/10/24 20:55:36 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -38,6 +38,15 @@ struct XidCache
|
|||||||
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS];
|
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Flags for PGPROC->vacuumFlags */
|
||||||
|
#define PROC_IS_AUTOVACUUM 0x01 /* is it an autovac worker? */
|
||||||
|
#define PROC_IN_VACUUM 0x02 /* currently running lazy vacuum */
|
||||||
|
#define PROC_IN_ANALYZE 0x04 /* currently running analyze */
|
||||||
|
#define PROC_VACUUM_FOR_WRAPAROUND 0x08 /* set by autovac only */
|
||||||
|
|
||||||
|
/* flags reset at EOXact */
|
||||||
|
#define PROC_VACUUM_STATE_MASK (0x0E)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each backend has a PGPROC struct in shared memory. There is also a list of
|
* Each backend has a PGPROC struct in shared memory. There is also a list of
|
||||||
* currently-unused PGPROC structs that will be reallocated to new backends.
|
* currently-unused PGPROC structs that will be reallocated to new backends.
|
||||||
@ -82,8 +91,7 @@ struct PGPROC
|
|||||||
|
|
||||||
bool inCommit; /* true if within commit critical section */
|
bool inCommit; /* true if within commit critical section */
|
||||||
|
|
||||||
bool inVacuum; /* true if current xact is a LAZY VACUUM */
|
uint8 vacuumFlags; /* vacuum-related flags, see above */
|
||||||
bool isAutovacuum; /* true if it's autovacuum */
|
|
||||||
|
|
||||||
/* Info about LWLock the process is currently waiting for, if any. */
|
/* Info about LWLock the process is currently waiting for, if any. */
|
||||||
bool lwWaiting; /* true if waiting for an LW lock */
|
bool lwWaiting; /* true if waiting for an LW lock */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user