mirror of
https://github.com/postgres/postgres.git
synced 2025-05-29 16:21:20 +03:00
Separate the code to start a new worker into its own function. The code is
exactly the same, modulo whitespace.
This commit is contained in:
parent
6287eb7adc
commit
a0abe87f1c
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.36 2007/03/23 21:23:13 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.37 2007/03/23 21:45:17 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -118,6 +118,7 @@ static pid_t avworker_forkexec(void);
|
|||||||
NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]);
|
NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]);
|
||||||
NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]);
|
NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]);
|
||||||
|
|
||||||
|
static void do_start_worker(void);
|
||||||
static void do_autovacuum(PgStat_StatDBEntry *dbentry);
|
static void do_autovacuum(PgStat_StatDBEntry *dbentry);
|
||||||
static List *autovac_get_database_list(void);
|
static List *autovac_get_database_list(void);
|
||||||
static void test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry,
|
static void test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry,
|
||||||
@ -218,9 +219,6 @@ NON_EXEC_STATIC void
|
|||||||
AutoVacLauncherMain(int argc, char *argv[])
|
AutoVacLauncherMain(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
sigjmp_buf local_sigjmp_buf;
|
sigjmp_buf local_sigjmp_buf;
|
||||||
List *dblist;
|
|
||||||
bool for_xid_wrap;
|
|
||||||
autovac_dbase *db;
|
|
||||||
MemoryContext avlauncher_cxt;
|
MemoryContext avlauncher_cxt;
|
||||||
|
|
||||||
/* we are a postmaster subprocess now */
|
/* we are a postmaster subprocess now */
|
||||||
@ -358,8 +356,6 @@ AutoVacLauncherMain(int argc, char *argv[])
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
TransactionId xidForceLimit;
|
|
||||||
ListCell *cell;
|
|
||||||
int worker_pid;
|
int worker_pid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -407,86 +403,8 @@ AutoVacLauncherMain(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a list of databases */
|
do_start_worker();
|
||||||
dblist = autovac_get_database_list();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine the oldest datfrozenxid/relfrozenxid that we will allow
|
|
||||||
* to pass without forcing a vacuum. (This limit can be tightened for
|
|
||||||
* particular tables, but not loosened.)
|
|
||||||
*/
|
|
||||||
recentXid = ReadNewTransactionId();
|
|
||||||
xidForceLimit = recentXid - autovacuum_freeze_max_age;
|
|
||||||
/* ensure it's a "normal" XID, else TransactionIdPrecedes misbehaves */
|
|
||||||
if (xidForceLimit < FirstNormalTransactionId)
|
|
||||||
xidForceLimit -= FirstNormalTransactionId;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Choose a database to connect to. We pick the database that was least
|
|
||||||
* recently auto-vacuumed, or one that needs vacuuming to prevent Xid
|
|
||||||
* wraparound-related data loss. If any db at risk of wraparound is
|
|
||||||
* found, we pick the one with oldest datfrozenxid, independently of
|
|
||||||
* autovacuum times.
|
|
||||||
*
|
|
||||||
* Note that a database with no stats entry is not considered, except for
|
|
||||||
* Xid wraparound purposes. The theory is that if no one has ever
|
|
||||||
* connected to it since the stats were last initialized, it doesn't need
|
|
||||||
* vacuuming.
|
|
||||||
*
|
|
||||||
* XXX This could be improved if we had more info about whether it needs
|
|
||||||
* vacuuming before connecting to it. Perhaps look through the pgstats
|
|
||||||
* data for the database's tables? One idea is to keep track of the
|
|
||||||
* number of new and dead tuples per database in pgstats. However it
|
|
||||||
* isn't clear how to construct a metric that measures that and not cause
|
|
||||||
* starvation for less busy databases.
|
|
||||||
*/
|
|
||||||
db = NULL;
|
|
||||||
for_xid_wrap = false;
|
|
||||||
foreach(cell, dblist)
|
|
||||||
{
|
|
||||||
autovac_dbase *tmp = lfirst(cell);
|
|
||||||
|
|
||||||
/* Find pgstat entry if any */
|
|
||||||
tmp->entry = pgstat_fetch_stat_dbentry(tmp->oid);
|
|
||||||
|
|
||||||
/* Check to see if this one is at risk of wraparound */
|
|
||||||
if (TransactionIdPrecedes(tmp->frozenxid, xidForceLimit))
|
|
||||||
{
|
|
||||||
if (db == NULL ||
|
|
||||||
TransactionIdPrecedes(tmp->frozenxid, db->frozenxid))
|
|
||||||
db = tmp;
|
|
||||||
for_xid_wrap = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (for_xid_wrap)
|
|
||||||
continue; /* ignore not-at-risk DBs */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Otherwise, skip a database with no pgstat entry; it means it
|
|
||||||
* hasn't seen any activity.
|
|
||||||
*/
|
|
||||||
if (!tmp->entry)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remember the db with oldest autovac time. (If we are here,
|
|
||||||
* both tmp->entry and db->entry must be non-null.)
|
|
||||||
*/
|
|
||||||
if (db == NULL ||
|
|
||||||
tmp->entry->last_autovac_time < db->entry->last_autovac_time)
|
|
||||||
db = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Found a database -- process it */
|
|
||||||
if (db != NULL)
|
|
||||||
{
|
|
||||||
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
|
|
||||||
AutoVacuumShmem->process_db = db->oid;
|
|
||||||
LWLockRelease(AutovacuumLock);
|
|
||||||
|
|
||||||
SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
sleep:
|
sleep:
|
||||||
/*
|
/*
|
||||||
* in emergency mode, exit immediately so that the postmaster can
|
* in emergency mode, exit immediately so that the postmaster can
|
||||||
@ -512,6 +430,103 @@ sleep:
|
|||||||
proc_exit(0); /* done */
|
proc_exit(0); /* done */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_start_worker
|
||||||
|
*
|
||||||
|
* Bare-bones procedure for starting an autovacuum worker from the launcher.
|
||||||
|
* It determines what database to work on, sets up shared memory stuff and
|
||||||
|
* signals postmaster to start the worker.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
do_start_worker(void)
|
||||||
|
{
|
||||||
|
List *dblist;
|
||||||
|
bool for_xid_wrap;
|
||||||
|
autovac_dbase *db;
|
||||||
|
ListCell *cell;
|
||||||
|
TransactionId xidForceLimit;
|
||||||
|
|
||||||
|
/* Get a list of databases */
|
||||||
|
dblist = autovac_get_database_list();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the oldest datfrozenxid/relfrozenxid that we will allow
|
||||||
|
* to pass without forcing a vacuum. (This limit can be tightened for
|
||||||
|
* particular tables, but not loosened.)
|
||||||
|
*/
|
||||||
|
recentXid = ReadNewTransactionId();
|
||||||
|
xidForceLimit = recentXid - autovacuum_freeze_max_age;
|
||||||
|
/* ensure it's a "normal" XID, else TransactionIdPrecedes misbehaves */
|
||||||
|
if (xidForceLimit < FirstNormalTransactionId)
|
||||||
|
xidForceLimit -= FirstNormalTransactionId;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Choose a database to connect to. We pick the database that was least
|
||||||
|
* recently auto-vacuumed, or one that needs vacuuming to prevent Xid
|
||||||
|
* wraparound-related data loss. If any db at risk of wraparound is
|
||||||
|
* found, we pick the one with oldest datfrozenxid, independently of
|
||||||
|
* autovacuum times.
|
||||||
|
*
|
||||||
|
* Note that a database with no stats entry is not considered, except for
|
||||||
|
* Xid wraparound purposes. The theory is that if no one has ever
|
||||||
|
* connected to it since the stats were last initialized, it doesn't need
|
||||||
|
* vacuuming.
|
||||||
|
*
|
||||||
|
* XXX This could be improved if we had more info about whether it needs
|
||||||
|
* vacuuming before connecting to it. Perhaps look through the pgstats
|
||||||
|
* data for the database's tables? One idea is to keep track of the
|
||||||
|
* number of new and dead tuples per database in pgstats. However it
|
||||||
|
* isn't clear how to construct a metric that measures that and not cause
|
||||||
|
* starvation for less busy databases.
|
||||||
|
*/
|
||||||
|
db = NULL;
|
||||||
|
for_xid_wrap = false;
|
||||||
|
foreach(cell, dblist)
|
||||||
|
{
|
||||||
|
autovac_dbase *tmp = lfirst(cell);
|
||||||
|
|
||||||
|
/* Find pgstat entry if any */
|
||||||
|
tmp->entry = pgstat_fetch_stat_dbentry(tmp->oid);
|
||||||
|
|
||||||
|
/* Check to see if this one is at risk of wraparound */
|
||||||
|
if (TransactionIdPrecedes(tmp->frozenxid, xidForceLimit))
|
||||||
|
{
|
||||||
|
if (db == NULL ||
|
||||||
|
TransactionIdPrecedes(tmp->frozenxid, db->frozenxid))
|
||||||
|
db = tmp;
|
||||||
|
for_xid_wrap = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (for_xid_wrap)
|
||||||
|
continue; /* ignore not-at-risk DBs */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Otherwise, skip a database with no pgstat entry; it means it
|
||||||
|
* hasn't seen any activity.
|
||||||
|
*/
|
||||||
|
if (!tmp->entry)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remember the db with oldest autovac time. (If we are here,
|
||||||
|
* both tmp->entry and db->entry must be non-null.)
|
||||||
|
*/
|
||||||
|
if (db == NULL ||
|
||||||
|
tmp->entry->last_autovac_time < db->entry->last_autovac_time)
|
||||||
|
db = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Found a database -- process it */
|
||||||
|
if (db != NULL)
|
||||||
|
{
|
||||||
|
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
|
||||||
|
AutoVacuumShmem->process_db = db->oid;
|
||||||
|
LWLockRelease(AutovacuumLock);
|
||||||
|
|
||||||
|
SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* SIGHUP: set flag to re-read config file at next convenient time */
|
/* SIGHUP: set flag to re-read config file at next convenient time */
|
||||||
static void
|
static void
|
||||||
avl_sighup_handler(SIGNAL_ARGS)
|
avl_sighup_handler(SIGNAL_ARGS)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user