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

Commitf495b65

Browse files
committed
Fix potential assertion failure when reindexing a pg_class index.
When reindexing individual indexes on pg_class it was possible toeither trigger an assertion failure:TRAP: FailedAssertion("!(!ReindexIsProcessingIndex(((index)->rd_id)))That's because reindex_index() called SetReindexProcessing() - whichenables an asserts ensuring no index insertions happen into the index- before calling RelationSetNewRelfilenode(). That not correct forindexes on pg_class, because RelationSetNewRelfilenode() updates therelevant pg_class row, which needs to update the indexes.The are two reasons this wasn't noticed earlier. Firstly the bugdoesn't trigger when reindexing all of pg_class, as reindex_relationhas code "hiding" all yet-to-be-reindexed indexes. Secondly, the bugonly triggers when the the update to pg_class doesn't turn out to be aHOT update - otherwise there's no index insertion to trigger thebug. Most of the time there's enough space, making this bug hard totrigger.To fix, move RelationSetNewRelfilenode() to before theSetReindexProcessing() (and, together with some other code, to outsideof the PG_TRY()).To make sure the error checking intended by SetReindexProcessing() ismore robust, modify CatalogIndexInsert() to checkReindexIsProcessingIndex() even when the update is a HOT update.Also add a few regression tests for REINDEXing of system catalogs.The last two improvements would have prevented some of the issuesfixed in5c15606 from being introduced in the first place.Reported-By: Michael PaquierDiagnosed-By: Tom Lane and Andres FreundAuthor: Andres FreundReviewed-By: Tom LaneDiscussion:https://postgr.es/m/20190418011430.GA19133@paquier.xyzBackpatch: 9.4-, the bug is present in all branches
1 parent10b2675 commitf495b65

File tree

6 files changed

+91
-20
lines changed

6 files changed

+91
-20
lines changed

‎contrib/test_decoding/expected/rewrite.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ COMMIT;
103103
-- repeated rewrites in different transactions
104104
VACUUM FULL pg_class;
105105
VACUUM FULL pg_class;
106+
-- reindexing of important relations / indexes
107+
REINDEX TABLE pg_class;
108+
REINDEX INDEX pg_class_oid_index;
109+
REINDEX INDEX pg_class_tblspc_relfilenode_index;
106110
INSERT INTO replication_example(somedata, testcolumn1) VALUES (5, 3);
107111
BEGIN;
108112
INSERT INTO replication_example(somedata, testcolumn1) VALUES (6, 4);

‎contrib/test_decoding/sql/rewrite.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ COMMIT;
7474
VACUUM FULL pg_class;
7575
VACUUM FULL pg_class;
7676

77+
-- reindexing of important relations / indexes
78+
REINDEX TABLE pg_class;
79+
REINDEX INDEX pg_class_oid_index;
80+
REINDEX INDEX pg_class_tblspc_relfilenode_index;
81+
7782
INSERT INTO replication_example(somedata, testcolumn1)VALUES (5,3);
7883

7984
BEGIN;

‎src/backend/catalog/index.c

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3363,29 +3363,35 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
33633363
*/
33643364
TransferPredicateLocksToHeapRelation(iRel);
33653365

3366+
/* Fetch info needed for index_build */
3367+
indexInfo=BuildIndexInfo(iRel);
3368+
3369+
/* If requested, skip checking uniqueness/exclusion constraints */
3370+
if (skip_constraint_checks)
3371+
{
3372+
if (indexInfo->ii_Unique||indexInfo->ii_ExclusionOps!=NULL)
3373+
skipped_constraint= true;
3374+
indexInfo->ii_Unique= false;
3375+
indexInfo->ii_ExclusionOps=NULL;
3376+
indexInfo->ii_ExclusionProcs=NULL;
3377+
indexInfo->ii_ExclusionStrats=NULL;
3378+
}
3379+
3380+
/*
3381+
* Build a new physical relation for the index. Need to do that before
3382+
* "officially" starting the reindexing with SetReindexProcessing -
3383+
* otherwise the necessary pg_class changes cannot be made with
3384+
* encountering assertions.
3385+
*/
3386+
RelationSetNewRelfilenode(iRel,persistence,InvalidTransactionId,
3387+
InvalidMultiXactId);
3388+
3389+
/* ensure SetReindexProcessing state isn't leaked */
33663390
PG_TRY();
33673391
{
33683392
/* Suppress use of the target index while rebuilding it */
33693393
SetReindexProcessing(heapId,indexId);
33703394

3371-
/* Fetch info needed for index_build */
3372-
indexInfo=BuildIndexInfo(iRel);
3373-
3374-
/* If requested, skip checking uniqueness/exclusion constraints */
3375-
if (skip_constraint_checks)
3376-
{
3377-
if (indexInfo->ii_Unique||indexInfo->ii_ExclusionOps!=NULL)
3378-
skipped_constraint= true;
3379-
indexInfo->ii_Unique= false;
3380-
indexInfo->ii_ExclusionOps=NULL;
3381-
indexInfo->ii_ExclusionProcs=NULL;
3382-
indexInfo->ii_ExclusionStrats=NULL;
3383-
}
3384-
3385-
/* We'll build a new physical relation for the index */
3386-
RelationSetNewRelfilenode(iRel,persistence,InvalidTransactionId,
3387-
InvalidMultiXactId);
3388-
33893395
/* Initialize the index and rebuild */
33903396
/* Note: we do not need to re-establish pkey setting */
33913397
index_build(heapRelation,iRel,indexInfo, false, true);

‎src/backend/catalog/indexing.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,15 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
8080
Datumvalues[INDEX_MAX_KEYS];
8181
boolisnull[INDEX_MAX_KEYS];
8282

83-
/* HOT update does not require index inserts */
83+
/*
84+
* HOT update does not require index inserts. But with asserts enabled we
85+
* want to check that it'd be legal to currently insert into the
86+
* table/index.
87+
*/
88+
#ifndefUSE_ASSERT_CHECKING
8489
if (HeapTupleIsHeapOnly(heapTuple))
8590
return;
91+
#endif
8692

8793
/*
8894
* Get information from the state structure. Fall out if nothing to do.
@@ -104,8 +110,10 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
104110
for (i=0;i<numIndexes;i++)
105111
{
106112
IndexInfo*indexInfo;
113+
Relationindex;
107114

108115
indexInfo=indexInfoArray[i];
116+
index=relationDescs[i];
109117

110118
/* If the index is marked as read-only, ignore it */
111119
if (!indexInfo->ii_ReadyForInserts)
@@ -118,7 +126,16 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
118126
Assert(indexInfo->ii_Expressions==NIL);
119127
Assert(indexInfo->ii_Predicate==NIL);
120128
Assert(indexInfo->ii_ExclusionOps==NULL);
121-
Assert(relationDescs[i]->rd_index->indimmediate);
129+
Assert(index->rd_index->indimmediate);
130+
131+
/* see earlier check above */
132+
#ifdefUSE_ASSERT_CHECKING
133+
if (HeapTupleIsHeapOnly(heapTuple))
134+
{
135+
Assert(!ReindexIsProcessingIndex(RelationGetRelid(index)));
136+
continue;
137+
}
138+
#endif/* USE_ASSERT_CHECKING */
122139

123140
/*
124141
* FormIndexDatum fills in its values and isnull parameters with the

‎src/test/regress/expected/create_index.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2998,6 +2998,24 @@ REINDEX (VERBOSE) TABLE reindex_verbose;
29982998
INFO: index "reindex_verbose_pkey" was reindexed
29992999
DROP TABLE reindex_verbose;
30003000
--
3001+
-- check that system tables can be reindexed
3002+
--
3003+
-- whole tables
3004+
REINDEX TABLE pg_class; -- mapped, non-shared, critical
3005+
REINDEX TABLE pg_index; -- non-mapped, non-shared, critical
3006+
REINDEX TABLE pg_operator; -- non-mapped, non-shared, critical
3007+
REINDEX TABLE pg_database; -- mapped, shared, critical
3008+
REINDEX TABLE pg_shdescription; -- mapped, shared non-critical
3009+
-- Check that individual system indexes can be reindexed. That's a bit
3010+
-- different from the entire-table case because reindex_relation
3011+
-- treats e.g. pg_class special.
3012+
REINDEX INDEX pg_class_oid_index; -- mapped, non-shared, critical
3013+
REINDEX INDEX pg_class_relname_nsp_index; -- mapped, non-shared, non-critical
3014+
REINDEX INDEX pg_index_indexrelid_index; -- non-mapped, non-shared, critical
3015+
REINDEX INDEX pg_index_indrelid_index; -- non-mapped, non-shared, non-critical
3016+
REINDEX INDEX pg_database_oid_index; -- mapped, shared, critical
3017+
REINDEX INDEX pg_shdescription_o_c_index; -- mapped, shared, non-critical
3018+
--
30013019
-- REINDEX SCHEMA
30023020
--
30033021
REINDEX SCHEMA schema_to_reindex; -- failure, schema does not exist

‎src/test/regress/sql/create_index.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,27 @@ CREATE TABLE reindex_verbose(id integer primary key);
10331033
REINDEX (VERBOSE) TABLE reindex_verbose;
10341034
DROPTABLE reindex_verbose;
10351035

1036+
--
1037+
-- check that system tables can be reindexed
1038+
--
1039+
1040+
-- whole tables
1041+
REINDEX TABLE pg_class;-- mapped, non-shared, critical
1042+
REINDEX TABLE pg_index;-- non-mapped, non-shared, critical
1043+
REINDEX TABLE pg_operator;-- non-mapped, non-shared, critical
1044+
REINDEX TABLE pg_database;-- mapped, shared, critical
1045+
REINDEX TABLE pg_shdescription;-- mapped, shared non-critical
1046+
1047+
-- Check that individual system indexes can be reindexed. That's a bit
1048+
-- different from the entire-table case because reindex_relation
1049+
-- treats e.g. pg_class special.
1050+
REINDEX INDEX pg_class_oid_index;-- mapped, non-shared, critical
1051+
REINDEX INDEX pg_class_relname_nsp_index;-- mapped, non-shared, non-critical
1052+
REINDEX INDEX pg_index_indexrelid_index;-- non-mapped, non-shared, critical
1053+
REINDEX INDEX pg_index_indrelid_index;-- non-mapped, non-shared, non-critical
1054+
REINDEX INDEX pg_database_oid_index;-- mapped, shared, critical
1055+
REINDEX INDEX pg_shdescription_o_c_index;-- mapped, shared, non-critical
1056+
10361057
--
10371058
-- REINDEX SCHEMA
10381059
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp