Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@

- `ok`: Boolean indicating if the operation was successful.
- `error` (optional): Error message if the operation failed.
- In HA deployments, this endpoint returns HTTP `409` with `error: "not_active"` when the request reaches a standby instance. See [HA responses](#ha-responses) for the optional `me`, `role`, and `group` fields that can also appear in this response.

Example:

Expand All @@ -83,6 +84,7 @@

- `ok`: Boolean indicating if the operation was successful.
- `error` (optional): Error message if the operation failed.
- In HA deployments, this endpoint returns HTTP `409` with `error: "not_active"` when the request reaches a standby instance. See [HA responses](#ha-responses) for the optional `me`, `role`, and `group` fields that can also appear in this response.

Example:

Expand All @@ -106,6 +108,7 @@

- `ok`: Boolean indicating if the operation was successful.
- `error` (optional): Error message if the operation failed.
- In HA deployments, this endpoint returns HTTP `409` with `error: "not_active"` when the request reaches a standby instance. See [HA responses](#ha-responses) for the optional `me`, `role`, and `group` fields that can also appear in this response.

Example:

Expand Down Expand Up @@ -137,6 +140,7 @@

- `ok`: Boolean indicating if the operation was successful.
- `error` (optional): Error message if the operation failed.
- In HA deployments, this endpoint returns HTTP `409` with `error: "not_active"` when the request reaches a standby instance. See [HA responses](#ha-responses) for the optional `me`, `role`, and `group` fields that can also appear in this response.

Example:

Expand Down Expand Up @@ -186,6 +190,8 @@
| `finalization.unsuccessfulIndexes[].type` | string | Machine-readable failure category (`failed`, `incomplete`, `inconsistent`) |
| `finalization.unsuccessfulIndexes[].reason` | string | Human-readable reason why finalization failed for this index |

In HA deployments, this endpoint returns HTTP `409` with `error: "not_active"` when the request reaches a standby instance. See [HA responses](#ha-responses) for the optional `me`, `role`, and `group` fields that can also appear in this response.

Example:

```json
Expand Down Expand Up @@ -225,6 +231,51 @@
}
```

### HA responses

Check warning on line 234 in docs/api.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/api.md#L234

[Google.Headings] 'HA responses' should use sentence-style capitalization.
Raw output
{"message": "[Google.Headings] 'HA responses' should use sentence-style capitalization.", "location": {"path": "docs/api.md", "range": {"start": {"line": 234, "column": 5}}}, "severity": "WARNING"}

The `/status`, `/start`, `/pause`, `/resume`, and `/finalize` endpoints can return the following optional HA fields when PCSM observes more than one live member:

Check notice on line 236 in docs/api.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/api.md#L236

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/api.md", "range": {"start": {"line": 236, "column": 122}}}, "severity": "INFO"}

| Field | Type | Description |
|-------|------|-------------|
| `me.instanceId` | string | Identifier of the instance that handled the request |
| `role` | string | Role of the instance that handled the request (`ACTIVE` or `STANDBY`) |

Check notice on line 241 in docs/api.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/api.md#L241

[Google.Parens] Use parentheses judiciously.
Raw output
{"message": "[Google.Parens] Use parentheses judiciously.", "location": {"path": "docs/api.md", "range": {"start": {"line": 241, "column": 67}}}, "severity": "INFO"}
| `group.term` | number | Current HA term |
| `group.members` | array | Live members observed by the instance |
| `group.members[].instanceId` | string | Identifier of the listed member |
| `group.members[].host` | string | Hostname of the listed member |
| `group.members[].port` | number | Port of the listed member |
Comment thread
rasika-chivate marked this conversation as resolved.
| `group.members[].role` | string | Role of the listed member (`ACTIVE` or `STANDBY`) |

Check notice on line 247 in docs/api.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/api.md#L247

[Google.Parens] Use parentheses judiciously.
Raw output
{"message": "[Google.Parens] Use parentheses judiciously.", "location": {"path": "docs/api.md", "range": {"start": {"line": 247, "column": 63}}}, "severity": "INFO"}
Comment on lines +240 to +247

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `me.instanceId` | string | Identifier of the instance that handled the request |
| `role` | string | Role of the instance that handled the request (`ACTIVE` or `STANDBY`) |
| `group.term` | number | Current HA term |
| `group.members` | array | Live members observed by the instance |
| `group.members[].instanceId` | string | Identifier of the listed member |
| `group.members[].host` | string | Hostname of the listed member |
| `group.members[].port` | number | Port of the listed member |
| `group.members[].role` | string | Role of the listed member (`ACTIVE` or `STANDBY`) |
| `me.instanceId` | string | Identifier of the instance that handled the request |
| `role` | string | Role of the instance that handled the request (`ACTIVE` or `STANDBY`) |
| `message` | string | Present in `not_active` responses. States the role of the responding instance and the `host:port` of the ACTIVE instance when one is known |
| `group.name` | string | Name of the HA group, set with `--group-name` |
| `group.term` | number | Current HA term |
| `group.members` | array | Live members observed by the instance |
| `group.members[].instanceId` | string | Identifier of the listed member |
| `group.members[].host` | string | Hostname of the listed member |
| `group.members[].port` | number | Port of the listed member |
| `group.members[].role` | string | Role of the listed member (`ACTIVE` or `STANDBY`) |


When one of these requests reaches a standby instance, PCSM returns HTTP `409` with `error: "not_active"` and can include the HA fields shown above:

Check notice on line 249 in docs/api.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/api.md#L249

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/api.md", "range": {"start": {"line": 249, "column": 56}}}, "severity": "INFO"}

Check warning on line 249 in docs/api.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/api.md#L249

[Google.WordListCase] Use 'preceding' instead of 'above'.
Raw output
{"message": "[Google.WordListCase] Use 'preceding' instead of 'above'.", "location": {"path": "docs/api.md", "range": {"start": {"line": 249, "column": 143}}}, "severity": "WARNING"}

```json
{
"ok": false,
"error": "not_active",
"me": {
"instanceId": "<instance-id>"
},
"role": "STANDBY",
"group": {
"term": 7,
"members": [
{
"instanceId": "<instance-id>",
"host": "pcsm0",
"port": 2242,
"role": "ACTIVE"
},
{
"instanceId": "<instance-id>",
"host": "pcsm1",
"port": 2243,
"role": "STANDBY"
}
]
}
}
```

## Error handling

The API uses standard HTTP status codes and returns error messages in the following format:
Expand All @@ -242,4 +293,3 @@
- 404 Not Found: Endpoint not found
- 500 Internal Server Error: Server-side issues


286 changes: 286 additions & 0 deletions docs/high-availability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
# High availability during replication

!!! admonition "Version added: 0.10.0"

Percona ClusterSync for MongoDB (PCSM) supports active-standby high availability during replication. Run two or more instances against the same source and target, and one of them takes charge while the rest wait. If the active instance becomes unavailable, another takes over and resumes replication from the last checkpoint.

Check notice on line 5 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L5

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 5, "column": 34}}}, "severity": "INFO"}

High availability is always enabled and requires no configuration. A single instance behaves the same as in earlier versions. To enable failover, start a second instance with the same source and target.

!!! info "Important"
High availability applies to the **replication phase after the initial clone completes**.

The initial clone is not resumable. If the active PCSM instance fails during the clone, a standby becomes active, but the interrupted clone cannot continue. Start a new synchronization run to clone the data again.

## How high availability works

The instances coordinate through a lease stored on the target cluster, so the MongoDB deployment you already have is the only coordinator involved. Exactly one instance holds the lease at a time. That instance is `ACTIVE` and runs replication.

PCSM uses the following mechanisms to ensure safe failover and track instance membership:

Check notice on line 18 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L18

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 18, "column": 1}}}, "severity": "INFO"}

