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

Commit12eece5

Browse files
author
Amit Kapila
committed
Fix uninitialized index information access during apply.
The issue happens when building conflict information during apply ofINSERT or UPDATE operations that violate unique constraints on leafpartitions.The problem was introduced in commit9ff6867, which removed theredundant calls to ExecOpenIndices/ExecCloseIndices. The previous code wasrelying on the redundant ExecOpenIndices call inapply_handle_tuple_routing() to build the index information required forunique key conflict detection.The fix is to delay building the index information until a conflict isdetected instead of relying on ExecOpenIndices to do the same. Theadditional benefit of this approach is that it avoids building indexinformation when there is no conflict.Author: Hou Zhijie <houzj.fnst@fujitsu.com>Reviewed-by:Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>Discussion:https://postgr.es/m/TYAPR01MB57244ADA33DDA57119B9D26494A62@TYAPR01MB5724.jpnprd01.prod.outlook.com
1 parent7ea21f4 commit12eece5

File tree

4 files changed

+70
-6
lines changed

4 files changed

+70
-6
lines changed

‎src/backend/executor/execIndexing.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,8 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
214214
ii=BuildIndexInfo(indexDesc);
215215

216216
/*
217-
* If the indexes are to be used for speculative insertion or conflict
218-
* detection in logical replication, add extra information required by
219-
* unique index entries.
217+
* If the indexes are to be used for speculative insertion, add extra
218+
* information required by unique index entries.
220219
*/
221220
if (speculative&&ii->ii_Unique&& !indexDesc->rd_index->indisexclusion)
222221
BuildSpeculativeIndexInfo(indexDesc,ii);

‎src/backend/executor/execReplication.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,30 @@ RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode,
431431
returnfound;
432432
}
433433

434+
/*
435+
* Build additional index information necessary for conflict detection.
436+
*/
437+
staticvoid
438+
BuildConflictIndexInfo(ResultRelInfo*resultRelInfo,Oidconflictindex)
439+
{
440+
for (inti=0;i<resultRelInfo->ri_NumIndices;i++)
441+
{
442+
RelationindexRelation=resultRelInfo->ri_IndexRelationDescs[i];
443+
IndexInfo*indexRelationInfo=resultRelInfo->ri_IndexRelationInfo[i];
444+
445+
if (conflictindex!=RelationGetRelid(indexRelation))
446+
continue;
447+
448+
/*
449+
* This Assert will fail if BuildSpeculativeIndexInfo() is called
450+
* twice for the given index.
451+
*/
452+
Assert(indexRelationInfo->ii_UniqueOps==NULL);
453+
454+
BuildSpeculativeIndexInfo(indexRelation,indexRelationInfo);
455+
}
456+
}
457+
434458
/*
435459
* Find the tuple that violates the passed unique index (conflictindex).
436460
*
@@ -452,6 +476,12 @@ FindConflictTuple(ResultRelInfo *resultRelInfo, EState *estate,
452476

453477
*conflictslot=NULL;
454478

479+
/*
480+
* Build additional information required to check constraints violations.
481+
* See check_exclusion_or_unique_constraint().
482+
*/
483+
BuildConflictIndexInfo(resultRelInfo,conflictindex);
484+
455485
retry:
456486
if (ExecCheckIndexConstraints(resultRelInfo,slot,estate,
457487
&conflictTid,&slot->tts_tid,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,7 +2457,7 @@ apply_handle_insert(StringInfo s)
24572457
{
24582458
ResultRelInfo*relinfo=edata->targetRelInfo;
24592459

2460-
ExecOpenIndices(relinfo,true);
2460+
ExecOpenIndices(relinfo,false);
24612461
apply_handle_insert_internal(edata,relinfo,remoteslot);
24622462
ExecCloseIndices(relinfo);
24632463
}
@@ -2680,7 +2680,7 @@ apply_handle_update_internal(ApplyExecutionData *edata,
26802680
MemoryContextoldctx;
26812681

26822682
EvalPlanQualInit(&epqstate,estate,NULL,NIL,-1,NIL);
2683-
ExecOpenIndices(relinfo,true);
2683+
ExecOpenIndices(relinfo,false);
26842684

26852685
found=FindReplTupleInLocalRel(edata,localrel,
26862686
&relmapentry->remoterel,

‎src/test/subscription/t/035_conflicts.pl

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,23 @@
2525
$node_publisher->safe_psql('postgres',
2626
"CREATE TABLE conf_tab (a int PRIMARY KEY, b int UNIQUE, c int UNIQUE);");
2727

28+
$node_publisher->safe_psql('postgres',
29+
"CREATE TABLE conf_tab_2 (a int PRIMARY KEY, b int UNIQUE, c int UNIQUE);");
30+
2831
# Create same table on subscriber
2932
$node_subscriber->safe_psql('postgres',
3033
"CREATE TABLE conf_tab (a int PRIMARY key, b int UNIQUE, c int UNIQUE);");
3134

35+
$node_subscriber->safe_psql(
36+
'postgres',qq[
37+
CREATE TABLE conf_tab_2 (a int PRIMARY KEY, b int, c int, unique(a,b)) PARTITION BY RANGE (a);
38+
CREATE TABLE conf_tab_2_p1 PARTITION OF conf_tab_2 FOR VALUES FROM (MINVALUE) TO (100);
39+
]);
40+
3241
# Setup logical replication
3342
my$publisher_connstr =$node_publisher->connstr .' dbname=postgres';
3443
$node_publisher->safe_psql('postgres',
35-
"CREATE PUBLICATION pub_tab FOR TABLE conf_tab");
44+
"CREATE PUBLICATION pub_tab FOR TABLE conf_tab, conf_tab_2");
3645

3746
# Create the subscription
3847
my$appname ='sub_tab';
@@ -110,4 +119,30 @@
110119

111120
pass('multiple_unique_conflicts detected during update');
112121

122+
# Truncate table to get rid of the error
123+
$node_subscriber->safe_psql('postgres',"TRUNCATE conf_tab;");
124+
125+
126+
##################################################
127+
# Test multiple_unique_conflicts due to INSERT on a leaf partition
128+
##################################################
129+
130+
# Insert data in the subscriber table
131+
$node_subscriber->safe_psql('postgres',
132+
"INSERT INTO conf_tab_2 VALUES (55,2,3);");
133+
134+
# Insert data in the publisher table
135+
$node_publisher->safe_psql('postgres',
136+
"INSERT INTO conf_tab_2 VALUES (55,2,3);");
137+
138+
$node_subscriber->wait_for_log(
139+
qr/conflict detected on relation\"public.conf_tab_2_p1\": conflict=multiple_unique_conflicts.*
140+
.*Key already exists in unique index\"conf_tab_2_p1_pkey\".*
141+
.*Key\(a\)=\(55\); existing local tuple\(55, 2, 3\); remote tuple\(55, 2, 3\).*
142+
.*Key already exists in unique index\"conf_tab_2_p1_a_b_key\".*
143+
.*Key\(a, b\)=\(55, 2\); existing local tuple\(55, 2, 3\); remote tuple\(55, 2, 3\)./,
144+
$log_offset);
145+
146+
pass('multiple_unique_conflicts detected on a leaf partition during insert');
147+
113148
done_testing();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp