Skip to content

Commit 22e2988

Browse files
committed
feat: explain the configuration for copy_data retries
1 parent b78bb96 commit 22e2988

8 files changed

Lines changed: 77 additions & 11 deletions

File tree

docs/configuration/pgdog.toml/general.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,18 @@ Available options:
457457

458458
`text` format is required when migrating from `INTEGER` to `BIGINT` primary keys during resharding.
459459

460+
### `resharding_copy_retry_max_attempts`
461+
462+
How many times PgDog retries a single table copy after a failure (e.g., a shard goes down mid-copy). The delay starts at [`resharding_copy_retry_min_delay`](#resharding_copy_retry_min_delay) and doubles each attempt, capped at 32× that value.
463+
464+
Default: **`5`**
465+
466+
### `resharding_copy_retry_min_delay`
467+
468+
Starting delay between retry attempts, in milliseconds. Doubles on each attempt, capped at 32× this value (`32_000` ms at the default).
469+
470+
Default: **`1_000`** (1s)
471+
460472
### `reload_schema_on_ddl`
461473

462474
!!! warning

docs/features/sharding/resharding/.pages

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ nav:
22
- 'index.md'
33
- 'databases.md'
44
- 'schema.md'
5-
- 'hash.md'
5+
- 'move.md'
66
- 'cutover.md'

docs/features/sharding/resharding/cutover.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ icon: material/set-right
88
This is a new and experimental feature. Please make sure to test it before deploying to production
99
and report any issues you find.
1010

11-
Traffic cutover involves moving application traffic (read and write queries) to the destination database. This happens when the source and destination databases are in sync: all source data is copied, and resharded with [logical replication](hash.md).
11+
Traffic cutover involves moving application traffic (read and write queries) to the destination database. This happens when the source and destination databases are in sync: all source data is copied, and resharded with [logical replication](move.md).
1212

1313
## Performing the cutover
1414

docs/features/sharding/resharding/databases.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ PgDog's strategy for resharding Postgres databases is to create a new, independe
88

99
## Requirements
1010

11-
New databases should be **empty**: don't migrate your [table definitions](schema.md) or [data](hash.md). These will be taken care of automatically by PgDog.
11+
New databases should be **empty**: don't migrate your [table definitions](schema.md) or [data](move.md). These will be taken care of automatically by PgDog.
1212

1313
### Database users
1414

docs/features/sharding/resharding/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The resharding process is composed of four independent operations. The first one
2424
|-|-|
2525
| [Create new cluster](databases.md) | Create a new set of empty databases that will be used for storing data in the new, sharded cluster. |
2626
| [Schema synchronization](schema.md) | Replicate table and index definitions to the new shards, making sure the new cluster has the same schema as the old one. |
27-
| [Move & reshard data](hash.md) | Copy data using logical replication, while redistributing rows in-flight between new shards. |
27+
| [Move & reshard data](move.md) | Copy data using logical replication, while redistributing rows in-flight between new shards. |
2828
| [Cutover traffic](cutover.md) | Make the new cluster service both reads and writes from the application, without taking downtime. |
2929

3030
While each step can be executed separately by the operator, PgDog provides an [admin database](../../../administration/index.md) command to perform online resharding and traffic cutover steps in a completely automated fashion:
@@ -50,5 +50,5 @@ The `<source>` and `<destination>` parameters accept the name of the source and
5050

5151
{{ next_steps_links([
5252
("Schema sync", "schema.md", "Synchronize table, index and other schema entities between the source and destination databases."),
53-
("Move data", "hash.md", "Redistribute data between shards using the configured sharding function. This happens without downtime and keeps the shards up-to-date with the source database until traffic cutover."),
53+
("Move data", "move.md", "Redistribute data between shards using the configured sharding function. This happens without downtime and keeps the shards up-to-date with the source database until traffic cutover."),
5454
]) }}
Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ PgDog will distribute the table copy load evenly between all replicas in the con
121121
To prevent the resharding process from impacting production queries, you can create a separate set of replicas just for resharding.
122122

123123
Managed clouds (e.g., AWS RDS) make this especially easy, but require a warm-up period to fetch all the data from the backup snapshot, before they can read data at full speed of their storage volumes.
124-
124+
125125
To make sure dedicated replicas are not used for read queries in production, you can configure PgDog to use them for resharding only:
126-
126+
127127
```toml
128128
[[databases]]
129129
name = "prod"
@@ -215,6 +215,60 @@ FROM pg_replication_slots;
215215
```
216216
The replication delay between the two database clusters is measured in bytes. When that number reaches zero, the two databases are byte-for-byte identical, and traffic can be [cut over](cutover.md) to the destination database.
217217

218+
## Troubleshooting
219+
220+
### Shard failure during copy
221+
222+
If a shard goes down mid-copy, PgDog retries that table with exponential backoff - up to **5 attempts**, starting at **1 second** and doubling each time.
223+
224+
The two cases behave differently:
225+
226+
- **Destination shard down** — PgDog opens a fresh connection on the next attempt.
227+
- **Source shard down** — the `TEMPORARY` slot for that table is re-created from scratch. No cleanup needed; `TEMPORARY` slots vanish when the connection closes (unlike the [permanent slot](#replication-slot) created at the start of the overall copy).
228+
229+
To change the defaults:
230+
231+
```toml
232+
[general]
233+
resharding_copy_retry_max_attempts = 5 # per-table retry attempts
234+
resharding_copy_retry_min_delay = 1000 # base backoff in ms; doubles each attempt, max 32×
235+
```
236+
237+
### Rows remaining in destination after failure
238+
239+
Most drops are clean: table copies run inside an implicit transaction, so Postgres rolls back on disconnect and the destination is left empty.
240+
241+
The awkward case: the connection drops *after* `COPY` commits on some or all shards but before PgDog records it as done. The rows survive, and the next attempt hits primary key violations immediately.
242+
243+
PgDog catches this and tells you exactly what to run:
244+
245+
```
246+
data sync for "public"."orders" failed with rows remaining in destination;
247+
truncate manually before retrying: TRUNCATE "public"."orders_new";
248+
```
249+
250+
Run the `TRUNCATE` on the destination (the table name is literal — copy it verbatim), then re-run `COPY_DATA`.
251+
252+
### Binary format mismatch
253+
254+
Different major Postgres versions can produce incompatible binary `COPY` data. PgDog surfaces this as a `BinaryFormatMismatch` error. Switch to text:
255+
256+
```toml
257+
[general]
258+
resharding_copy_format = "text"
259+
```
260+
261+
See [Integer primary keys](#integer-primary-keys) for the other common reason to use text format.
262+
263+
### Replication slot not dropped after abort
264+
265+
Aborting `COPY_DATA` without restarting it leaves the **permanent** replication slot sitting on the source. Postgres won't recycle WAL until it's gone. Drop it manually:
266+
267+
```postgresql
268+
SELECT pg_drop_replication_slot('slot_name');
269+
```
270+
271+
The slot name appears in the `COPY_DATA` startup log and in `SHOW REPLICATION_SLOTS`.
218272
## Next steps
219273

220274
{{ next_steps_links([

docs/features/sharding/resharding/schema.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The schema synchronization process is composed of 4 distinct steps, all of which
1212
| Phase | Description |
1313
|-|-|
1414
| [Pre-data](#pre-data-phase) | Create identical tables on all shards along with the primary key constraint (and index). Secondary indexes are _not_ created yet. |
15-
| [Post-data](#post-data-phase) | Create secondary indexes on all tables and shards. This is done after [moving data](hash.md), as a separate step, because it's considerably faster to create indexes on whole tables than while inserting individual rows. |
15+
| [Post-data](#post-data-phase) | Create secondary indexes on all tables and shards. This is done after [moving data](move.md), as a separate step, because it's considerably faster to create indexes on whole tables than while inserting individual rows. |
1616
| [Cutover](#cutover) | This step is executed during traffic cutover, while application queries are blocked from executing on the database. |
1717
| Post-cutover | This step makes sure the rollback database cluster can handle reverse logical replication. |
1818

@@ -110,7 +110,7 @@ This will make sure all tables and schemas in your database are copied and resha
110110

111111
## Post-data phase
112112

113-
The post-data phase is performed after the [data copy](hash.md) is complete and tables have been synchronized with logical replication. Its job is to create all secondary indexes (e.g., `CREATE INDEX`).
113+
The post-data phase is performed after the [data copy](move.md) is complete and tables have been synchronized with logical replication. Its job is to create all secondary indexes (e.g., `CREATE INDEX`).
114114

115115
This step is performed after copying data because it makes the copy process considerably faster: Postgres doesn't need to update several indexes while writing rows into the tables.
116116

@@ -189,5 +189,5 @@ pg_dump_path = "/path/to/pg_dump"
189189
## Next steps
190190

191191
{{ next_steps_links([
192-
("Move data", "hash.md", "Redistribute data between shards using the configured sharding function. This happens without downtime and keeps the shards up-to-date with the source database until traffic cutover."),
192+
("Move data", "move.md", "Redistribute data between shards using the configured sharding function. This happens without downtime and keeps the shards up-to-date with the source database until traffic cutover."),
193193
]) }}

docs/roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ Support for sorting rows in [cross-shard](features/sharding/cross-shard-queries/
8989

9090
| Feature | Status | Notes |
9191
|-|-|-|
92-
| [Data sync](features/sharding/resharding/hash.md) | :material-wrench: | Sync table data with logical replication. |
92+
| [Data sync](features/sharding/resharding/move.md) | :material-wrench: | Sync table data with logical replication. |
9393
| [Schema sync](features/sharding/resharding/schema.md) | :material-wrench: | Sync table, index and constraint definitions. |
9494
| Online rebalancing | :material-calendar-check: | Not automated yet, requires manual orchestration. |
9595

0 commit comments

Comments
 (0)