mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
Diagnose !indisvalid in more SQL functions.
pgstatindex failed with ERRCODE_DATA_CORRUPTED, of the "can't-happen" class XX. The other functions succeeded on an empty index; they might have malfunctioned if the failed index build left torn I/O or other complex state. Report an ERROR in statistics functions pgstatindex, pgstatginindex, pgstathashindex, and pgstattuple. Report DEBUG1 and skip all index I/O in maintenance functions brin_desummarize_range, brin_summarize_new_values, brin_summarize_range, and gin_clean_pending_list. Back-patch to v11 (all supported versions). Discussion: https://postgr.es/m/20231001195309.a3@google.com
This commit is contained in:
@@ -1102,8 +1102,14 @@ brin_summarize_range(PG_FUNCTION_ARGS)
|
||||
errmsg("could not open parent table of index \"%s\"",
|
||||
RelationGetRelationName(indexRel))));
|
||||
|
||||
/* OK, do it */
|
||||
brinsummarize(indexRel, heapRel, heapBlk, true, &numSummarized, NULL);
|
||||
/* see gin_clean_pending_list() */
|
||||
if (indexRel->rd_index->indisvalid)
|
||||
brinsummarize(indexRel, heapRel, heapBlk, true, &numSummarized, NULL);
|
||||
else
|
||||
ereport(DEBUG1,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("index \"%s\" is not valid",
|
||||
RelationGetRelationName(indexRel))));
|
||||
|
||||
/* Roll back any GUC changes executed by index functions */
|
||||
AtEOXact_GUC(false, save_nestlevel);
|
||||
@@ -1185,12 +1191,21 @@ brin_desummarize_range(PG_FUNCTION_ARGS)
|
||||
errmsg("could not open parent table of index \"%s\"",
|
||||
RelationGetRelationName(indexRel))));
|
||||
|
||||
/* the revmap does the hard work */
|
||||
do
|
||||
/* see gin_clean_pending_list() */
|
||||
if (indexRel->rd_index->indisvalid)
|
||||
{
|
||||
done = brinRevmapDesummarizeRange(indexRel, heapBlk);
|
||||
/* the revmap does the hard work */
|
||||
do
|
||||
{
|
||||
done = brinRevmapDesummarizeRange(indexRel, heapBlk);
|
||||
}
|
||||
while (!done);
|
||||
}
|
||||
while (!done);
|
||||
else
|
||||
ereport(DEBUG1,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("index \"%s\" is not valid",
|
||||
RelationGetRelationName(indexRel))));
|
||||
|
||||
relation_close(indexRel, ShareUpdateExclusiveLock);
|
||||
relation_close(heapRel, ShareUpdateExclusiveLock);
|
||||
|
@@ -1032,7 +1032,6 @@ gin_clean_pending_list(PG_FUNCTION_ARGS)
|
||||
Oid indexoid = PG_GETARG_OID(0);
|
||||
Relation indexRel = index_open(indexoid, RowExclusiveLock);
|
||||
IndexBulkDeleteResult stats;
|
||||
GinState ginstate;
|
||||
|
||||
if (RecoveryInProgress())
|
||||
ereport(ERROR,
|
||||
@@ -1064,8 +1063,26 @@ gin_clean_pending_list(PG_FUNCTION_ARGS)
|
||||
RelationGetRelationName(indexRel));
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
initGinState(&ginstate, indexRel);
|
||||
ginInsertCleanup(&ginstate, true, true, true, &stats);
|
||||
|
||||
/*
|
||||
* Can't assume anything about the content of an !indisready index. Make
|
||||
* those a no-op, not an error, so users can just run this function on all
|
||||
* indexes of the access method. Since an indisready&&!indisvalid index
|
||||
* is merely awaiting missed aminsert calls, we're capable of processing
|
||||
* it. Decline to do so, out of an abundance of caution.
|
||||
*/
|
||||
if (indexRel->rd_index->indisvalid)
|
||||
{
|
||||
GinState ginstate;
|
||||
|
||||
initGinState(&ginstate, indexRel);
|
||||
ginInsertCleanup(&ginstate, true, true, true, &stats);
|
||||
}
|
||||
else
|
||||
ereport(DEBUG1,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("index \"%s\" is not valid",
|
||||
RelationGetRelationName(indexRel))));
|
||||
|
||||
index_close(indexRel, RowExclusiveLock);
|
||||
|
||||
|
Reference in New Issue
Block a user