From 4946910a875ce84823236f2a06e576b16080465f Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 13 Jul 2023 15:03:24 +0900 Subject: [PATCH] Doc: clarify the conditions of usable indexes for REPLICA IDENTITY FULL tables. Commit 89e46da5e allowed REPLICA IDENTITY FULL tables to use an index on the subscriber during apply of update/delete. This commit clarifies in the documentation that the leftmost field of candidate indexes must be a column (not an expression) that references the published relation column. The source code comments are also updated accordingly. Reviewed-by: Peter Smith, Amit Kapila Discussion: https://postgr.es/m/CAD21AoDJjffEvUFKXT27Q5U8-UU9JHv4rrJ9Ke8Zkc5UPWHLvA@mail.gmail.com Backpatch-through: 16 --- doc/src/sgml/logical-replication.sgml | 12 ++++++------ src/backend/executor/execReplication.c | 6 +++--- src/backend/replication/logical/relation.c | 11 ++++------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index c5de2040f7..c2a749d882 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -134,12 +134,12 @@ to replica identity FULL, which means the entire row becomes the key. When replica identity FULL is specified, indexes can be used on the subscriber side for searching the rows. Candidate - indexes must be btree, non-partial, and have at least one column reference - (i.e. cannot consist of only expressions). These restrictions - on the non-unique index properties adhere to some of the restrictions that - are enforced for primary keys. If there are no such suitable indexes, - the search on the subscriber side can be very inefficient, therefore - replica identity FULL should only be used as a + indexes must be btree, non-partial, and the leftmost index field must be a + column (not an expression) that references the published table column. These + restrictions on the non-unique index properties adhere to some of the + restrictions that are enforced for primary keys. If there are no such + suitable indexes, the search on the subscriber side can be very inefficient, + therefore replica identity FULL should only be used as a fallback if no other solution is possible. If a replica identity other than FULL is set on the publisher side, a replica identity comprising the same or fewer columns must also be set on the subscriber diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index 9dd7168461..af09342881 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -47,9 +47,9 @@ static bool tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2, * * Returns how many columns to use for the index scan. * - * This is not generic routine, it expects the idxrel to be a btree, non-partial - * and have at least one column reference (i.e. cannot consist of only - * expressions). + * This is not generic routine, idxrel must be PK, RI, or an index that can be + * used for REPLICA IDENTITY FULL table. See FindUsableIndexForReplicaIdentityFull() + * for details. * * By definition, replication identity of a rel meets all limitations associated * with that. Note that any other index could also meet these limitations. diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c index 57ad22b48a..c545b90636 100644 --- a/src/backend/replication/logical/relation.c +++ b/src/backend/replication/logical/relation.c @@ -779,9 +779,10 @@ RemoteRelContainsLeftMostColumnOnIdx(IndexInfo *indexInfo, AttrMap *attrmap) /* * Returns the oid of an index that can be used by the apply worker to scan - * the relation. The index must be btree, non-partial, and have at least - * one column reference (i.e. cannot consist of only expressions). These - * limitations help to keep the index scan similar to PK/RI index scans. + * the relation. The index must be btree, non-partial, and the leftmost + * field must be a column (not an expression) that references the remote + * relation column. These limitations help to keep the index scan similar + * to PK/RI index scans. * * Note that the limitations of index scans for replica identity full only * adheres to a subset of the limitations of PK/RI. For example, we support @@ -796,10 +797,6 @@ RemoteRelContainsLeftMostColumnOnIdx(IndexInfo *indexInfo, AttrMap *attrmap) * none of the tuples satisfy the expression for the index scan, we fall-back * to sequential execution, which might not be a good idea in some cases. * - * We also skip indexes if the remote relation does not contain the leftmost - * column of the index. This is because in most such cases sequential scan is - * favorable over index scan. - * * We expect to call this function when REPLICA IDENTITY FULL is defined for * the remote relation. *