From 3e0c0a9f877149d84117fdd5fa51bc23e1aa932b Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 7 Sep 2026 23:06:42 +0530 Subject: [PATCH 01/31] PCSM-330 Multiple PCSMs against the same source --- docs/multiple-targets.md | 365 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 docs/multiple-targets.md diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md new file mode 100644 index 00000000..ac91eb13 --- /dev/null +++ b/docs/multiple-targets.md @@ -0,0 +1,365 @@ +# Replicate from one source to multiple targets + +!!! admonition "Version added: 0.10.0" + +You can run multiple {{pcsm.full_name}} (PCSM) instances against the same source cluster and replicate different namespaces to different target clusters at the same time. This lets you split one cluster across several destinations in a single pass, with each instance moving only the data you assign to it. + +## How it works + +Each PCSM instance has: + +- The same source cluster +- A different target cluster +- Its own namespace filter + +Every instance runs the full replication workflow on its own: clone, replication, and finalization. See [How PCSM works](intro.md) for what happens at each stage. + +!!! note + + You run `start`, `status`, and `finalize` against each instance separately. Instances in separate containers can all use the default port 2242. See [Percona ClusterSync for MongoDB startup configuration](install/parameters.md) for the available options. + +The examples below replicate `db_0` to the first target and `db_1` to the second. Select the tab that matches your deployment. + +!!! warning "Technical preview" + + Sharding support in PCSM is a technical preview and is not recommended for production. See [Sharding support in Percona ClusterSync for MongoDB](sharding.md). + +=== "Replica set" + + ## Replicate from a replica set to two targets + + This example uses a source replica set `rs1` and two target replica sets, `rs2` and `rs3`. + + | **PCSM instance** | **Source** | **Target** | **Included namespaces** | + |-------------------|------------|------------|-------------------------| + | csync-a | rs1 | rs2 | `db_0.*` | + | csync-b | rs1 | rs3 | `db_1.*` | + + Follow these steps: + {.power-number} + + 1. Start `csync-a` with `rs1` as the source and `rs2` as the target: + +```bash + pcsm \ + --source "mongodb://csync:@rs101:27017/?replicaSet=rs1" \ + --target "mongodb://csync:@rs201:27017/?replicaSet=rs2" +``` + + 2. Start `csync-b` against the same source, with `rs3` as the target: + +```bash + pcsm \ + --source "mongodb://csync:@rs101:27017/?replicaSet=rs1" \ + --target "mongodb://csync:@rs301:27017/?replicaSet=rs3" +``` + + 3. Start replication on `csync-a`, filtered to the namespaces it replicates: + +```bash + pcsm start --include-namespaces="db_0.*" +``` + + ??? example "Expected output" + + ```{.json .no-copy} + { + "ok": true + } + ``` + + 4. Start replication on `csync-b` with its own filter: + + ```bash + pcsm start --include-namespaces="db_1.*" + ``` + + For how include and exclude filters interact, see [Start the filtered replication](install/usage.md#start-the-filtered-replication). For the full flag list, see [PCSM commands](pcsm-commands.md). You can also drive every step through the [PCSM HTTP API](api.md). + + 5. Check each instance and wait for the clone and replication stages to complete: + + ```bash + pcsm status + ``` + + 6. Finalize each instance: + + ```bash + pcsm finalize + ``` + + 7. Check the status of each instance after finalization. The following output is from `csync-a`. The `csync-b` output has the same structure with its own operation time and finalization timestamps: + + ```bash + pcsm status + ``` + + ??? example "Expected output" + + ```{.json .no-copy} + { + "ok": true, + "state": "finalized", + "info": "Finalized", + "lagTimeSeconds": 0, + "eventsRead": 0, + "eventsApplied": 0, + "lastReplicatedOpTime": { + "ts": "1787298593.1", + "isoDate": "2026-08-21T07:49:53Z" + }, + "initialSync": { + "estimatedCloneSizeBytes": 9877780, + "clonedSizeBytes": 9877780, + "completed": true, + "cloneCompleted": true + }, + "finalization": { + "completed": true, + "startedAt": "2026-08-21T07:49:53.633159569Z", + "completedAt": "2026-08-21T07:49:53.759444616Z" + } + } + ``` + + ### Verify the result on replica set targets + + Connect to each target and confirm it holds only the namespaces that its instance replicated. + + **On `rs2`.** List the databases, then count the documents. The `db_0` database returns the full count and `db_1` returns zero: + + ```javascript + show databases + db.getSiblingDB('db_0').docs.countDocuments({}) + db.getSiblingDB('db_1').docs.countDocuments({}) + ``` + + Check the indexes that PCSM recreated on the target: + + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [ + '_id_', + 'value_1', + 'value_1_uid_-1', + 'uid_1', + 'tag_text', + '_id_hashed', + 'created_at_1', + 'value_partial', + 'tag_sparse' + ] + ``` + + The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: + + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` + + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs + ``` + + **On `rs3`.** Run the same checks with the databases reversed. Here `db_1` holds the data, and querying `db_0.docs` returns `ns does not exist: db_0.docs`. + + Finally, check the logs of each instance for errors. See [Logging in Percona ClusterSync for MongoDB](logging.md). + +=== "Sharded cluster" + + ## Replicate from a sharded cluster to two targets + + This example uses three sharded clusters, each with its own [mongos :octicons-link-external-16:](https://www.mongodb.com/docs/manual/core/sharded-cluster-query-router/){:target="_blank"}, config server, and two shards. One cluster is the source and two are targets. + + | **PCSM instance** | **Source** | **Target** | **Included namespaces** | + |-------------------|------------|------------|-------------------------| + | csync-a | mongos1 | mongos2 | `db_0.*` | + | csync-b | mongos1 | mongos3 | `db_1.*` | + + PCSM connects through `mongos` on both the source and the target, so you do not need to list individual shard members or config servers in the connection strings. + {.power-number} + + 1. Start `csync-a` against the source `mongos` and the first target `mongos`: + + ```bash + pcsm \ + --source "mongodb://csync:@mongos1:27017" \ + --target "mongodb://csync:@mongos2:27017" + ``` + + 2. Start `csync-b` against the same source `mongos` and the second target `mongos`: + + ```bash + pcsm \ + --source "mongodb://csync:@mongos1:27017" \ + --target "mongodb://csync:@mongos3:27017" + ``` + + 3. Start replication on `csync-a`: + + ```bash + pcsm start --include-namespaces="db_0.*" + ``` + + ??? example "Expected output" + + ```{.json .no-copy} + { + "ok": true + } + ``` + + 4. Start replication on `csync-b`: + + ```bash + pcsm start --include-namespaces="db_1.*" + ``` + + 5. Check each instance and wait for the clone and replication stages to complete: + + ```bash + pcsm status + ``` + + 6. Finalize each instance: + + ```bash + pcsm finalize + ``` + + 7. Check the status of each instance after finalization. The following output is from `csync-a`: + + ```bash + pcsm status + ``` + + ??? example "Expected output" + + ```{.json .no-copy} + { + "ok": true, + "state": "finalized", + "info": "Finalized", + "lagTimeSeconds": 2, + "eventsRead": 6, + "eventsApplied": 5, + "lastReplicatedOpTime": { + "ts": "1787301347.3", + "isoDate": "2026-08-21T08:35:47Z" + }, + "initialSync": { + "estimatedCloneSizeBytes": 9877780, + "clonedSizeBytes": 9877780, + "completed": true, + "cloneCompleted": true + }, + "finalization": { + "completed": true, + "startedAt": "2026-08-21T08:35:47.949454942Z", + "completedAt": "2026-08-21T08:35:48.21823288Z" + } + } + ``` + + ### Verify the result on sharded targets + + Connect to the `mongos` of each target cluster and confirm it holds only the namespaces that its instance replicated. + + **On `mongos2`.** List the databases: + + ```javascript + show databases + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + admin 172.00 KiB + config 2.11 MiB + db_0 31.56 MiB + percona_clustersync_mongodb 168.00 KiB + ``` + + Count the documents. The `db_0` database returns the full count and `db_1` returns zero: + + ```javascript + db.getSiblingDB('db_0').docs.countDocuments({}) + db.getSiblingDB('db_1').docs.countDocuments({}) + ``` + + Check the indexes: + + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + [ + '_id_', + 'value_1', + 'value_1_uid_-1', + 'uid_1', + 'tag_text', + '_id_hashed', + 'created_at_1', + 'value_partial', + 'tag_sparse' + ] + ``` + + The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: + + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` + + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs + ``` + + **On `mongos3`.** List the databases: + + ```javascript + show databases + ``` + + ??? example "Expected output" + + ```{.text .no-copy} + admin 172.00 KiB + config 2.11 MiB + db_1 31.55 MiB + percona_clustersync_mongodb 168.00 KiB + ``` + + Count the documents. The `db_1` database returns the full count and `db_0` returns zero: + + ```javascript + db.getSiblingDB('db_1').docs.countDocuments({}) + db.getSiblingDB('db_0').docs.countDocuments({}) + ``` + + Check the indexes: + + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` + + Querying the collection replicated to the other target returns an error: + + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` + + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_0.docs + ``` + + Finally, check the logs of each instance for errors. See [Logging in Percona ClusterSync for MongoDB](logging.md). \ No newline at end of file From f822f648edf6f041254c42582df6cce203da70a6 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 7 Sep 2026 23:07:42 +0530 Subject: [PATCH 02/31] Update mkdocs-base.yml --- mkdocs-base.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs-base.yml b/mkdocs-base.yml index bb68e601..7fb1095e 100644 --- a/mkdocs-base.yml +++ b/mkdocs-base.yml @@ -180,6 +180,7 @@ nav: - install/parameters.md - Use PCSM: - Usage: install/usage.md + - Replicate from one source to multiple targets: multiple-targets.md - Cross-version replication: version-compatibility.md - pqs.md - PCSM commands: pcsm-commands.md From 163ed712c6524f0fa4044afb24699d85739c5d39 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 7 Sep 2026 23:10:29 +0530 Subject: [PATCH 03/31] fixed indentation --- docs/multiple-targets.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index ac91eb13..a1a44c4c 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -40,25 +40,25 @@ The examples below replicate `db_0` to the first target and `db_1` to the second 1. Start `csync-a` with `rs1` as the source and `rs2` as the target: -```bash - pcsm \ - --source "mongodb://csync:@rs101:27017/?replicaSet=rs1" \ - --target "mongodb://csync:@rs201:27017/?replicaSet=rs2" -``` + ```bash + pcsm \ + --source "mongodb://csync:@rs101:27017/?replicaSet=rs1" \ + --target "mongodb://csync:@rs201:27017/?replicaSet=rs2" + ``` 2. Start `csync-b` against the same source, with `rs3` as the target: -```bash - pcsm \ - --source "mongodb://csync:@rs101:27017/?replicaSet=rs1" \ - --target "mongodb://csync:@rs301:27017/?replicaSet=rs3" -``` + ```bash + pcsm \ + --source "mongodb://csync:@rs101:27017/?replicaSet=rs1" \ + --target "mongodb://csync:@rs301:27017/?replicaSet=rs3" + ``` 3. Start replication on `csync-a`, filtered to the namespaces it replicates: -```bash - pcsm start --include-namespaces="db_0.*" -``` + ```bash + pcsm start --include-namespaces="db_0.*" + ``` ??? example "Expected output" From 20a376ac35bffa09965b73f15a67825a35d21be0 Mon Sep 17 00:00:00 2001 From: Rasika Chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 7 Sep 2026 23:12:36 +0530 Subject: [PATCH 04/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index a1a44c4c..0c44a37a 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -76,7 +76,7 @@ The examples below replicate `db_0` to the first target and `db_1` to the second For how include and exclude filters interact, see [Start the filtered replication](install/usage.md#start-the-filtered-replication). For the full flag list, see [PCSM commands](pcsm-commands.md). You can also drive every step through the [PCSM HTTP API](api.md). - 5. Check each instance and wait for the clone and replication stages to complete: + 5. Check each instance and wait for the clone to complete and replication lag to reach an acceptable value: ```bash pcsm status From c140cd8c174ac4b18b587b8ce44ed847b267080c Mon Sep 17 00:00:00 2001 From: Rasika Chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 7 Sep 2026 23:12:49 +0530 Subject: [PATCH 05/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/multiple-targets.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 0c44a37a..3d739ee0 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -228,15 +228,15 @@ The examples below replicate `db_0` to the first target and `db_1` to the second 6. Finalize each instance: - ```bash - pcsm finalize - ``` + ```bash + pcsm finalize + ``` 7. Check the status of each instance after finalization. The following output is from `csync-a`: - ```bash - pcsm status - ``` + ```bash + pcsm status + ``` ??? example "Expected output" From b800de2c17f80b97e1a04634d03b7bf2b0a893d3 Mon Sep 17 00:00:00 2001 From: Rasika Chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 7 Sep 2026 23:13:01 +0530 Subject: [PATCH 06/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 3d739ee0..ab183125 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -16,7 +16,7 @@ Every instance runs the full replication workflow on its own: clone, replication !!! note - You run `start`, `status`, and `finalize` against each instance separately. Instances in separate containers can all use the default port 2242. See [Percona ClusterSync for MongoDB startup configuration](install/parameters.md) for the available options. + Run each PCSM server in a separate container or host, or assign a unique `--port` when servers share a network namespace. Run every `start`, `status`, and `finalize` command in the corresponding container or host; for a shared host, pass that instance's `--port` to every subcommand. The examples below assume separate environments, where all instances can use the default port `2242`. See [Percona ClusterSync for MongoDB startup configuration](install/parameters.md) for the available options. The examples below replicate `db_0` to the first target and `db_1` to the second. Select the tab that matches your deployment. From 5f10cd5528209e60d548004bccc432042882e417 Mon Sep 17 00:00:00 2001 From: Rasika Chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 7 Sep 2026 23:13:10 +0530 Subject: [PATCH 07/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index ab183125..dec703ef 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -312,7 +312,7 @@ The examples below replicate `db_0` to the first target and `db_1` to the second 'value_partial', 'tag_sparse' ] - ``` + ``` The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: From e456a84a6fc33cc7e2ee5abca349d6a4e2b0969d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 7 Sep 2026 17:43:30 +0000 Subject: [PATCH 08/31] List all replica set members in examples Co-authored-by: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> --- docs/multiple-targets.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index dec703ef..bdbd5c25 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -42,16 +42,16 @@ The examples below replicate `db_0` to the first target and `db_1` to the second ```bash pcsm \ - --source "mongodb://csync:@rs101:27017/?replicaSet=rs1" \ - --target "mongodb://csync:@rs201:27017/?replicaSet=rs2" + --source "mongodb://csync:@rs101:27017,rs102:27017,rs103:27017/?replicaSet=rs1" \ + --target "mongodb://csync:@rs201:27017,rs202:27017,rs203:27017/?replicaSet=rs2" ``` 2. Start `csync-b` against the same source, with `rs3` as the target: ```bash pcsm \ - --source "mongodb://csync:@rs101:27017/?replicaSet=rs1" \ - --target "mongodb://csync:@rs301:27017/?replicaSet=rs3" + --source "mongodb://csync:@rs101:27017,rs102:27017,rs103:27017/?replicaSet=rs1" \ + --target "mongodb://csync:@rs301:27017,rs302:27017,rs303:27017/?replicaSet=rs3" ``` 3. Start replication on `csync-a`, filtered to the namespaces it replicates: From ff97720fc1a0ce543fd1f262af058057d8d0ebc1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 8 Sep 2026 05:15:46 +0000 Subject: [PATCH 09/31] Clarify multi-instance source/target limitation Co-authored-by: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> --- docs/limitations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/limitations.md b/docs/limitations.md index 6308ecd9..96a63119 100644 --- a/docs/limitations.md +++ b/docs/limitations.md @@ -52,7 +52,7 @@ The following limitations apply specifically to sharded cluster replication: The following functionalities are not supported: -* Multiple source or multiple target clusters +* A single PCSM instance cannot have multiple source or target endpoints. Multiple isolated PCSM instances can share one source cluster and replicate to different targets, as described in [Replicate from one source to multiple targets](multiple-targets.md). * You cannot resume initial synchronization if an issue occurred. You must start it from scratch. * Arbitrary database upgrades during a sync are not supported. For supported staged upgrades from lower to higher MongoDB major versions, follow the cross-version replication procedure. * Reverse synchronization From d40457767eea526a5017373920b703e8b49debc4 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Tue, 8 Sep 2026 10:46:03 +0530 Subject: [PATCH 10/31] fix indentation --- docs/multiple-targets.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index bdbd5c25..6da775a0 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -187,23 +187,23 @@ The examples below replicate `db_0` to the first target and `db_1` to the second 1. Start `csync-a` against the source `mongos` and the first target `mongos`: ```bash - pcsm \ - --source "mongodb://csync:@mongos1:27017" \ - --target "mongodb://csync:@mongos2:27017" + pcsm \ + --source "mongodb://csync:@mongos1:27017" \ + --target "mongodb://csync:@mongos2:27017" ``` 2. Start `csync-b` against the same source `mongos` and the second target `mongos`: ```bash - pcsm \ - --source "mongodb://csync:@mongos1:27017" \ - --target "mongodb://csync:@mongos3:27017" + pcsm \ + --source "mongodb://csync:@mongos1:27017" \ + --target "mongodb://csync:@mongos3:27017" ``` 3. Start replication on `csync-a`: ```bash - pcsm start --include-namespaces="db_0.*" + pcsm start --include-namespaces="db_0.*" ``` ??? example "Expected output" From 9487474dadb304ca4c11127edfde1d0a1f3e4550 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Tue, 8 Sep 2026 10:54:50 +0530 Subject: [PATCH 11/31] fixed formatting issues --- docs/multiple-targets.md | 230 +++++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 116 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 6da775a0..c16a72d8 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -41,37 +41,37 @@ The examples below replicate `db_0` to the first target and `db_1` to the second 1. Start `csync-a` with `rs1` as the source and `rs2` as the target: ```bash - pcsm \ - --source "mongodb://csync:@rs101:27017,rs102:27017,rs103:27017/?replicaSet=rs1" \ - --target "mongodb://csync:@rs201:27017,rs202:27017,rs203:27017/?replicaSet=rs2" + pcsm \ + --source "mongodb://csync:@rs101:27017,rs102:27017,rs103:27017/?replicaSet=rs1" \ + --target "mongodb://csync:@rs201:27017,rs202:27017,rs203:27017/?replicaSet=rs2" ``` 2. Start `csync-b` against the same source, with `rs3` as the target: ```bash - pcsm \ - --source "mongodb://csync:@rs101:27017,rs102:27017,rs103:27017/?replicaSet=rs1" \ - --target "mongodb://csync:@rs301:27017,rs302:27017,rs303:27017/?replicaSet=rs3" + pcsm \ + --source "mongodb://csync:@rs101:27017,rs102:27017,rs103:27017/?replicaSet=rs1" \ + --target "mongodb://csync:@rs301:27017,rs302:27017,rs303:27017/?replicaSet=rs3" ``` 3. Start replication on `csync-a`, filtered to the namespaces it replicates: ```bash - pcsm start --include-namespaces="db_0.*" + pcsm start --include-namespaces="db_0.*" ``` ??? example "Expected output" ```{.json .no-copy} - { - "ok": true - } + { + "ok": true + } ``` 4. Start replication on `csync-b` with its own filter: ```bash - pcsm start --include-namespaces="db_1.*" + pcsm start --include-namespaces="db_1.*" ``` For how include and exclude filters interact, see [Start the filtered replication](install/usage.md#start-the-filtered-replication). For the full flag list, see [PCSM commands](pcsm-commands.md). You can also drive every step through the [PCSM HTTP API](api.md). @@ -79,47 +79,47 @@ The examples below replicate `db_0` to the first target and `db_1` to the second 5. Check each instance and wait for the clone to complete and replication lag to reach an acceptable value: ```bash - pcsm status + pcsm status ``` 6. Finalize each instance: ```bash - pcsm finalize + pcsm finalize ``` 7. Check the status of each instance after finalization. The following output is from `csync-a`. The `csync-b` output has the same structure with its own operation time and finalization timestamps: ```bash - pcsm status + pcsm status ``` ??? example "Expected output" ```{.json .no-copy} - { - "ok": true, - "state": "finalized", - "info": "Finalized", - "lagTimeSeconds": 0, - "eventsRead": 0, - "eventsApplied": 0, - "lastReplicatedOpTime": { - "ts": "1787298593.1", - "isoDate": "2026-08-21T07:49:53Z" - }, - "initialSync": { - "estimatedCloneSizeBytes": 9877780, - "clonedSizeBytes": 9877780, - "completed": true, - "cloneCompleted": true - }, - "finalization": { - "completed": true, - "startedAt": "2026-08-21T07:49:53.633159569Z", - "completedAt": "2026-08-21T07:49:53.759444616Z" - } - } + { + "ok": true, + "state": "finalized", + "info": "Finalized", + "lagTimeSeconds": 0, + "eventsRead": 0, + "eventsApplied": 0, + "lastReplicatedOpTime": { + "ts": "1787298593.1", + "isoDate": "2026-08-21T07:49:53Z" + }, + "initialSync": { + "estimatedCloneSizeBytes": 9877780, + "clonedSizeBytes": 9877780, + "completed": true, + "cloneCompleted": true + }, + "finalization": { + "completed": true, + "startedAt": "2026-08-21T07:49:53.633159569Z", + "completedAt": "2026-08-21T07:49:53.759444616Z" + } + } ``` ### Verify the result on replica set targets @@ -128,17 +128,17 @@ The examples below replicate `db_0` to the first target and `db_1` to the second **On `rs2`.** List the databases, then count the documents. The `db_0` database returns the full count and `db_1` returns zero: - ```javascript - show databases - db.getSiblingDB('db_0').docs.countDocuments({}) - db.getSiblingDB('db_1').docs.countDocuments({}) - ``` + ```javascript + show databases + db.getSiblingDB('db_0').docs.countDocuments({}) + db.getSiblingDB('db_1').docs.countDocuments({}) + ``` Check the indexes that PCSM recreated on the target: - ```javascript - db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` ??? example "Expected output" @@ -159,11 +159,11 @@ The examples below replicate `db_0` to the first target and `db_1` to the second The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: ```javascript - db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) ``` ```{.text .no-copy} - MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs + MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs ``` **On `rs3`.** Run the same checks with the databases reversed. Here `db_1` holds the data, and querying `db_0.docs` returns `ns does not exist: db_0.docs`. @@ -209,9 +209,9 @@ The examples below replicate `db_0` to the first target and `db_1` to the second ??? example "Expected output" ```{.json .no-copy} - { - "ok": true - } + { + "ok": true + } ``` 4. Start replication on `csync-b`: @@ -241,62 +241,60 @@ The examples below replicate `db_0` to the first target and `db_1` to the second ??? example "Expected output" ```{.json .no-copy} - { - "ok": true, - "state": "finalized", - "info": "Finalized", - "lagTimeSeconds": 2, - "eventsRead": 6, - "eventsApplied": 5, - "lastReplicatedOpTime": { - "ts": "1787301347.3", - "isoDate": "2026-08-21T08:35:47Z" - }, - "initialSync": { - "estimatedCloneSizeBytes": 9877780, - "clonedSizeBytes": 9877780, - "completed": true, - "cloneCompleted": true - }, - "finalization": { - "completed": true, - "startedAt": "2026-08-21T08:35:47.949454942Z", - "completedAt": "2026-08-21T08:35:48.21823288Z" - } - } - ``` - - ### Verify the result on sharded targets + { + "ok": true, + "state": "finalized", + "info": "Finalized", + "lagTimeSeconds": 2, + "eventsRead": 6, + "eventsApplied": 5, + "lastReplicatedOpTime": { + "ts": "1787301347.3", + "isoDate": "2026-08-21T08:35:47Z" + }, + "initialSync": { + "estimatedCloneSizeBytes": 9877780, + "clonedSizeBytes": 9877780, + "completed": true, + "cloneCompleted": true + }, + "finalization": { + "completed": true, + "startedAt": "2026-08-21T08:35:47.949454942Z", + "completedAt": "2026-08-21T08:35:48.21823288Z" + } + } + ``` ### Verify the result on sharded targets Connect to the `mongos` of each target cluster and confirm it holds only the namespaces that its instance replicated. **On `mongos2`.** List the databases: - ```javascript - show databases - ``` + ```javascript + show databases + ``` ??? example "Expected output" ```{.text .no-copy} - admin 172.00 KiB - config 2.11 MiB - db_0 31.56 MiB - percona_clustersync_mongodb 168.00 KiB + admin 172.00 KiB + config 2.11 MiB + db_0 31.56 MiB + percona_clustersync_mongodb 168.00 KiB ``` Count the documents. The `db_0` database returns the full count and `db_1` returns zero: - ```javascript - db.getSiblingDB('db_0').docs.countDocuments({}) - db.getSiblingDB('db_1').docs.countDocuments({}) - ``` + ```javascript + db.getSiblingDB('db_0').docs.countDocuments({}) + db.getSiblingDB('db_1').docs.countDocuments({}) + ``` Check the indexes: - ```javascript - db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` ??? example "Expected output" @@ -316,50 +314,50 @@ The examples below replicate `db_0` to the first target and `db_1` to the second The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: - ```javascript - db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` - ```{.text .no-copy} - MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs - ``` + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs + ``` **On `mongos3`.** List the databases: - ```javascript - show databases - ``` + ```javascript + show databases + ``` ??? example "Expected output" ```{.text .no-copy} - admin 172.00 KiB - config 2.11 MiB - db_1 31.55 MiB - percona_clustersync_mongodb 168.00 KiB + admin 172.00 KiB + config 2.11 MiB + db_1 31.55 MiB + percona_clustersync_mongodb 168.00 KiB ``` Count the documents. The `db_1` database returns the full count and `db_0` returns zero: - ```javascript - db.getSiblingDB('db_1').docs.countDocuments({}) - db.getSiblingDB('db_0').docs.countDocuments({}) - ``` + ```javascript + db.getSiblingDB('db_1').docs.countDocuments({}) + db.getSiblingDB('db_0').docs.countDocuments({}) + ``` Check the indexes: - ```javascript - db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` Querying the collection replicated to the other target returns an error: - ```javascript - db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` - ```{.text .no-copy} - MongoServerError[NamespaceNotFound]: ns does not exist: db_0.docs - ``` + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_0.docs + ``` Finally, check the logs of each instance for errors. See [Logging in Percona ClusterSync for MongoDB](logging.md). \ No newline at end of file From e150ae833159d0d2812ed4b2fe42ac2be942f07e Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Tue, 8 Sep 2026 11:05:06 +0530 Subject: [PATCH 12/31] added numbered list to verify section --- docs/multiple-targets.md | 205 ++++++++++++++++++++------------------- 1 file changed, 104 insertions(+), 101 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index c16a72d8..4f1e21c8 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -126,49 +126,49 @@ The examples below replicate `db_0` to the first target and `db_1` to the second Connect to each target and confirm it holds only the namespaces that its instance replicated. - **On `rs2`.** List the databases, then count the documents. The `db_0` database returns the full count and `db_1` returns zero: + 1. **On `rs2`.** List the databases, then count the documents. The `db_0` database returns the full count and `db_1` returns zero: - ```javascript - show databases - db.getSiblingDB('db_0').docs.countDocuments({}) - db.getSiblingDB('db_1').docs.countDocuments({}) - ``` + ```javascript + show databases + db.getSiblingDB('db_0').docs.countDocuments({}) + db.getSiblingDB('db_1').docs.countDocuments({}) + ``` - Check the indexes that PCSM recreated on the target: + 2. Check the indexes that PCSM recreated on the target: - ```javascript - db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` - ??? example "Expected output" + ??? example "Expected output" - ```{.text .no-copy} - [ - '_id_', - 'value_1', - 'value_1_uid_-1', - 'uid_1', - 'tag_text', - '_id_hashed', - 'created_at_1', - 'value_partial', - 'tag_sparse' - ] - ``` + ```{.text .no-copy} + [ + '_id_', + 'value_1', + 'value_1_uid_-1', + 'uid_1', + 'tag_text', + '_id_hashed', + 'created_at_1', + 'value_partial', + 'tag_sparse' + ] + ``` - The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: + The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: - ```javascript - db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` - ```{.text .no-copy} - MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs - ``` + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs + ``` - **On `rs3`.** Run the same checks with the databases reversed. Here `db_1` holds the data, and querying `db_0.docs` returns `ns does not exist: db_0.docs`. + 3. **On `rs3`.** Run the same checks with the databases reversed. Here `db_1` holds the data, and querying `db_0.docs` returns `ns does not exist: db_0.docs`. - Finally, check the logs of each instance for errors. See [Logging in Percona ClusterSync for MongoDB](logging.md). + 4. Finally, check the logs of each instance for errors. See [Logging in Percona ClusterSync for MongoDB](logging.md). === "Sharded cluster" @@ -264,100 +264,103 @@ The examples below replicate `db_0` to the first target and `db_1` to the second "completedAt": "2026-08-21T08:35:48.21823288Z" } } - ``` ### Verify the result on sharded targets + ``` + + ### Verify the result on sharded targets Connect to the `mongos` of each target cluster and confirm it holds only the namespaces that its instance replicated. + {.power-number} - **On `mongos2`.** List the databases: + 1. **On `mongos2`.** List the databases: - ```javascript - show databases - ``` + ```javascript + show databases + ``` - ??? example "Expected output" + ??? example "Expected output" - ```{.text .no-copy} - admin 172.00 KiB - config 2.11 MiB - db_0 31.56 MiB - percona_clustersync_mongodb 168.00 KiB - ``` + ```{.text .no-copy} + admin 172.00 KiB + config 2.11 MiB + db_0 31.56 MiB + percona_clustersync_mongodb 168.00 KiB + ``` - Count the documents. The `db_0` database returns the full count and `db_1` returns zero: + 2. Count the documents. The `db_0` database returns the full count and `db_1` returns zero: - ```javascript - db.getSiblingDB('db_0').docs.countDocuments({}) - db.getSiblingDB('db_1').docs.countDocuments({}) - ``` + ```javascript + db.getSiblingDB('db_0').docs.countDocuments({}) + db.getSiblingDB('db_1').docs.countDocuments({}) + ``` - Check the indexes: + 3. Check the indexes: - ```javascript - db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` - ??? example "Expected output" + ??? example "Expected output" - ```{.text .no-copy} - [ + ```{.text .no-copy} + [ '_id_', 'value_1', - 'value_1_uid_-1', - 'uid_1', - 'tag_text', - '_id_hashed', - 'created_at_1', - 'value_partial', - 'tag_sparse' - ] - ``` + 'value_1_uid_-1', + 'uid_1', + 'tag_text', + '_id_hashed', + 'created_at_1', + 'value_partial', + 'tag_sparse' + ] + ``` - The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: + The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: - ```javascript - db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` - ```{.text .no-copy} - MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs - ``` + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs + ``` - **On `mongos3`.** List the databases: + 4. **On `mongos3`.** List the databases: - ```javascript - show databases - ``` + ```javascript + show databases + ``` - ??? example "Expected output" + ??? example "Expected output" - ```{.text .no-copy} - admin 172.00 KiB - config 2.11 MiB - db_1 31.55 MiB - percona_clustersync_mongodb 168.00 KiB - ``` + ```{.text .no-copy} + admin 172.00 KiB + config 2.11 MiB + db_1 31.55 MiB + percona_clustersync_mongodb 168.00 KiB + ``` - Count the documents. The `db_1` database returns the full count and `db_0` returns zero: + 5. Count the documents. The `db_1` database returns the full count and `db_0` returns zero: - ```javascript - db.getSiblingDB('db_1').docs.countDocuments({}) - db.getSiblingDB('db_0').docs.countDocuments({}) - ``` + ```javascript + db.getSiblingDB('db_1').docs.countDocuments({}) + db.getSiblingDB('db_0').docs.countDocuments({}) + ``` - Check the indexes: + 6. Check the indexes: - ```javascript - db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` - Querying the collection replicated to the other target returns an error: + Querying the collection replicated to the other target returns an error: - ```javascript - db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` - ```{.text .no-copy} - MongoServerError[NamespaceNotFound]: ns does not exist: db_0.docs - ``` + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_0.docs + ``` - Finally, check the logs of each instance for errors. See [Logging in Percona ClusterSync for MongoDB](logging.md). \ No newline at end of file + 7. Finally, check the logs of each instance for errors. See [Logging in Percona ClusterSync for MongoDB](logging.md). \ No newline at end of file From b6ade10148bc6f74b602a16ed879a79b53be0745 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Tue, 8 Sep 2026 11:59:33 +0530 Subject: [PATCH 13/31] Update multiple-targets.md --- docs/multiple-targets.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 4f1e21c8..f91b11dd 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -143,17 +143,17 @@ The examples below replicate `db_0` to the first target and `db_1` to the second ??? example "Expected output" ```{.text .no-copy} - [ - '_id_', - 'value_1', - 'value_1_uid_-1', - 'uid_1', - 'tag_text', - '_id_hashed', - 'created_at_1', - 'value_partial', - 'tag_sparse' - ] + [ + '_id_', + 'value_1', + 'value_1_uid_-1', + 'uid_1', + 'tag_text', + '_id_hashed', + 'created_at_1', + 'value_partial', + 'tag_sparse' + ] ``` The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: From 7e8529b6ddf93cd86f43e8919c88c15505447c8b Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Tue, 8 Sep 2026 12:17:16 +0530 Subject: [PATCH 14/31] Update multiple-targets.md --- docs/multiple-targets.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index f91b11dd..5121a617 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -18,11 +18,6 @@ Every instance runs the full replication workflow on its own: clone, replication Run each PCSM server in a separate container or host, or assign a unique `--port` when servers share a network namespace. Run every `start`, `status`, and `finalize` command in the corresponding container or host; for a shared host, pass that instance's `--port` to every subcommand. The examples below assume separate environments, where all instances can use the default port `2242`. See [Percona ClusterSync for MongoDB startup configuration](install/parameters.md) for the available options. -The examples below replicate `db_0` to the first target and `db_1` to the second. Select the tab that matches your deployment. - -!!! warning "Technical preview" - - Sharding support in PCSM is a technical preview and is not recommended for production. See [Sharding support in Percona ClusterSync for MongoDB](sharding.md). === "Replica set" @@ -172,6 +167,10 @@ The examples below replicate `db_0` to the first target and `db_1` to the second === "Sharded cluster" + !!! warning "Technical preview" + + Sharding support in PCSM is a technical preview and is not recommended for production. See [Sharding support in Percona ClusterSync for MongoDB](sharding.md). + ## Replicate from a sharded cluster to two targets This example uses three sharded clusters, each with its own [mongos :octicons-link-external-16:](https://www.mongodb.com/docs/manual/core/sharded-cluster-query-router/){:target="_blank"}, config server, and two shards. One cluster is the source and two are targets. From 1f00a15ff0347dd18a3e62574577167bf20ce530 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Tue, 8 Sep 2026 12:26:35 +0530 Subject: [PATCH 15/31] Update multiple-targets.md --- docs/multiple-targets.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 5121a617..a64ce769 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -69,7 +69,7 @@ Every instance runs the full replication workflow on its own: clone, replication pcsm start --include-namespaces="db_1.*" ``` - For how include and exclude filters interact, see [Start the filtered replication](install/usage.md#start-the-filtered-replication). For the full flag list, see [PCSM commands](pcsm-commands.md). You can also drive every step through the [PCSM HTTP API](api.md). + For information on how include and exclude filters interact, see [Start the filtered replication](install/usage.md#start-the-filtered-replication). For the full flag list, see [PCSM commands](pcsm-commands.md). You can also drive every step through the [PCSM HTTP API](api.md). 5. Check each instance and wait for the clone to complete and replication lag to reach an acceptable value: @@ -270,7 +270,7 @@ Every instance runs the full replication workflow on its own: clone, replication Connect to the `mongos` of each target cluster and confirm it holds only the namespaces that its instance replicated. {.power-number} - 1. **On `mongos2`.** List the databases: + 1. **On `mongos2`.**, list the databases: ```javascript show databases @@ -324,7 +324,7 @@ Every instance runs the full replication workflow on its own: clone, replication MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs ``` - 4. **On `mongos3`.** List the databases: + 4. **On `mongos3`.**, list the databases: ```javascript show databases From 67da3ef0ba0b93317d1502424e0770a4b53ffe93 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Tue, 8 Sep 2026 13:06:53 +0530 Subject: [PATCH 16/31] Update multiple-targets.md --- docs/multiple-targets.md | 106 +++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index a64ce769..85685f54 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -18,6 +18,14 @@ Every instance runs the full replication workflow on its own: clone, replication Run each PCSM server in a separate container or host, or assign a unique `--port` when servers share a network namespace. Run every `start`, `status`, and `finalize` command in the corresponding container or host; for a shared host, pass that instance's `--port` to every subcommand. The examples below assume separate environments, where all instances can use the default port `2242`. See [Percona ClusterSync for MongoDB startup configuration](install/parameters.md) for the available options. +## Before you begin + +Map out which instance owns which namespaces and which target before you start. You need that mapping again for every command you run, and it is the only record of which instance owns which data. + +!!! warning "Starting replication overwrites target collections" + `pcsm start` drops and recreates the collections that match your filter on the target, discarding any data already in them. Collections outside the filter stay as they are. Review each filter first, since a mistyped pattern affects only the target and leaves no trace on the source. + +The examples below replicate `db_0` to the first target and `db_1` to the second. Select the tab that matches your deployment. === "Replica set" @@ -71,18 +79,21 @@ Every instance runs the full replication workflow on its own: clone, replication For information on how include and exclude filters interact, see [Start the filtered replication](install/usage.md#start-the-filtered-replication). For the full flag list, see [PCSM commands](pcsm-commands.md). You can also drive every step through the [PCSM HTTP API](api.md). - 5. Check each instance and wait for the clone to complete and replication lag to reach an acceptable value: + 5. Check each instance and wait for the clone to complete and replication lag to reach an acceptable value. Look for `initialSync.completed` set to `true` and a low `lagTimeSeconds`: ```bash pcsm status ``` - 6. Finalize each instance: + 6. Finalize each instance. PCSM stops replication, creates the remaining indexes on the target, and exits: ```bash pcsm finalize ``` + !!! warning "Finalization cannot be undone" + You cannot resume an instance after you finalize it. Running `start` again begins a fresh initial sync and overwrites the target collections a second time. For a migration cutover, stop application writes to the namespaces the instance owns, wait for `lagTimeSeconds` to reach `0`, and finalize only then. Instances you are not cutting over yet keep replicating and are unaffected. + 7. Check the status of each instance after finalization. The following output is from `csync-a`. The `csync-b` output has the same structure with its own operation time and finalization timestamps: ```bash @@ -115,21 +126,32 @@ Every instance runs the full replication workflow on its own: clone, replication "completedAt": "2026-08-21T07:49:53.759444616Z" } } - ``` + ``` + + If the `finalization` object contains an `unsuccessfulIndexes` array, review it before you send traffic to that target. See [Unsuccessful indexes](install/usage.md#unsuccessful-indexes). ### Verify the result on replica set targets Connect to each target and confirm it holds only the namespaces that its instance replicated. - 1. **On `rs2`.** List the databases, then count the documents. The `db_0` database returns the full count and `db_1` returns zero: + ```sh + show databases + ``` + + You see `db_0` next to `admin`, `config`, and `percona_clustersync_mongodb`, which is where PCSM keeps its own replication metadata. The `db_1` database is absent, because `csync-a` never replicated it. + + + Counting documents confirms the same thing from the data side: ```javascript - show databases db.getSiblingDB('db_0').docs.countDocuments({}) db.getSiblingDB('db_1').docs.countDocuments({}) ``` - 2. Check the indexes that PCSM recreated on the target: + The first count matches the source. The second returns `0` rather than an error, + + + PCSM recreates the source indexes on the target during finalization, so check that they arrived: ```javascript db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) @@ -151,7 +173,7 @@ Every instance runs the full replication workflow on its own: clone, replication ] ``` - The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: + The collection replicated to the other target does not exist here, so querying it returns an error. ```javascript db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) @@ -161,9 +183,7 @@ Every instance runs the full replication workflow on its own: clone, replication MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs ``` - 3. **On `rs3`.** Run the same checks with the databases reversed. Here `db_1` holds the data, and querying `db_0.docs` returns `ns does not exist: db_0.docs`. - - 4. Finally, check the logs of each instance for errors. See [Logging in Percona ClusterSync for MongoDB](logging.md). + Repeat the same three checks on `rs3` with the databases reversed. There, `db_1` holds the data and its indexes, and `db_0.docs` returns `ns does not exist: db_0.docs`. === "Sharded cluster" @@ -183,6 +203,10 @@ Every instance runs the full replication workflow on its own: clone, replication PCSM connects through `mongos` on both the source and the target, so you do not need to list individual shard members or config servers in the connection strings. {.power-number} + !!! note "Requirements for sharded deployments" + + The source and both targets must be sharded clusters running the same MongoDB version, unless you are using [cross-version replication](version-compatibility.md). You do not need to disable the balancer on any of them. See [Sharding support in Percona ClusterSync for MongoDB](sharding.md). + 1. Start `csync-a` against the source `mongos` and the first target `mongos`: ```bash @@ -213,13 +237,19 @@ Every instance runs the full replication workflow on its own: clone, replication } ``` + Before the clone begins, PCSM checks which of the selected collections are sharded on the source and creates matching sharded collections on the target, carrying over the shard key. + + 4. Start replication on `csync-b`: ```bash pcsm start --include-namespaces="db_1.*" ``` + + For information on how include and exclude filters interact, see [Start the filtered replication](install/usage.md#start-the-filtered-replication). For the full flag list, see [PCSM commands](pcsm-commands.md). You can also drive every step through the [PCSM HTTP API](api.md). + - 5. Check each instance and wait for the clone and replication stages to complete: + 5. Check each instance and wait for the clone to complete and replication lag to reach an acceptable value. Look for `initialSync.completed` set to `true` and a low `lagTimeSeconds`: ```bash pcsm status @@ -231,6 +261,10 @@ Every instance runs the full replication workflow on its own: clone, replication pcsm finalize ``` + !!! warning "Finalization cannot be undone" + + You cannot resume an instance after you finalize it. Running `start` again begins a fresh initial sync and overwrites the target collections a second time. For a migration cutover, stop application writes to the namespaces the instance owns, wait for `lagTimeSeconds` to reach `0`, and finalize only then. + 7. Check the status of each instance after finalization. The following output is from `csync-a`: ```bash @@ -267,10 +301,8 @@ Every instance runs the full replication workflow on its own: clone, replication ### Verify the result on sharded targets - Connect to the `mongos` of each target cluster and confirm it holds only the namespaces that its instance replicated. - {.power-number} + Connect to the `mongos` of each target cluster, not to the shards directly. On `mongos2`, list the databases: - 1. **On `mongos2`.**, list the databases: ```javascript show databases @@ -285,14 +317,14 @@ Every instance runs the full replication workflow on its own: clone, replication percona_clustersync_mongodb 168.00 KiB ``` - 2. Count the documents. The `db_0` database returns the full count and `db_1` returns zero: + Count the documents. The `db_0` database returns the full count and `db_1` returns zero: ```javascript db.getSiblingDB('db_0').docs.countDocuments({}) db.getSiblingDB('db_1').docs.countDocuments({}) ``` - 3. Check the indexes: + Check that the indexes PCSM recreated during finalization are present: ```javascript db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) @@ -324,42 +356,20 @@ Every instance runs the full replication workflow on its own: clone, replication MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs ``` - 4. **On `mongos3`.**, list the databases: - - ```javascript - show databases - ``` - - ??? example "Expected output" - - ```{.text .no-copy} - admin 172.00 KiB - config 2.11 MiB - db_1 31.55 MiB - percona_clustersync_mongodb 168.00 KiB - ``` - - 5. Count the documents. The `db_1` database returns the full count and `db_0` returns zero: + If the source collection was sharded, confirm that the target collection is sharded too. - ```javascript - db.getSiblingDB('db_1').docs.countDocuments({}) - db.getSiblingDB('db_0').docs.countDocuments({}) - ``` + !!! note "Chunk distribution differs by design" + PCSM replicates data, not sharding metadata. The shard key comes across, but chunk distribution and the primary shard are decided by the target cluster and its balancer, so they will not match the source. A different layout here is expected and does not indicate a problem. See [Chunk distribution](sharding.md#chunk-distribution). - 6. Check the indexes: + Run the same checks on `mongos3` with the databases reversed. There, `db_1` holds the data and its indexes, and `db_0.docs` returns `ns does not exist: db_0.docs`. - ```javascript - db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) - ``` +## Check the logs - Querying the collection replicated to the other target returns an error: +Every instance logs separately, so check each one for errors before you decommission the source or send traffic to a target. Command responses go to `stdout` and logs and errors go to `stderr`. See [Logging in Percona ClusterSync for MongoDB](logging.md). - ```javascript - db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) - ``` +If an instance stops because of lost connectivity or a similar failure and you have not finalized it yet, bring it back with `pcsm resume --from-failure`. See [Resume the replication](pcsm-commands.md#resume) and the [Troubleshooting guide](troubleshooting.md). - ```{.text .no-copy} - MongoServerError[NamespaceNotFound]: ns does not exist: db_0.docs - ``` +## Next steps - 7. Finally, check the logs of each instance for errors. See [Logging in Percona ClusterSync for MongoDB](logging.md). \ No newline at end of file +- [Use Percona ClusterSync for MongoDB](./install/usage.md) +- [Sharding support in Percona ClusterSync for MongoDB](./sharding.md) \ No newline at end of file From 31c757115b64f3d9ec9fa5c8a848c56324c3be06 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Tue, 8 Sep 2026 13:13:50 +0530 Subject: [PATCH 17/31] Update multiple-targets.md --- docs/multiple-targets.md | 144 +++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 85685f54..53beacef 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -143,45 +143,45 @@ The examples below replicate `db_0` to the first target and `db_1` to the second Counting documents confirms the same thing from the data side: - ```javascript - db.getSiblingDB('db_0').docs.countDocuments({}) - db.getSiblingDB('db_1').docs.countDocuments({}) - ``` + ```javascript + db.getSiblingDB('db_0').docs.countDocuments({}) + db.getSiblingDB('db_1').docs.countDocuments({}) + ``` The first count matches the source. The second returns `0` rather than an error, PCSM recreates the source indexes on the target during finalization, so check that they arrived: - ```javascript - db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` - ??? example "Expected output" + ??? example "Expected output" - ```{.text .no-copy} - [ - '_id_', - 'value_1', - 'value_1_uid_-1', - 'uid_1', - 'tag_text', - '_id_hashed', - 'created_at_1', - 'value_partial', - 'tag_sparse' - ] - ``` + ```{.text .no-copy} + [ + '_id_', + 'value_1', + 'value_1_uid_-1', + 'uid_1', + 'tag_text', + '_id_hashed', + 'created_at_1', + 'value_partial', + 'tag_sparse' + ] + ``` - The collection replicated to the other target does not exist here, so querying it returns an error. + The collection replicated to the other target does not exist here, so querying it returns an error. - ```javascript - db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` - ```{.text .no-copy} - MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs - ``` + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs + ``` Repeat the same three checks on `rs3` with the databases reversed. There, `db_1` holds the data and its indexes, and `db_0.docs` returns `ns does not exist: db_0.docs`. @@ -189,7 +189,7 @@ The examples below replicate `db_0` to the first target and `db_1` to the second !!! warning "Technical preview" - Sharding support in PCSM is a technical preview and is not recommended for production. See [Sharding support in Percona ClusterSync for MongoDB](sharding.md). + Sharding support in PCSM is a technical preview and is not recommended for production. See [Sharding support in Percona ClusterSync for MongoDB](sharding.md). ## Replicate from a sharded cluster to two targets @@ -200,13 +200,12 @@ The examples below replicate `db_0` to the first target and `db_1` to the second | csync-a | mongos1 | mongos2 | `db_0.*` | | csync-b | mongos1 | mongos3 | `db_1.*` | - PCSM connects through `mongos` on both the source and the target, so you do not need to list individual shard members or config servers in the connection strings. - {.power-number} - !!! note "Requirements for sharded deployments" - The source and both targets must be sharded clusters running the same MongoDB version, unless you are using [cross-version replication](version-compatibility.md). You do not need to disable the balancer on any of them. See [Sharding support in Percona ClusterSync for MongoDB](sharding.md). + PCSM connects through `mongos` on both the source and the target, so you do not need to list individual shard members or config servers in the connection strings. + {.power-number} + 1. Start `csync-a` against the source `mongos` and the first target `mongos`: ```bash @@ -246,7 +245,7 @@ The examples below replicate `db_0` to the first target and `db_1` to the second pcsm start --include-namespaces="db_1.*" ``` - For information on how include and exclude filters interact, see [Start the filtered replication](install/usage.md#start-the-filtered-replication). For the full flag list, see [PCSM commands](pcsm-commands.md). You can also drive every step through the [PCSM HTTP API](api.md). + For information on how include and exclude filters interact, see [Start the filtered replication](install/usage.md#start-the-filtered-replication). For the full flag list, see [PCSM commands](pcsm-commands.md). You can also drive every step through the [PCSM HTTP API](api.md). 5. Check each instance and wait for the clone to complete and replication lag to reach an acceptable value. Look for `initialSync.completed` set to `true` and a low `lagTimeSeconds`: @@ -262,7 +261,6 @@ The examples below replicate `db_0` to the first target and `db_1` to the second ``` !!! warning "Finalization cannot be undone" - You cannot resume an instance after you finalize it. Running `start` again begins a fresh initial sync and overwrites the target collections a second time. For a migration cutover, stop application writes to the namespaces the instance owns, wait for `lagTimeSeconds` to reach `0`, and finalize only then. 7. Check the status of each instance after finalization. The following output is from `csync-a`: @@ -304,57 +302,57 @@ The examples below replicate `db_0` to the first target and `db_1` to the second Connect to the `mongos` of each target cluster, not to the shards directly. On `mongos2`, list the databases: - ```javascript - show databases - ``` + ```javascript + show databases + ``` - ??? example "Expected output" + ??? example "Expected output" - ```{.text .no-copy} - admin 172.00 KiB - config 2.11 MiB - db_0 31.56 MiB - percona_clustersync_mongodb 168.00 KiB - ``` + ```{.text .no-copy} + admin 172.00 KiB + config 2.11 MiB + db_0 31.56 MiB + percona_clustersync_mongodb 168.00 KiB + ``` Count the documents. The `db_0` database returns the full count and `db_1` returns zero: - ```javascript - db.getSiblingDB('db_0').docs.countDocuments({}) - db.getSiblingDB('db_1').docs.countDocuments({}) - ``` + ```javascript + db.getSiblingDB('db_0').docs.countDocuments({}) + db.getSiblingDB('db_1').docs.countDocuments({}) + ``` Check that the indexes PCSM recreated during finalization are present: - ```javascript - db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_0').docs.getIndexes().map(i => i.name) + ``` - ??? example "Expected output" + ??? example "Expected output" - ```{.text .no-copy} - [ - '_id_', - 'value_1', - 'value_1_uid_-1', - 'uid_1', - 'tag_text', - '_id_hashed', - 'created_at_1', - 'value_partial', - 'tag_sparse' - ] - ``` + ```{.text .no-copy} + [ + '_id_', + 'value_1', + 'value_1_uid_-1', + 'uid_1', + 'tag_text', + '_id_hashed', + 'created_at_1', + 'value_partial', + 'tag_sparse' + ] + ``` - The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: + The collection replicated to the other target does not exist here, so querying it returns an error. This is the expected result: - ```javascript - db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) - ``` + ```javascript + db.getSiblingDB('db_1').docs.getIndexes().map(i => i.name) + ``` - ```{.text .no-copy} - MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs - ``` + ```{.text .no-copy} + MongoServerError[NamespaceNotFound]: ns does not exist: db_1.docs + ``` If the source collection was sharded, confirm that the target collection is sharded too. From 541b2d9faeceabf24f66041b615894d42f66ba93 Mon Sep 17 00:00:00 2001 From: Rasika Chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 14 Sep 2026 13:29:41 +0530 Subject: [PATCH 18/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 53beacef..1a364dd1 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -276,7 +276,7 @@ The examples below replicate `db_0` to the first target and `db_1` to the second "ok": true, "state": "finalized", "info": "Finalized", - "lagTimeSeconds": 2, + "lagTimeSeconds": 0, "eventsRead": 6, "eventsApplied": 5, "lastReplicatedOpTime": { From 5e3380851439f9facaf0adf5558466e1f25cb0a5 Mon Sep 17 00:00:00 2001 From: Rasika Chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 14 Sep 2026 13:29:55 +0530 Subject: [PATCH 19/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 1a364dd1..c8dc11bc 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -25,7 +25,7 @@ Map out which instance owns which namespaces and which target before you start. !!! warning "Starting replication overwrites target collections" `pcsm start` drops and recreates the collections that match your filter on the target, discarding any data already in them. Collections outside the filter stay as they are. Review each filter first, since a mistyped pattern affects only the target and leaves no trace on the source. -The examples below replicate `db_0` to the first target and `db_1` to the second. Select the tab that matches your deployment. +The examples below use target clusters with no pre-existing application namespaces. They replicate `db_0` to the first target and `db_1` to the second. Select the tab that matches your deployment. === "Replica set" From cd9ce8c03c6ceb95efee2b48c364fc8864a852ba Mon Sep 17 00:00:00 2001 From: Rasika Chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 14 Sep 2026 13:30:07 +0530 Subject: [PATCH 20/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index c8dc11bc..149a6a2b 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -148,7 +148,7 @@ The examples below use target clusters with no pre-existing application namespac db.getSiblingDB('db_1').docs.countDocuments({}) ``` - The first count matches the source. The second returns `0` rather than an error, + The first count matches the source. The second returns `0` rather than an error. PCSM recreates the source indexes on the target during finalization, so check that they arrived: From 6a8064a936a58d008f511cda09e465c15b094a21 Mon Sep 17 00:00:00 2001 From: Rasika Chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 14 Sep 2026 13:30:23 +0530 Subject: [PATCH 21/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 149a6a2b..be7b4207 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -365,7 +365,7 @@ The examples below use target clusters with no pre-existing application namespac Every instance logs separately, so check each one for errors before you decommission the source or send traffic to a target. Command responses go to `stdout` and logs and errors go to `stderr`. See [Logging in Percona ClusterSync for MongoDB](logging.md). -If an instance stops because of lost connectivity or a similar failure and you have not finalized it yet, bring it back with `pcsm resume --from-failure`. See [Resume the replication](pcsm-commands.md#resume) and the [Troubleshooting guide](troubleshooting.md). +If an instance stops because of lost connectivity or a similar failure after `initialSync.completed` becomes `true` and before finalization, bring it back with `pcsm resume --from-failure`. An interruption during initial synchronization cannot be resumed; restart the clone as described in [Recover PCSM during initial data clone](troubleshooting.md#recover-pcsm-during-initial-data-clone). See [Resume the replication](pcsm-commands.md#resume) for command details. ## Next steps From 3c1c8f2f4e5f067c3df2f88cb24a49d011227612 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Mon, 14 Sep 2026 15:52:07 +0530 Subject: [PATCH 22/31] Update multiple-targets.md --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index be7b4207..203fe6a5 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -9,7 +9,7 @@ You can run multiple {{pcsm.full_name}} (PCSM) instances against the same source Each PCSM instance has: - The same source cluster -- A different target cluster +- Its own target cluster - Its own namespace filter Every instance runs the full replication workflow on its own: clone, replication, and finalization. See [How PCSM works](intro.md) for what happens at each stage. From d57faef043c8d37589b6e8504899e14a637a8ecd Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Tue, 15 Sep 2026 12:33:33 +0530 Subject: [PATCH 23/31] Update multiple-targets.md --- docs/multiple-targets.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 203fe6a5..64f87ec9 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -356,8 +356,9 @@ The examples below use target clusters with no pre-existing application namespac If the source collection was sharded, confirm that the target collection is sharded too. - !!! note "Chunk distribution differs by design" - PCSM replicates data, not sharding metadata. The shard key comes across, but chunk distribution and the primary shard are decided by the target cluster and its balancer, so they will not match the source. A different layout here is expected and does not indicate a problem. See [Chunk distribution](sharding.md#chunk-distribution). + +!!! note + For a ranged shard key, PCSM recreates the source chunk boundaries on the target before the clone. Later sharding metadata changes are not replicated, so the layouts diverge as each balancer works. That is expected. See [Chunk distribution](sharding.md#chunk-distribution). Run the same checks on `mongos3` with the databases reversed. There, `db_1` holds the data and its indexes, and `db_0.docs` returns `ns does not exist: db_0.docs`. From 17f333180c7165ebbec3e461f590788e57dc6579 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Wed, 16 Sep 2026 13:25:13 +0530 Subject: [PATCH 24/31] Implemented feedback --- docs/multiple-targets.md | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 64f87ec9..e201c471 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -85,16 +85,20 @@ The examples below use target clusters with no pre-existing application namespac pcsm status ``` - 6. Finalize each instance. PCSM stops replication, creates the remaining indexes on the target, and exits: + 6. Initiate finalization for each instance: + ```bash pcsm finalize ``` + The command returns while the PCSM server continues creating the remaining indexes on the target. Use \`pcsm status\` to monitor the server and confirm when finalization is complete. + !!! warning "Finalization cannot be undone" You cannot resume an instance after you finalize it. Running `start` again begins a fresh initial sync and overwrites the target collections a second time. For a migration cutover, stop application writes to the namespaces the instance owns, wait for `lagTimeSeconds` to reach `0`, and finalize only then. Instances you are not cutting over yet keep replicating and are unaffected. - 7. Check the status of each instance after finalization. The following output is from `csync-a`. The `csync-b` output has the same structure with its own operation time and finalization timestamps: + 7. Check each instance with \`pcsm status\` until its server reports \`state\` as \`finalized\` and \`finalization.completed\` as \`true\`. The following output is from \`csync-a\`. The \`csync-b\` output has the same structure with its own operation time and finalization timestamps: + ```bash pcsm status @@ -254,16 +258,19 @@ The examples below use target clusters with no pre-existing application namespac pcsm status ``` - 6. Finalize each instance: + 6. Initiate finalization for each instance: ```bash pcsm finalize ``` + The command returns while the PCSM server continues creating the remaining indexes on the target. Use \`pcsm status\` to monitor the server and confirm when finalization is complete. + + !!! warning "Finalization cannot be undone" You cannot resume an instance after you finalize it. Running `start` again begins a fresh initial sync and overwrites the target collections a second time. For a migration cutover, stop application writes to the namespaces the instance owns, wait for `lagTimeSeconds` to reach `0`, and finalize only then. - 7. Check the status of each instance after finalization. The following output is from `csync-a`: + 7. Check each instance with \`pcsm status\` until its server reports \`state\` as \`finalized\` and \`finalization.completed\` as \`true\`. The following output is from \`csync-a\`: ```bash pcsm status @@ -295,7 +302,10 @@ The examples below use target clusters with no pre-existing application namespac "completedAt": "2026-08-21T08:35:48.21823288Z" } } - ``` + ``` + + If the \`finalization\` object contains an \`unsuccessfulIndexes\` array, review it before you send traffic to that target. See [Unsuccessful indexes]\(install/usage.md#unsuccessful-indexes). + ### Verify the result on sharded targets @@ -357,16 +367,21 @@ The examples below use target clusters with no pre-existing application namespac If the source collection was sharded, confirm that the target collection is sharded too. -!!! note - For a ranged shard key, PCSM recreates the source chunk boundaries on the target before the clone. Later sharding metadata changes are not replicated, so the layouts diverge as each balancer works. That is expected. See [Chunk distribution](sharding.md#chunk-distribution). + !!! note + For a ranged shard key, PCSM recreates the source chunk boundaries on the target before the clone. Later sharding metadata changes are not replicated, so the layouts diverge as each balancer works. That is expected. See [Chunk distribution](sharding.md#chunk-distribution). Run the same checks on `mongos3` with the databases reversed. There, `db_1` holds the data and its indexes, and `db_0.docs` returns `ns does not exist: db_0.docs`. ## Check the logs -Every instance logs separately, so check each one for errors before you decommission the source or send traffic to a target. Command responses go to `stdout` and logs and errors go to `stderr`. See [Logging in Percona ClusterSync for MongoDB](logging.md). +Every instance logs separately, so check each one for errors before you decommission the source or send traffic to a target. + +- The PCSM server writes logs to `stdout`. +- Client subcommands write command responses to `stdout` and logs and errors to `stderr`. + +See [Logging in Percona ClusterSync for MongoDB](logging.md). -If an instance stops because of lost connectivity or a similar failure after `initialSync.completed` becomes `true` and before finalization, bring it back with `pcsm resume --from-failure`. An interruption during initial synchronization cannot be resumed; restart the clone as described in [Recover PCSM during initial data clone](troubleshooting.md#recover-pcsm-during-initial-data-clone). See [Resume the replication](pcsm-commands.md#resume) for command details. +If replication fails after initial sync has finished but before finalization, use `pcsm resume --from-failure` while the PCSM server is running. If the PCSM process has stopped, restart it before running the command. An interruption during initial sync cannot be resumed. Restart the clone as described in [Recover PCSM during initial data clone](troubleshooting.md#recover-pcsm-during-initial-data-clone). For command details, see [Resume the replication](pcsm-commands.md#resume). ## Next steps From c65aafc968080cedfeac769f6d38d30abf0e92ca Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Wed, 16 Sep 2026 13:40:14 +0530 Subject: [PATCH 25/31] Update multiple-targets.md --- docs/multiple-targets.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index e201c471..54c246fb 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -264,13 +264,13 @@ The examples below use target clusters with no pre-existing application namespac pcsm finalize ``` - The command returns while the PCSM server continues creating the remaining indexes on the target. Use \`pcsm status\` to monitor the server and confirm when finalization is complete. + The command returns while the PCSM server continues creating the remaining indexes on the target. Use `pcsm status` to monitor the server and confirm when finalization is complete. !!! warning "Finalization cannot be undone" You cannot resume an instance after you finalize it. Running `start` again begins a fresh initial sync and overwrites the target collections a second time. For a migration cutover, stop application writes to the namespaces the instance owns, wait for `lagTimeSeconds` to reach `0`, and finalize only then. - 7. Check each instance with \`pcsm status\` until its server reports \`state\` as \`finalized\` and \`finalization.completed\` as \`true\`. The following output is from \`csync-a\`: + 7. Check each instance with `pcsm status` until its server reports `state` as `finalized` and `finalization.completed` as `true`. The following output is from `csync-a`: ```bash pcsm status @@ -304,7 +304,7 @@ The examples below use target clusters with no pre-existing application namespac } ``` - If the \`finalization\` object contains an \`unsuccessfulIndexes\` array, review it before you send traffic to that target. See [Unsuccessful indexes]\(install/usage.md#unsuccessful-indexes). + If the `finalization` object contains an `unsuccessfulIndexes` array, review it before you send traffic to that target. See [Unsuccessful indexes](install/usage.md#unsuccessful-indexes). ### Verify the result on sharded targets From bb10d4a167fecaf9c249d3ad638add572f3f75f0 Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Wed, 16 Sep 2026 13:51:15 +0530 Subject: [PATCH 26/31] Update multiple-targets.md --- docs/multiple-targets.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 54c246fb..735fb220 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -92,12 +92,12 @@ The examples below use target clusters with no pre-existing application namespac pcsm finalize ``` - The command returns while the PCSM server continues creating the remaining indexes on the target. Use \`pcsm status\` to monitor the server and confirm when finalization is complete. + The command returns while the PCSM server continues creating the remaining indexes on the target. Use `pcsm status` to monitor the server and confirm when finalization is complete. !!! warning "Finalization cannot be undone" You cannot resume an instance after you finalize it. Running `start` again begins a fresh initial sync and overwrites the target collections a second time. For a migration cutover, stop application writes to the namespaces the instance owns, wait for `lagTimeSeconds` to reach `0`, and finalize only then. Instances you are not cutting over yet keep replicating and are unaffected. - 7. Check each instance with \`pcsm status\` until its server reports \`state\` as \`finalized\` and \`finalization.completed\` as \`true\`. The following output is from \`csync-a\`. The \`csync-b\` output has the same structure with its own operation time and finalization timestamps: + 7. Check each instance with `pcsm status` until its server reports `state` as `finalized` and `finalization.completed` as `true`. The following output is from `csync-a`. The `csync-b` output has the same structure with its own operation time and finalization timestamps: ```bash From 31803571a5101ad833b5f6be3658161a4ac27c4b Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Wed, 16 Sep 2026 13:52:47 +0530 Subject: [PATCH 27/31] Update multiple-targets.md --- docs/multiple-targets.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 735fb220..bddc0870 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -385,5 +385,6 @@ If replication fails after initial sync has finished but before finalization, us ## Next steps -- [Use Percona ClusterSync for MongoDB](./install/usage.md) -- [Sharding support in Percona ClusterSync for MongoDB](./sharding.md) \ No newline at end of file +- [Use Percona ClusterSync for MongoDB](./install/usage.md){.md-button} + +- [Sharding support in Percona ClusterSync for MongoDB](./sharding.md){.md-button} \ No newline at end of file From cc0142cdfb83330ff603ba170cd8e94cb07e670b Mon Sep 17 00:00:00 2001 From: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Wed, 16 Sep 2026 14:04:08 +0530 Subject: [PATCH 28/31] Update multiple-targets.md --- docs/multiple-targets.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index bddc0870..817bf06f 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -97,7 +97,9 @@ The examples below use target clusters with no pre-existing application namespac !!! warning "Finalization cannot be undone" You cannot resume an instance after you finalize it. Running `start` again begins a fresh initial sync and overwrites the target collections a second time. For a migration cutover, stop application writes to the namespaces the instance owns, wait for `lagTimeSeconds` to reach `0`, and finalize only then. Instances you are not cutting over yet keep replicating and are unaffected. - 7. Check each instance with `pcsm status` until its server reports `state` as `finalized` and `finalization.completed` as `true`. The following output is from `csync-a`. The `csync-b` output has the same structure with its own operation time and finalization timestamps: + 7. For each instance, run `pcsm status` until its server reports `state` as `finalized` and `finalization.completed` as `true`. + + The following output is from `csync-a`. The `csync-b` output has the same structure with its own operation time and finalization timestamps: ```bash @@ -270,7 +272,9 @@ The examples below use target clusters with no pre-existing application namespac !!! warning "Finalization cannot be undone" You cannot resume an instance after you finalize it. Running `start` again begins a fresh initial sync and overwrites the target collections a second time. For a migration cutover, stop application writes to the namespaces the instance owns, wait for `lagTimeSeconds` to reach `0`, and finalize only then. - 7. Check each instance with `pcsm status` until its server reports `state` as `finalized` and `finalization.completed` as `true`. The following output is from `csync-a`: + 7. For each instance, run `pcsm status` until the server reports both `state: finalized` and `finalization.completed: true`. + + The following output is from `csync-a`: ```bash pcsm status From bb8470101f365a7ec691413f638f94fd4399b82a Mon Sep 17 00:00:00 2001 From: Rasika Chivate <95711051+rasika-chivate@users.noreply.github.com> Date: Thu, 17 Sep 2026 16:21:11 +0530 Subject: [PATCH 29/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 817bf06f..5dbbcbad 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -385,7 +385,7 @@ Every instance logs separately, so check each one for errors before you decommis See [Logging in Percona ClusterSync for MongoDB](logging.md). -If replication fails after initial sync has finished but before finalization, use `pcsm resume --from-failure` while the PCSM server is running. If the PCSM process has stopped, restart it before running the command. An interruption during initial sync cannot be resumed. Restart the clone as described in [Recover PCSM during initial data clone](troubleshooting.md#recover-pcsm-during-initial-data-clone). For command details, see [Resume the replication](pcsm-commands.md#resume). +If replication enters the `failed` state after initial sync while the PCSM server is still running, resolve the underlying issue and use `pcsm resume --from-failure`. If the PCSM process stops unexpectedly during real-time replication, restart it; PCSM resumes automatically from its last saved checkpoint. An interruption during initial sync cannot be resumed. Restart the clone as described in [Recover PCSM during initial data clone](troubleshooting.md#recover-pcsm-during-initial-data-clone). For command details, see [Resume the replication](pcsm-commands.md#resume). ## Next steps From 228d89f8ef7a4fa5a79aa2bbe35620c2c17471a8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 17 Sep 2026 10:53:45 +0000 Subject: [PATCH 30/31] Clarify sharded chunk distribution docs Co-authored-by: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> --- docs/limitations.md | 4 +--- docs/sharding.md | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/limitations.md b/docs/limitations.md index 96a63119..e5f749c8 100644 --- a/docs/limitations.md +++ b/docs/limitations.md @@ -31,7 +31,7 @@ The following limitations apply specifically to sharded cluster replication: * {{pcsm.short}} replicates the data and doesn't replicate metadata. This means that the following information is not preserved from the source cluster: * The primary shard name for a collection. The target cluster may have a different primary shard name. - * The chunk distribution information. The target cluster manages chunk distribution according to its own sharding configuration. See [Sharding support](sharding.md#limitations) for more information. + * Subsequent chunk distribution changes. For ranged shard keys, {{pcsm.short}} recreates the source chunk boundaries on the target before the initial clone starts, but later chunk distribution changes are not preserved. The target cluster then manages chunk distribution according to its own sharding configuration. See [Sharding support](sharding.md#chunk-distribution) for more information. * The configuration of [zones for sharded data :octicons-link-external-16:](https://www.mongodb.com/docs/manual/core/zone-sharding/). * During data replication, the following commands are not supported: `movePrimary`, `reshardCollecton`, `unshardCollection`, `refineCollectionShardKey`. Running them results in failed replication and you must start it anew, from the initial data sync stage. @@ -57,5 +57,3 @@ The following functionalities are not supported: * Arbitrary database upgrades during a sync are not supported. For supported staged upgrades from lower to higher MongoDB major versions, follow the cross-version replication procedure. * Reverse synchronization * External authentication via Kerberos, AWS and LDAP - - diff --git a/docs/sharding.md b/docs/sharding.md index 34b13d88..3c6ee3bf 100644 --- a/docs/sharding.md +++ b/docs/sharding.md @@ -36,7 +36,7 @@ For detailed information about authentication and connection string configuratio ### Initial sync preparation -Before starting the initial sync, {{pcsm.short}} checks which collections are sharded on the source cluster and creates corresponding sharded collections on the destination cluster. The only sharding configuration preserved from the source cluster is the sharding key; all other sharding details are handled internally by the destination cluster. +Before starting the initial sync, {{pcsm.short}} checks which collections are sharded on the source cluster and creates corresponding sharded collections on the destination cluster. The sharding key is preserved from the source cluster. For ranged shard keys, {{pcsm.short}} also recreates the source chunk boundaries on the destination before the clone starts. Later sharding metadata changes are not replicated. ### Balancer operation @@ -44,9 +44,9 @@ Before starting the initial sync, {{pcsm.short}} checks which collections are sh ### Chunk distribution -{{pcsm.short}} does not preserve chunk distribution information from the source cluster. The target cluster manages chunk distribution internally through its balancer. This means that after replication, chunks may be distributed differently on the target cluster compared to the source cluster, which is expected behavior. +For ranged shard keys, {{pcsm.short}} recreates the source chunk boundaries on the target before the initial clone starts. After replication begins, later chunk distribution changes on the source cluster are not replicated. The target cluster manages chunk distribution internally through its balancer, so chunks may later be distributed differently on the target cluster compared to the source cluster, which is expected behavior. -Since the target cluster already has information about which collections are sharded, it handles sharding internally. {{pcsm.short}} does not interfere with the target cluster's sharding configuration or chunk distribution. +Since the target cluster already has information about which collections are sharded, it handles sharding internally. After the initial preparation, {{pcsm.short}} does not interfere with the target cluster's sharding configuration or chunk distribution. ## Usage From dca92feedbf434c7ea17984f52553512950abc32 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 17 Sep 2026 10:54:23 +0000 Subject: [PATCH 31/31] Align sharded clone wording Co-authored-by: rasika-chivate <95711051+rasika-chivate@users.noreply.github.com> --- docs/multiple-targets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/multiple-targets.md b/docs/multiple-targets.md index 5dbbcbad..f942834f 100644 --- a/docs/multiple-targets.md +++ b/docs/multiple-targets.md @@ -242,7 +242,7 @@ The examples below use target clusters with no pre-existing application namespac } ``` - Before the clone begins, PCSM checks which of the selected collections are sharded on the source and creates matching sharded collections on the target, carrying over the shard key. + Before the clone begins, PCSM checks which of the selected collections are sharded on the source and creates matching sharded collections on the target, carrying over the shard key and, for ranged shard keys, recreating the source chunk boundaries. 4. Start replication on `csync-b`: