diff --git a/product_docs/docs/pgd/3.7/bdr/conflicts.mdx b/product_docs/docs/pgd/3.7/bdr/conflicts.mdx index 336d203b2d4..2ca74c59e81 100644 --- a/product_docs/docs/pgd/3.7/bdr/conflicts.mdx +++ b/product_docs/docs/pgd/3.7/bdr/conflicts.mdx @@ -114,7 +114,7 @@ user-defined conflict handler. This conflict will generate the `insert_exists` conflict type, which is by default resolved by choosing the newer (based on commit time) row and keeping only that one (`update_if_newer` resolver). Other resolvers can be configured - -see [Conflict Resolution] for details. +see [Conflict Resolution](#conflict-resolution) for details. To resolve this conflict type, you can also use column-level conflict resolution and user-defined conflict triggers. @@ -167,11 +167,11 @@ BDR cannot currently perform conflict resolution where the `PRIMARY KEY` is changed by an `UPDATE` operation. It is permissible to update the primary key, but you must ensure that no conflict with existing values is possible. -Conflicts on the update of the primary key are [Divergent Conflicts] and -require manual operator intervention. +Conflicts on the update of the primary key are [Divergent +Conflicts](#divergent-conflicts) and require manual operator intervention. -Updating a PK is possible in PostgreSQL, but there are -issues in both PostgreSQL and BDR. +Updating a PK is possible in PostgreSQL, but there are issues in both PostgreSQL +and BDR. Let's create a very simple example schema to explain: @@ -318,29 +318,29 @@ It is possible for one node to `UPDATE` a row that another node simultaneously If the `DELETE`d row is still detectable (the deleted row wasn't removed by `VACUUM`), the `update_recently_deleted` conflict will be generated. By default the `UPDATE` will just be skipped, but the resolution for this can be configured; -see [Conflict Resolution] for details. +see [Conflict Resolution](#conflict-resolution) for details. The deleted row can be cleaned up from the database by the time the `UPDATE` is received in case the local node is lagging behind in replication. In this case BDR cannot differentiate between `UPDATE`/`DELETE` -conflicts and [INSERT/UPDATE Conflicts] and will simply generate the +conflicts and [INSERT/UPDATE Conflicts](#insertupdate-conflicts) and will simply generate the `update_missing` conflict. -Another type of conflicting `DELETE` and `UPDATE` is a `DELETE` operation -that comes after the row was `UPDATEd` locally. In this situation, the -outcome depends upon the type of conflict detection used. When using the -default, [Origin Conflict Detection], no conflict is detected at all, -leading to the `DELETE` being applied and the row removed. If you enable -[Row Version Conflict Detection], a `delete_recently_updated` conflict is -generated. The default resolution for this conflict type is to to apply the -`DELETE` and remove the row, but this can be configured or handled via -a conflict trigger. +Another type of conflicting `DELETE` and `UPDATE` is a `DELETE` operation that +comes after the row was `UPDATEd` locally. In this situation, the outcome +depends upon the type of conflict detection used. When using the default, +[Origin Conflict Detection](#origin-conflict-detection), no conflict is detected at all, leading to the +`DELETE` being applied and the row removed. If you enable [Row Version Conflict +Detection], a `delete_recently_updated` conflict is generated. The default +resolution for a `delete_recently_updated` conflict is to `skip` the deletion. +However, you can configure the resolution or a conflict trigger can be +configured to handle it. #### INSERT/UPDATE Conflicts When using the default asynchronous mode of operation, a node may receive an `UPDATE` of a row before the original `INSERT` was received. This can only -happen with 3 or more nodes being active (see [Conflicts with 3 or more nodes] below). +happen with 3 or more nodes being active (see [Conflicts with 3 or more nodes](#conflicts-with-3-or-more-nodes)). When this happens, the `update_missing` conflict is generated. The default conflict resolver is `insert_or_skip`, though `insert_or_error` or `skip` @@ -350,14 +350,14 @@ from the `UPDATE` when possible (when the whole row was received). For the reconstruction of the row to be possible, the table either needs to have `REPLICA IDENTITY FULL` or the row must not contain any TOASTed data. -See [TOAST Support Details] for more info about TOASTed data. +See [TOAST Support Details](#toast-support-details) for more info about TOASTed data. #### INSERT/DELETE Conflicts Similarly to the `INSERT`/`UPDATE` conflict, the node may also receive a `DELETE` operation on a row for which it didn't receive an `INSERT` yet. This is again only possible with 3 or more nodes set up (see [Conflicts with 3 or -more nodes] below). +more nodes](#conflicts-with-3-or-more-nodes)). BDR cannot currently detect this conflict type: the `INSERT` operation will not generate any conflict type and the `INSERT` will be applied. @@ -409,7 +409,7 @@ these conflicts. Note however that enabling this option opens the door for If these are problems, it's recommended to tune freezing settings for a table or database so that they are correctly detected as `update_recently_deleted`. -Another alternative is to use [Eager Replication] to prevent these conflicts. +Another alternative is to use [Eager Replication](eager) to prevent these conflicts. INSERT/DELETE conflicts can also occur with 3 or more nodes. Such a conflict is identical to `INSERT`/`UPDATE`, except with the @@ -776,8 +776,8 @@ mechanisms to cope with the conflict. BDR provides these mechanisms for conflict detection: -- [Origin Conflict Detection] \(default) -- [Row Version Conflict Detection] +- [Origin Conflict Detection](#origin-conflict-detection) (default) +- [Row Version Conflict Detection](#row-version-conflict-detection) - [Column-Level Conflict Detection](column-level-conflicts) ### Origin Conflict Detection @@ -865,7 +865,7 @@ Alternatively, BDR provides the option to use row versioning and make conflict detection independent of the nodes' system clock. Row version conflict detection requires 3 things to be enabled. If any of these -steps are not performed correctly then [Origin Conflict Detection] will be used. +steps are not performed correctly then [Origin Conflict Detection](#origin-conflict-detection) will be used. 1. `check_full_tuple` must be enabled for the BDR node group. @@ -883,12 +883,12 @@ Although the counter is incremented only on UPDATE, this technique allows This approach resembles Lamport timestamps and fully prevents the ABA problem for conflict detection. -!!! Note +!!! Note The row-level conflict resolution is still handled based on the - [Conflict Resolution] configuration even with row versioning. The way - the row version is generated is only useful for detection of conflicts - and should not be relied to as authoritative information about which - version of row is newer. + [Conflict Resolution](#conflict-resolution) configuration even with row + versioning. The way the row version is generated is only useful for + detection of conflicts and should not be relied to as authoritative + information about which version of row is newer. To determine the current conflict resolution strategy used for a specific table, refer to the column `conflict_detection` of the view `bdr.tables`. @@ -916,9 +916,9 @@ bdr.alter_table_conflict_detection(relation regclass, The recognized methods for conflict detection are: -- `row_origin` - origin of the previous change made on the tuple (see - [Origin Conflict Detection] above). This is the only method supported which - does not require an extra column in the table. +- `row_origin` - origin of the previous change made on the tuple (see [Origin + Conflict Detection](#origin-conflict-detection)). This is the only method + supported which does not require an extra column in the table. - `row_version` - row version column (see [Row Version Conflict Detection] above). - `column_commit_timestamp` - per-column commit timestamps (described in the diff --git a/product_docs/docs/pgd/4/bdr/conflicts.mdx b/product_docs/docs/pgd/4/bdr/conflicts.mdx index c48fa48065e..4984beed7d3 100644 --- a/product_docs/docs/pgd/4/bdr/conflicts.mdx +++ b/product_docs/docs/pgd/4/bdr/conflicts.mdx @@ -323,15 +323,15 @@ case, BDR can't differentiate between `UPDATE`/`DELETE` conflicts and [INSERT/UPDATE conflicts](#insertupdate-conflicts) and generates the `update_missing` conflict. -Another type of conflicting `DELETE` and `UPDATE` is a `DELETE` -that comes after the row was updated locally. In this situation, the -outcome depends on the type of conflict detection used. When using the -default, [origin conflict detection](#origin-conflict-detection), no conflict is detected at all, -leading to the `DELETE` being applied and the row removed. If you enable -[row version conflict detection](#row-version-conflict-detection), a `delete_recently_updated` conflict is -generated. The default resolution for this conflict type is to apply the -`DELETE` and remove the row, but you can configure this or this can be handled by -a conflict trigger. +Another type of conflicting `DELETE` and `UPDATE` is a `DELETE` that comes after +the row was updated locally. In this situation, the outcome depends on the type +of conflict detection used. When using the default, [origin conflict +detection](#origin-conflict-detection), no conflict is detected at all, leading +to the `DELETE` being applied and the row removed. If you enable [row version +conflict detection](#row-version-conflict-detection), a +`delete_recently_updated` conflict is generated. The default resolution for a +`delete_recently_updated` conflict is to `skip` the deletion. However, you can +configure the resolution or a conflict trigger can be configured to handle it. #### INSERT/UPDATE conflicts diff --git a/product_docs/docs/pgd/5/consistency/conflicts.mdx b/product_docs/docs/pgd/5/consistency/conflicts.mdx index 0c95109560d..36c915ac514 100644 --- a/product_docs/docs/pgd/5/consistency/conflicts.mdx +++ b/product_docs/docs/pgd/5/consistency/conflicts.mdx @@ -211,7 +211,7 @@ If the deleted row is still detectable (the deleted row wasn't removed by `VACUU The database can clean up the deleted row by the time the `UPDATE` is received in case the local node is lagging behind in replication. In this case, PGD can't differentiate between `UPDATE`/`DELETE` conflicts and [INSERT/UPDATE conflicts](#insertupdate-conflicts). It generates the `update_missing` conflict. Another type of conflicting `DELETE` and `UPDATE` is a `DELETE` that comes after the row was updated locally. In this situation, the outcome depends on the type of conflict detection used. When using the -default, [origin conflict detection](#origin-conflict-detection), no conflict is detected, leading to the `DELETE` being applied and the row removed. If you enable [row version conflict detection](#row-version-conflict-detection), a `delete_recently_updated` conflict is generated. The default resolution for this conflict type is to apply the `DELETE` and remove the row. However, you can configure this or a conflict trigger can handled it. +default, [origin conflict detection](#origin-conflict-detection), no conflict is detected, leading to the `DELETE` being applied and the row removed. If you enable [row version conflict detection](#row-version-conflict-detection), a `delete_recently_updated` conflict is generated. The default resolution for a `delete_recently_updated` conflict is to `skip` the deletion. However, you can configure the resolution or a conflict trigger can be configured to handle it. #### INSERT/UPDATE conflicts