Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbae063d

Browse files
committed
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 mighthave malfunctioned if the failed index build left torn I/O or othercomplex state. Report an ERROR in statistics functions pgstatindex,pgstatginindex, pgstathashindex, and pgstattuple. Report DEBUG1 andskip all index I/O in maintenance functions brin_desummarize_range,brin_summarize_new_values, brin_summarize_range, andgin_clean_pending_list. Back-patch to v11 (all supported versions).Discussion:https://postgr.es/m/20231001195309.a3@google.com
1 parente04509f commitbae063d

File tree

4 files changed

+74
-9
lines changed

4 files changed

+74
-9
lines changed

‎contrib/pgstattuple/pgstatindex.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,18 @@ pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo)
236236
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
237237
errmsg("cannot access temporary tables of other sessions")));
238238

239+
/*
240+
* A !indisready index could lead to ERRCODE_DATA_CORRUPTED later, so exit
241+
* early. We're capable of assessing an indisready&&!indisvalid index,
242+
* but the results could be confusing. For example, the index's size
243+
* could be too low for a valid index of the table.
244+
*/
245+
if (!rel->rd_index->indisvalid)
246+
ereport(ERROR,
247+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
248+
errmsg("index \"%s\" is not valid",
249+
RelationGetRelationName(rel))));
250+
239251
/*
240252
* Read metapage
241253
*/
@@ -537,6 +549,13 @@ pgstatginindex_internal(Oid relid, FunctionCallInfo fcinfo)
537549
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
538550
errmsg("cannot access temporary indexes of other sessions")));
539551

552+
/* see pgstatindex_impl */
553+
if (!rel->rd_index->indisvalid)
554+
ereport(ERROR,
555+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
556+
errmsg("index \"%s\" is not valid",
557+
RelationGetRelationName(rel))));
558+
540559
/*
541560
* Read metapage
542561
*/
@@ -614,6 +633,13 @@ pgstathashindex(PG_FUNCTION_ARGS)
614633
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
615634
errmsg("cannot access temporary indexes of other sessions")));
616635

636+
/* see pgstatindex_impl */
637+
if (!rel->rd_index->indisvalid)
638+
ereport(ERROR,
639+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
640+
errmsg("index \"%s\" is not valid",
641+
RelationGetRelationName(rel))));
642+
617643
/* Get the information we need from the metapage. */
618644
memset(&stats,0,sizeof(stats));
619645
metabuf=_hash_getbuf(rel,HASH_METAPAGE,HASH_READ,LH_META_PAGE);

‎contrib/pgstattuple/pgstattuple.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,13 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
259259
caseRELKIND_SEQUENCE:
260260
returnpgstat_heap(rel,fcinfo);
261261
caseRELKIND_INDEX:
262+
/* see pgstatindex_impl */
263+
if (!rel->rd_index->indisvalid)
264+
ereport(ERROR,
265+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
266+
errmsg("index \"%s\" is not valid",
267+
RelationGetRelationName(rel))));
268+
262269
switch (rel->rd_rel->relam)
263270
{
264271
caseBTREE_AM_OID:

‎src/backend/access/brin/brin.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,8 +1036,14 @@ brin_summarize_range(PG_FUNCTION_ARGS)
10361036
errmsg("could not open parent table of index %s",
10371037
RelationGetRelationName(indexRel))));
10381038

1039-
/* OK, do it */
1040-
brinsummarize(indexRel,heapRel,heapBlk, true,&numSummarized,NULL);
1039+
/* see gin_clean_pending_list() */
1040+
if (indexRel->rd_index->indisvalid)
1041+
brinsummarize(indexRel,heapRel,heapBlk, true,&numSummarized,NULL);
1042+
else
1043+
ereport(DEBUG1,
1044+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1045+
errmsg("index \"%s\" is not valid",
1046+
RelationGetRelationName(indexRel))));
10411047

10421048
/* Roll back any GUC changes executed by index functions */
10431049
AtEOXact_GUC(false,save_nestlevel);
@@ -1122,12 +1128,21 @@ brin_desummarize_range(PG_FUNCTION_ARGS)
11221128
errmsg("could not open parent table of index %s",
11231129
RelationGetRelationName(indexRel))));
11241130

1125-
/*the revmap does the hard work */
1126-
do
1131+
/*see gin_clean_pending_list() */
1132+
if (indexRel->rd_index->indisvalid)
11271133
{
1128-
done=brinRevmapDesummarizeRange(indexRel,heapBlk);
1134+
/* the revmap does the hard work */
1135+
do
1136+
{
1137+
done=brinRevmapDesummarizeRange(indexRel,heapBlk);
1138+
}
1139+
while (!done);
11291140
}
1130-
while (!done);
1141+
else
1142+
ereport(DEBUG1,
1143+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1144+
errmsg("index \"%s\" is not valid",
1145+
RelationGetRelationName(indexRel))));
11311146

11321147
relation_close(indexRel,ShareUpdateExclusiveLock);
11331148
relation_close(heapRel,ShareUpdateExclusiveLock);

‎src/backend/access/gin/ginfast.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,6 @@ gin_clean_pending_list(PG_FUNCTION_ARGS)
10181018
Oidindexoid=PG_GETARG_OID(0);
10191019
RelationindexRel=index_open(indexoid,AccessShareLock);
10201020
IndexBulkDeleteResultstats;
1021-
GinStateginstate;
10221021

10231022
if (RecoveryInProgress())
10241023
ereport(ERROR,
@@ -1050,8 +1049,26 @@ gin_clean_pending_list(PG_FUNCTION_ARGS)
10501049
RelationGetRelationName(indexRel));
10511050

10521051
memset(&stats,0,sizeof(stats));
1053-
initGinState(&ginstate,indexRel);
1054-
ginInsertCleanup(&ginstate, true, true, true,&stats);
1052+
1053+
/*
1054+
* Can't assume anything about the content of an !indisready index. Make
1055+
* those a no-op, not an error, so users can just run this function on all
1056+
* indexes of the access method. Since an indisready&&!indisvalid index
1057+
* is merely awaiting missed aminsert calls, we're capable of processing
1058+
* it. Decline to do so, out of an abundance of caution.
1059+
*/
1060+
if (indexRel->rd_index->indisvalid)
1061+
{
1062+
GinStateginstate;
1063+
1064+
initGinState(&ginstate,indexRel);
1065+
ginInsertCleanup(&ginstate, true, true, true,&stats);
1066+
}
1067+
else
1068+
ereport(DEBUG1,
1069+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1070+
errmsg("index \"%s\" is not valid",
1071+
RelationGetRelationName(indexRel))));
10551072

10561073
index_close(indexRel,AccessShareLock);
10571074

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp