From 7ad5ee333bc8fee0c860be2ad537eeb5d5d728ce Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 5 Apr 2018 18:43:45 +0000 Subject: [PATCH v7 09/12] Skip ANALYZE with VACOPT_SKIP_LOCKED if acquire_inherited_sample_rows() blocks. --- src/backend/commands/analyze.c | 54 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 0421d77ad7..1997726fd1 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -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); @@ -353,6 +354,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, @@ -550,9 +552,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, @@ -1337,15 +1353,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; @@ -1363,7 +1384,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