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

Commit8c19977

Browse files
committed
Avoid changing an index's indcheckxmin horizon during REINDEX.
There can never be a need to push the indcheckxmin horizon forward, sinceany HOT chains that are actually broken with respect to the index mustpre-date its original creation. So we can just avoid changing pg_indexaltogether during a REINDEX operation.This offers a cleaner solution than my previous patch for the problemfound a few days ago that we mustn't try to update pg_index while we arereindexing it. System catalog indexes will always be created withindcheckxmin = false during initdb, and with this modified code we shouldnever try to change their pg_index entries. This avoids special-casingsystem catalogs as the former patch did, and should provide a performancebenefit for many cases where REINDEX formerly caused an index to beconsidered unusable for a short time.Back-patch to 8.3 to cover all versions containing HOT. Note that thispatch changes the API for index_build(), but I believe it is unlikely thatany add-on code is calling that directly.
1 parentc096d19 commit8c19977

File tree

6 files changed

+42
-11
lines changed

6 files changed

+42
-11
lines changed

‎src/backend/bootstrap/bootstrap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,7 @@ build_indices(void)
11341134
heap=heap_open(ILHead->il_heap,NoLock);
11351135
ind=index_open(ILHead->il_ind,NoLock);
11361136

1137-
index_build(heap,ind,ILHead->il_info, false);
1137+
index_build(heap,ind,ILHead->il_info, false, false);
11381138

11391139
index_close(ind,NoLock);
11401140
heap_close(heap,NoLock);

‎src/backend/catalog/heap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2569,7 +2569,7 @@ RelationTruncateIndexes(Relation heapRelation)
25692569

25702570
/* Initialize the index and rebuild */
25712571
/* Note: we do not need to re-establish pkey setting */
2572-
index_build(heapRelation,currentIndex,indexInfo, false);
2572+
index_build(heapRelation,currentIndex,indexInfo, false, true);
25732573

25742574
/* We're done with this index */
25752575
index_close(currentIndex,NoLock);

‎src/backend/catalog/index.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,7 @@ index_create(Relation heapRelation,
10611061
}
10621062
else
10631063
{
1064-
index_build(heapRelation,indexRelation,indexInfo,isprimary);
1064+
index_build(heapRelation,indexRelation,indexInfo,isprimary, false);
10651065
}
10661066

