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

Commit35c85c3

Browse files
Remove unnecessary checks for indexes for REPLICA IDENTITY FULL tables.
Previously, when selecting an usable index for update/delete for theREPLICA IDENTITY FULL table, in IsIndexOnlyExpression(), we used tocheck if all index fields are not expressions. However, it was notnecessary, because it is enough to check if only the leftmost indexfield is not an expression (and references the remote table column)and this check has already been done byRemoteRelContainsLeftMostColumnOnIdx().This commit removes IsIndexOnlyExpression() andRemoteRelContainsLeftMostColumnOnIdx() and all checks for usableindexes for REPLICA IDENTITY FULL tables are now performed byIsIndexUsableForReplicaIdentityFull().Backpatch this to remain the code consistent.Reported-by: Peter SmithReviewed-by: Amit Kapila, Önder KalacıDiscussion:https://postgr.es/m/CAHut%2BPsGRE5WSsY0jcLHJEoA17MrbP9yy8FxdjC_ZOAACxbt%2BQ%40mail.gmail.comBackpatch-through: 16
1 parentad486b0 commit35c85c3

File tree

4 files changed

+73
-90
lines changed

4 files changed

+73
-90
lines changed

‎src/backend/executor/execReplication.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,16 +175,7 @@ RelationFindReplTupleByIndex(Relation rel, Oid idxoid,
175175
if (!isIdxSafeToSkipDuplicates)
176176
{
177177
if (eq==NULL)
178-
{
179-
#ifdefUSE_ASSERT_CHECKING
180-
/* apply assertions only once for the input idxoid */
181-
IndexInfo*indexInfo=BuildIndexInfo(idxrel);
182-
183-
Assert(IsIndexUsableForReplicaIdentityFull(indexInfo));
184-
#endif
185-
186178
eq=palloc0(sizeof(*eq)*outslot->tts_tupleDescriptor->natts);
187-
}
188179

189180
if (!tuples_equal(outslot,searchslot,eq))
190181
continue;

‎src/backend/replication/logical/relation.c

Lines changed: 53 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -731,71 +731,9 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root,
731731
returnentry;
732732
}
733733

734-
/*
735-
* Returns true if the given index consists only of expressions such as:
736-
* CREATE INDEX idx ON table(foo(col));
737-
*
738-
* Returns false even if there is one column reference:
739-
* CREATE INDEX idx ON table(foo(col), col_2);
740-
*/
741-
staticbool
742-
IsIndexOnlyOnExpression(IndexInfo*indexInfo)
743-
{
744-
for (inti=0;i<indexInfo->ii_NumIndexKeyAttrs;i++)
745-
{
746-
AttrNumberattnum=indexInfo->ii_IndexAttrNumbers[i];
747-
748-
if (AttributeNumberIsValid(attnum))
749-
return false;
750-
}
751-
752-
return true;
753-
}
754-
755-
/*
756-
* Returns true if the attrmap contains the leftmost column of the index.
757-
* Otherwise returns false.
758-
*
759-
* attrmap is a map of local attributes to remote ones. We can consult this
760-
* map to check whether the local index attribute has a corresponding remote
761-
* attribute.
762-
*/
763-
staticbool
764-
RemoteRelContainsLeftMostColumnOnIdx(IndexInfo*indexInfo,AttrMap*attrmap)
765-
{
766-
AttrNumberkeycol;
767-
768-
Assert(indexInfo->ii_NumIndexAttrs >=1);
769-
770-
keycol=indexInfo->ii_IndexAttrNumbers[0];
771-
if (!AttributeNumberIsValid(keycol))
772-
return false;
773-
774-
if (attrmap->maplen <=AttrNumberGetAttrOffset(keycol))
775-
return false;
776-
777-
returnattrmap->attnums[AttrNumberGetAttrOffset(keycol)] >=0;
778-
}
779-
780734
/*
781735
* Returns the oid of an index that can be used by the apply worker to scan
782-
* the relation. The index must be btree, non-partial, and the leftmost
783-
* field must be a column (not an expression) that references the remote
784-
* relation column. These limitations help to keep the index scan similar
785-
* to PK/RI index scans.
786-
*
787-
* Note that the limitations of index scans for replica identity full only
788-
* adheres to a subset of the limitations of PK/RI. For example, we support
789-
* columns that are marked as [NULL] or we are not interested in the [NOT
790-
* DEFERRABLE] aspect of constraints here. It works for us because we always
791-
* compare the tuples for non-PK/RI index scans. See
792-
* RelationFindReplTupleByIndex().
793-
*
794-
* XXX: There are no fundamental problems for supporting non-btree indexes.
795-
* We mostly need to relax the limitations in RelationFindReplTupleByIndex().
796-
* For partial indexes, the required changes are likely to be larger. If
797-
* none of the tuples satisfy the expression for the index scan, we fall-back
798-
* to sequential execution, which might not be a good idea in some cases.
736+
* the relation.
799737
*
800738
* We expect to call this function when REPLICA IDENTITY FULL is defined for
801739
* the remote relation.
@@ -812,37 +750,77 @@ FindUsableIndexForReplicaIdentityFull(Relation localrel, AttrMap *attrmap)
812750
{
813751
Oididxoid=lfirst_oid(lc);
814752
boolisUsableIdx;
815-
boolcontainsLeftMostCol;
816753
RelationidxRel;
817754
IndexInfo*idxInfo;
818755

819756
idxRel=index_open(idxoid,AccessShareLock);
820757
idxInfo=BuildIndexInfo(idxRel);
821-
isUsableIdx=IsIndexUsableForReplicaIdentityFull(idxInfo);
822-
containsLeftMostCol=
823-
RemoteRelContainsLeftMostColumnOnIdx(idxInfo,attrmap);
758+
isUsableIdx=IsIndexUsableForReplicaIdentityFull(idxInfo,attrmap);
824759
index_close(idxRel,AccessShareLock);
825760

826761
/* Return the first eligible index found */
827-
if (isUsableIdx&&containsLeftMostCol)
762+
if (isUsableIdx)
828763
returnidxoid;
829764
}
830765

