From d47fa05fd947839267cdd79317f4bb29b689e49f Mon Sep 17 00:00:00 2001 From: Antony Pegg Date: Thu, 29 Jan 2026 04:20:58 -0500 Subject: [PATCH] Fix documentation inaccuracies based on source code analysis This commit addresses 10 documentation issues identified by comparing docs against the Spock source code: 1. limitations.md: Clarify encoding requirement (matching, not UTF-8 specific) 2. limitations.md: TRUNCATE RESTART IDENTITY is actually replicated 3. limitations.md: REPLICA IDENTITY FULL works with Delta-Apply + PK 4. limitations.md: Deferrable constraints are silently skipped in conflict detection 5. limitations.md: Add Delta-Apply NOT NULL requirement section 6. README.md: Explicitly list supported PG versions (15, 16, 17, 18) 7. two_node_cluster.md: Fix subscriber_dsn -> provider_dsn parameter 8. index.md: Add PostgreSQL 18 to supported versions 9. sub_mgmt.md: Fix sub_enable description (start, not stop) 10. node_mgmt.md: Fix node_drop example description Co-Authored-By: Claude Opus 4.5 --- .gitignore | 1 + README.md | 2 +- docs/index.md | 2 +- docs/limitations.md | 39 +++++++++++++++++++++++++------ docs/spock_functions/node_mgmt.md | 2 +- docs/spock_functions/sub_mgmt.md | 2 +- docs/two_node_cluster.md | 2 +- 7 files changed, 38 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 595f2ae9..fbe0df49 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ spock_create_subscriber spock.control tags .vscode +tmp/ diff --git a/README.md b/README.md index 696f4711..0096ba81 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ## Spock Multi-Master Replication for PostgreSQL - Prerequisites and Requirements -The Spock extension provides multi-master replication for PostgreSQL versions 15 and later. Take the following requirements into consideration as you design your cluster: +The Spock extension provides multi-master replication for PostgreSQL versions 15, 16, 17, and 18. Take the following requirements into consideration as you design your cluster: * You will need to install the `Spock` extension on each node in your cluster. If you're performing a major version upgrade, the old node can be running a recent version of pgLogical2 before upgrading it to become a Spock node. diff --git a/docs/index.md b/docs/index.md index 38fc8609..73e36979 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # The Spock Extension -The Spock extension provides multi-master (active-active) replication for pgEdge Distributed and Enterprise Postgres, versions 15, 16, and 17. The extension leverages the pgLogical open-source project as a solid foundation to build upon for this enterprise-class extension. +The Spock extension provides multi-master (active-active) replication for pgEdge Distributed and Enterprise Postgres, versions 15, 16, 17, and 18. The extension leverages the pgLogical open-source project as a solid foundation to build upon for this enterprise-class extension. !!! info "Welcome to Spock - Live Long and Prosper!" diff --git a/docs/limitations.md b/docs/limitations.md index aee085fa..216274e0 100644 --- a/docs/limitations.md +++ b/docs/limitations.md @@ -23,7 +23,11 @@ not partial, not deferrable, and include only columns marked NOT NULL. Replication has no way to find the tuple that should be updated/deleted since there is no unique identifier. -`REPLICA IDENTITY FULL` is not supported yet. +`REPLICA IDENTITY FULL` is not supported as a standalone replication identity +for UPDATE/DELETE operations. However, it is supported when used in conjunction +with Delta-Apply columns on tables that have a primary key. For tables without +a primary key or Delta-Apply configuration, UPDATE and DELETE operations require +a PRIMARY KEY or explicit REPLICA IDENTITY USING INDEX. ### Only one unique index/constraint/PK @@ -37,13 +41,20 @@ Partial secondary unique indexes are permitted, but will be ignored for conflict ### Unique constraints must not be deferrable -On the downstream end spock does not support index-based constraints -defined as `DEFERRABLE`. It will emit the error: +Deferrable unique constraints and primary keys are **silently skipped** during +INSERT conflict resolution. This means that if your only unique constraint on a +table is deferrable, INSERT conflicts will not be detected, potentially leading +to duplicate rows on subscriber nodes. + +On the downstream end, spock may also emit the error: `ERROR: spock doesn't support index rechecks needed for deferrable indexes` `DETAIL: relation "public"."test_relation" has deferrable indexes: "index1", "index2"` -if such an index is present when it attempts to apply changes to a table. +in certain apply scenarios. + +**Recommendation:** Ensure all tables have at least one non-deferrable unique +constraint (preferably the primary key) for reliable conflict detection. ### No replication queue flush @@ -81,8 +92,9 @@ provider side. (Properly handling this would probably require the addition of `ON TRUNCATE CASCADE` support for foreign keys in PostgreSQL). -`TRUNCATE ... RESTART IDENTITY` is not supported. The identity restart step is -not replicated to the replica. +`TRUNCATE ... RESTART IDENTITY` is replicated. The sequence restart is +applied on subscriber nodes. Note that this may cause sequence value +divergence if sequences are not managed via pgEdge Snowflake. ### Sequences @@ -132,7 +144,10 @@ Replicating between different minor versions makes no difference at all. ### Database encoding differences Spock does not support replication between databases with different -encoding. We recommend using `UTF-8` encoding in all replicated databases. +encoding. The encoding must match on all nodes in the cluster. While +`UTF-8` is commonly used and recommended for international character +support, any encoding is acceptable as long as it is consistent across +all nodes. ### Large objects @@ -142,3 +157,13 @@ to [large objects](https://www.postgresql.org/docs/current/largeobjects.html); w Note that DDL limitations apply, so extra care needs to be taken when using `replicate_ddl_command()`. +### Delta-Apply Column Requirements + +Columns configured for Delta-Apply conflict resolution **must** have a `NOT NULL` +constraint. If a NULL value is encountered during delta application, the apply +worker will error with: + +`ERROR: delta apply column can't operate NULL values` + +Ensure all Delta-Apply columns are defined with `NOT NULL` before enabling this feature. + diff --git a/docs/spock_functions/node_mgmt.md b/docs/spock_functions/node_mgmt.md index 57d81f28..a4d997a5 100644 --- a/docs/spock_functions/node_mgmt.md +++ b/docs/spock_functions/node_mgmt.md @@ -45,7 +45,7 @@ For example, the following command: `SELECT spock.node_drop(n1, true)` -Creates a node named `n1` that connects to the `accounting` database on `178.12.15.12`, authenticating with the credentials of a user named `carol`. +Drops a node named `n1`. If the node does not exist, an error message will be suppressed because `ifexists` is set to `true`. ## Node Management Functions diff --git a/docs/spock_functions/sub_mgmt.md b/docs/spock_functions/sub_mgmt.md index c72f9274..cbf6521c 100644 --- a/docs/spock_functions/sub_mgmt.md +++ b/docs/spock_functions/sub_mgmt.md @@ -113,7 +113,7 @@ Enables a disabled subscription. Parameters: - `subscription_name` is the name of the existing subscription. -- `immediate` tells Spock when to stop the subscription. If set to `true`, the subscription is stopped immediately; if set to `false` (the default), it will be only stopped at the end of current transaction. +- `immediate` tells Spock when to start the subscription. If set to `true`, the subscription is started immediately; if set to `false` (the default), it will only be started at the end of the current transaction. ### spock.sub_alter_interface diff --git a/docs/two_node_cluster.md b/docs/two_node_cluster.md index 5abab8e2..85992a7e 100644 --- a/docs/two_node_cluster.md +++ b/docs/two_node_cluster.md @@ -50,7 +50,7 @@ After installing and initializing Postgres and creating the Spock Extension, you 7. On `n1`, create a corresponding subscription to `n2` named `sub_n1_n2`: - `SELECT spock.sub_create (subscription_name := 'sub_n1_n2', subscriber_dsn := 'host= port= dbname=');` + `SELECT spock.sub_create (subscription_name := 'sub_n1_n2', provider_dsn := 'host= port= dbname=');` 8. To ensure that modifications to your [DDL statements are automatically replicated](managing/spock_autoddl.md), connect to each node with a Postgres client and invoke the following SQL commands: