From: Alvaro Herrera Date: Fri, 13 Nov 2020 13:39:31 -0300 Subject: [PATCH v3] Avoid errors in brin summarization.. ..which can happen if an index is reindexed concurrently --- src/backend/access/brin/brin.c | 22 +++++++++++++++------- src/test/regress/expected/brin.out | 6 +++++- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 1f72562c60..46e5269260 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -887,16 +887,24 @@ brin_summarize_range(PG_FUNCTION_ARGS) /* * We must lock table before index to avoid deadlocks. However, if the * passed indexoid isn't an index then IndexGetRelation() will fail. - * Rather than emitting a not-very-helpful error message, postpone - * complaining, expecting that the is-it-an-index test below will fail. + * Rather than emitting a not-very-helpful error message, prepare to + * return without doing anything. This allows autovacuum work-items to be + * silently discarded rather than uselessly accumulating error messages in + * the server log. */ heapoid = IndexGetRelation(indexoid, true); - if (OidIsValid(heapoid)) - heapRel = table_open(heapoid, ShareUpdateExclusiveLock); - else - heapRel = NULL; + heapRel = OidIsValid(heapoid) ? + table_open(heapoid, ShareUpdateExclusiveLock) : NULL; - indexRel = index_open(indexoid, ShareUpdateExclusiveLock); + if (heapRel == NULL) + PG_RETURN_INT32(0); + + indexRel = try_relation_open(indexoid, ShareUpdateExclusiveLock); + if (indexRel == NULL) + { + table_close(heapRel, ShareUpdateExclusiveLock); + PG_RETURN_INT32(0); + } /* Must be a BRIN index */ if (indexRel->rd_rel->relkind != RELKIND_INDEX || diff --git a/src/test/regress/expected/brin.out b/src/test/regress/expected/brin.out index e53d6e4885..51dff7295d 100644 --- a/src/test/regress/expected/brin.out +++ b/src/test/regress/expected/brin.out @@ -405,7 +405,11 @@ UPDATE brintest SET int8col = int8col * int4col; UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL; -- Tests for brin_summarize_new_values SELECT brin_summarize_new_values('brintest'); -- error, not an index -ERROR: "brintest" is not an index + brin_summarize_new_values +--------------------------- + 0 +(1 row) + SELECT brin_summarize_new_values('tenk1_unique1'); -- error, not a BRIN index ERROR: "tenk1_unique1" is not a BRIN index SELECT brin_summarize_new_values('brinidx'); -- ok, no change expected -- 2.17.0 --lQSB8Tqijvu1+4Ba--