### Lease election

PCSM uses a lease to ensure that only one instance is ACTIVE at a time. Lease acquisition and renewal use atomic single-document operations. If several standby instances try to acquire an expired lease, only one can become active.

Check notice on line 22 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L22

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 22, "column": 1}}}, "severity": "INFO"}

PCSM evaluates lease expiration using the target MongoDB server clock. Differences between the clocks on PCSM hosts therefore do not affect the election.

Check notice on line 24 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L24

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 24, "column": 1}}}, "severity": "INFO"}

Check notice on line 24 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L24

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 24, "column": 106}}}, "severity": "INFO"}

Check notice on line 24 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L24

[Google.Contractions] Use 'don't' instead of 'do not'.
Raw output
{"message": "[Google.Contractions] Use 'don't' instead of 'do not'.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 24, "column": 127}}}, "severity": "INFO"}

For more information about atomic single-document operations, see [Atomicity and Transactions :octicons-link-external-16:](https://www.mongodb.com/docs/manual/core/write-operations-atomicity/){:target="_blank"} in the MongoDB documentation.

PCSM stores the lease as a single document in the `percona_clustersync_mongodb.lease` collection. For example:

Check notice on line 28 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L28

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 28, "column": 1}}}, "severity": "INFO"}

```sh
{ "_id": "lease",
"group": "default",
"term": 7,
"instanceId": "b3f1c2a4-9d7e-4c11-8a2f-1e6b0d5c9a77",
"electionDate": { "$date": "2026-07-17T09:14:02.190Z" },
"expiresAt": { "$date": "2026-07-17T09:20:41.882Z" }
}
```

The document identifies the active instance and records the current lease term, election time, and expiration time.

### Term fencing

Each lease has a `term` value that increases whenever a new `ACTIVE` instance is elected. PCSM includes this value in every checkpoint written by the active instance.

Check notice on line 44 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L44

[Google.Passive] In general, use active voice instead of passive voice ('is elected').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is elected').", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 44, "column": 79}}}, "severity": "INFO"}

Check notice on line 44 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L44

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 44, "column": 91}}}, "severity": "INFO"}

If a previous active instance resumes after losing its lease, its checkpoint writes contain an outdated term and are rejected. The instance then switches to `STANDBY`, which prevents it from overwriting the current replication state.

Check notice on line 46 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L46

[Google.Passive] In general, use active voice instead of passive voice ('are rejected').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('are rejected').", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 46, "column": 114}}}, "severity": "INFO"}

### Checkpoint recovery

When a standby becomes `ACTIVE`, PCSM resumes replication from the last persisted checkpoint. Failover uses the existing recovery mechanism and happens automatically.

Check notice on line 50 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L50

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 50, "column": 34}}}, "severity": "INFO"}

The timings are fixed:

Check notice on line 52 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L52

[Google.Passive] In general, use active voice instead of passive voice ('are fixed').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('are fixed').", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 52, "column": 13}}}, "severity": "INFO"}

| **Setting** | **Value** |
|---------|-------|
| Lease TTL | 10 seconds |

Check notice on line 56 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L56

[Google.Acronyms] Spell out 'TTL', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'TTL', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 56, "column": 9}}}, "severity": "INFO"}
| Lease renewal by the active instance | Every 3 seconds |
| Heartbeat interval | Every 3 seconds |
| Stale member threshold | 3 missed heartbeats |

If the active instance stops unexpectedly, a standby can take over after the lease expires and continue replication from the latest checkpoint.

Check notice on line 61 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L61

[Google.Timeless] Avoid time-based words like 'latest' in product documentation.
Raw output
{"message": "[Google.Timeless] Avoid time-based words like 'latest' in product documentation.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 61, "column": 126}}}, "severity": "INFO"}

### Instance membership

Each PCSM instance records its identity and liveness information in the `percona_clustersync_mongodb.members` collection on the target cluster. The instance refreshes this information with each heartbeat.

Check notice on line 65 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L65

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 65, "column": 6}}}, "severity": "INFO"}


For example:

```sh
{
"_id": "b3f1c2a4-9d7e-4c11-8a2f-1e6b0d5c9a77",
"group": "default",
"host": "pcsm0",
"port": 2242,
"role": "ACTIVE",
"term": 7,
"pcsmVersion": "0.10.0",
"startedAt": { "$date": "2026-07-17T09:14:02.113Z" },
"lastHeartbeat": { "$date": "2026-07-17T09:20:31.882Z" }
}
```

A member that does not send a heartbeat within the stale-member threshold is removed from the current group view.

Check notice on line 84 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L84

[Google.Contractions] Use 'doesn't' instead of 'does not'.
Raw output
{"message": "[Google.Contractions] Use 'doesn't' instead of 'does not'.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 84, "column": 15}}}, "severity": "INFO"}

Check notice on line 84 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L84

[Google.Passive] In general, use active voice instead of passive voice ('is removed').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is removed').", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 84, "column": 75}}}, "severity": "INFO"}

## Set up high availability

Run at least two PCSM instances on separate hosts, containers, or pods. Configure every instance with the same source and target clusters.

Check notice on line 88 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L88

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 88, "column": 18}}}, "severity": "INFO"}

For example, run the following command on each host:

```bash
pcsm \
--source "<source-mongodb-uri>" \
--target "<target-mongodb-uri>"
```

No additional HA option is required.

Check notice on line 98 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L98

[Google.Passive] In general, use active voice instead of passive voice ('is required').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is required').", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 98, "column": 25}}}, "severity": "INFO"}

If you run multiple PCSM instances on the same host, configure a different `--port` for each instance. For protection against a host failure, run the instances on separate hosts or pods.

Check notice on line 100 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L100

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 100, "column": 21}}}, "severity": "INFO"}

See [Start PCSM](install/start-pcsm.md) for startup options and [Percona ClusterSync for MongoDB startup configuration](install/parameters.md) for the available parameters.

Check notice on line 102 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L102

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 102, "column": 12}}}, "severity": "INFO"}

### Identify the HA group

Check warning on line 104 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L104

[Google.Headings] 'Identify the HA group' should use sentence-style capitalization.
Raw output
{"message": "[Google.Headings] 'Identify the HA group' should use sentence-style capitalization.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 104, "column": 5}}}, "severity": "WARNING"}

You can use `--group-name` or the `PCSM_GROUP_NAME` environment variable to assign a name that identifies the HA deployment in member information, API responses, metrics, and logs.

For example:

```sh
pcsm \
--source "<source-mongodb-uri>" \
--target "<target-mongodb-uri>" \
--group-name migration-1
```

The default group name is `default`.

!!! info "Important"

In PCSM 0.10.0, the group name is used for identification and observability. It does not isolate HA coordination between different groups that use the same target cluster.

Do not rely on different group names to create independent HA deployments against the same target.

## Failover during the initial clone

High availability applies to the replication phase after the initial clone completes. The initial clone is not resumable because PCSM does not persist progress for individual collections.

Check notice on line 127 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L127

[Google.Contractions] Use 'isn't' instead of 'is not'.
Raw output
{"message": "[Google.Contractions] Use 'isn't' instead of 'is not'.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 127, "column": 105}}}, "severity": "INFO"}

Check notice on line 127 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L127

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 127, "column": 130}}}, "severity": "INFO"}

Check notice on line 127 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L127

[Google.Contractions] Use 'doesn't' instead of 'does not'.
Raw output
{"message": "[Google.Contractions] Use 'doesn't' instead of 'does not'.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 127, "column": 135}}}, "severity": "INFO"}

If the `ACTIVE` instance becomes unavailable during the initial clone, a standby is promoted. During recovery, the new `ACTIVE` detects that the clone was interrupted and stops the synchronization. PCSM reports the reason in the logs and through the /status endpoint:

Check notice on line 129 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L129

[Google.Passive] In general, use active voice instead of passive voice ('is promoted').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is promoted').", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 129, "column": 82}}}, "severity": "INFO"}

Check notice on line 129 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L129

[Google.Passive] In general, use active voice instead of passive voice ('was interrupted').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('was interrupted').", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 129, "column": 152}}}, "severity": "INFO"}

Check notice on line 129 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L129

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 129, "column": 199}}}, "severity": "INFO"}

```sh
initial clone interrupted by failover and is not resumable; start a new run to re-clone from scratch
```

!!! info "Important"

To recover, start a new synchronization run on the `ACTIVE` instance. PCSM starts the initial clone again from the beginning. Automatic recovery from the last checkpoint becomes available after the initial clone completes and PCSM enters the replication phase.

See the [PCSM HTTP API](api.md) for information about the `/status` endpoint and [Start the replication](install/usage.md#start-the-replication) for information about starting a new synchronization run.

Check notice on line 139 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L139

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 139, "column": 10}}}, "severity": "INFO"}

## Operate an HA deployment

Check warning on line 141 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L141

[Google.Headings] 'Operate an HA deployment' should use sentence-style capitalization.
Raw output
{"message": "[Google.Headings] 'Operate an HA deployment' should use sentence-style capitalization.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 141, "column": 4}}}, "severity": "WARNING"}

During normal operation, you need to know which PCSM instance is active, send replication commands to that instance, and monitor all members of the deployment. PCSM exposes the information you need through its API and `/metrics` endpoint.

Check notice on line 143 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L143

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 143, "column": 49}}}, "severity": "INFO"}

Check notice on line 143 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L143

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 143, "column": 161}}}, "severity": "INFO"}

### Check the active instance

Use the `percona_clustersync_mongodb_ha_active` metric to check the role of a PCSM instance:

Check notice on line 147 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L147

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 147, "column": 79}}}, "severity": "INFO"}

```bash
curl -sS http://localhost:2242/metrics | grep percona_clustersync_mongodb_ha_active
```

A value of `1` identifies the active instance. A value of `0` identifies a standby.

When PCSM sees more than one live member, API responses can also include the `me`, `role`, and `group` fields. These fields identify the instance that handled the request and list the live PCSM instances and their current roles.

Check notice on line 155 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L155

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 155, "column": 6}}}, "severity": "INFO"}

Check notice on line 155 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L155

[Google.Anthropomorphism] Don't attribute human qualities to software or hardware ('sees').
Raw output
{"message": "[Google.Anthropomorphism] Don't attribute human qualities to software or hardware ('sees').", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 155, "column": 11}}}, "severity": "INFO"}

Check notice on line 155 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L155

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 155, "column": 190}}}, "severity": "INFO"}

For example, an operational request sent to a standby returns HTTP `409` with `error: "not_active"`:

```{.json .no-copy}
{
"ok": false,
"error": "not_active",
"me": {
"instanceId": "<instance-id>"
},
"role": "STANDBY",
"group": {
"term": 7,
"members": [
{
"instanceId": "<instance-id>",
"host": "pcsm0",
"port": 2242,
"role": "ACTIVE"
},
{
"instanceId": "<instance-id>",
"host": "pcsm1",
"port": 2243,
"role": "STANDBY"
}
]
}
}
```
The response shows which instance handled the request and identifies the current active member.

!!! info "Important"

The `me`, `role`, and `group` fields are included only when the instance observes more than one live member. Applications that consume the PCSM API must therefore treat these fields as optional.

A single PCSM instance continues to return API responses in the same format as earlier releases.

See the [PCSM HTTP API](api.md) for endpoint details.

Check notice on line 194 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L194

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 194, "column": 10}}}, "severity": "INFO"}
Comment thread
rasika-chivate marked this conversation as resolved.

### Send operational commands to the active instance

Replication commands must be sent to the active PCSM instance.

Check notice on line 198 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L198

[Google.Passive] In general, use active voice instead of passive voice ('be sent').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('be sent').", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 198, "column": 27}}}, "severity": "INFO"}

Check notice on line 198 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L198

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 198, "column": 49}}}, "severity": "INFO"}

The following endpoints return HTTP `409` with `error: "not_active"` when called on a standby:

* `/status`
* `/start`
* `/pause`
* `/resume`
* `/finalize`

When group information is available, the 409 response includes the member list so you can locate the active instance.

See [PCSM commands](pcsm-commands.md) for information about managing a synchronization run.

Check notice on line 210 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L210

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 210, "column": 6}}}, "severity": "INFO"}

## Configure health probes

Use `/metrics` for liveness and readiness probes in an HA deployment. This endpoint is available regardless of whether an instance is active or standby.

Do not use `/status` for a readiness probe. A healthy standby returns HTTP `409` from this endpoint because replication status is available only from the active instance.

Check notice on line 216 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L216

[Google.Contractions] Use 'don't' instead of 'Do not'.
Raw output
{"message": "[Google.Contractions] Use 'don't' instead of 'Do not'.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 216, "column": 1}}}, "severity": "INFO"}

!!! warning

A healthy standby returns HTTP `409` from this endpoint because replication status is available only from the active instance. A probe pointed there marks every standby unhealthy. For Kubernetes deployments, see [Configure Liveness, Readiness and Startup Probes :octicons-link-external-16:](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/){:target="_blank"}.


## High availability metrics

PCSM exposes the following HA metrics through `/metrics`:

Check notice on line 225 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L225

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 225, "column": 1}}}, "severity": "INFO"}

| Metric | Description |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `percona_clustersync_mongodb_ha_active` | Shows the current role. `1` means ACTIVE and `0` means STANDBY. |
| `percona_clustersync_mongodb_ha_term` | Shows the current HA lease term. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha_term is the term the instance advertises which is if an instance lost the election advertises 0 even while the active holds something else, eg. 7. The STANDBY samples here at L168 and in api.md showing "term": 7 can't happen.
The metric help in the code already says "term this instance advertises". Can we word both the metric and the group.term row that way as well and set the standby samples to 0?

| `percona_clustersync_mongodb_ha_role_transitions_total` | Counts role changes for the PCSM instance. |

Check notice on line 231 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L231

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 231, "column": 89}}}, "severity": "INFO"}
| `percona_clustersync_mongodb_ha_info` | Reports instance information. The metric has a constant value of `1` and includes the `instance_id` and `group` labels. |
Comment thread
rasika-chivate marked this conversation as resolved.

You can use these metrics to identify the active instance, detect role changes, and monitor failover behavior.

## Reset HA state

Check warning on line 236 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L236

[Google.Headings] 'Reset HA state' should use sentence-style capitalization.
Raw output
{"message": "[Google.Headings] 'Reset HA state' should use sentence-style capitalization.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 236, "column": 4}}}, "severity": "WARNING"}

PCSM provides commands to clear the stored HA membership or lease state.

Check notice on line 238 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L238

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 238, "column": 1}}}, "severity": "INFO"}
Comment thread
rasika-chivate marked this conversation as resolved.

!!! warning
Stop all PCSM server instances that use the target cluster before running these commands. Do not reset HA state while PCSM is running.

Check notice on line 241 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L241

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 241, "column": 14}}}, "severity": "INFO"}

Check notice on line 241 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L241

[Google.Contractions] Use 'don't' instead of 'Do not'.
Raw output
{"message": "[Google.Contractions] Use 'don't' instead of 'Do not'.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 241, "column": 95}}}, "severity": "INFO"}

Check notice on line 241 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L241

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 241, "column": 123}}}, "severity": "INFO"}

Clear the recorded member information:

```bash
pcsm reset members --target "<target-mongodb-uri>"
```

Clear the HA lease:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reset lease leaves the checkpoint in place. The new lease starts at term 1 while the checkpoint still holds the old term and the next instance gets fenced on its first checkpoint write and demotes itself.
It's a maintenance command for a leftover lease with no replication state and that's is also why its hidden from the CLI. Not sure where you got it from but let's drop it either way.

Point this at pcsm reset instead.


```bash
pcsm reset lease --target "<target-mongodb-uri>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pcsm reset lease --target "<target-mongodb-uri>
pcsm reset lease --target "<target-mongodb-uri>"

Unterminated quote, copying this leaves the shell waiting for input. Flagged earlier by Copilot(?!) and marked resolved however it's still here.

```

Use these commands only when you need to clear HA coordination state. To clear all PCSM state, use `pcsm reset`.

Check notice on line 255 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L255

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 255, "column": 84}}}, "severity": "INFO"}

## Upgrade from PCSM 0.9.0

Check warning on line 257 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L257

[Google.Headings] 'Upgrade from PCSM 0.9.0' should use sentence-style capitalization.
Raw output
{"message": "[Google.Headings] 'Upgrade from PCSM 0.9.0' should use sentence-style capitalization.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 257, "column": 4}}}, "severity": "WARNING"}

Check notice on line 257 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L257

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 257, "column": 17}}}, "severity": "INFO"}

Replication state created by PCSM 0.9.0 is not compatible with PCSM 0.10.0.

Check notice on line 259 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L259

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 259, "column": 30}}}, "severity": "INFO"}

Check notice on line 259 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L259

[Google.Contractions] Use 'isn't' instead of 'is not'.
Raw output
{"message": "[Google.Contractions] Use 'isn't' instead of 'is not'.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 259, "column": 41}}}, "severity": "INFO"}

Check notice on line 259 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L259

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 259, "column": 64}}}, "severity": "INFO"}

Before starting PCSM 0.10.0:

Check notice on line 261 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L261

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 261, "column": 17}}}, "severity": "INFO"}
{.power-number}

1. Stop all PCSM 0.9.0 instances that use the target cluster.

Check notice on line 264 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L264

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 264, "column": 13}}}, "severity": "INFO"}

2. Reset the stored PCSM state on the target:

Check notice on line 266 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L266

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 266, "column": 21}}}, "severity": "INFO"}

```bash
pcsm reset --target "<target-mongodb-uri>"
```

3. Start PCSM 0.10.0

Check notice on line 272 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L272

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 272, "column": 10}}}, "severity": "INFO"}
4. Start a new synchronization run.

!!! info "Important"
Do not run PCSM 0.9.0 and PCSM 0.10.0 against the same target at the same time.

Check notice on line 276 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L276

[Google.Contractions] Use 'don't' instead of 'Do not'.
Raw output
{"message": "[Google.Contractions] Use 'don't' instead of 'Do not'.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 276, "column": 5}}}, "severity": "INFO"}

Check notice on line 276 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L276

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 276, "column": 16}}}, "severity": "INFO"}

Check notice on line 276 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L276

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 276, "column": 31}}}, "severity": "INFO"}

## Next steps

[Use the PCSM HTTP API](api.md){.md-button}

Check notice on line 280 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L280

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 280, "column": 10}}}, "severity": "INFO"}

[Manage synchronization with PCSM commands](pcsm-commands.md){.md-button}

Check notice on line 282 in docs/high-availability.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/high-availability.md#L282

[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'PCSM', if it's unfamiliar to the audience.", "location": {"path": "docs/high-availability.md", "range": {"start": {"line": 282, "column": 30}}}, "severity": "INFO"}

[Set up observability with Percona Monitoring and Management](pmm-setup.md){.md-button}


Loading
Loading