831766
returnInvalidOid;
832767
}
833768

834769
/*
835-
* Returns true if the index is usable for replica identity full. For details,
836-
* see FindUsableIndexForReplicaIdentityFull.
770+
* Returns true if the index is usable for replica identity full.
771+
*
772+
* The index must be btree, non-partial, and the leftmost field must be a
773+
* column (not an expression) that references the remote relation column.
774+
* These limitations help to keep the index scan similar to PK/RI index
775+
* scans.
776+
*
777+
* attrmap is a map of local attributes to remote ones. We can consult this
778+
* map to check whether the local index attribute has a corresponding remote
779+
* attribute.
780+
*
781+
* Note that the limitations of index scans for replica identity full only
782+
* adheres to a subset of the limitations of PK/RI. For example, we support
783+
* columns that are marked as [NULL] or we are not interested in the [NOT
784+
* DEFERRABLE] aspect of constraints here. It works for us because we always
785+
* compare the tuples for non-PK/RI index scans. See
786+
* RelationFindReplTupleByIndex().
787+
*
788+
* XXX: There are no fundamental problems for supporting non-btree indexes.
789+
* We mostly need to relax the limitations in RelationFindReplTupleByIndex().
790+
* For partial indexes, the required changes are likely to be larger. If
791+
* none of the tuples satisfy the expression for the index scan, we fall-back
792+
* to sequential execution, which might not be a good idea in some cases.
837793
*/
838794
bool
839-
IsIndexUsableForReplicaIdentityFull(IndexInfo*indexInfo)
795+
IsIndexUsableForReplicaIdentityFull(IndexInfo*indexInfo,AttrMap*attrmap)
840796
{
841-
boolis_btree= (indexInfo->ii_Am==BTREE_AM_OID);
842-
boolis_partial= (indexInfo->ii_Predicate!=NIL);
843-
boolis_only_on_expression=IsIndexOnlyOnExpression(indexInfo);
797+
AttrNumberkeycol;
798+
799+
/* The index must be a Btree index */
800+
if (indexInfo->ii_Am!=BTREE_AM_OID)
801+
return false;
802+
803+
/* The index must not be a partial index */
804+
if (indexInfo->ii_Predicate!=NIL)
805+
return false;
806+
807+
Assert(indexInfo->ii_NumIndexAttrs >=1);
844808

845-
returnis_btree&& !is_partial&& !is_only_on_expression;
809+
/* The leftmost index field must not be an expression */
810+
keycol=indexInfo->ii_IndexAttrNumbers[0];
811+
if (!AttributeNumberIsValid(keycol))
812+
return false;
813+
814+
/*
815+
* And the leftmost index field must reference the remote relation column.
816+
* This is because if it doesn't, the sequential scan is favorable over
817+
* index scan in most cases.
818+
*/
819+
if (attrmap->maplen <=AttrNumberGetAttrOffset(keycol)||
820+
attrmap->attnums[AttrNumberGetAttrOffset(keycol)]<0)
821+
return false;
822+
823+
return true;
846824
}
847825