10671067
/*
@@ -1680,8 +1680,11 @@ index_update_stats(Relation rel,
16801680
* entries of the index and heap relation as needed, using statistics
16811681
* returned by ambuild as well as data passed by the caller.
16821682
*
1683-
* Note: when reindexing an existing index, isprimary can be false;
1684-
* the index is already properly marked and need not be re-marked.
1683+
* isprimary tells whether to mark the index as a primary-key index.
1684+
* isreindex indicates we are recreating a previously-existing index.
1685+
*
1686+
* Note: when reindexing an existing index, isprimary can be false even if
1687+
* the index is a PK; it's already properly marked and need not be re-marked.
16851688
*
16861689
* Note: before Postgres 8.2, the passed-in heap and index Relations
16871690
* were automatically closed by this routine. This is no longer the case.
@@ -1691,7 +1694,8 @@ void
16911694
index_build(RelationheapRelation,
16921695
RelationindexRelation,
16931696
IndexInfo*indexInfo,
1694-
boolisprimary)
1697+
boolisprimary,
1698+
boolisreindex)
16951699
{
16961700
RegProcedureprocedure;
16971701
IndexBuildResult*stats;
@@ -1762,8 +1766,15 @@ index_build(Relation heapRelation,
17621766
* If we found any potentially broken HOT chains, mark the index as not
17631767
* being usable until the current transaction is below the event horizon.
17641768
* See src/backend/access/heap/README.HOT for discussion.
1765-
*/
1766-
if (indexInfo->ii_BrokenHotChain)
1769+
*
1770+
* However, when reindexing an existing index, we should do nothing here.
1771+
* Any HOT chains that are broken with respect to the index must predate
1772+
* the index's original creation, so there is no need to change the
1773+
* index's usability horizon. Moreover, we *must not* try to change
1774+
* the index's pg_index entry while reindexing pg_index itself, and this
1775+
* optimization nicely prevents that.
1776+
*/
1777+
if (indexInfo->ii_BrokenHotChain&& !isreindex)
17671778
{
17681779
OidindexId=RelationGetRelid(indexRelation);
17691780
Relationpg_index;
@@ -1778,6 +1789,9 @@ index_build(Relation heapRelation,
17781789
elog(ERROR,"cache lookup failed for index %u",indexId);
17791790
indexForm= (Form_pg_index)GETSTRUCT(indexTuple);
17801791

1792+
/* If it's a new index, indcheckxmin shouldn't be set ... */
1793+
Assert(!indexForm->indcheckxmin);
1794+
17811795
indexForm->indcheckxmin= true;
17821796
simple_heap_update(pg_index,&indexTuple->t_self,indexTuple);
17831797
CatalogUpdateIndexes(pg_index,indexTuple);
@@ -2767,7 +2781,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks)
27672781

27682782
/* Initialize the index and rebuild */
27692783
/* Note: we do not need to re-establish pkey setting */
2770-
index_build(heapRelation,iRel,indexInfo, false);
2784+
index_build(heapRelation,iRel,indexInfo, false, true);
27712785
}
27722786
PG_CATCH();
27732787
{
@@ -2787,6 +2801,16 @@ reindex_index(Oid indexId, bool skip_constraint_checks)
27872801
* We can also reset indcheckxmin, because we have now done a
27882802
* non-concurrent index build, *except* in the case where index_build
27892803
* found some still-broken HOT chains.
2804+
*
2805+
* Note that it is important to not update the pg_index entry if we don't
2806+
* have to, because updating it will move the index's usability horizon
2807+
* (recorded as the tuple's xmin value) if indcheckxmin is true. We don't
2808+
* really want REINDEX to move the usability horizon forward ever, but we
2809+
* have no choice if we are to fix indisvalid or indisready. Of course,
2810+
* clearing indcheckxmin eliminates the issue, so we're happy to do that
2811+
* if we can. Another reason for caution here is that while reindexing
2812+
* pg_index itself, we must not try to update it. We assume that
2813+
* pg_index's indexes will always have these flags in their clean state.
27902814
*/
27912815
if (!skipped_constraint)
27922816
{

‎src/backend/commands/cluster.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,12 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
13981398
* advantage to the other order anyway because this is all transactional,
13991399
* so no chance to reclaim disk space before commit. We do not need a
14001400
* final CommandCounterIncrement() because reindex_relation does it.
1401+
*
1402+
* Note: because index_build is called via reindex_relation, it will never
1403+
* set indcheckxmin true for the indexes. This is OK even though in some
1404+
* sense we are building new indexes rather than rebuilding existing ones,
1405+
* because the new heap won't contain any HOT chains at all, let alone
1406+
* broken ones, so it can't be necessary to set indcheckxmin.
14011407
*/
14021408
reindex_flags=REINDEX_REL_SUPPRESS_INDEX_USE;
14031409
if (check_constraints)

‎src/backend/commands/indexcmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ DefineIndex(RangeVar *heapRelation,
505505
indexInfo->ii_BrokenHotChain= false;
506506

507507
/* Now build the index */
508-
index_build(rel,indexRelation,indexInfo,primary);
508+
index_build(rel,indexRelation,indexInfo,primary, false);
509509

510510
/* Close both the relations, but keep the locks */
511511
heap_close(rel,NoLock);

‎src/include/catalog/index.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ extern void FormIndexDatum(IndexInfo *indexInfo,
7575
externvoidindex_build(RelationheapRelation,
7676
RelationindexRelation,
7777
IndexInfo*indexInfo,
78-
boolisprimary);
78+
boolisprimary,
79+
boolisreindex);
7980

8081
externdoubleIndexBuildHeapScan(RelationheapRelation,
8182
RelationindexRelation,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp