aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/analyze.c55
-rw-r--r--src/backend/commands/vacuum.c169
-rw-r--r--src/include/commands/vacuum.h2
3 files changed, 117 insertions, 109 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index d11b559b20a..da757f09747 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -120,7 +120,6 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
int elevel;
AcquireSampleRowsFunc acquirefunc = NULL;
BlockNumber relpages = 0;
- bool rel_lock = true;
/* Select logging level */
if (options & VACOPT_VERBOSE)
@@ -142,58 +141,16 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
* concurrent VACUUM, which doesn't matter much at the moment but might
* matter if we ever try to accumulate stats on dead tuples.) If the rel
* has been dropped since we last saw it, we don't need to process it.
+ *
+ * Make sure to generate only logs for ANALYZE in this case.
*/
- if (!(options & VACOPT_SKIP_LOCKED))
- onerel = try_relation_open(relid, ShareUpdateExclusiveLock);
- else if (ConditionalLockRelationOid(relid, ShareUpdateExclusiveLock))
- onerel = try_relation_open(relid, NoLock);
- else
- {
- onerel = NULL;
- rel_lock = false;
- }
+ onerel = vacuum_open_relation(relid, relation, params,
+ options & ~(VACOPT_VACUUM),
+ ShareUpdateExclusiveLock);
- /*
- * If we failed to open or lock the relation, emit a log message before
- * exiting.
- */
+ /* leave if relation could not be opened or locked */
if (!onerel)
- {
- /*
- * If the RangeVar is not defined, we do not have enough information
- * to provide a meaningful log statement. Chances are that
- * analyze_rel's caller has intentionally not provided this
- * information so that this logging is skipped, anyway.
- */
- if (relation == NULL)
- return;
-
- /*
- * Determine the log level. For autovacuum logs, we emit a LOG if
- * log_autovacuum_min_duration is not disabled. For manual ANALYZE,
- * we emit a WARNING to match the log statements in the permissions
- * checks.
- */
- if (!IsAutoVacuumWorkerProcess())
- elevel = WARNING;
- else if (params->log_min_duration >= 0)
- elevel = LOG;
- else
- return;
-
- if (!rel_lock)
- ereport(elevel,
- (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
- errmsg("skipping analyze of \"%s\" --- lock not available",
- relation->relname)));
- else
- ereport(elevel,
- (errcode(ERRCODE_UNDEFINED_TABLE),
- errmsg("skipping analyze of \"%s\" --- relation no longer exists",
- relation->relname)));
-
return;
- }
/*
* Check if relation needs to be skipped based on ownership. This check
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index f1665097346..4e3823b0f0a 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -483,6 +483,112 @@ vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options)
/*
+ * vacuum_open_relation
+ *
+ * This routine is used for attempting to open and lock a relation which
+ * is going to be vacuumed or analyzed. If the relation cannot be opened
+ * or locked, a log is emitted if possible.
+ */
+Relation
+vacuum_open_relation(Oid relid, RangeVar *relation, VacuumParams *params,
+ int options, LOCKMODE lmode)
+{
+ Relation onerel;
+ bool rel_lock = true;
+ int elevel;
+
+ Assert(params != NULL);
+ Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0);
+
+ /*
+ * Open the relation and get the appropriate lock on it.
+ *
+ * There's a race condition here: the relation may have gone away since
+ * the last time we saw it. If so, we don't need to vacuum or analyze it.
+ *
+ * If we've been asked not to wait for the relation lock, acquire it first
+ * in non-blocking mode, before calling try_relation_open().
+ */
+ if (!(options & VACOPT_SKIP_LOCKED))
+ onerel = try_relation_open(relid, lmode);
+ else if (ConditionalLockRelationOid(relid, lmode))
+ onerel = try_relation_open(relid, NoLock);
+ else
+ {
+ onerel = NULL;
+ rel_lock = false;
+ }
+
+ /* if relation is opened, leave */
+ if (onerel)
+ return onerel;
+
+ /*
+ * Relation could not be opened, hence generate if possible a log
+ * informing on the situation.
+ *
+ * If the RangeVar is not defined, we do not have enough information to
+ * provide a meaningful log statement. Chances are that the caller has
+ * intentionally not provided this information so that this logging is
+ * skipped, anyway.
+ */
+ if (relation == NULL)
+ return NULL;
+
+ /*
+ * Determine the log level.
+ *
+ * For autovacuum logs, we emit a LOG if log_autovacuum_min_duration is
+ * not disabled. For manual VACUUM or ANALYZE, we emit a WARNING to match
+ * the log statements in the permission checks.
+ */
+ if (!IsAutoVacuumWorkerProcess())
+ elevel = WARNING;
+ else if (params->log_min_duration >= 0)
+ elevel = LOG;
+ else
+ return NULL;
+
+ if ((options & VACOPT_VACUUM) != 0)
+ {
+ if (!rel_lock)
+ ereport(elevel,
+ (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
+ errmsg("skipping vacuum of \"%s\" --- lock not available",
+ relation->relname)));
+ else
+ ereport(elevel,
+ (errcode(ERRCODE_UNDEFINED_TABLE),
+ errmsg("skipping vacuum of \"%s\" --- relation no longer exists",
+ relation->relname)));
+
+ /*
+ * For VACUUM ANALYZE, both logs could show up, but just generate
+ * information for VACUUM as that would be the first one to be
+ * processed.
+ */
+ return NULL;
+ }
+
+ if ((options & VACOPT_ANALYZE) != 0)
+ {
+ if (!rel_lock)
+ ereport(elevel,
+ (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
+ errmsg("skipping analyze of \"%s\" --- lock not available",
+ relation->relname)));
+ else
+ ereport(elevel,
+ (errcode(ERRCODE_UNDEFINED_TABLE),
+ errmsg("skipping analyze of \"%s\" --- relation no longer exists",
+ relation->relname)));
+ }
+
+ return NULL;
+}
+
+
+/*
* Given a VacuumRelation, fill in the table OID if it wasn't specified,
* and optionally add VacuumRelations for partitions of the table.
*
@@ -1400,7 +1506,6 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
Oid save_userid;
int save_sec_context;
int save_nestlevel;
- bool rel_lock = true;
Assert(params != NULL);
@@ -1455,68 +1560,12 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
*/
lmode = (options & VACOPT_FULL) ? AccessExclusiveLock : ShareUpdateExclusiveLock;
- /*
- * Open the relation and get the appropriate lock on it.
- *
- * There's a race condition here: the rel may have gone away since the
- * last time we saw it. If so, we don't need to vacuum it.
- *
- * If we've been asked not to wait for the relation lock, acquire it first
- * in non-blocking mode, before calling try_relation_open().
- */
- if (!(options & VACOPT_SKIP_LOCKED))
- onerel = try_relation_open(relid, lmode);
- else if (ConditionalLockRelationOid(relid, lmode))
- onerel = try_relation_open(relid, NoLock);
- else
- {
- onerel = NULL;
- rel_lock = false;
- }
+ /* open the relation and get the appropriate lock on it */
+ onerel = vacuum_open_relation(relid, relation, params, options, lmode);
- /*
- * If we failed to open or lock the relation, emit a log message before
- * exiting.
- */
+ /* leave if relation could not be opened or locked */
if (!onerel)
{
- int elevel = 0;
-
- /*
- * Determine the log level.
- *
- * If the RangeVar is not defined, we do not have enough information
- * to provide a meaningful log statement. Chances are that
- * vacuum_rel's caller has intentionally not provided this information
- * so that this logging is skipped, anyway.
- *
- * Otherwise, for autovacuum logs, we emit a LOG if
- * log_autovacuum_min_duration is not disabled. For manual VACUUM, we
- * emit a WARNING to match the log statements in the permission
- * checks.
- */
- if (relation != NULL)
- {
- if (!IsAutoVacuumWorkerProcess())
- elevel = WARNING;
- else if (params->log_min_duration >= 0)
- elevel = LOG;
- }
-
- if (elevel != 0)
- {
- if (!rel_lock)
- ereport(elevel,
- (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
- errmsg("skipping vacuum of \"%s\" --- lock not available",
- relation->relname)));
- else
- ereport(elevel,
- (errcode(ERRCODE_UNDEFINED_TABLE),
- errmsg("skipping vacuum of \"%s\" --- relation no longer exists",
- relation->relname)));
- }
-
PopActiveSnapshot();
CommitTransactionCommand();
return false;
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 5af96fdc8a2..2f4303e40d8 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -188,6 +188,8 @@ extern void vac_update_datfrozenxid(void);
extern void vacuum_delay_point(void);
extern bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple,
int options);
+extern Relation vacuum_open_relation(Oid relid, RangeVar *relation,
+ VacuumParams *params, int options, LOCKMODE lmode);
/* in commands/vacuumlazy.c */
extern void lazy_vacuum_rel(Relation onerel, int options,