本文整理汇总了C++中IsAutoVacuumWorkerProcess函数的典型用法代码示例。如果您正苦于以下问题:C++ IsAutoVacuumWorkerProcess函数的具体用法?C++ IsAutoVacuumWorkerProcess怎么用?C++ IsAutoVacuumWorkerProcess使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了IsAutoVacuumWorkerProcess函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CommitTranGTM
int
CommitTranGTM(GlobalTransactionId gxid)
{
int ret;
if (!GlobalTransactionIdIsValid(gxid))
return 0;
CheckConnection();
ret = commit_transaction(conn, gxid);
/*
* If something went wrong (timeout), try and reset GTM connection.
* We will close the transaction locally anyway, and closing GTM will force
* it to be closed on GTM.
*/
if (ret < 0)
{
CloseGTM();
InitGTM();
}
/* Close connection in case commit is done by autovacuum worker or launcher */
if (IsAutoVacuumWorkerProcess() || IsAutoVacuumLauncherProcess())
CloseGTM();
return ret;
}
示例2: InitGTM
void
InitGTM(void)
{
/* 256 bytes should be enough */
char conn_str[256];
/* If this thread is postmaster itself, it contacts gtm identifying itself */
if (!IsUnderPostmaster)
{
GTM_PGXCNodeType remote_type = GTM_NODE_DEFAULT;
if (IS_PGXC_COORDINATOR)
remote_type = GTM_NODE_COORDINATOR;
else if (IS_PGXC_DATANODE)
remote_type = GTM_NODE_DATANODE;
sprintf(conn_str, "host=%s port=%d node_name=%s remote_type=%d postmaster=1",
GtmHost, GtmPort, PGXCNodeName, remote_type);
/* Log activity of GTM connections */
elog(DEBUG1, "Postmaster: connection established to GTM with string %s", conn_str);
}
else
{
sprintf(conn_str, "host=%s port=%d node_name=%s", GtmHost, GtmPort, PGXCNodeName);
/* Log activity of GTM connections */
if (IsAutoVacuumWorkerProcess())
elog(DEBUG1, "Autovacuum worker: connection established to GTM with string %s", conn_str);
else if (IsAutoVacuumLauncherProcess())
elog(DEBUG1, "Autovacuum launcher: connection established to GTM with string %s", conn_str);
else
elog(DEBUG1, "Postmaster child: connection established to GTM with string %s", conn_str);
}
conn = PQconnectGTM(conn_str);
if (GTMPQstatus(conn) != CONNECTION_OK)
{
int save_errno = errno;
ereport(WARNING,
(errcode(ERRCODE_CONNECTION_EXCEPTION),
errmsg("can not connect to GTM: %m")));
errno = save_errno;
CloseGTM();
}
#ifdef XCP
else if (IS_PGXC_COORDINATOR)
register_session(conn, PGXCNodeName, MyProcPid, MyBackendId);
#endif
}
示例3: proc_exit
/* ----------------------------------------------------------------
* proc_exit
*
* this function calls all the callbacks registered
* for it (to free resources) and then calls exit.
*
* This should be the only function to call exit().
* -cim 2/6/90
*
* Unfortunately, we can't really guarantee that add-on code
* obeys the rule of not calling exit() directly. So, while
* this is the preferred way out of the system, we also register
* an atexit callback that will make sure cleanup happens.
* ----------------------------------------------------------------
*/
void
proc_exit(int code)
{
pqsignal(SIGALRM, SIG_IGN);
/* Clean up everything that must be cleaned up */
proc_exit_prepare(code);
#ifdef PROFILE_PID_DIR
{
/*
* If we are profiling ourself then gprof's mcleanup() is about to
* write out a profile to ./gmon.out. Since mcleanup() always uses a
* fixed file name, each backend will overwrite earlier profiles. To
* fix that, we create a separate subdirectory for each backend
* (./gprof/pid) and 'cd' to that subdirectory before we exit() - that
* forces mcleanup() to write each profile into its own directory. We
* end up with something like: $PGDATA/gprof/8829/gmon.out
* $PGDATA/gprof/8845/gmon.out ...
*
* To avoid undesirable disk space bloat, autovacuum workers are
* discriminated against: all their gmon.out files go into the same
* subdirectory. Without this, an installation that is "just sitting
* there" nonetheless eats megabytes of disk space every few seconds.
*
* Note that we do this here instead of in an on_proc_exit() callback
* because we want to ensure that this code executes last - we don't
* want to interfere with any other on_proc_exit() callback. For the
* same reason, we do not include it in proc_exit_prepare ... so if
* you are exiting in the "wrong way" you won't drop your profile in a
* nice place.
*/
char gprofDirName[32];
if (IsAutoVacuumWorkerProcess())
snprintf(gprofDirName, 32, "gprof/avworker");
else
snprintf(gprofDirName, 32, "gprof/%d", (int) getpid());
mkdir("gprof", S_IRWXU | S_IRWXG | S_IRWXO);
mkdir(gprofDirName, S_IRWXU | S_IRWXG | S_IRWXO);
chdir(gprofDirName);
}
#endif
elog(DEBUG3, "exit(%d)", code);
exit(code);
}
示例4: CloseGTM
void
CloseGTM(void)
{
GTMPQfinish(conn);
conn = NULL;
/* Log activity of GTM connections */
if (!IsUnderPostmaster)
elog(DEBUG1, "Postmaster: connection to GTM closed");
else if (IsAutoVacuumWorkerProcess())
elog(DEBUG1, "Autovacuum worker: connection to GTM closed");
else if (IsAutoVacuumLauncherProcess())
elog(DEBUG1, "Autovacuum launcher: connection to GTM closed");
else
elog(DEBUG1, "Postmaster child: connection to GTM closed");
}
示例5: CommitTranGTM
int
CommitTranGTM(GlobalTransactionId gxid, int waited_xid_count,
GlobalTransactionId *waited_xids)
{
int ret;
if (!GlobalTransactionIdIsValid(gxid))
return 0;
CheckConnection();
#ifdef XCP
ret = -1;
if (conn)
#endif
ret = commit_transaction(conn, gxid, waited_xid_count, waited_xids);
/*
* If something went wrong (timeout), try and reset GTM connection.
* We will close the transaction locally anyway, and closing GTM will force
* it to be closed on GTM.
*/
if (ret < 0)
{
CloseGTM();
InitGTM();
#ifdef XCP
if (conn)
ret = commit_transaction(conn, gxid, waited_xid_count, waited_xids);
#endif
}
/* Close connection in case commit is done by autovacuum worker or launcher */
if (IsAutoVacuumWorkerProcess() || IsAutoVacuumLauncherProcess())
CloseGTM();
currentGxid = InvalidGlobalTransactionId;
return ret;
}
示例6: InitPostgres
//.........这里部分代码省略.........
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist",
dbname),
errdetail("The database subdirectory \"%s\" is missing.",
fullpath)));
else
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not access directory \"%s\": %m",
fullpath)));
}
ValidatePgVersion(fullpath);
}
SetDatabasePath(fullpath);
/*
* It's now possible to do real access to the system catalogs.
*
* Load relcache entries for the system catalogs. This must create at
* least the minimum set of "nailed-in" cache entries.
*/
RelationCacheInitializePhase3();
/*
* Perform client authentication if necessary, then figure out our
* postgres user ID, and see if we are a superuser.
*
* In standalone mode and in autovacuum worker processes, we use a fixed
* ID, otherwise we figure it out from the authenticated user name.
*/
if (bootstrap || IsAutoVacuumWorkerProcess())
{
InitializeSessionUserIdStandalone();
am_superuser = true;
}
else if (!IsUnderPostmaster)
{
InitializeSessionUserIdStandalone();
am_superuser = true;
if (!ThereIsAtLeastOneRole())
ereport(WARNING,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("no roles are defined in this database system"),
errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
username)));
}
else
{
/* normal multiuser case */
Assert(MyProcPort != NULL);
PerformAuthentication(MyProcPort);
InitializeSessionUserId(username);
am_superuser = superuser();
}
/* set up ACL framework (so CheckMyDatabase can check permissions) */
initialize_acl();
/* Process pg_db_role_setting options */
process_settings(MyDatabaseId, GetSessionUserId());
/*
* Re-read the pg_database row for our database, check permissions and set
示例7: InitPostgres
/* --------------------------------
* InitPostgres
* Initialize POSTGRES.
*
* The database can be specified by name, using the in_dbname parameter, or by
* OID, using the dboid parameter. In the latter case, the computed database
* name is passed out to the caller as a palloc'ed string in out_dbname.
*
* In bootstrap mode no parameters are used.
*
* The return value indicates whether the userID is a superuser. (That
* can only be tested inside a transaction, so we want to do it during
* the startup transaction rather than doing a separate one in postgres.c.)
*
* As of PostgreSQL 8.2, we expect InitProcess() was already called, so we
* already have a PGPROC struct ... but it's not filled in yet.
*
* Note:
* Be very careful with the order of calls in the InitPostgres function.
* --------------------------------
*/
bool
InitPostgres(const char *in_dbname, Oid dboid, const char *username,
char **out_dbname)
{
bool bootstrap = IsBootstrapProcessingMode();
bool autovacuum = IsAutoVacuumWorkerProcess();
bool am_superuser;
char *fullpath;
char dbname[NAMEDATALEN];
/*
* Set up the global variables holding database id and path. But note we
* won't actually try to touch the database just yet.
*
* We take a shortcut in the bootstrap case, otherwise we have to look up
* the db name in pg_database.
*/
if (bootstrap)
{
MyDatabaseId = TemplateDbOid;
MyDatabaseTableSpace = DEFAULTTABLESPACE_OID;
}
else
{
/*
* Find tablespace of the database we're about to open. Since we're
* not yet up and running we have to use one of the hackish
* FindMyDatabase variants, which look in the flat-file copy of
* pg_database.
*
* If the in_dbname param is NULL, lookup database by OID.
*/
if (in_dbname == NULL)
{
if (!FindMyDatabaseByOid(dboid, dbname, &MyDatabaseTableSpace))
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database %u does not exist", dboid)));
MyDatabaseId = dboid;
/* pass the database name to the caller */
*out_dbname = pstrdup(dbname);
}
else
{
if (!FindMyDatabase(in_dbname, &MyDatabaseId, &MyDatabaseTableSpace))
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist",
in_dbname)));
/* our database name is gotten from the caller */
strlcpy(dbname, in_dbname, NAMEDATALEN);
}
}
fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);
SetDatabasePath(fullpath);
/*
* Finish filling in the PGPROC struct, and add it to the ProcArray. (We
* need to know MyDatabaseId before we can do this, since it's entered
* into the PGPROC struct.)
*
* Once I have done this, I am visible to other backends!
*/
InitProcessPhase2();
/*
* Initialize my entry in the shared-invalidation manager's array of
* per-backend data.
*
* Sets up MyBackendId, a unique backend identifier.
*/
MyBackendId = InvalidBackendId;
SharedInvalBackendInit();
if (MyBackendId > MaxBackends || MyBackendId <= 0)
elog(FATAL, "bad backend id: %d", MyBackendId);
//.........这里部分代码省略.........
示例8: lazy_vacuum_rel
/*
* lazy_vacuum_rel() -- perform LAZY VACUUM for one heap relation
*
* This routine vacuums a single heap, cleans out its indexes, and
* updates its relpages and reltuples statistics.
*
* At entry, we have already established a transaction and opened
* and locked the relation.
*
* The return value indicates whether this function has held off
* interrupts -- caller must RESUME_INTERRUPTS() after commit if true.
*/
bool
lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
BufferAccessStrategy bstrategy, List *updated_stats)
{
LVRelStats *vacrelstats;
Relation *Irel;
int nindexes;
BlockNumber possibly_freeable;
PGRUsage ru0;
TimestampTz starttime = 0;
bool heldoff = false;
pg_rusage_init(&ru0);
/* measure elapsed time iff autovacuum logging requires it */
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration > 0)
starttime = GetCurrentTimestamp();
if (vacstmt->verbose)
elevel = INFO;
else
elevel = DEBUG2;
if (Gp_role == GP_ROLE_DISPATCH)
elevel = DEBUG2; /* vacuum and analyze messages aren't interesting from the QD */
#ifdef FAULT_INJECTOR
if (vacuumStatement_IsInAppendOnlyDropPhase(vacstmt))
{
FaultInjector_InjectFaultIfSet(
CompactionBeforeSegmentFileDropPhase,
DDLNotSpecified,
"", // databaseName
""); // tableName
}
if (vacummStatement_IsInAppendOnlyCleanupPhase(vacstmt))
{
FaultInjector_InjectFaultIfSet(
CompactionBeforeCleanupPhase,
DDLNotSpecified,
"", // databaseName
""); // tableName
}
#endif
/*
* MPP-23647. Update xid limits for heap as well as appendonly
* relations. This allows setting relfrozenxid to correct value
* for an appendonly (AO/CO) table.
*/
vac_strategy = bstrategy;
vacuum_set_xid_limits(vacstmt->freeze_min_age, onerel->rd_rel->relisshared,
&OldestXmin, &FreezeLimit);
/*
* Execute the various vacuum operations. Appendonly tables are treated
* differently.
*/
if (RelationIsAoRows(onerel) || RelationIsAoCols(onerel))
{
lazy_vacuum_aorel(onerel, vacstmt, updated_stats);
return false;
}
vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
/* heap relation */
/* Set threshold for interesting free space = average request size */
/* XXX should we scale it up or down? Adjust vacuum.c too, if so */
vacrelstats->threshold = GetAvgFSMRequestSize(&onerel->rd_node);
vacrelstats->num_index_scans = 0;
/* Open all indexes of the relation */
vac_open_indexes(onerel, RowExclusiveLock, &nindexes, &Irel);
vacrelstats->hasindex = (nindexes > 0);
/* Do the vacuuming */
lazy_scan_heap(onerel, vacrelstats, Irel, nindexes, updated_stats);
/* Done with indexes */
vac_close_indexes(nindexes, Irel, NoLock);
/*
* Optionally truncate the relation.
*
//.........这里部分代码省略.........
示例9: ginInsertCleanup
/*
* Move tuples from pending pages into regular GIN structure.
*
* On first glance it looks completely not crash-safe. But if we crash
* after posting entries to the main index and before removing them from the
* pending list, it's okay because when we redo the posting later on, nothing
* bad will happen.
*
* fill_fsm indicates that ginInsertCleanup should add deleted pages
* to FSM otherwise caller is responsible to put deleted pages into
* FSM.
*
* If stats isn't null, we count deleted pending pages into the counts.
*/
void
ginInsertCleanup(GinState *ginstate, bool full_clean,
bool fill_fsm, IndexBulkDeleteResult *stats)
{
Relation index = ginstate->index;
Buffer metabuffer,
buffer;
Page metapage,
page;
GinMetaPageData *metadata;
MemoryContext opCtx,
oldCtx;
BuildAccumulator accum;
KeyArray datums;
BlockNumber blkno,
blknoFinish;
bool cleanupFinish = false;
bool fsm_vac = false;
Size workMemory;
bool inVacuum = (stats == NULL);
/*
* We would like to prevent concurrent cleanup process. For that we will
* lock metapage in exclusive mode using LockPage() call. Nobody other
* will use that lock for metapage, so we keep possibility of concurrent
* insertion into pending list
*/
if (inVacuum)
{
/*
* We are called from [auto]vacuum/analyze or gin_clean_pending_list()
* and we would like to wait concurrent cleanup to finish.
*/
LockPage(index, GIN_METAPAGE_BLKNO, ExclusiveLock);
workMemory =
(IsAutoVacuumWorkerProcess() && autovacuum_work_mem != -1) ?
autovacuum_work_mem : maintenance_work_mem;
}
else
{
/*
* We are called from regular insert and if we see concurrent cleanup
* just exit in hope that concurrent process will clean up pending
* list.
*/
if (!ConditionalLockPage(index, GIN_METAPAGE_BLKNO, ExclusiveLock))
return;
workMemory = work_mem;
}
metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO);
LockBuffer(metabuffer, GIN_SHARE);
metapage = BufferGetPage(metabuffer);
metadata = GinPageGetMeta(metapage);
if (metadata->head == InvalidBlockNumber)
{
/* Nothing to do */
UnlockReleaseBuffer(metabuffer);
UnlockPage(index, GIN_METAPAGE_BLKNO, ExclusiveLock);
return;
}
/*
* Remember a tail page to prevent infinite cleanup if other backends add
* new tuples faster than we can cleanup.
*/
blknoFinish = metadata->tail;
/*
* Read and lock head of pending list
*/
blkno = metadata->head;
buffer = ReadBuffer(index, blkno);
LockBuffer(buffer, GIN_SHARE);
page = BufferGetPage(buffer);
LockBuffer(metabuffer, GIN_UNLOCK);
/*
* Initialize. All temporary space will be in opCtx
*/
opCtx = AllocSetContextCreate(CurrentMemoryContext,
"GIN insert cleanup temporary context",
ALLOCSET_DEFAULT_MINSIZE,
//.........这里部分代码省略.........
示例10: InitPostgres
//.........这里部分代码省略.........
/*
* Start a new transaction here before first access to db, and get a
* snapshot. We don't have a use for the snapshot itself, but we're
* interested in the secondary effect that it sets RecentGlobalXmin. (This
* is critical for anything that reads heap pages, because HOT may decide
* to prune them even if the process doesn't attempt to modify any
* tuples.)
*/
if (!bootstrap)
{
/* statement_timestamp must be set for timeouts to work correctly */
SetCurrentStatementStartTimestamp();
StartTransactionCommand();
/*
* transaction_isolation will have been set to the default by the
* above. If the default is "serializable", and we are in hot
* standby, we will fail if we don't change it to something lower.
* Fortunately, "read committed" is plenty good enough.
*/
XactIsoLevel = XACT_READ_COMMITTED;
(void) GetTransactionSnapshot();
}
/*
* Perform client authentication if necessary, then figure out our
* postgres user ID, and see if we are a superuser.
*
* In standalone mode and in autovacuum worker processes, we use a fixed
* ID, otherwise we figure it out from the authenticated user name.
*/
if (bootstrap || IsAutoVacuumWorkerProcess())
{
InitializeSessionUserIdStandalone();
am_superuser = true;
}
else if (!IsUnderPostmaster)
{
InitializeSessionUserIdStandalone();
am_superuser = true;
if (!ThereIsAtLeastOneRole())
ereport(WARNING,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("no roles are defined in this database system"),
errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
username)));
}
else if (IsBackgroundWorker)
{
if (username == NULL)
{
InitializeSessionUserIdStandalone();
am_superuser = true;
}
else
{
InitializeSessionUserId(username);
am_superuser = superuser();
}
}
else
{
/* normal multiuser case */
Assert(MyProcPort != NULL);
示例11: lazy_vacuum_rel
/*
* lazy_vacuum_rel() -- perform LAZY VACUUM for one heap relation
*
* This routine vacuums a single heap, cleans out its indexes, and
* updates its relpages and reltuples statistics.
*
* At entry, we have already established a transaction and opened
* and locked the relation.
*/
void
lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
BufferAccessStrategy bstrategy)
{
LVRelStats *vacrelstats;
Relation *Irel;
int nindexes;
BlockNumber possibly_freeable;
PGRUsage ru0;
TimestampTz starttime = 0;
long secs;
int usecs;
double read_rate,
write_rate;
bool scan_all;
TransactionId freezeTableLimit;
BlockNumber new_rel_pages;
double new_rel_tuples;
BlockNumber new_rel_allvisible;
TransactionId new_frozen_xid;
/* measure elapsed time iff autovacuum logging requires it */
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
{
pg_rusage_init(&ru0);
starttime = GetCurrentTimestamp();
}
if (vacstmt->options & VACOPT_VERBOSE)
elevel = INFO;
else
elevel = DEBUG2;
vac_strategy = bstrategy;
vacuum_set_xid_limits(vacstmt->freeze_min_age, vacstmt->freeze_table_age,
onerel->rd_rel->relisshared,
&OldestXmin, &FreezeLimit, &freezeTableLimit);
scan_all = TransactionIdPrecedesOrEquals(onerel->rd_rel->relfrozenxid,
freezeTableLimit);
vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
vacrelstats->old_rel_pages = onerel->rd_rel->relpages;
vacrelstats->old_rel_tuples = onerel->rd_rel->reltuples;
vacrelstats->num_index_scans = 0;
/* Open all indexes of the relation */
vac_open_indexes(onerel, RowExclusiveLock, &nindexes, &Irel);
vacrelstats->hasindex = (nindexes > 0);
/* Do the vacuuming */
lazy_scan_heap(onerel, vacrelstats, Irel, nindexes, scan_all);
/* Done with indexes */
vac_close_indexes(nindexes, Irel, NoLock);
/*
* Optionally truncate the relation.
*
* Don't even think about it unless we have a shot at releasing a goodly
* number of pages. Otherwise, the time taken isn't worth it.
*/
possibly_freeable = vacrelstats->rel_pages - vacrelstats->nonempty_pages;
if (possibly_freeable > 0 &&
(possibly_freeable >= REL_TRUNCATE_MINIMUM ||
possibly_freeable >= vacrelstats->rel_pages / REL_TRUNCATE_FRACTION))
lazy_truncate_heap(onerel, vacrelstats);
/* Vacuum the Free Space Map */
FreeSpaceMapVacuum(onerel);
/*
* Update statistics in pg_class.
*
* A corner case here is that if we scanned no pages at all because every
* page is all-visible, we should not update relpages/reltuples, because
* we have no new information to contribute. In particular this keeps
* us from replacing relpages=reltuples=0 (which means "unknown tuple
* density") with nonzero relpages and reltuples=0 (which means "zero
* tuple density") unless there's some actual evidence for the latter.
*
* We do update relallvisible even in the corner case, since if the
* table is all-visible we'd definitely like to know that. But clamp
* the value to be not more than what we're setting relpages to.
*
* Also, don't change relfrozenxid if we skipped any pages, since then
* we don't know for certain that all tuples have a newer xmin.
*/
new_rel_pages = vacrelstats->rel_pages;
new_rel_tuples = vacrelstats->new_rel_tuples;
//.........这里部分代码省略.........
示例12: vacuum
/*
* Primary entry point for VACUUM and ANALYZE commands.
*
* relid is normally InvalidOid; if it is not, then it provides the relation
* OID to be processed, and vacstmt->relation is ignored. (The non-invalid
* case is currently only used by autovacuum.)
*
* do_toast is passed as FALSE by autovacuum, because it processes TOAST
* tables separately.
*
* for_wraparound is used by autovacuum to let us know when it's forcing
* a vacuum for wraparound, which should not be auto-cancelled.
*
* bstrategy is normally given as NULL, but in autovacuum it can be passed
* in to use the same buffer strategy object across multiple vacuum() calls.
*
* isTopLevel should be passed down from ProcessUtility.
*
* It is the caller's responsibility that vacstmt and bstrategy
* (if given) be allocated in a memory context that won't disappear
* at transaction commit.
*/
void
vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
{
const char *stmttype;
volatile bool all_rels,
in_outer_xact,
use_own_xacts;
List *relations;
/* sanity checks on options */
Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE));
Assert((vacstmt->options & VACOPT_VACUUM) ||
!(vacstmt->options & (VACOPT_FULL | VACOPT_FREEZE)));
Assert((vacstmt->options & VACOPT_ANALYZE) || vacstmt->va_cols == NIL);
stmttype = (vacstmt->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
/*
* We cannot run VACUUM inside a user transaction block; if we were inside
* a transaction, then our commit- and start-transaction-command calls
* would not have the intended effect! There are numerous other subtle
* dependencies on this, too.
*
* ANALYZE (without VACUUM) can run either way.
*/
if (vacstmt->options & VACOPT_VACUUM)
{
PreventTransactionChain(isTopLevel, stmttype);
in_outer_xact = false;
}
else
in_outer_xact = IsInTransactionChain(isTopLevel);
/*
* Send info about dead objects to the statistics collector, unless we are
* in autovacuum --- autovacuum.c does this for itself.
*/
if ((vacstmt->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
pgstat_vacuum_stat();
/*
* Create special memory context for cross-transaction storage.
*
* Since it is a child of PortalContext, it will go away eventually even
* if we suffer an error; there's no need for special abort cleanup logic.
*/
vac_context = AllocSetContextCreate(PortalContext,
"Vacuum",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
/*
* If caller didn't give us a buffer strategy object, make one in the
* cross-transaction memory context.
*/
if (bstrategy == NULL)
{
MemoryContext old_context = MemoryContextSwitchTo(vac_context);
bstrategy = GetAccessStrategy(BAS_VACUUM);
MemoryContextSwitchTo(old_context);
}
vac_strategy = bstrategy;
/* Remember whether we are processing everything in the DB */
all_rels = (!OidIsValid(relid) && vacstmt->relation == NULL);
/*
* Build list of relations to process, unless caller gave us one. (If we
* build one, we put it in vac_context for safekeeping.)
*/
relations = get_rel_oids(relid, vacstmt->relation);
/*
* Decide whether we need to start/commit our own transactions.
*
//.........这里部分代码省略.........
示例13: DtmXactCallback
static void
DtmXactCallback(XactEvent event, void *arg)
{
//XTM_INFO("%d: DtmXactCallbackevent=%d nextxid=%d\n", getpid(), event, DtmNextXid);
switch (event)
{
case XACT_EVENT_START:
//XTM_INFO("%d: normal=%d, initialized=%d, replication=%d, bgw=%d, vacuum=%d\n",
// getpid(), IsNormalProcessingMode(), dtm->initialized, MMDoReplication, IsBackgroundWorker, IsAutoVacuumWorkerProcess());
if (IsNormalProcessingMode() && dtm->initialized && MMDoReplication && !am_walsender && !IsBackgroundWorker && !IsAutoVacuumWorkerProcess()) {
MMBeginTransaction();
}
break;
#if 0
case XACT_EVENT_PRE_COMMIT:
case XACT_EVENT_PARALLEL_PRE_COMMIT:
{
TransactionId xid = GetCurrentTransactionIdIfAny();
if (!MMIsDistributedTrans && TransactionIdIsValid(xid)) {
XTM_INFO("%d: Will ignore transaction %u\n", getpid(), xid);
MMMarkTransAsLocal(xid);
}
break;
}
#endif
case XACT_EVENT_COMMIT:
case XACT_EVENT_ABORT:
if (TransactionIdIsValid(DtmNextXid))
{
if (!DtmVoted) {
ArbiterSetTransStatus(DtmNextXid, TRANSACTION_STATUS_ABORTED, false);
}
if (event == XACT_EVENT_COMMIT)
{
/*
* Now transaction status is already written in CLOG,
* so we can remove information about it from hash table
*/
LWLockAcquire(dtm->hashLock, LW_EXCLUSIVE);
hash_search(xid_in_doubt, &DtmNextXid, HASH_REMOVE, NULL);
LWLockRelease(dtm->hashLock);
}
#if 0 /* should be handled now using DtmVoted flag */
else
{
/*
* Transaction at the node can be aborted because of transaction failure at some other node
* before it starts doing anything and assigned Xid, in this case Postgres is not calling SetTransactionStatus,
* so we have to send report to DTMD here
*/
if (!TransactionIdIsValid(GetCurrentTransactionIdIfAny())) {
XTM_INFO("%d: abort transation on DTMD\n", getpid());
ArbiterSetTransStatus(DtmNextXid, TRANSACTION_STATUS_ABORTED, false);
}
}
#endif
DtmNextXid = InvalidTransactionId;
DtmLastSnapshot = NULL;
}
MMIsDistributedTrans = false;
break;
default:
break;
}
}
示例14: vacuum
/*
* Primary entry point for VACUUM and ANALYZE commands.
*
* options is a bitmask of VacuumOption flags, indicating what to do.
*
* relid, if not InvalidOid, indicate the relation to process; otherwise,
* the RangeVar is used. (The latter must always be passed, because it's
* used for error messages.)
*
* params contains a set of parameters that can be used to customize the
* behavior.
*
* va_cols is a list of columns to analyze, or NIL to process them all.
*
* bstrategy is normally given as NULL, but in autovacuum it can be passed
* in to use the same buffer strategy object across multiple vacuum() calls.
*
* isTopLevel should be passed down from ProcessUtility.
*
* It is the caller's responsibility that all parameters are allocated in a
* memory context that will not disappear at transaction commit.
*/
void
vacuum(int options, RangeVar *relation, Oid relid, VacuumParams *params,
List *va_cols, BufferAccessStrategy bstrategy, bool isTopLevel)
{
const char *stmttype;
volatile bool in_outer_xact,
use_own_xacts;
List *relations;
static bool in_vacuum = false;
Assert(params != NULL);
stmttype = (options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
/*
* We cannot run VACUUM inside a user transaction block; if we were inside
* a transaction, then our commit- and start-transaction-command calls
* would not have the intended effect! There are numerous other subtle
* dependencies on this, too.
*
* ANALYZE (without VACUUM) can run either way.
*/
if (options & VACOPT_VACUUM)
{
PreventTransactionChain(isTopLevel, stmttype);
in_outer_xact = false;
}
else
in_outer_xact = IsInTransactionChain(isTopLevel);
/*
* Due to static variables vac_context, anl_context and vac_strategy,
* vacuum() is not reentrant. This matters when VACUUM FULL or ANALYZE
* calls a hostile index expression that itself calls ANALYZE.
*/
if (in_vacuum)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("%s cannot be executed from VACUUM or ANALYZE",
stmttype)));
/*
* Sanity check DISABLE_PAGE_SKIPPING option.
*/
if ((options & VACOPT_FULL) != 0 &&
(options & VACOPT_DISABLE_PAGE_SKIPPING) != 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
/*
* Send info about dead objects to the statistics collector, unless we are
* in autovacuum --- autovacuum.c does this for itself.
*/
if ((options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
pgstat_vacuum_stat();
/*
* Create special memory context for cross-transaction storage.
*
* Since it is a child of PortalContext, it will go away eventually even
* if we suffer an error; there's no need for special abort cleanup logic.
*/
vac_context = AllocSetContextCreate(PortalContext,
"Vacuum",
ALLOCSET_DEFAULT_SIZES);
/*
* If caller didn't give us a buffer strategy object, make one in the
* cross-transaction memory context.
*/
if (bstrategy == NULL)
{
MemoryContext old_context = MemoryContextSwitchTo(vac_context);
bstrategy = GetAccessStrategy(BAS_VACUUM);
MemoryContextSwitchTo(old_context);
}
//.........这里部分代码省略.........
示例15: InitProcess
/*
* InitProcess -- initialize a per-process data structure for this backend
*/
void
InitProcess(void)
{
/* use volatile pointer to prevent code rearrangement */
volatile PROC_HDR *procglobal = ProcGlobal;
/*
* ProcGlobal should be set up already (if we are a backend, we inherit
* this by fork() or EXEC_BACKEND mechanism from the postmaster).
*/
if (procglobal == NULL)
elog(PANIC, "proc header uninitialized");
if (MyProc != NULL)
elog(ERROR, "you already exist");
/*
* Try to get a proc struct from the free list. If this fails, we must be
* out of PGPROC structures (not to mention semaphores).
*
* While we are holding the ProcStructLock, also copy the current shared
* estimate of spins_per_delay to local storage.
*/
SpinLockAcquire(ProcStructLock);
set_spins_per_delay(procglobal->spins_per_delay);
if (IsAnyAutoVacuumProcess())
MyProc = procglobal->autovacFreeProcs;
else if (IsBackgroundWorker)
MyProc = procglobal->bgworkerFreeProcs;
else
MyProc = procglobal->freeProcs;
if (MyProc != NULL)
{
if (IsAnyAutoVacuumProcess())
procglobal->autovacFreeProcs = (PGPROC *) MyProc->links.next;
else if (IsBackgroundWorker)
procglobal->bgworkerFreeProcs = (PGPROC *) MyProc->links.next;
else
procglobal->freeProcs = (PGPROC *) MyProc->links.next;
SpinLockRelease(ProcStructLock);
}
else
{
/*
* If we reach here, all the PGPROCs are in use. This is one of the
* possible places to detect "too many backends", so give the standard
* error message. XXX do we need to give a different failure message
* in the autovacuum case?
*/
SpinLockRelease(ProcStructLock);
ereport(FATAL,
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
errmsg("sorry, too many clients already")));
}
MyPgXact = &ProcGlobal->allPgXact[MyProc->pgprocno];
/*
* Now that we have a PGPROC, mark ourselves as an active postmaster
* child; this is so that the postmaster can detect it if we exit without
* cleaning up. (XXX autovac launcher currently doesn't participate in
* this; it probably should.)
*/
if (IsUnderPostmaster && !IsAutoVacuumLauncherProcess())
MarkPostmasterChildActive();
/*
* Initialize all fields of MyProc, except for those previously
* initialized by InitProcGlobal.
*/
SHMQueueElemInit(&(MyProc->links));
MyProc->waitStatus = STATUS_OK;
MyProc->lxid = InvalidLocalTransactionId;
MyProc->fpVXIDLock = false;
MyProc->fpLocalTransactionId = InvalidLocalTransactionId;
MyPgXact->xid = InvalidTransactionId;
MyPgXact->xmin = InvalidTransactionId;
MyProc->pid = MyProcPid;
/* backendId, databaseId and roleId will be filled in later */
MyProc->backendId = InvalidBackendId;
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyPgXact->delayChkpt = false;
MyPgXact->vacuumFlags = 0;
/* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
if (IsAutoVacuumWorkerProcess())
MyPgXact->vacuumFlags |= PROC_IS_AUTOVACUUM;
MyProc->lwWaiting = false;
MyProc->lwWaitMode = 0;
MyProc->waitLock = NULL;
MyProc->waitProcLock = NULL;
#ifdef USE_ASSERT_CHECKING
{
int i;
//.........这里部分代码省略.........