Skip to content

Commit 49ddc13

Browse files
committed
[PGPRO-4074] Use unique index on not null keys as replica identity index if it
was not specified explicitly and there is no primary key. Cherry pick of commit 8b0dad8fa8142fb8c8c3df9b2f6fd094f0b22a61 Author: Konstantin Knizhnik <knizhnik@garret.ru> Date: Wed Aug 14 14:57:44 2019 +0300 [PGPRO-4435] Use unique index on not null keys as replica identity index if it was not specified explicitly and there is no primary key Tags: multimaster. And commit 7ca988b1e304f6ffabfcbf5077cd0a4f20ff09e7 Author: Andrey Lepikhov <a.lepikhov@postgrespro.ru> Date: Fri Nov 13 13:09:49 2020 +0500 [PGPRO-4435] creative port of the patch f0e5b970539 from EE11. With changes caused by [PGPRO-4175]. Main idea of this change proposed by K.Knizhnik (see the comments on the jira's task. Change contrib/test_decoding/expected/ddl.out because of changed, by this patch, replication logic. Tags: multimaster. tags: multimaster (cherry picked from commit 996c9b34ee6240a95c785a87e30979bf3366c9e3)
1 parent 0cf68d0 commit 49ddc13

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

contrib/test_decoding/expected/ddl.out

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -648,19 +648,19 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc
648648
table public.table_with_unique_not_null: INSERT: id[integer]:2 data[integer]:2
649649
COMMIT
650650
BEGIN
651-
table public.table_with_unique_not_null: DELETE: id[integer]:1 data[integer]:1
651+
table public.table_with_unique_not_null: DELETE: id[integer]:1
652652
COMMIT
653653
BEGIN
654-
table public.table_with_unique_not_null: UPDATE: old-key: id[integer]:2 data[integer]:2 new-tuple: id[integer]:2 data[integer]:3
654+
table public.table_with_unique_not_null: UPDATE: id[integer]:2 data[integer]:3
655655
COMMIT
656656
BEGIN
657-
table public.table_with_unique_not_null: UPDATE: old-key: id[integer]:2 data[integer]:3 new-tuple: id[integer]:-2 data[integer]:3
657+
table public.table_with_unique_not_null: UPDATE: old-key: id[integer]:2 new-tuple: id[integer]:-2 data[integer]:3
658658
COMMIT
659659
BEGIN
660-
table public.table_with_unique_not_null: UPDATE: old-key: id[integer]:-2 data[integer]:3 new-tuple: id[integer]:2 data[integer]:3
660+
table public.table_with_unique_not_null: UPDATE: old-key: id[integer]:-2 new-tuple: id[integer]:2 data[integer]:3
661661
COMMIT
662662
BEGIN
663-
table public.table_with_unique_not_null: DELETE: id[integer]:2 data[integer]:3
663+
table public.table_with_unique_not_null: DELETE: id[integer]:2
664664
COMMIT
665665
BEGIN
666666
table public.table_with_unique_not_null: INSERT: id[integer]:3 data[integer]:1

src/backend/utils/cache/relcache.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4521,6 +4521,7 @@ RelationGetIndexList(Relation relation)
45214521
char replident = relation->rd_rel->relreplident;
45224522
Oid pkeyIndex = InvalidOid;
45234523
Oid candidateIndex = InvalidOid;
4524+
Oid uniqueIndex = InvalidOid;
45244525
MemoryContext oldcxt;
45254526

45264527
/* Quick exit if we already computed the list. */
@@ -4578,6 +4579,36 @@ RelationGetIndexList(Relation relation)
45784579
/* remember explicitly chosen replica index */
45794580
if (index->indisreplident)
45804581
candidateIndex = index->indexrelid;
4582+
4583+
/*
4584+
* If there is no primary key and explicitly specified replica identity index,
4585+
* then try to use any unique index with not-null keys as replica identity index.
4586+
*/
4587+
if (!OidIsValid(candidateIndex) &&
4588+
!OidIsValid(pkeyIndex) &&
4589+
!OidIsValid(uniqueIndex) &&
4590+
heap_attisnull(htup, Anum_pg_index_indexprs, NULL))
4591+
{
4592+
int i;
4593+
for (i = 0; i < index->indnatts; i++)
4594+
{
4595+
int attno = index->indkey.values[i];
4596+
if (attno > 0)
4597+
{
4598+
Form_pg_attribute attr = TupleDescAttr(relation->rd_att, attno - 1);
4599+
if (!attr->attnotnull)
4600+
break;
4601+
}
4602+
else
4603+
/*
4604+
* Disallow index on system column to be a replica identity.
4605+
* Their values may differ on different instances.
4606+
*/
4607+
break;
4608+
}
4609+
if (i == index->indnatts)
4610+
uniqueIndex = index->indexrelid;
4611+
}
45814612
}
45824613

45834614
systable_endscan(indscan);
@@ -4596,6 +4627,8 @@ RelationGetIndexList(Relation relation)
45964627
relation->rd_replidindex = pkeyIndex;
45974628
else if (replident == REPLICA_IDENTITY_INDEX && OidIsValid(candidateIndex))
45984629
relation->rd_replidindex = candidateIndex;
4630+
else if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(uniqueIndex))
4631+
relation->rd_replidindex = uniqueIndex;
45994632
else
46004633
relation->rd_replidindex = InvalidOid;
46014634
relation->rd_indexvalid = true;

0 commit comments

Comments
 (0)