|
| 1 | +# ALTER TABLE EXPORT PARTITION |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +The `ALTER TABLE EXPORT PARTITION` command exports entire partitions from Replicated*MergeTree tables to object storage (S3, Azure Blob Storage, etc.), typically in Parquet format. This feature coordinates export part operations across all replicas using ZooKeeper. |
| 6 | + |
| 7 | +Each MergeTree part will become a separate file with the following name convention: `<table_directory>/<partitioning>/<data_part_name>_<merge_tree_part_checksum>.<format>`. To ensure atomicity, a commit file containing the relative paths of all exported parts is also shipped. A data file should only be considered part of the dataset if a commit file references it. The commit file will be named using the following convention: `<table_directory>/commit_<partition_id>_<transaction_id>`. |
| 8 | + |
| 9 | +The set of parts that are exported is based on the list of parts the replica that received the export command sees. The other replicas will assist in the export process if they have those parts locally. Otherwise they will ignore it. |
| 10 | + |
| 11 | +The partition export tasks can be observed through `system.replicated_partition_exports`. Querying this table results in a query to ZooKeeper, so it must be used with care. Individual part export progress can be observed as usual through `system.exports`. |
| 12 | + |
| 13 | +The same partition can not be exported to the same destination more than once. There are two ways to override this behavior: either by setting the `export_merge_tree_partition_force_export` setting or waiting for the task to expire. |
| 14 | + |
| 15 | +The export task can be killed by issuing the kill command: `KILL EXPORT PARTITION <where predicate for system.replicated_partition_exports>`. |
| 16 | + |
| 17 | +The task is persistent - it should be resumed after crashes, failures and etc. |
| 18 | + |
| 19 | +## Syntax |
| 20 | + |
| 21 | +```sql |
| 22 | +ALTER TABLE [database.]table_name |
| 23 | +EXPORT PARTITION ID 'partition_id' |
| 24 | +TO TABLE [destination_database.]destination_table |
| 25 | +[SETTINGS setting_name = value, ...] |
| 26 | +``` |
| 27 | + |
| 28 | +### Parameters |
| 29 | + |
| 30 | +- **`table_name`**: The source Replicated*MergeTree table containing the partition to export |
| 31 | +- **`partition_id`**: The partition identifier to export (e.g., `'2020'`, `'2021'`) |
| 32 | +- **`destination_table`**: The target table for the export (typically an S3, Azure, or other object storage table) |
| 33 | + |
| 34 | +## Settings |
| 35 | + |
| 36 | +### Server Settings |
| 37 | + |
| 38 | +#### `enable_experimental_export_merge_tree_partition_feature` (Required) |
| 39 | + |
| 40 | +- **Type**: `Bool` |
| 41 | +- **Default**: `false` |
| 42 | +- **Description**: Enable export replicated merge tree partition feature. It is experimental and not yet ready for production use. |
| 43 | + |
| 44 | +### Query Settings |
| 45 | + |
| 46 | +#### `export_merge_tree_partition_force_export` (Optional) |
| 47 | + |
| 48 | +- **Type**: `Bool` |
| 49 | +- **Default**: `false` |
| 50 | +- **Description**: Ignore existing partition export and overwrite the ZooKeeper entry. Allows re-exporting a partition to the same destination before the manifest expires. |
| 51 | + |
| 52 | +#### `export_merge_tree_partition_max_retries` (Optional) |
| 53 | + |
| 54 | +- **Type**: `UInt64` |
| 55 | +- **Default**: `3` |
| 56 | +- **Description**: Maximum number of retries for exporting a merge tree part in an export partition task. If it exceeds, the entire task fails. |
| 57 | + |
| 58 | +#### `export_merge_tree_partition_manifest_ttl` (Optional) |
| 59 | + |
| 60 | +- **Type**: `UInt64` |
| 61 | +- **Default**: `180` (seconds) |
| 62 | +- **Description**: Determines how long the manifest will live in ZooKeeper. It prevents the same partition from being exported twice to the same destination. This setting does not affect or delete in-progress tasks; it only cleans up completed ones. |
| 63 | + |
| 64 | +#### `export_merge_tree_part_file_already_exists_policy` (Optional) |
| 65 | + |
| 66 | +- **Type**: `MergeTreePartExportFileAlreadyExistsPolicy` |
| 67 | +- **Default**: `skip` |
| 68 | +- **Description**: Policy for handling files that already exist during export. Possible values: |
| 69 | + - `skip` - Skip the file if it already exists |
| 70 | + - `error` - Throw an error if the file already exists |
| 71 | + - `overwrite` - Overwrite the file |
| 72 | + |
| 73 | +## Examples |
| 74 | + |
| 75 | +### Basic Export to S3 |
| 76 | + |
| 77 | +```sql |
| 78 | +CREATE TABLE rmt_table (id UInt64, year UInt16) |
| 79 | +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{database}/rmt_table', 'replica1') |
| 80 | +PARTITION BY year ORDER BY tuple(); |
| 81 | + |
| 82 | +CREATE TABLE s3_table (id UInt64, year UInt16) |
| 83 | +ENGINE = S3(s3_conn, filename='data', format=Parquet, partition_strategy='hive') |
| 84 | +PARTITION BY year; |
| 85 | + |
| 86 | +INSERT INTO rmt_table VALUES (1, 2020), (2, 2020), (3, 2020), (4, 2021); |
| 87 | + |
| 88 | +ALTER TABLE rmt_table EXPORT PARTITION ID '2020' TO TABLE s3_table; |
| 89 | + |
| 90 | +## Killing Exports |
| 91 | + |
| 92 | +You can cancel in-progress partition exports using the `KILL EXPORT PARTITION` command: |
| 93 | + |
| 94 | +```sql |
| 95 | +KILL EXPORT PARTITION |
| 96 | +WHERE partition_id = '2020' |
| 97 | + AND source_table = 'rmt_table' |
| 98 | + AND destination_table = 's3_table' |
| 99 | +``` |
| 100 | + |
| 101 | +The `WHERE` clause filters exports from the `system.replicated_partition_exports` table. You can use any columns from that table in the filter. |
| 102 | + |
| 103 | +## Monitoring |
| 104 | + |
| 105 | +### Active and Completed Exports |
| 106 | + |
| 107 | +Monitor partition exports using the `system.replicated_partition_exports` table: |
| 108 | + |
| 109 | +```sql |
| 110 | +arthur :) select * from system.replicated_partition_exports Format Vertical; |
| 111 | +
|
| 112 | +SELECT * |
| 113 | +FROM system.replicated_partition_exports |
| 114 | +FORMAT Vertical |
| 115 | +
|
| 116 | +Query id: 9efc271a-a501-44d1-834f-bc4d20156164 |
| 117 | +
|
| 118 | +Row 1: |
| 119 | +────── |
| 120 | +source_database: default |
| 121 | +source_table: replicated_source |
| 122 | +destination_database: default |
| 123 | +destination_table: replicated_destination |
| 124 | +create_time: 2025-11-21 18:21:51 |
| 125 | +partition_id: 2022 |
| 126 | +transaction_id: 7397746091717128192 |
| 127 | +source_replica: r1 |
| 128 | +parts: ['2022_0_0_0','2022_1_1_0','2022_2_2_0'] |
| 129 | +parts_count: 3 |
| 130 | +parts_to_do: 0 |
| 131 | +status: COMPLETED |
| 132 | +exception_replica: |
| 133 | +last_exception: |
| 134 | +exception_part: |
| 135 | +exception_count: 0 |
| 136 | +
|
| 137 | +Row 2: |
| 138 | +────── |
| 139 | +source_database: default |
| 140 | +source_table: replicated_source |
| 141 | +destination_database: default |
| 142 | +destination_table: replicated_destination |
| 143 | +create_time: 2025-11-21 18:20:35 |
| 144 | +partition_id: 2021 |
| 145 | +transaction_id: 7397745772618674176 |
| 146 | +source_replica: r1 |
| 147 | +parts: ['2021_0_0_0'] |
| 148 | +parts_count: 1 |
| 149 | +parts_to_do: 0 |
| 150 | +status: COMPLETED |
| 151 | +exception_replica: |
| 152 | +last_exception: |
| 153 | +exception_part: |
| 154 | +exception_count: 0 |
| 155 | +
|
| 156 | +2 rows in set. Elapsed: 0.019 sec. |
| 157 | +
|
| 158 | +arthur :) |
| 159 | +``` |
| 160 | + |
| 161 | +Status values include: |
| 162 | +- `PENDING` - Export is queued / in progress |
| 163 | +- `COMPLETED` - Export finished successfully |
| 164 | +- `FAILED` - Export failed |
| 165 | +- `KILLED` - Export was cancelled |
| 166 | + |
| 167 | +## Related Features |
| 168 | + |
| 169 | +- [ALTER TABLE EXPORT PART](/docs/en/engines/table-engines/mergetree-family/part_export.md) - Export individual parts (non-replicated) |
| 170 | + |
0 commit comments