848826
/*

‎src/backend/replication/logical/worker.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
#include<sys/stat.h>
141141
#include<unistd.h>
142142

143+
#include"access/genam.h"
143144
#include"access/table.h"
144145
#include"access/tableam.h"
145146
#include"access/twophase.h"
@@ -410,7 +411,7 @@ static void apply_handle_delete_internal(ApplyExecutionData *edata,
410411
ResultRelInfo*relinfo,
411412
TupleTableSlot*remoteslot,
412413
Oidlocalindexoid);
413-
staticboolFindReplTupleInLocalRel(EState*estate,Relationlocalrel,
414+
staticboolFindReplTupleInLocalRel(ApplyExecutionData*edata,Relationlocalrel,
414415
LogicalRepRelation*remoterel,
415416
Oidlocalidxoid,
416417
TupleTableSlot*remoteslot,
@@ -2663,7 +2664,7 @@ apply_handle_update_internal(ApplyExecutionData *edata,
26632664
EvalPlanQualInit(&epqstate,estate,NULL,NIL,-1,NIL);
26642665
ExecOpenIndices(relinfo, false);
26652666

2666-
found=FindReplTupleInLocalRel(estate,localrel,
2667+
found=FindReplTupleInLocalRel(edata,localrel,
26672668
&relmapentry->remoterel,
26682669
localindexoid,
26692670
remoteslot,&localslot);
@@ -2816,7 +2817,7 @@ apply_handle_delete_internal(ApplyExecutionData *edata,
28162817
EvalPlanQualInit(&epqstate,estate,NULL,NIL,-1,NIL);
28172818
ExecOpenIndices(relinfo, false);
28182819

2819-
found=FindReplTupleInLocalRel(estate,localrel,remoterel,localindexoid,
2820+
found=FindReplTupleInLocalRel(edata,localrel,remoterel,localindexoid,
28202821
remoteslot,&localslot);
28212822

28222823
/* If found delete it. */
@@ -2855,12 +2856,13 @@ apply_handle_delete_internal(ApplyExecutionData *edata,
28552856
* Local tuple, if found, is returned in '*localslot'.
28562857
*/
28572858
staticbool
2858-
FindReplTupleInLocalRel(EState*estate,Relationlocalrel,
2859+
FindReplTupleInLocalRel(ApplyExecutionData*edata,Relationlocalrel,
28592860
LogicalRepRelation*remoterel,
28602861
Oidlocalidxoid,
28612862
TupleTableSlot*remoteslot,
28622863
TupleTableSlot**localslot)
28632864
{
2865+
EState*estate=edata->estate;
28642866
boolfound;
28652867

28662868
/*
@@ -2875,9 +2877,21 @@ FindReplTupleInLocalRel(EState *estate, Relation localrel,
28752877
(remoterel->replident==REPLICA_IDENTITY_FULL));
28762878

28772879
if (OidIsValid(localidxoid))
2880+
{
2881+
#ifdefUSE_ASSERT_CHECKING
2882+
Relationidxrel=index_open(localidxoid,AccessShareLock);
2883+
2884+
/* Index must be PK, RI, or usable for REPLICA IDENTITY FULL tables */
2885+
Assert(GetRelationIdentityOrPK(idxrel)==localidxoid||
2886+
IsIndexUsableForReplicaIdentityFull(BuildIndexInfo(idxrel),
2887+
edata->targetRel->attrmap));
2888+
index_close(idxrel,AccessShareLock);
2889+
#endif
2890+
28782891
found=RelationFindReplTupleByIndex(localrel,localidxoid,
28792892
LockTupleExclusive,
28802893
remoteslot,*localslot);
2894+
}
28812895
else
28822896
found=RelationFindReplTupleSeq(localrel,LockTupleExclusive,
28832897
remoteslot,*localslot);
@@ -2995,7 +3009,7 @@ apply_handle_tuple_routing(ApplyExecutionData *edata,
29953009
boolfound;
29963010

29973011
/* Get the matching local tuple from the partition. */
2998-
found=FindReplTupleInLocalRel(estate,partrel,
3012+
found=FindReplTupleInLocalRel(edata,partrel,
29993013
&part_entry->remoterel,
30003014
part_entry->localindexoid,
30013015
remoteslot_part,&localslot);

‎src/include/replication/logicalrelation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ extern LogicalRepRelMapEntry *logicalrep_partition_open(LogicalRepRelMapEntry *r
4848
Relationpartrel,AttrMap*map);
4949
externvoidlogicalrep_rel_close(LogicalRepRelMapEntry*rel,
5050
LOCKMODElockmode);
51-
externboolIsIndexUsableForReplicaIdentityFull(IndexInfo*indexInfo);
51+
externboolIsIndexUsableForReplicaIdentityFull(IndexInfo*indexInfo,AttrMap*attrmap);
5252
externOidGetRelationIdentityOrPK(Relationrel);
5353

5454
#endif/* LOGICALRELATION_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp