|
| 1 | +--- |
| 2 | +icon: material/format-list-checks |
| 3 | +--- |
| 4 | + |
| 5 | +# Background tasks |
| 6 | + |
| 7 | +Long-running operations like [resharding](../features/sharding/resharding/index.md) don't block the connection that started them. Instead, `RESHARD`, `COPY_DATA`, `REPLICATE`, and `SCHEMA_SYNC` each return a `task_id` and run in the background. `SHOW TASKS` is how you track those tasks: it reports their lifecycle status and progress, lets you find the `task_id` to pass to [`STOP_TASK`](#stopping-a-task) or [`CUTOVER`](../features/sharding/resharding/cutover.md), and surfaces failures. |
| 8 | + |
| 9 | +Run it on the [admin database](index.md): |
| 10 | + |
| 11 | +``` |
| 12 | +SHOW TASKS; |
| 13 | +``` |
| 14 | + |
| 15 | +!!! note "Admin database tasks only" |
| 16 | + `SHOW TASKS` lists the background tasks running *inside this PgDog process* — the ones started by the admin database commands above. The equivalent [CLI commands](../features/sharding/resharding/index.md#running-the-steps-manually) (`pgdog data-sync`, `pgdog schema-sync`) run as a separate, one-off `pgdog` process in the foreground: they block until they finish and are stopped with `Ctrl-C`, so they neither return a `task_id` nor appear here. |
| 17 | + |
| 18 | +=== "Output" |
| 19 | + ``` |
| 20 | + -[ RECORD 1 ]+---------------------------------- |
| 21 | + id | 14 |
| 22 | + scope | root |
| 23 | + type | reshard prod -> prod_sharded |
| 24 | + status | running |
| 25 | + inner_status | syncing data |
| 26 | + started_at | 2026-06-30 18:02:11.004 UTC |
| 27 | + updated_at | 2026-06-30 18:05:42.119 UTC |
| 28 | + elapsed | 00:03:31:115 |
| 29 | + elapsed_ms | 211115 |
| 30 | + -[ RECORD 2 ]+---------------------------------- |
| 31 | + id | |
| 32 | + scope | subtask |
| 33 | + type | copy_data prod -> prod_sharded |
| 34 | + status | running |
| 35 | + inner_status | |
| 36 | + started_at | 2026-06-30 18:02:30.550 UTC |
| 37 | + updated_at | 2026-06-30 18:05:42.119 UTC |
| 38 | + elapsed | 00:03:11:569 |
| 39 | + elapsed_ms | 191569 |
| 40 | + ``` |
| 41 | + |
| 42 | +The most recently started task is listed first. |
| 43 | + |
| 44 | +## Columns |
| 45 | + |
| 46 | +| Column | Description | |
| 47 | +|-|-| |
| 48 | +| `id` | The task's id. This is the handle you pass to [`STOP_TASK`](#stopping-a-task) and [`CUTOVER`](../features/sharding/resharding/cutover.md). Only **root** rows carry an id; subtasks share their root's id and leave this column empty. | |
| 49 | +| `scope` | `root` for a top-level task, `subtask` for a step it spawned (e.g. the `copy_data` and `replication` steps of a `reshard`). | |
| 50 | +| `type` | What the task is, usually with the source and destination databases — e.g. `reshard`, `copy_data`, `replication`, `replication ... (reverse)`, `schema_sync(pre)`. | |
| 51 | +| `status` | The lifecycle status of the task. See [Statuses](#statuses). | |
| 52 | +| `inner_status` | Fine-grained progress within the current status. See [Progress](#progress). For a finished or failed task, this keeps the last progress it reported. | |
| 53 | +| `started_at` | When the task started. | |
| 54 | +| `updated_at` | When the task last changed status or progress. For a terminal task this is when it finished. | |
| 55 | +| `elapsed` / `elapsed_ms` | How long the task ran. For a terminal task this is the total run time (measured to `updated_at`), not a clock that keeps ticking. | |
| 56 | + |
| 57 | +## Statuses |
| 58 | + |
| 59 | +The `status` column describes where the task is in its lifecycle: |
| 60 | + |
| 61 | +| Status | Meaning | |
| 62 | +|-|-| |
| 63 | +| `started` | The task is being set up. | |
| 64 | +| `running` | The task is actively working. | |
| 65 | +| `cancelling` | A [`STOP_TASK`](#stopping-a-task) was requested and the task is winding down cooperatively. | |
| 66 | +| `finished` | The task completed successfully. | |
| 67 | +| `cancelled` | The task was stopped before completing. | |
| 68 | +| `failed: <error>` | The task errored. The error message is included in the status. | |
| 69 | +| `panicked: <error>` | The task hit an unexpected internal error. | |
| 70 | + |
| 71 | +`finished`, `cancelled`, `failed`, and `panicked` are **terminal**. Terminal tasks stay listed with their final status (and last progress) for a while so you can inspect the outcome, then they're pruned automatically. |
| 72 | + |
| 73 | +## Progress |
| 74 | + |
| 75 | +The `inner_status` column shows what the task is doing within its current `status`. The values depend on the task `type`: |
| 76 | + |
| 77 | +| Task | Progress values | |
| 78 | +|-|-| |
| 79 | +| `reshard` | `syncing schema` → `syncing data` → `finalizing schema` → `replicating` | |
| 80 | +| `copy_data` | (no sub-status; track copy progress with [`SHOW TABLE_COPIES`](../features/sharding/resharding/move.md#monitoring-progress)) | |
| 81 | +| `replication` | `replicating` → `cutting over` (or `rolling back` for a reverse stream) / `stopping` | |
| 82 | +| `schema_sync` | `loading schema` → `syncing tables` → `creating indexes` (or `syncing cutover schema`) | |
| 83 | + |
| 84 | +## Finding the right id |
| 85 | + |
| 86 | +`STOP_TASK` and `CUTOVER` always operate on the **root** `id`: |
| 87 | + |
| 88 | +- A `RESHARD` or `COPY_DATA` shows as a `root` task with its child steps listed as `subtask` rows. Target the root id, not a subtask — subtask rows have an empty `id` on purpose. |
| 89 | +- After a cutover, the [reverse replication](../features/sharding/resharding/cutover.md#after-the-cutover) stream appears as its own `root` task of type `replication ... (reverse)`. Use its id to [roll back](../features/sharding/resharding/cutover.md#rolling-back) (`CUTOVER <id>`) or to [finalize the migration](../features/sharding/resharding/cutover.md#finalizing-the-migration) (`STOP_TASK <id>`). |
| 90 | + |
| 91 | +## Spotting issues |
| 92 | + |
| 93 | +| Symptom | What to check | |
| 94 | +|-|-| |
| 95 | +| `status` is `failed: ...` or `panicked: ...` | Read the error message in the `status` column, then check the PgDog logs for the full context. The task is stopped; address the cause and re-run the command. | |
| 96 | +| Task stuck at one `inner_status` for a long time | Cross-reference [`SHOW TABLE_COPIES`](../features/sharding/resharding/move.md#monitoring-progress) (during `syncing data`) and [`SHOW REPLICATION_SLOTS`](../features/sharding/resharding/move.md#streaming-updates) (during `replicating`) to see whether data is still flowing. | |
| 97 | +| `status` is `cancelling` and not clearing | The task is draining its replication streams. A cutover that has already started runs to completion before the status settles. | |
| 98 | +| Terminal task you expected to still be running | It reached a terminal state (`finished`/`cancelled`/`failed`). Check `inner_status` and `updated_at` to see where and when it stopped. | |
| 99 | + |
| 100 | +## Stopping a task |
| 101 | + |
| 102 | +Stop any running task by its root `id`: |
| 103 | + |
| 104 | +``` |
| 105 | +STOP_TASK <task_id>; |
| 106 | +``` |
| 107 | + |
| 108 | +This requests cancellation; the task winds down gracefully and stops appearing as `running` once it has actually stopped. For replication and copy tasks, a graceful stop also drops the replication slot the task created. See [finalizing the migration](../features/sharding/resharding/cutover.md#finalizing-the-migration) for how this is used after a cutover. |
0 commit comments