From 42bfc6d314624692d1c376b9a36d660e2e102810 Mon Sep 17 00:00:00 2001 From: Vigneshwaran C Date: Fri, 29 Jul 2022 10:33:38 +0530 Subject: [PATCH v41 2/2] Document the steps for replication between primaries in various scenarios. Document the steps for the following: a) Setting replication between two primaries. b) Adding a new node when there is no table data on any of the nodes. c) Adding a new node when table data is present on the existing nodes. d) Generic steps for adding a new node to an existing primaries. Author: Vignesh C Reviewed-By: Peter Smith, Amit Kapila, Shi yu, Jonathan Katz, Wang wei Discussion: https://www.postgresql.org/message-id/CALDaNm0gwjY_4HFxvvty01BOT01q_fJLKQ3pWP9=9orqubhjcQ@mail.gmail.com --- doc/src/sgml/logical-replication.sgml | 440 ++++++++++++++++++++++ doc/src/sgml/ref/create_subscription.sgml | 5 +- 2 files changed, 444 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index bdf1e7b727..8c971e0220 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -514,6 +514,446 @@ test_sub=# SELECT * FROM t3; + + Replication between primaries + + + Replication between primaries is useful for creating a multi-master + database environment for replicating write operations performed by any of + the member primaries. The steps to create replication between primaries in + various scenarios are given below. + + + + + The user is responsible for designing their schemas in a way to minimize + the risk of conflicts. See + for the details of logical replication conflicts. The logical replication + restrictions apply to the replication between primaries also. See + for the details of + logical replication restrictions. + + + + + + Setting up replication between primaries requires multiple steps to be + performed on various primaries. Because not all operations are + transactional, the user is advised to take backups. Backups can be taken + as described in . + + + + + Setting replication between two primaries + + The following steps demonstrate how to set up replication between two + primaries (primary1 and primary2) + when there is no table data present on both primaries: + + + + Create a publication on primary1: + +primary1=# CREATE PUBLICATION pub_primary1 FOR TABLE t1; +CREATE PUBLICATION + + + + Create a publication on primary2: + +primary2=# CREATE PUBLICATION pub_primary2 FOR TABLE t1; +CREATE PUBLICATION + + + + Lock the table t1 on primary1 and + primary2 in EXCLUSIVE mode until the + setup is completed. + + + + Create a subscription on primary2 to subscribe to + primary1: + +primary2=# CREATE SUBSCRIPTION sub_primary2_primary1 +primary2-# CONNECTION 'dbname=foo host=primary1 user=repuser' +primary2-# PUBLICATION pub_primary1 +primary2-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary1 to subscribe to + primary2: + +primary1=# CREATE SUBSCRIPTION sub_primary1_primary2 +primary1-# CONNECTION 'dbname=foo host=primary2 user=repuser' +primary1-# PUBLICATION pub_primary2 +primary1-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Now the replication setup between primaries primary1 and + primary2 is complete. Any incremental changes from + primary1 will be replicated to + primary2, and any incremental changes from + primary2 will be replicated to + primary1. + + + + + Adding a new primary when there is no table data on any of the primaries + + The following steps demonstrate adding a new primary + (primary3) to the existing primaries + (primary1 and primary2) when there is + no t1 data on any of the primaries. This requires + creating subscriptions on primary1 and + primary2 to replicate the data from + primary3 and creating subscriptions on + primary3 to replicate data from + primary1 and primary2. Note: These + steps assume that the replication between the primaries + primary1 and primary2 is already + completed. + + + + Create a publication on primary3: + +primary3=# CREATE PUBLICATION pub_primary3 FOR TABLE t1; +CREATE PUBLICATION + + + + Lock table t1 on all the primaries + primary1, primary2 and + primary3 in EXCLUSIVE mode until the + setup is completed. + + + + Create a subscription on primary1 to subscribe to + primary3: + +primary1=# CREATE SUBSCRIPTION sub_primary1_primary3 +primary1-# CONNECTION 'dbname=foo host=primary3 user=repuser' +primary1-# PUBLICATION pub_primary3 +primary1-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary2 to subscribe to + primary3: + +primary2=# CREATE SUBSCRIPTION sub_primary2_primary3 +primary2-# CONNECTION 'dbname=foo host=primary3 user=repuser' +primary2-# PUBLICATION pub_primary3 +primary2-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary3 to subscribe to + primary1: + +primary3=# CREATE SUBSCRIPTION sub_primary3_primary1 +primary3-# CONNECTION 'dbname=foo host=primary1 user=repuser' +primary3-# PUBLICATION pub_primary1 +primary3-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary3 to subscribe to + primary2: + +primary3=# CREATE SUBSCRIPTION sub_primary3_primary2 +primary3-# CONNECTION 'dbname=foo host=primary2 user=repuser' +primary3-# PUBLICATION pub_primary2 +primary3-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Now the replication setup between primaries primary1, + primary2 and primary3 is complete. + Incremental changes made on any primary will be replicated to the other two + primaries. + + + + + Adding a new primary when table data is present on the existing primaries + + The following steps demonstrate adding a new primary + (primary3) + that has no t1 data to the existing primaries + (primary1 and primary2) where + t1 data is present. This needs similar steps; the only + change required here is that primary3 should create a + subscription with copy_data = force to one of the + existing primaries so it can receive the existing t1 + data during initial data synchronization. Note: These steps assume that + the replication between the primaries primary1 and + primary2 is already completed, and the pre-existing + data in table t1 is already synchronized on both those + primaries. + + + + Create a publication on primary3: + +primary3=# CREATE PUBLICATION pub_primary3 FOR TABLE t1; +CREATE PUBLICATION + + + + Lock table t1 on primary2 and + primary3 in EXCLUSIVE mode until the + setup is completed. There is no need to lock table t1 on + primary1 because any data changes made will be + synchronized while creating the subscription with + copy_data = force. + + + + Create a subscription on primary1 to subscribe to + primary3: + +primary1=# CREATE SUBSCRIPTION sub_primary1_primary3 +primary1-# CONNECTION 'dbname=foo host=primary3 user=repuser' +primary1-# PUBLICATION pub_primary3 +primary1-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary2 to subscribe to + primary3: + +primary2=# CREATE SUBSCRIPTION sub_primary2_primary3 +primary2-# CONNECTION 'dbname=foo host=primary3 user=repuser' +primary2-# PUBLICATION pub_primary3 +primary2-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary3 to subscribe to + primary1. Use copy_data = force so + that the existing table data is copied during initial sync: + +primary3=# CREATE SUBSCRIPTION sub_primary3_primary1 +primary3-# CONNECTION 'dbname=foo host=primary1 user=repuser' +primary3-# PUBLICATION pub_primary1 +primary3-# WITH (copy_data = force, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary3 to subscribe to + primary2. Use copy_data = false + because the initial table data would have been + already copied in the previous step: + +primary3=# CREATE SUBSCRIPTION sub_primary3_primary2 +primary3-# CONNECTION 'dbname=foo host=primary2 user=repuser' +primary3-# PUBLICATION pub_primary2 +primary3-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Now the replication setup between primaries primary1, + primary2 and primary3 is complete. + Incremental changes made on any primary will be replicated to the other two + primaries. + + + + + Generic steps for adding a new primary to an existing set of primaries + + Step-1: Create a publication on the new primary. + + + Step-2: Lock the required tables of the new primary in + EXCLUSIVE mode until the setup is complete. (This lock + is necessary to prevent any modifications from happening on the new + primary. If data modifications occurred after Step-3, there is a chance + they could be published to the first primary and then synchronized back to + the new primary while creating the subscription in Step-5. This would + result in inconsistent data). + + + Step-3. Create subscriptions on existing primaries to the publication on + the new primary with origin = none and + copy_data = false. (The + copy_data = false is OK here because it is asserted that + the published tables of the new primary will have no pre-existing data). + + + Step-4. Lock the required tables of the existing primaries except the first + primary in EXCLUSIVE mode until the setup is complete. + (This lock is necessary to prevent any modifications from happening. If + data modifications occur, there is a chance that modifications done between + Step-5 and Step-6 will not be synchronized to the new primary. This would + result in inconsistent data. There is no need to lock the required tables + on the first primary because any data changes made will be synchronized + while creating the subscription with copy_data = force). + + + Step-5. Create a subscription on the new primary to the publication on the + first primary with origin = none and + copy_data = force. (This will copy the same table data + from the existing primaries to the new primary). + + + Step-6. Create subscriptions on the new primary to publications on the + remaining primaries with origin = none and + copy_data = false. (The copy_data = false is OK here + because the existing primary data was already copied to the new primary in + Step-5). + + + + Let's see an example using the above steps for adding a new primary + (primary4) to the existing primaries + (primary1, primary2 and + primary3). Note: These steps assume that the replication + between the primaries (primary1, + primary2 and primary3) is already + completed, and the pre-existing data in table t1 is + already synchronized on the primaries. + + + + Step-1. Create a publication on primary4: + +primary4=# CREATE PUBLICATION pub_primary4 FOR TABLE t1; +CREATE PUBLICATION + + + + Step-2. Lock table t1 on primary4 in + EXCLUSIVE mode until the setup is completed. + + + + Step-3. Create subscriptions on existing primaries to the publication on + the new primary with origin = none and + copy_data = false. + + + + Create a subscription on primary1 to subscribe to + primary4: + +primary1=# CREATE SUBSCRIPTION sub_primary1_primary4 +primary1-# CONNECTION 'dbname=foo host=primary4 user=repuser' +primary1-# PUBLICATION pub_primary4 +primary1-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary2 to subscribe to + primary4: + +primary2=# CREATE SUBSCRIPTION sub_primary2_primary4 +primary2-# CONNECTION 'dbname=foo host=primary4 user=repuser' +primary2-# PUBLICATION pub_primary4 +primary2-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary3 to subscribe to + primary4: + +primary3=# CREATE SUBSCRIPTION sub_primary3_primary4 +primary3-# CONNECTION 'dbname=foo host=primary4 user=repuser' +primary3-# PUBLICATION pub_primary4 +primary3-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Step-4. Lock table t1 on primary2 and + primary3 in EXCLUSIVE mode until the + setup is completed. There is no need to lock table t1 on + primary1 because any data changes made will be + synchronized while creating the subscription with + copy_data = force. + + + + Step-5. Create a subscription on the new primary to the publication on the + first primary with origin = none and + copy_data = force. + + + + Create a subscription on primary4 to subscribe to + primary1. Use copy_data = force so + that the existing table data is copied during initial sync: + +primary4=# CREATE SUBSCRIPTION sub_primary4_primary1 +primary4-# CONNECTION 'dbname=foo host=primary1 user=repuser' +primary4-# PUBLICATION pub_primary1 +primary4-# WITH (copy_data = force, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary4 to subscribe to + primary2. Use copy_data = false + because the initial table data would have been + already copied in the previous step: + +primary4=# CREATE SUBSCRIPTION sub_primary4_primary2 +primary4-# CONNECTION 'dbname=foo host=primary2 user=repuser' +primary4-# PUBLICATION pub_primary2 +primary4-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Create a subscription on primary4 to subscribe to + primary3. Use copy_data = false + because the initial table data would have been + already copied in the previous step: + +primary4=# CREATE SUBSCRIPTION sub_primary4_primary3 +primary4-# CONNECTION 'dbname=foo host=primary3 user=repuser' +primary4-# PUBLICATION pub_primary3 +primary4-# WITH (copy_data = false, origin = none); +CREATE SUBSCRIPTION + + + + Now the replication setup between primaries primary1, + primary2, primary3 and + primary4 is complete. Incremental changes made on any + primary will be replicated to the other three primaries. + + + + + Adding a new primary that has existing table data + + + Adding a new primary that has existing table data is not supported. + + + + + Row Filters diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml index c4e7a357a3..fe295c9021 100644 --- a/doc/src/sgml/ref/create_subscription.sgml +++ b/doc/src/sgml/ref/create_subscription.sgml @@ -407,7 +407,10 @@ CREATE SUBSCRIPTION subscription_namecopy_data = force. + copy_data = force. Refer to + for how + copy_data and origin can be used to + set up replication between primaries. -- 2.32.0