Doc: clarify the conditions of usable indexes for REPLICA IDENTITY FULL tables.
authorMasahiko Sawada <msawada@postgresql.org>
Thu, 13 Jul 2023 06:03:17 +0000 (15:03 +0900)
committerMasahiko Sawada <msawada@postgresql.org>
Thu, 13 Jul 2023 06:03:17 +0000 (15:03 +0900)
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
src/backend/executor/execReplication.c
src/backend/replication/logical/relation.c

index c5de2040f78a51d0a4073c039fba6cdd05038be6..c2a749d8828bb10ab73dc43af818ded29d6c7cf2 100644 (file)
    to replica identity <literal>FULL</literal>, which means the entire row becomes
    the key.  When replica identity <literal>FULL</literal> 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 <literal>FULL</literal> 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 <literal>FULL</literal> should only be used as a
    fallback if no other solution is possible.  If a replica identity other
    than <literal>FULL</literal> is set on the publisher side, a replica identity
    comprising the same or fewer columns must also be set on the subscriber
index 9dd716846157b63da9a0582258162c93c9a1cd5c..af093428813b30473c5c38f99a0e1d9821394f90 100644 (file)
@@ -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.
index 57ad22b48a1bd40a6bb0c8f751ab62458b31d646..c545b90636f8c4daac2f1081168dab9278bc2da9 100644 (file)
@@ -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.
  *