v9-0005-Skip-ANALYZE-with-VACOPT_SKIP_LOCKED-if-acquire_i.patch
application/octet-stream
Filename: v9-0005-Skip-ANALYZE-with-VACOPT_SKIP_LOCKED-if-acquire_i.patch
Type: application/octet-stream
Part: 2
Patch
Format: format-patch
Series: patch v9-0005
Subject: Skip ANALYZE with VACOPT_SKIP_LOCKED if acquire_inherited_sample_rows() blocks.
| File | + | − |
|---|---|---|
| src/backend/commands/analyze.c | 51 | 11 |
From c181744cdf9c7970209013787b6e62fb5de5dac7 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Wed, 5 Sep 2018 14:44:15 +0000
Subject: [PATCH v9 5/7] Skip ANALYZE with VACOPT_SKIP_LOCKED if
acquire_inherited_sample_rows() blocks.
---
src/backend/commands/analyze.c | 62 ++++++++++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 11 deletions(-)
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 26fa7bcd55..bc215e7c00 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -84,7 +84,7 @@ static BufferAccessStrategy vac_strategy;
static void do_analyze_rel(Relation onerel, int options,
VacuumParams *params, List *va_cols,
AcquireSampleRowsFunc acquirefunc, BlockNumber relpages,
- bool inh, bool in_outer_xact, int elevel);
+ bool inh, bool in_outer_xact, int elevel, RangeVar *rangeVar);
static void compute_index_stats(Relation onerel, double totalrows,
AnlIndexData *indexdata, int nindexes,
HeapTuple *rows, int numrows,
@@ -97,7 +97,8 @@ static int acquire_sample_rows(Relation onerel, int elevel,
static int compare_rows(const void *a, const void *b);
static int acquire_inherited_sample_rows(Relation onerel, int elevel,
HeapTuple *rows, int targrows,
- double *totalrows, double *totaldeadrows);
+ double *totalrows, double *totaldeadrows,
+ bool skip_locked, bool *skipped);
static void update_attstats(Oid relid, bool inh,
int natts, VacAttrStats **vacattrstats);
static Datum std_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull);
@@ -284,14 +285,14 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
*/
if (onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
do_analyze_rel(onerel, options, params, va_cols, acquirefunc,
- relpages, false, in_outer_xact, elevel);
+ relpages, false, in_outer_xact, elevel, relation);
/*
* If there are child tables, do recursive ANALYZE.
*/
if (onerel->rd_rel->relhassubclass)
do_analyze_rel(onerel, options, params, va_cols, acquirefunc, relpages,
- true, in_outer_xact, elevel);
+ true, in_outer_xact, elevel, relation);
/*
* Close source relation now, but keep lock so that no one deletes it
@@ -321,7 +322,7 @@ static void
do_analyze_rel(Relation onerel, int options, VacuumParams *params,
List *va_cols, AcquireSampleRowsFunc acquirefunc,
BlockNumber relpages, bool inh, bool in_outer_xact,
- int elevel)
+ int elevel, RangeVar *rangeVar)
{
int attr_cnt,
tcnt,
@@ -343,6 +344,7 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params,
Oid save_userid;
int save_sec_context;
int save_nestlevel;
+ bool skipped = false;
if (inh)
ereport(elevel,
@@ -521,9 +523,23 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params,
*/
rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple));
if (inh)
+ {
numrows = acquire_inherited_sample_rows(onerel, elevel,
rows, targrows,
- &totalrows, &totaldeadrows);
+ &totalrows, &totaldeadrows,
+ (options & VACOPT_SKIP_LOCKED), &skipped);
+
+ /*
+ * If SKIP LOCKED is specified and we would have to wait for a lock on
+ * a child relation, skip analyzing the relation.
+ */
+ if (skipped)
+ {
+ do_analyze_rel_cleanup(save_nestlevel, save_userid, save_sec_context,
+ caller_context, rangeVar, params);
+ return;
+ }
+ }
else
numrows = (*acquirefunc) (onerel, elevel,
rows, targrows,
@@ -1308,15 +1324,20 @@ compare_rows(const void *a, const void *b)
/*
* acquire_inherited_sample_rows -- acquire sample rows from inheritance tree
*
- * This has the same API as acquire_sample_rows, except that rows are
+ * This has roughly the same API as acquire_sample_rows, except that rows are
* collected from all inheritance children as well as the specified table.
- * We fail and return zero if there are no inheritance children, or if all
- * children are foreign tables that don't support ANALYZE.
+ * We fail and return zero if there are no inheritance children, if all
+ * children are foreign tables that don't support ANALYZE, or if skip_locked
+ * is true and we cannot obtain a lock on all children without waiting.
+ *
+ * If skipped is supplied, it will be set to true if skip_locked takes effect
+ * (false otherwise).
*/
static int
acquire_inherited_sample_rows(Relation onerel, int elevel,
HeapTuple *rows, int targrows,
- double *totalrows, double *totaldeadrows)
+ double *totalrows, double *totaldeadrows,
+ bool skip_locked, bool *skipped)
{
List *tableOIDs;
Relation *rels;
@@ -1334,7 +1355,26 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
* the children.
*/
tableOIDs =
- find_all_inheritors(RelationGetRelid(onerel), AccessShareLock, NULL, false);
+ find_all_inheritors(RelationGetRelid(onerel), AccessShareLock, NULL, skip_locked);
+
+ /*
+ * If tableOIDs is NIL, skip_locked took effect. In that case, we should
+ * fail, being sure to set skipped if it is provided.
+ */
+ if (tableOIDs == NIL)
+ {
+ if (skipped != NULL)
+ *skipped = true;
+
+ return 0;
+ }
+
+ /*
+ * All skip_locked-related logic precedes this point, so we can just set
+ * skipped to false if it is provided.
+ */
+ if (skipped != NULL)
+ *skipped = false;
/*
* Check that there's at least one descendant, else fail. This could
--
2.16.2