From e181b2701e6f5f770eb93db6f59ebf9d409dadff Mon Sep 17 00:00:00 2001 From: Aolin Date: Fri, 2 Dec 2022 22:14:01 +0800 Subject: [PATCH] Refactor br (#11481) --- .gitignore | 1 + TOC.md | 55 +- backup-and-restore-use-cases-for-maintain.md | 474 ---------------- ...up-and-restore-using-dumpling-lightning.md | 2 +- basic-features.md | 2 +- br-usage-backup-for-maintain.md | 216 -------- br-usage-restore-for-maintain.md | 234 -------- br/backup-and-restore-design.md | 85 +-- br/backup-and-restore-faq.md | 237 -------- br/backup-and-restore-overview.md | 159 +++--- br/backup-and-restore-storages.md | 332 ++++++----- br/backup-and-restore-use-cases.md | 522 ++++-------------- br/backup-storage-S3.md | 83 --- br/backup-storage-azblob.md | 155 ------ br/backup-storage-gcs.md | 36 -- br/br-auto-tune.md | 18 +- br/br-batch-create-table.md | 26 +- br/br-deployment.md | 41 -- br/br-incremental-guide.md | 51 ++ br/br-log-architecture.md | 152 +++++ ...nd-alert.md => br-monitoring-and-alert.md} | 44 +- br/br-pitr-guide.md | 133 +++++ ...-log-command-line.md => br-pitr-manual.md} | 123 ++--- br/br-snapshot-architecture.md | 158 ++++++ br/br-snapshot-guide.md | 180 ++++++ br/br-snapshot-manual.md | 228 ++++++++ br/br-usage-backup.md | 216 -------- br/br-usage-restore.md | 234 -------- br/br-use-overview.md | 101 ++++ br/external-storage.md | 237 ++++++++ br/pitr-known-issues.md | 62 --- br/pitr-troubleshoot.md | 81 --- br/pitr-usage.md | 165 ------ br/point-in-time-recovery.md | 131 ----- br/rawkv-backup-and-restore.md | 2 +- br/use-br-command-line-tool.md | 113 ++-- ecosystem-tool-user-case.md | 2 +- ecosystem-tool-user-guide.md | 6 +- faq/backup-and-restore-faq.md | 337 +++++++++++ faq/faq-overview.md | 2 +- faq/manage-cluster-faq.md | 2 +- faq/migration-tidb-faq.md | 4 +- media/br/br-log-arch.png | Bin 81426 -> 83424 bytes media/br/br-log-backup-ts.png | Bin 0 -> 38823 bytes media/br/br-snapshot-arch.png | Bin 0 -> 74071 bytes media/br/br-snapshot-backup-ts.png | Bin 0 -> 32361 bytes media/br/br-snapshot-restore-ts.png | Bin 0 -> 28870 bytes media/br/pitr-ts.png | Bin 0 -> 32289 bytes migrate-from-tidb-to-tidb.md | 4 +- releases/release-5.0.0-rc.md | 4 +- releases/release-5.4.0.md | 2 +- releases/release-6.2.0.md | 10 +- releases/release-6.3.0.md | 4 +- releases/release-6.4.0.md | 4 +- ...-between-primary-and-secondary-clusters.md | 6 +- sql-statements/sql-statement-recover-table.md | 2 +- system-variables.md | 2 +- ticdc/ticdc-faq.md | 4 +- tidb-lightning/tidb-lightning-overview.md | 4 +- tikv-configuration-file.md | 2 +- 60 files changed, 2167 insertions(+), 3323 deletions(-) delete mode 100644 backup-and-restore-use-cases-for-maintain.md delete mode 100644 br-usage-backup-for-maintain.md delete mode 100644 br-usage-restore-for-maintain.md delete mode 100644 br/backup-and-restore-faq.md delete mode 100644 br/backup-storage-S3.md delete mode 100644 br/backup-storage-azblob.md delete mode 100644 br/backup-storage-gcs.md delete mode 100644 br/br-deployment.md create mode 100644 br/br-incremental-guide.md create mode 100644 br/br-log-architecture.md rename br/{pitr-monitoring-and-alert.md => br-monitoring-and-alert.md} (89%) create mode 100644 br/br-pitr-guide.md rename br/{br-log-command-line.md => br-pitr-manual.md} (64%) create mode 100644 br/br-snapshot-architecture.md create mode 100644 br/br-snapshot-guide.md create mode 100644 br/br-snapshot-manual.md delete mode 100644 br/br-usage-backup.md delete mode 100644 br/br-usage-restore.md create mode 100644 br/br-use-overview.md create mode 100644 br/external-storage.md delete mode 100644 br/pitr-known-issues.md delete mode 100644 br/pitr-troubleshoot.md delete mode 100644 br/pitr-usage.md delete mode 100644 br/point-in-time-recovery.md create mode 100644 faq/backup-and-restore-faq.md create mode 100644 media/br/br-log-backup-ts.png create mode 100644 media/br/br-snapshot-arch.png create mode 100644 media/br/br-snapshot-backup-ts.png create mode 100644 media/br/br-snapshot-restore-ts.png create mode 100644 media/br/pitr-ts.png diff --git a/.gitignore b/.gitignore index d29d17d41c85a..bbf3d54d032cc 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .idea/ .vscode/ *.iml +uml/ out gen .DS_Store diff --git a/TOC.md b/TOC.md index acbd41779ae10..5ed2d69963fea 100644 --- a/TOC.md +++ b/TOC.md @@ -135,9 +135,29 @@ - [Use TiUP (Recommended)](/scale-tidb-using-tiup.md) - [Use TiDB Operator](https://docs.pingcap.com/tidb-in-kubernetes/stable/scale-a-tidb-cluster) - Backup and Restore - - [Use BR to Back Up Cluster Data](/br-usage-backup-for-maintain.md) - - [Use BR to Restore Cluster Data](/br-usage-restore-for-maintain.md) - - [BR Use Cases](/backup-and-restore-use-cases-for-maintain.md) + - [Overview](/br/backup-and-restore-overview.md) + - Architecture + - [Architecture Overview](/br/backup-and-restore-design.md) + - [Snapshot Backup and Restore Architecture](/br/br-snapshot-architecture.md) + - [Log Backup and PITR Architecture](/br/br-log-architecture.md) + - Use BR + - [Use Overview](/br/br-use-overview.md) + - [Snapshot Backup and Restore Guide](/br/br-snapshot-guide.md) + - [Log Backup and PITR Guide](/br/br-pitr-guide.md) + - [Use Cases](/br/backup-and-restore-use-cases.md) + - [Backup Storages](/br/backup-and-restore-storages.md) + - BR CLI Manuals + - [Overview](/br/use-br-command-line-tool.md) + - [Snapshot Backup and Restore Command Manual](/br/br-snapshot-manual.md) + - [Log Backup and PITR Command Manual](/br/br-pitr-manual.md) + - References + - BR Features + - [Backup Auto-Tune](/br/br-auto-tune.md) + - [Batch Create Table](/br/br-batch-create-table.md) + - [Back up and Restore Data Using Dumpling and TiDB Lightning](/backup-and-restore-using-dumpling-lightning.md) + - [Back Up and Restore RawKV](/br/rawkv-backup-and-restore.md) + - [Incremental Backup and Restore](/br/br-incremental-guide.md) + - [External Storages](/br/external-storage.md) - [Configure Time Zone](/configure-time-zone.md) - [Daily Checklist](/daily-check.md) - [Maintain TiFlash](/tiflash/maintain-tiflash.md) @@ -153,6 +173,7 @@ - [TiDB Cluster Alert Rules](/alert-rules.md) - [TiFlash Alert Rules](/tiflash/tiflash-alert-rules.md) - [Customize Configurations of Monitoring Servers](/tiup/customized-montior-in-tiup-environment.md) + - [BR Monitoring and Alert](/br/br-monitoring-and-alert.md) - Troubleshoot - [TiDB Troubleshooting Map](/tidb-troubleshooting-map.md) - [Identify Slow Queries](/identify-slow-queries.md) @@ -470,33 +491,6 @@ - [FAQ](/dm/dm-faq.md) - [Handle Errors](/dm/dm-error-handling.md) - [Release Notes](/dm/dm-release-notes.md) - - Backup & Restore (BR) - - [BR Overview](/br/backup-and-restore-overview.md) - - [Deploy and Use BR](/br/br-deployment.md) - - [Use BR to Back Up Cluster Data](/br/br-usage-backup.md) - - [Use BR to Restore Cluster Data](/br/br-usage-restore.md) - - [BR Use Cases](/br/backup-and-restore-use-cases.md) - - BR Features - - [Auto Tune](/br/br-auto-tune.md) - - [Batch Create Table](/br/br-batch-create-table.md) - - [Checkpoint Backup](/br/br-checkpoint.md) - - References - - [BR Design Principles](/br/backup-and-restore-design.md) - - [BR Command-line](/br/use-br-command-line-tool.md) - - [External Storages](/br/backup-and-restore-storages.md) - - [Back Up and Restore Data on Amazon S3 Using BR](/br/backup-storage-S3.md) - - [Back Up and Restore Data on Azure Blob Storage Using BR](/br/backup-storage-azblob.md) - - [Back Up and Restore Data on Google Cloud Storage Using BR](/br/backup-storage-gcs.md) - - [Back Up and Restore RawKV](/br/rawkv-backup-and-restore.md) - - [Back up and Restore Data Using Dumpling and TiDB Lightning](/backup-and-restore-using-dumpling-lightning.md) - - [BR FAQs](/br/backup-and-restore-faq.md) - - Point-in-Time Recovery - - [PITR Overview](/br/point-in-time-recovery.md) - - [Use PITR via CLI](/br/br-log-command-line.md) - - [Usage Scenarios](/br/pitr-usage.md) - - [Monitoring and Alert](/br/pitr-monitoring-and-alert.md) - - [Troubleshooting](/br/pitr-troubleshoot.md) - - [Known Issues](/br/pitr-known-issues.md) - TiDB Binlog - [Overview](/tidb-binlog/tidb-binlog-overview.md) - [Quick Start](/tidb-binlog/get-started-with-tidb-binlog.md) @@ -896,6 +890,7 @@ - [Cluster Management FAQs](/faq/manage-cluster-faq.md) - [High Availability FAQs](/faq/high-availability-faq.md) - [High Reliability FAQs](/faq/high-reliability-faq.md) + - [Backup and Restore FAQs](/faq/backup-and-restore-faq.md) - Release Notes - [All Releases](/releases/release-notes.md) - [Release Timeline](/releases/release-timeline.md) diff --git a/backup-and-restore-use-cases-for-maintain.md b/backup-and-restore-use-cases-for-maintain.md deleted file mode 100644 index 8699c421bbf24..0000000000000 --- a/backup-and-restore-use-cases-for-maintain.md +++ /dev/null @@ -1,474 +0,0 @@ ---- -title: BR Use Cases -summary: Learn the use cases of backing up and restoring data using BR. ---- - -# BR Use Cases - -[Backup & Restore (BR)](/br/backup-and-restore-overview.md) is a tool for distributed backup and restoration of the TiDB cluster data. - -This document describes common backup and restoration scenarios: - -- [Back up a single table to a network disk (recommended for production environments)](#back-up-a-single-table-to-a-network-disk-recommended-for-production-environments) -- [Restore data from a network disk (recommended for production environments)](#restore-data-from-a-network-disk-recommended-for-production-environments) -- [Back up a single table to a local disk](#back-up-a-single-table-to-a-local-disk-recommended-for-testing-environments) -- [Restore data from a local disk](#restore-data-from-a-local-disk-recommended-for-testing-environments) - -This document aims to help you achieve the following goals: - -- Back up and restore data using a network disk or local disk correctly. -- Get the status of a backup or restoration operation through monitoring metrics. -- Learn how to tune performance during the backup or restoration operation. -- Troubleshoot the possible anomalies during the backup operation. - -## Audience - -You are expected to have a basic understanding of TiDB and [TiKV](https://tikv.org/). - -Before reading on, make sure you have read [BR Overview](/br/backup-and-restore-overview.md), especially [Usage Restrictions](/br/backup-and-restore-overview.md#usage-restrictions) and [Some tips](/br/backup-and-restore-overview.md#some-tips). - -## Prerequisites - -This section introduces the recommended method of deploying TiDB, cluster versions, the hardware information of the TiKV cluster, and the cluster configuration for the use case demonstrations. - -You can estimate the performance of your backup or restoration operation based on your own hardware and configuration. It is recommended that you use a network disk to back up and restore data. This spares you from collecting backup files and greatly improves the backup efficiency especially when the TiKV cluster is in a large scale. - -### Deployment method - -It is recommended that you deploy the TiDB cluster using [TiUP](/tiup/tiup-cluster.md) and install BR using TiUP. - -### Cluster versions - -- TiDB: v6.4.0 -- TiKV: v6.4.0 -- PD: v6.4.0 -- BR: v6.4.0 - -> **Note:** -> -> It is recommended that you use the latest version of [TiDB/TiKV/PD/BR](/releases/release-notes.md) and make sure that the BR version is **consistent with** the TiDB version. - -### TiKV hardware information - -- Operating system: CentOS Linux release 7.6.1810 (Core) -- CPU: 16-Core Common KVM processor -- RAM: 32 GB -- Disk: 500 GB SSD * 2 -- NIC: 10 Gigabit network card - -### Cluster configuration - -BR directly sends commands to the TiKV cluster and are not dependent on the TiDB server, so you do not need to configure the TiDB server when using BR. - -- TiKV: default configuration -- PD: default configuration - -### Others - -In addition to the preceding prerequisites, you should also perform the following checks before performing the backup and restoration. - -#### Check before backup - -Before running the [`br backup` command](/br/use-br-command-line-tool.md#br-command-line-description), make sure the following conditions are met: - -- No DDL statements are running on the TiDB cluster. -- The target storage device has required space (no less than 1/3 of the disk space of the backup cluster). - -#### Check before restoration - -Before running the [`br restore` command](/br/use-br-command-line-tool.md#br-command-line-description), check the target cluster to ensure that the table in this cluster does not have a duplicate name. - -## Back up a single table to a network disk (recommended for production environments) - -Run the `br backup` command to back up the single table data `--db batchmark --table order_line` to the specified path `local:///br_data` in the network disk. - -### Backup prerequisites - -- [Check before backup](#check-before-backup) -- Configure a high-performance SSD hard disk host as the NFS server to store data, and all BR nodes, TiKV nodes, and TiFlash nodes as NFS clients. Mount the same path (for example, `/br_data`) to the NFS server for NFS clients to access the server. -- The total transfer rate between the NFS server and all NFS clients must reach at least `the number of TiKV instances * 150MB/s`. Otherwise, the network I/O might become the performance bottleneck. - -> **Note:** -> -> - During data backup, because only the data of leader replicas are backed up, even if there is a TiFlash replica in the cluster, BR can complete the backup without mounting TiFlash nodes. -> - When restoring data, BR will restore the data of all replicas. Also, TiFlash nodes need access to the backup data for BR to complete the restore. Therefore, before the restore, you must mount TiFlash nodes to the NFS server. - -### Topology - -The following diagram shows the typology of BR: - -![img](/media/br/backup-nfs-deploy.png) - -### Backup operation - -Run the `br backup` command: - -{{< copyable "shell-regular" >}} - -```shell -bin/br backup table \ - --db batchmark \ - --table order_line \ - -s local:///br_data \ - --pd ${PD_ADDR}:2379 \ - --log-file backup-nfs.log -``` - -### Monitoring metrics for the backup - -During the backup process, pay attention to the following metrics on the monitoring panels to get the status of the backup process. - -**Backup CPU Utilization**: the CPU usage rate of each working TiKV node in the backup operation (for example, backup-worker and backup-endpoint). - -![img](/media/br/backup-cpu.png) - -**IO Utilization**: the I/O usage rate of each working TiKV node in the backup operation. - -![img](/media/br/backup-io.png) - -**BackupSST Generation Throughput**: the backupSST generation throughput of each working TiKV node in the backup operation, which is normally around 150 MB/s. - -![img](/media/br/backup-throughput.png) - -**One Backup Range Duration**: the duration of backing up a range, which is the total time cost of scanning KVs and storing the range as the backupSST file. - -![img](/media/br/backup-range-duration.png) - -**One Backup Subtask Duration**: the duration of each sub-task into which a backup task is divided. - -> **Note:** -> -> - In this task, the single table to be backed up has three indexes and the task is normally divided into four sub-tasks. -> - The panel in the following image has 20 points on it, 10 blue and 10 yellow, indicating that there are 10 sub-tasks. Region scheduling might occur during the backup process, so a few retries is normal. - -![img](/media/br/backup-subtask-duration.png) - -**Backup Errors**: the errors occurred during the backup process. No error occurs in normal situations. Even if a few errors occur, the backup operation has the retry mechanism which might increase the backup time but does not affect the operation correctness. - -![img](/media/br/backup-errors.png) - -**Checksum Request Duration**: the duration of the admin checksum request in the backup cluster. - -![img](/media/br/checksum-duration.png) - -### Backup results explanation - -When finishing the backup, BR outputs the backup summary to the console. - -In the log specified before running the backup command, you can get the statistical information of the backup operation from this log. Search "summary" in this log, you can see the following information: - -``` -["Full backup Success summary: - total backup ranges: 2, - total success: 2, - total failed: 0, - total take(Full backup time): 31.802912166s, - total take(real time): 49.799662427s, - total size(MB): 5997.49, - avg speed(MB/s): 188.58, - total kv: 120000000"] - ["backup checksum"=17.907153678s] - ["backup fast checksum"=349.333µs] - ["backup total regions"=43] - [BackupTS=422618409346269185] - [Size=826765915] -``` - -The preceding log includes the following information: - -- `total take(Full backup time)`: Backup duration -- `total take(real time)`: Total runtime of the application -- `total size(MB)`: The size of the backup data -- `avg speed(MB/s)`: Backup throughput -- `total kv`: The number of backed-up KV pairs -- `backup checksum`: Backup checksum duration -- `backup fast checksum`: The total duration of calculating the checksum, KV pairs, and bytes of each table -- `backup total regions`: The total number of backup Regions -- `BackupTS`: The snapshot timestamp of the backup data -- `Size`: The actual size of the backup data in the disk after compression - -From the preceding information, the throughput of a single TiKV instance can be calculated: `avg speed(MB/s)`/`tikv_count` = `62.86`. - -### Performance tuning - -If the resource usage of TiKV does not become an obvious bottleneck during the backup process (for example, in the [Monitoring metrics for the backup](#monitoring-metrics-for-the-backup), the highest CPU usage rate of backup-worker is around `1500%` and the overall I/O usage rate is below `30%`), you can try to increase the value of `--concurrency` (`4` by default) to tune the performance. But this performance tuning method is not suitable for the use cases of many small tables. See the following example: - -{{< copyable "shell-regular" >}} - -```shell -bin/br backup table \ - --db batchmark \ - --table order_line \ - -s local:///br_data/ \ - --pd ${PD_ADDR}:2379 \ - --log-file backup-nfs.log \ - --concurrency 16 -``` - -![img](/media/br/backup-diff.png) - -![img](/media/br/backup-diff2.png) - -The tuned performance results are as follows (with the same data size): - -- Backup duration (`total take(s)`): reduced from `986.43` to `535.53` -- Backup throughput (`avg speed(MB/s)`): increased from `358.09` to `659.59` -- Throughput of a single TiKV instance (`avg speed(MB/s)/tikv_count`): increased from `89` to `164.89` - -## Restore data from a network disk (recommended for production environments) - -Use the `br restore` command to restore the complete backup data to an offline cluster. Currently, BR does not support restoring data to an online cluster. - -### Restoration prerequisites - -- [Check before restore](#check-before-restoration) - -### Topology - -The following diagram shows the typology of BR: - -![img](/media/br/restore-nfs-deploy.png) - -### Restoration operation - -Run the `br restore` command: - -{{< copyable "shell-regular" >}} - -```shell -bin/br restore table --db batchmark --table order_line -s local:///br_data --pd 172.16.5.198:2379 --log-file restore-nfs.log -``` - -### Monitoring metrics for the restoration - -During the restoration process, pay attention to the following metrics on the monitoring panels to get the status of the restoration process. - -**CPU**: the CPU usage rate of each working TiKV node in the restoration operation. - -![img](/media/br/restore-cpu.png) - -**IO Utilization**: the I/O usage rate of each working TiKV node in the restoration operation. - -![img](/media/br/restore-io.png) - -**Region**: the Region distribution. The more even Regions are distributed, the better the restoration resources are used. - -![img](/media/br/restore-region.png) - -**Process SST Duration**: the delay of processing the SST files. When restoring a table, if `tableID` is changed, you need to rewrite `tableID`. Otherwise, `tableID` is renamed. Generally, the delay of rewriting is longer than that of renaming. - -![img](/media/br/restore-process-sst.png) - -**DownLoad SST Throughput**: the throughput of downloading SST files from External Storage. - -![img](/media/br/restore-download-sst.png) - -**Restore Errors**: the errors occurred during the restoration process. - -![img](/media/br/restore-errors.png) - -**Checksum Request Duration**: the duration of the admin checksum request. This duration for the restoration is longer than that for the backup. - -![img](/media/br/restore-checksum.png) - -### Restoration results explanation - -In the log specified before running the restoration command, you can get the statistical information of the restoration operation from this log. Search "summary" in this log, you can see the following information: - -``` -["Table Restore summary: - total restore tables: 1, - total success: 1, - total failed: 0, - total take(Full restore time): 17m1.001611365s, - total take(real time): 16m1.371611365s, - total kv: 5659888624, - total size(MB): 353227.18, - avg speed(MB/s): 367.42"] - ["restore files"=9263] - ["restore ranges"=6888] - ["split region"=49.049182743s] - ["restore checksum"=6m34.879439498s] - [Size=48693068713] -``` - -The preceding log includes the following information: - -- `total take(Full restore time)`: The restoration duration -- `total take(real time)`: The total runtime of the application -- `total size(MB)`: The size of the data to be restored -- `total kv`: The number of restored KV pairs -- `avg speed(MB/s)`: The restoration throughput -- `split region`: The Region split duration -- `restore checksum`: The restoration checksum duration -- `Size`: The actual size of the restored data in the disk - -From the preceding information, the following items can be calculated: - -- The throughput of a single TiKV instance: `avg speed(MB/s)`/`tikv_count` = `91.8` -- The average restore speed of a single TiKV instance: `total size(MB)`/(`split time` + `restore time`)/`tikv_count` = `87.4` - -#### Performance tuning - -If the resource usage of TiKV does not become an obvious bottleneck during the restore process, you can increase the value of `--concurrency` (defaults to `128`). See the following example: - -{{< copyable "shell-regular" >}} - -```shell -bin/br restore table --db batchmark --table order_line -s local:///br_data/ --pd 172.16.5.198:2379 --log-file restore-concurrency.log --concurrency 1024 -``` - -The tuned performance results are as follows (with the same data size): - -- Restoration duration (`total take(s)`): reduced from `961.37` to `443.49` -- Restoration throughput (`avg speed(MB/s)`): increased from `367.42` to `796.47` -- Throughput of a single TiKV instance (`avg speed(MB/s)`/`tikv_count`): increased from `91.8` to `199.1` -- Average restore speed of a single TiKV instance (`total size(MB)`/(`split time` + `restore time`)/`tikv_count`): increased from `87.4` to `162.3` - -## Back up a single table to a local disk (recommended for testing environments) - -Run the `br backup` command to back up a single table `--db batchmark --table order_line` to the specified path `local:///home/tidb/backup_local` in the local disk. - -### Backup prerequisites - -* [Check before backup](#check-before-backup) -* Each TiKV node has a separate disk to store backupSST files. -* The `backup_endpoint` node has a separate disk to store `backupmeta` files. -* TiKV and the `backup_endpoint` node share the same directory (for example, `/home/tidb/backup_local`) for backup. - -### Topology - -The following diagram shows the typology of BR: - -![img](/media/br/backup-local-deploy.png) - -### Backup operation - -Run the `br backup` command: - -{{< copyable "shell-regular" >}} - -```shell -bin/br backup table \ - --db batchmark \ - --table order_line \ - -s local:///home/tidb/backup_local/ \ - --pd ${PD_ADDR}:2379 \ - --log-file backup_local.log -``` - -During the backup process, pay attention to the metrics on the monitoring panels to get the status of the backup process. See [Monitoring metrics for the backup](#monitoring-metrics-for-the-backup) for details. - -#### Backup results explanation - -In the log specified before running the backup command, you can get the statistical information of the restoration operation from this log. Search "summary" in this log, you can see the following information: - -``` -["Table backup summary: - total backup ranges: 4, - total success: 4, - total failed: 0, - total take(s): 551.31, - total kv: 5659888624, - total size(MB): 353227.18, - avg speed(MB/s): 640.71"] - ["backup total regions"=6795] - ["backup checksum"=6m33.962719217s] - ["backup fast checksum"=22.995552ms] -``` - -The preceding log includes the following information: - -- `total take(s)`: The backup duration -- `total size(MB)`: The data size -- `avg speed(MB/s)`: The backup throughput -- `backup checksum`: The backup checksum duration - -From the preceding information, the throughput of a single TiKV instance can be calculated: `avg speed(MB/s)`/`tikv_count` = `160`. - -## Restore data from a local disk (recommended for testing environments) - -Run the `br restore` command to restore the complete backup data to an offline cluster. Currently, BR does not support restoring data to an online cluster. - -### Restoration prerequisites - -- [Check before restore](#check-before-restoration) -- The TiKV cluster and the backup data do not have a duplicate database or table. Currently, BR does not support table route. -- Each TiKV node has a separate disk to store backupSST files. -- The `restore_endpoint` node has a separate disk to store `backupmeta` files. -- TiKV and the `restore_endpoint` node share the same directory (for example, `/home/tidb/backup_local/`) for restoration. - -Before the restoration, follow these steps: - -1. Collect all backupSST files into the same directory. -2. Copy the collected backupSST files to all TiKV nodes of the cluster. -3. Copy the `backupmeta` files to the `restore endpoint` node. - -### Topology - -The following diagram shows the typology of BR: - -![img](/media/br/restore-local-deploy.png) - -### Restoration operation - -Run the `br restore` command: - -{{< copyable "shell-regular" >}} - -```shell -bin/br restore table --db batchmark --table order_line -s local:///home/tidb/backup_local/ --pd 172.16.5.198:2379 --log-file restore_local.log -``` - -During the restoration process, pay attention to the metrics on the monitoring panels to get the status of the restoration process. See [Monitoring metrics for the restoration](#monitoring-metrics-for-the-restoration) for details. - -### Restoration results explanation - -In the log specified before running the restoration command, you can get the statistical information of the restoration operation from this log. Search "summary" in this log, you can see the following information: - -``` -["Table Restore summary: - total restore tables: 1, - total success: 1, - total failed: 0, - total take(s): 908.42, - total kv: 5659888624, - total size(MB): 353227.18, - avg speed(MB/s): 388.84"] - ["restore files"=9263] - ["restore ranges"=6888] - ["split region"=58.7885518s] - ["restore checksum"=6m19.349067937s] -``` - -The preceding log includes the following information: - -- `total take(s)`: The restoration duration -- `total size(MB)`: The data size -- `avg speed(MB/s)`: The restoration throughput -- `split region`: The region split duration -- `restore checksum`: The restoration checksum duration - -From the preceding information, the following items can be calculated: - -- The throughput of a single TiKV instance: `avg speed(MB/s)`/`tikv_count` = `97.2` -- The average restoration speed of a single TiKV instance: `total size(MB)`/(`split time` + `restore time`)/`tikv_count` = `92.4` - -## Error handling during backup - -This section introduces the common errors that might occur during the backup process. - -### `key locked Error` in the backup log - -Error message in the log: `log - ["backup occur kv error"][error="{\"KvError\":{\"locked\":` - -If a key is locked during the backup process, BR tries to resolve the lock. A small number of this error do not affect the correctness of the backup. - -### Backup failure - -Error message in the log: `log - Error: msg:"Io(Custom { kind: AlreadyExists, error: \"[5_5359_42_123_default.sst] is already exists in /dir/backup_local/\" })"` - -If the backup operation fails and the preceding message occurs, perform one of the following operations and then start the backup operation again: - -- Change the directory for the backup. For example, change `/dir/backup-2020-01-01/` to `/dir/backup_local/`. -- Delete the backup directory of all TiKV nodes and BR nodes. diff --git a/backup-and-restore-using-dumpling-lightning.md b/backup-and-restore-using-dumpling-lightning.md index d593ab880dc4f..a48dd2e8c8f76 100644 --- a/backup-and-restore-using-dumpling-lightning.md +++ b/backup-and-restore-using-dumpling-lightning.md @@ -7,7 +7,7 @@ summary: Learn how to use Dumpling and TiDB Lightning to back up and restore ful This document introduces how to use Dumpling and TiDB Lightning to back up and restore full data of TiDB. -If you need to back up a small amount of data (for example, less than 50 GB) and do not require high backup speed, you can use [Dumpling](/dumpling-overview.md) to export data from the TiDB database and then use [TiDB Lightning](/tidb-lightning/tidb-lightning-overview.md) to import the data into another TiDB database. For more information about backup and restore, see [Use BR to Back Up Cluster Data](/br/br-usage-backup.md) and [Use BR to Restore Cluster Data](/br/br-usage-restore.md). +If you need to back up a small amount of data (for example, less than 50 GB) and do not require high backup speed, you can use [Dumpling](/dumpling-overview.md) to export data from the TiDB database and then use [TiDB Lightning](/tidb-lightning/tidb-lightning-overview.md) to import the data into another TiDB database. For more information about backup and restore, see [TiDB Backup & Restore Overview](/br/backup-and-restore-overview.md). ## Requirements diff --git a/basic-features.md b/basic-features.md index ca7f1ee83ad66..df0d051af41d4 100644 --- a/basic-features.md +++ b/basic-features.md @@ -190,7 +190,7 @@ This document lists the features supported in each TiDB version. Note that suppo | [DM WebUI](/dm/dm-webui-guide.md) | Experimental| Experimental | Experimental| Experimental | Experimental | N | N | N | N | N | N | | [Foreground Quota Limiter](/tikv-configuration-file.md#foreground-quota-limiter) | Y | Y | Y| Experimental | Experimental | N | N | N | N | N | N | | [EBS volume snapshot backup and restore](https://docs.pingcap.com/tidb-in-kubernetes/v1.4/backup-to-aws-s3-by-snapshot) | Y | N | N | N | N | N | N | N | N | N | N | -| [PITR](/br/point-in-time-recovery.md) | Y | Y | Y | N | N | N | N | N | N | N | N | +| [PITR](/br/backup-and-restore-overview.md) | Y | Y | Y | N | N | N | N | N | N | N | N | [^1]: TiDB incorrectly treats latin1 as a subset of utf8. See [TiDB #18955](https://github.com/pingcap/tidb/issues/18955) for more details. diff --git a/br-usage-backup-for-maintain.md b/br-usage-backup-for-maintain.md deleted file mode 100644 index 69d7b43f8c595..0000000000000 --- a/br-usage-backup-for-maintain.md +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: Use BR to Back Up Cluster Data -summary: Learn how to back up data using BR commands ---- - -# Use BR to Back Up Cluster Data - -This document describes how to back up TiDB cluster data in the following scenarios: - -- [Back up TiDB cluster snapshots](#back-up-tidb-cluster-snapshots) -- [Back up a database](#back-up-a-database) -- [Back up a table](#back-up-a-table) -- [Back up multiple tables with table filter](#back-up-multiple-tables-with-table-filter) -- [Back up data to external storage](#back-up-data-to-external-storage) -- [Back up incremental data](#back-up-incremental-data) -- [Encrypt backup data](#encrypt-backup-data) - -If you are not familiar with the backup and restore tools, it is recommended that you read the following documents to fully understand usage principles and methods of these tools: - -- [BR Overview](/br/backup-and-restore-overview.md) -- [Use BR Command-line for Backup and Restoration](/br/use-br-command-line-tool.md) - -If you need to back up a small amount of data (for example, less than 50 GB) and do not require high backup speed, you can use Dumpling to export data to implement backup. For detailed backup operations, see [Use Dumpling to back up full data](/backup-and-restore-using-dumpling-lightning.md#use-dumpling-to-back-up-full-data). - -## Back up TiDB cluster snapshots - -A snapshot of a TiDB cluster contains only the latest and transactionally consistent data at a specific time. You can back up the latest or specified snapshot data of a TiDB cluster by running the `br backup full` command. To get help on this command, run the `br backup full --help` command. - -Example: Back up the snapshot generated at `2022-01-30 07:42:23` to the `2022-01-30/` directory in the `backup-data` bucket of Amazon S3. - -{{< copyable "shell-regular" >}} - -```shell -br backup full \ - --pd "${PDIP}:2379" \ - --backupts '2022-01-30 07:42:23' \ - --storage "s3://backup-data/2022-01-30/" \ - --ratelimit 128 \ - --log-file backupfull.log -``` - -In the preceding command: - -- `--backupts`: The physical time of the snapshot. If data of this snapshot is processed by Garbage Collection (GC), the `br backup` command will exit with an error. If you leave this parameter unspecified, BR picks the snapshot corresponding to the backup start time. -- `--ratelimit`: The maximum speed **per TiKV** performing backup tasks (in MiB/s). -- `--log-file`: The target file for BR logging. - -During backup, a progress bar is displayed in the terminal, as shown below. When the progress bar advances to 100%, the backup is complete. - -```shell -br backup full \ - --pd "${PDIP}:2379" \ - --storage "s3://backup-data/2022-01-30/" \ - --ratelimit 128 \ - --log-file backupfull.log -Full Backup <---------/................................................> 17.12%. -``` - -After the backup is completed, BR compares the checksum of the backup data with the [admin checksum table](/sql-statements/sql-statement-admin-checksum-table.md) of the cluster to ensure data correctness and security. - -## Back up a database or a table - -BR supports backing up partial data of a specified database or table from a cluster snapshot or incremental data backup. This feature allows you to filter out unwanted data from snapshot backup and incremental data backup, and back up only business-critical data. - -### Back up a database - -To back up a database in a cluster, run the `br backup db` command. To get help on this command, run the `br backup db --help` command. - -Example: Back up the `test` database to the `db-test/2022-01-30/` directory in the `backup-data` bucket of Amazon S3. - -{{< copyable "shell-regular" >}} - -```shell -br backup db \ - --pd "${PDIP}:2379" \ - --db test \ - --storage "s3://backup-data/db-test/2022-01-30/" \ - --ratelimit 128 \ - --log-file backuptable.log -``` - -In the preceding command, `--db` specifies the database name, and other parameters are the same as those in [Back up TiDB cluster snapshots](#back-up-tidb-cluster-snapshots). - -### Back up a table - -To back up a table in a cluster, run the `br backup table` command. To get help on this command, run the `br backup table --help` command. - -Example: Back up `test.usertable` to the `table-db-usertable/2022-01-30/` directory in the `backup-data` bucket of Amazon S3. - -{{< copyable "shell-regular" >}} - -```shell -br backup table \ - --pd "${PDIP}:2379" \ - --db test \ - --table usertable \ - --storage "s3://backup-data/table-db-usertable/2022-01-30/" \ - --ratelimit 128 \ - --log-file backuptable.log -``` - -In the preceding command, `--db` and `--table` specify the database name and table name respectively, and other parameters are the same as those in [Back up TiDB cluster snapshots](#back-up-tidb-cluster-snapshots). - -### Back up multiple tables with table filter - -To back up multiple tables with more criteria, run the `br backup full` command and specify the [table filters](/table-filter.md) with `--filter` or `-f`. - -Example: Back up `db*.tbl*` data of a table to the `table-filter/2022-01-30/` directory in the `backup-data` bucket of Amazon S3. - -{{< copyable "shell-regular" >}} - -```shell -br backup full \ - --pd "${PDIP}:2379" \ - --filter 'db*.tbl*' \ - --storage "s3://backup-data/table-filter/2022-01-30/" \ - --ratelimit 128 \ - --log-file backupfull.log -``` - -## Back up data to external storage - -BR supports backing up data to Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, NFS, or other S3-compatible file storage services. For details, see the following documents: - -- [Back up data on Amazon S3 using BR](/br/backup-storage-S3.md) -- [Back up data on Google Cloud Storage using BR](/br/backup-storage-gcs.md) -- [Back up data on Azure Blob Storage using BR](/br/backup-storage-azblob.md) - -## Back up incremental data - -> **Warning:** -> -> This is still an experimental feature. It is **NOT** recommended that you use it in the production environment. - -Incremental data of a TiDB cluster is differentiated data between the snapshot of a starting point and that of an end point. Compared with snapshot data, incremental data is smaller and therefore it is a supplementary to snapshot backup, which reduces the volume of backup data. - -To back up incremental data, run the `br backup` command with **the last backup timestamp** `--lastbackupts` specified. To get `--lastbackupts`, run the `validate` command. The following is an example: - -{{< copyable "shell-regular" >}} - -```shell -LAST_BACKUP_TS=`br validate decode --field="end-version" -s s3://backup-data/2022-01-30/ | tail -n1` -``` - -> **Note:** -> -> - You need to save the incremental backup data under a different path from the previous snapshot backup. -> - GC safepoint must be prior to `lastbackupts`. The defalt GC lifetime is 10 minutes in TiDB, which means that TiDB only backs up incremental data generated in the last 10 minutes. To back up earlier incremental data, you need to [adjust TiDB GC Lifetime setting](/system-variables.md#tidb_gc_life_time-new-in-v50). - -{{< copyable "shell-regular" >}} - -```shell -br backup full\ - --pd ${PDIP}:2379 \ - --ratelimit 128 \ - --storage "s3://backup-data/2022-01-30/incr" \ - --lastbackupts ${LAST_BACKUP_TS} -``` - -The preceding command backs up the incremental data between `(LAST_BACKUP_TS, current PD timestamp]` and the DDLs generated during this time period. When restoring incremental data, BR restores all DDLs first, and then restores data. - -## Encrypt backup data - -> **Warning:** -> -> This is still an experimental feature. It is **NOT** recommended that you use it in the production environment. - -BR supports encrypting backup data at the backup end and at the storage end when backing up to Amazon S3. You can choose either encryption method as required. - -### Encrypt backup data at the backup end - -Since TiDB v5.3.0, you can encrypt backup data by configuring the following parameters: - -- `--crypter.method`: Encryption algorithm, which can be `aes128-ctr`, `aes192-ctr`, or `aes256-ctr`. The default value is `plaintext`, indicating that data is not encrypted. -- `--crypter.key`: Encryption key in hexadecimal string format. It is a 128-bit (16 bytes) key for the algorithm `aes128-ctr`, 24-byte key for the algorithm `aes192-ctr`, and 32-byte key for the algorithm `aes256-ctr`. -- `--crypter.key-file`: The key file. You can directly pass in the file path where the key is stored as a parameter without passing in "crypter.key". - -Example: Encrypt backup data at the backup end. - -{{< copyable "shell-regular" >}} - -```shell -br backup full\ - --pd ${PDIP}:2379 \ - --storage "s3://backup-data/2022-01-30/" \ - --crypter.method aes128-ctr \ - --crypter.key 0123456789abcdef0123456789abcdef -``` - -> **Note:** -> -> - If the key is lost, the backup data cannot be restored to the cluster. -> - The encryption feature needs to be used on BR tools and TiDB clusters v5.3.0 or later versions. The encrypted backup data cannot be restored on clusters earlier than v5.3.0. - -### Encrypt backup data when backing up to Amazon S3 - -BR supports server-side encryption (SSE) when backing up data to S3. In this scenario, you can use AWS KMS keys you have created to encrypt data. For details, see [BR S3 server-side encryption](/encryption-at-rest.md#br-s3-server-side-encryption). - -## Backup performance and impact - -The backup feature has some impact on cluster performance (transaction latency and QPS). However, you can mitigate the impact by adjusting the number of backup threads [`backup.num-threads`](/tikv-configuration-file.md#num-threads-1) or by adding more clusters. - -To illustrate the impact of backup, this document lists the test conclusions of several snapshot backup tests: - -- (5.3.0 and earlier) When the backup threads of BR on a TiKV node takes up 75% of the total CPU of the node, the QPS is reduced by 30% of the original QPS. -- (5.4.0 and later) When there are no more than `8` threads of BR on a TiKV node and the cluster's total CPU utilization does not exceed 80%, the impact of BR tasks on the cluster (write and read) is 20% at most. -- (5.4.0 and later) When there are no more than `8` threads of BR on a TiKV node and the cluster's total CPU utilization does not exceed 75%, the impact of BR tasks on the cluster (write and read) is 10% at most. -- (5.4.0 and later) When there are no more than `8` threads of BR on a TiKV node and the cluster's total CPU utilization does not exceed 60%, BR tasks has little impact on the cluster (write and read). - -You can mitigate impact on cluster performance by reducing the number of backup threads. However, this might cause backup performance to deteriorate. Based on the preceding test results: (On a single TiKV node) the backup speed is proportional to the number of backup threads. When the number of threads is small, the backup speed is about 20 MB/thread. For example, a single node with 5 backup threads can deliver a backup speed of 100 MB/s. - -> **Note:** -> -> The impact and speed of backup depends much on cluser configuration, deployment, and running services. The preceding test conclusions, based on simulation tests in many scenarios and verified in some customer sites, are worthy of reference. However, the exact impact and performance cap may vary depending on the scenarios. Therefore, you should always run the test and verify the test results. - - Since v5.3.0, BR introduces the auto tunning feature (enabled by default) to adjust the number of backup threads. It can maintain the CPU utilization of the cluster below 80% during backup tasks. For details, see [BR Auto-Tune](/br/br-auto-tune.md). diff --git a/br-usage-restore-for-maintain.md b/br-usage-restore-for-maintain.md deleted file mode 100644 index 678a1861e8b82..0000000000000 --- a/br-usage-restore-for-maintain.md +++ /dev/null @@ -1,234 +0,0 @@ ---- -title: Use BR to Restore Cluster Data -summary: Learn how to restore data using BR commands ---- - -# Use BR to Restore Cluster Data - -This document describes how to restore TiDB cluster data in the following scenarios: - -- [Restore TiDB cluster snapshots](#restore-tidb-cluster-snapshots) -- [Restore a database](#restore-a-database) -- [Restore a table](#restore-a-table) -- [Restore multiple tables with table filter](#restore-multiple-tables-with-table-filter) -- [Restore backup data from external storage](#restore-backup-data-from-external-storage) -- [Restore incremental data](#restore-incremental-data) -- [Restore encrypted backup data](#restore-encrypted-backup-data) -- [Restore tables in the `mysql` schema](#restore-tables-in-the-mysql-schema) - -If you are not familiar with backup and restore tools, it is recommended that you read the following documents to fully understand usage principles and methods of these tools: - -- [BR Overview](/br/backup-and-restore-overview.md) -- [Use BR Command-line for Backup and Restoration](/br/use-br-command-line-tool.md) - -If you need to restore data exported by Dumpling, CSV files, or Apache Parquet files generated by Amazon Aurora, you can use TiDB Lightning to import data to implement restore. For details, see [Use TiDB Lightning to restore full data](/backup-and-restore-using-dumpling-lightning.md#use-tidb-lightning-to-restore-full-data). - -## Restore TiDB cluster snapshots - -BR supports restoring snapshot backup on an empty cluster to restore the target cluster to the latest state when the snapshot is backed up. - -Example: Restore the snapshot generated at `2022-01-30 07:42:23` from the `2022-01-30/` directory in the `backup-data` bucket of Amazon S3 to the target cluster. - -{{< copyable "shell-regular" >}} - -```shell -br restore full \ - --pd "${PDIP}:2379" \ - --storage "s3://backup-data/2022-01-30/" \ - --ratelimit 128 \ - --log-file restorefull.log -``` - -In the preceding command, - -- `--ratelimit`: The maximum speed for **each TiKV** to perform a restoration task (unit: MiB/s) -- `--log-file` The target file for BR logging - -During restoration, a progress bar is displayed in the terminal, as shown below. When the progress bar advances to 100%, the restoration is complete. To ensure data security, BR performs a check on the restored data. - -```shell -br restore full \ - --pd "${PDIP}:2379" \ - --storage "s3://backup-data/2022-01-30/" \ - --ratelimit 128 \ - --log-file restorefull.log -Full Restore <---------/...............................................> 17.12%. -``` - -## Restore a database or a table - -BR supports restoring partial data of a specified database or table from backup data. This feature allows you to filter out unwanted data and back up only a specific database or table. - -### Restore a database - -To restore a database to the cluster, run the `br restore db` command. To get help on this command, run the `br restore db --help` command. - -Example: Restore the `test` database from the `db-test/2022-01-30/` directory in the `backup-data` bucket of Amazon S3 to the target cluster. - -{{< copyable "shell-regular" >}} - -```shell -br restore db \ - --pd "${PDIP}:2379" \ - --db "test" \ - --ratelimit 128 \ - --storage "s3://backup-data/db-test/2022-01-30/" \ - --log-file restore_db.log -``` - -In the preceding command, `--db` specifies the name of the database to be restored, and other parameters are the same as those in [Restore TiDB cluster snapshots](#restore-tidb-cluster-snapshots). - -> **Note:** -> -> When you restore the backup data, the database name specified by `--db` must be the same as the one specified by `-- db` in the backup command. Otherwise, the restoration fails. This is because the metafile of the backup data ( `backupmeta` file) records the database name, and you can only restore data to the database with the same name. The recommended method is to restore the backup data to the database with the same name in another cluster. - -### Restore a table - -To restore a single table to the cluster, run the `br restore table` command. To get help on this command, run the `br restore table --help` command. - -Example: Restore `test`.`usertable` from the `table-db-usertable/2022-01-30/`directory in the `backup-data` bucket of Amazon S3 to the target cluster. - -{{< copyable "shell-regular" >}} - -```shell -br restore table \ - --pd "${PDIP}:2379" \ - --db "test" \ - --table "usertable" \ - --ratelimit 128 \ - --storage "s3://backup-data/table-db-usertable/2022-01-30/" \ - --log-file restore_table.log -``` - -In the preceding command, `--table` specifies the name of the table to be restored, and other parameters are the same as those in [Restore TiDB cluster snapshots](#restore-tidb-cluster-snapshots). - -### Restore multiple tables with table filter - -To restore multiple tables with more criteria, run the `br restore full` command and specify the [table filters](/table-filter.md) with `--filter` or `-f`. - -Example: Restore data matching the `db*.tbl*` table from the `table-filter/2022-01-30/` directory in the `backup-data` bucket of Amazon S3 to the target cluster. - -{{< copyable "shell-regular" >}} - -```shell -br restore full \ - --pd "${PDIP}:2379" \ - --filter 'db*.tbl*' \ - --storage "s3://backup-data/table-filter/2022-01-30/" \ - --log-file restorefull.log -``` - -## Restore backup data from external storage - -BR supports restoring data to Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, NFS, or other S3-compatible file storage services. For details, see the following documents: - -- [Restore data on Amazon S3 using BR](/br/backup-storage-S3.md) -- [Restore data on Google Cloud Storage using BR](/br/backup-storage-gcs.md) -- [Restore data on Azure Blob Storage using BR](/br/backup-storage-azblob.md) - -## Restore incremental data - -> **Warning:** -> -> This is still an experimental feature. It is **NOT** recommended that you use it in the production environment. - -Restoring incremental data is similar to restoring full data using BR. When restoring incremental data, make sure that all the data backed up before `last backup ts` has been restored to the target cluster. Also, because incremental restoration updates ts data, you need to ensure that there are no other writes during the restoration. Otherwise, conflicts might occur. - -```shell -br restore full \ - --pd "${PDIP}:2379" \ - --storage "s3://backup-data/2022-01-30/incr" \ - --ratelimit 128 \ - --log-file restorefull.log -``` - -## Restore encrypted backup data - -> **Warning:** -> -> This is still an experimental feature. It is **NOT** recommended that you use it in the production environment. - -After encrypting the backup data, you need to pass in the corresponding decryption parameters to restore the data. Ensure that the decryption algorithm and key are correct. If the decryption algorithm or key is incorrect, the data cannot be restored. - -{{< copyable "shell-regular" >}} - -```shell -br restore full\ - --pd ${PDIP}:2379 \ - --storage "s3://backup-data/2022-01-30/" \ - --crypter.method aes128-ctr \ - --crypter.key 0123456789abcdef0123456789abcdef -``` - -## Restore tables in the `mysql` schema - -Starting from BR v5.1.0, when you perform a full backup, BR backs up the **system tables**. Before BR v6.2.0, under default configuration, BR only restores user data, but does not restore data in the system tables. Starting from BR v6.2.0, if the backup data contains system tables, and if you configure `--with-sys-table`, BR restores **data in some system tables**. - -BR can restore data in **the following system tables**: - -``` -+----------------------------------+ -| mysql.columns_priv | -| mysql.db | -| mysql.default_roles | -| mysql.global_grants | -| mysql.global_priv | -| mysql.role_edges | -| mysql.tables_priv | -| mysql.user | -+----------------------------------+ -``` - -**BR does not restore the following system tables**: - -- Statistics tables (`mysql.stat_*`) -- System variable tables (`mysql.tidb`, `mysql.global_variables`) -- [Other system tables](https://github.com/pingcap/tidb/blob/master/br/pkg/restore/systable_restore.go#L31) - -When you restore data related to system privileges, note the following: - -- BR does not restore user data with `user` as `cloud_admin` and `host` as `'%'`. This user is reserved for TiDB Cloud. Do not create a user or role named `cloud_admin` in your environment, because the user privileges related to `cloud_admin` cannot be restored correctly. -- Before BR restores data, it checks whether the system tables in the target cluster are compatible with those in the backup data. "Compatible" means that all the following conditions are met: - - - The target cluster has the same system tables as the backup data. - - The **number of columns** in the system privilege table of the target cluster is consistent with that of the backup data. The order of the columns can be different. - - The columns in the system privilege table of the target cluster are compatible with those in the backup data. If the data type of the column is a type with length (for example, int or char), the length in the target cluster must be >= the length in the backup data. If the data type of the column is an enum type, the enum values in the target cluster must be a superset of the enum values in the backup data. - -If the target cluster is not empty or the target cluster is not compatible with the backup data, BR returns the following information. You can remove `--with-sys-table` to skip restoring system tables. - -``` -####################################################################### -# the target cluster is not compatible with the backup data, -# br cannot restore system tables. -# you can remove 'with-sys-table' flag to skip restoring system tables -####################################################################### -``` - -To restore a table created by the user in the `mysql` schema (not system tables), you can explicitly include the table using [table filters](/table-filter.md#syntax). The following example shows how to restore the `mysql.usertable` table when BR performs a normal restoration. - -```shell -br restore full -f '*.*' -f '!mysql.*' -f 'mysql.usertable' -s $external_storage_url --with-sys-table -``` - -In the preceding command, - -- `-f '*.*'` is used to override the default rules -- `-f '!mysql.*'` instructs BR not to restore tables in `mysql` unless otherwise stated. -- `-f 'mysql.usertable'` indicates that `mysql.usertable` should be restored. - -If you only need to restore `mysql.usertable`, run the following command: - -{{< copyable "shell-regular" >}} - -```shell -br restore full -f 'mysql.usertable' -s $external_storage_url --with-sys-table -``` - -## Restoration performance and impact - -- TiDB fully uses TiKV CPU, disk IO, network bandwidth, and other resources when restoring data. Therefore, it is recommended that you restore backup data on an empty cluster to avoid affecting running services. -- The restoration speed depends much on cluser configuration, deployment, and running services. Generally, the restoration speed can reach 100 MB/s (per TiKV node). - -> **Note:** -> -> The preceding test conclusions, based on simulation tests in many scenarios and verified in some customer sites, are worthy of reference. However, the restoration speed may vary depending on the scenarios. Therefore, you should always run the test and verify the test results. diff --git a/br/backup-and-restore-design.md b/br/backup-and-restore-design.md index b6d180de942e9..0e75cd4598532 100644 --- a/br/backup-and-restore-design.md +++ b/br/backup-and-restore-design.md @@ -1,84 +1,23 @@ --- -title: BR Design Principles -summary: Learn about the design details of BR. +title: Overview of TiDB Backup & Restore Architecture +summary: Learn about the architecture design of TiDB backup and restore features. --- -# BR Design Principles +# Overview of TiDB Backup & Restore Architecture -This document describes the design principles of Backup & Restore (BR), including its architecture and backup files. +As described in [TiDB Backup & Restore Overview](/br/backup-and-restore-overview.md), TiDB supports backing up and restoring multiple types of cluster data. You can use Backup & Restore (BR) and TiDB Operator to access these features, and create tasks to back up data from TiKV nodes or restore data to TiKV nodes. -## BR architecture +For details about the architecture of each backup and restore feature, see the following documents: -BR sends a backup or restoration command to each TiKV node. After receiving the command, TiKV performs the corresponding backup or restoration operation. +- Full data backup and restore -Each TiKV node has a path in which the backup files generated in the backup operation are stored and from which the stored backup files are read during the restoration. + - [Back up snapshot data](/br/br-snapshot-architecture.md#process-of-backup) + - [Restore snapshot backup data](/br/br-snapshot-architecture.md#process-of-restore) -![br-arch](/media/br-arch.png) +- Data change log backup -## Backup files + - [Log backup: backup of KV data change](/br/br-log-architecture.md#process-of-log-backup) -This section describes the design of backup files generated by BR. +- Point-in-time recovery (PITR) -### Types of backup files - -BR can generate the following types of backup files: - -- `SST` file: stores the data that the TiKV node backs up. -- `backupmeta` file: stores the metadata of a backup operation, including the number, the key range, the size, and the Hash (sha256) value of the backup files. -- `backup.lock` file: prevents multiple backup operations from storing data to the same directory. - -### Naming format of SST files - -When data is backed up to Google Cloud Storage or Azure Blob Storage, SST files are named in the format of `storeID_regionID_regionEpoch_keyHash_timestamp_cf`. The fields in the format are explained as follows: - -- `storeID` is the TiKV node ID. -- `regionID` is the Region ID. -- `regionEpoch` is the version number of a Region. -- `keyHash` is the Hash (sha256) value of the startKey of a range, which ensures the uniqueness of a key. -- `timestamp` is the Unix timestamp of an SST file when it is generated at TiKV. -- `cf` indicates the Column Family of RocksDB (`default` or `write` by default). - -When data is backed up to Amazon S3 or a network disk, the SST files are named in the format of `regionID_regionEpoch_keyHash_timestamp_cf`. The fields in the format are explained as follows: - -- `regionID` is the Region ID. -- `regionEpoch` is the version number of a Region. -- `keyHash` is the Hash (sha256) value of the startKey of a range, which ensures the uniqueness of a key. -- `timestamp` is the Unix timestamp of an SST file when it is generated at TiKV. -- `cf` indicates the Column Family of RocksDB (`default` or `write` by default). - -### Storage format of SST files - -- For details about the storage format of SST files, see [Rocksdb BlockBasedTable Format](https://github.com/facebook/rocksdb/wiki/Rocksdb-BlockBasedTable-Format). -- For details about the encoding format of backup data in SST files, see [Mapping of table data to Key-Value](/tidb-computing.md#mapping-of-table-data-to-key-value). - -### Backup file structure - -When you back up data to Google Cloud Storage or Azure Blob Storage, the SST files, backupmeta files, and backup.lock files are stored in the same directory in the following structure: - -``` -. -└── 20220621 - ├── backupmeta - |—— backup.lock - ├── {storeID}-{regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst - ├── {storeID}-{regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst - └── {storeID}-{regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst -``` - -When you back up data to Amazon S3 or a network disk, the SST files are stored in sub-directories based on the storeID. The structure is as follows: - -``` -. -└── 20220621 - ├── backupmeta - |—— backup.lock - ├── store1 - │   └── {regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst - ├── store100 - │   └── {regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst - ├── store2 - │   └── {regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst - ├── store3 - ├── store4 - └── store5 -``` + - [PITR](/br/br-log-architecture.md#process-of-pitr) diff --git a/br/backup-and-restore-faq.md b/br/backup-and-restore-faq.md deleted file mode 100644 index 2f75f24e5f862..0000000000000 --- a/br/backup-and-restore-faq.md +++ /dev/null @@ -1,237 +0,0 @@ ---- -title: Backup & Restore FAQs -summary: Learn about Frequently Asked Questions (FAQs) and the solutions of BR. -aliases: ['/docs/dev/br/backup-and-restore-faq/'] ---- - -# Backup & Restore FAQs - -This document lists the frequently asked questions (FAQs) and the solutions about Backup & Restore (BR). - -## In TiDB v5.4.0 and later versions, when backup tasks are performed on the cluster under high workload, why does the speed of backup tasks become slow? - -Starting from TiDB v5.4.0, BR introduces the auto-tune feature for backup tasks. For clusters in v5.4.0 or later versions, this feature is enabled by default. When the cluster workload is heavy, the feature limits the resources used by backup tasks to reduce the impact on the online cluster. For more information, refer to [BR Auto-Tune](/br/br-auto-tune.md). - -TiKV supports [dynamically configuring](/tikv-control.md#modify-the-tikv-configuration-dynamically) the auto-tune feature. You can enable or disable the feature by the following methods without restarting your cluster: - -- Disable auto-tune: Set the TiKV configuration item [`backup.enable-auto-tune`](/tikv-configuration-file.md#enable-auto-tune-new-in-v540) to `false`. -- Enable auto-tune: Set `backup.enable-auto-tune` to `true`. For clusters upgraded from v5.3.x to v5.4.0 or later versions, the auto-tune feature is disabled by default. You need to manually enable it. - -To use `tikv-ctl` to enable or disable auto-tune, refer to [Use auto-tune](/br/br-auto-tune.md#use-auto-tune). - -In addition, auto-tune reduces the default number of threads used by backup tasks. For details, see `backup.num-threads`](/tikv-configuration-file.md#num-threads-1). Therefore, on the Grafana Dashboard, the speed, CPU usage, and I/O resource utilization used by backup tasks are lower than those of versions earlier than v5.4.0. Before v5.4.0, the default value of `backup.num-threads` was `CPU * 0.75`, that is, the number of threads used by backup tasks makes up 75% of the logical CPU cores. The maximum value of it was `32`. Starting from v5.4.0, the default value of this configuration item is `CPU * 0.5`, and its maximum value is `8`. - -When you perform backup tasks on an offline cluster, to speed up the backup, you can modify the value of `backup.num-threads` to a larger number using `tikv-ctl`. - -## What should I do if the error message `could not read local://...:download sst failed` is returned during data restoration? - -When you restore data, each node must have access to **all** backup files (SST files). By default, if `local` storage is used, you cannot restore data because the backup files are scattered among different nodes. Therefore, you have to copy the backup file of each TiKV node to the other TiKV nodes. - -It is recommended that you mount an NFS disk as a backup disk during backup. For details, see [Back up a single table to a network disk](/br/backup-and-restore-use-cases.md#back-up-a-single-table-to-a-network-disk-recommended-for-production-environments). - -## How much impact does a backup operation have on the cluster? - -For TiDB v5.4.0 or later versions, BR not only reduces the default CPU utilization used by backup tasks, but also introduces the [BR Auto-tune](/br/br-auto-tune.md) feature to limit the resources used by backup tasks in the cluster with heavy workloads. Therefore, when you use the default configuration for backup tasks in a v5.4.0 cluster with heavy workloads, the impact of the tasks on the cluster performance is significantly less than that on the clusters earlier than v5.4.0. - -The following is an internal test on a single node. The test results show that when you use the default configuration of v5.4.0 and v5.3.0 in the **full-speed backup** scenario, the impact of backup using BR on cluster performance is quite different. The detailed test results are as follows: - -- When BR uses the default configuration of v5.3.0, the QPS of write-only workload is reduced by 75%. -- When BR uses the default configuration of v5.4.0, the QPS for the same workload is reduced by 25%. However, when this configuration is used, the duration of backup tasks using BR becomes correspondingly longer. The time required is 1.7 times that of the v5.3.0 configuration. - -You can use either of the following solutions to manually control the impact of backup tasks on cluster performance. Note that these methods reduce the impact of backup tasks on the cluster, but they also reduce the speed of backup tasks. - -- Use the `--ratelimit` parameter to limit the speed of backup tasks. Note that this parameter limits the speed of **saving backup files to external storage**. When calculating the total size of backup files, use the `backup data size(after compressed)` in the backup log as a benchmark. -- Adjust the TiKV configuration item [`backup.num-threads`](/tikv-configuration-file.md#num-threads-1) to limit the number of threads used by backup tasks. When BR uses no more than `8` threads for backup tasks, and the total CPU utilization of the cluster does not exceed 60%, the backup tasks have little impact on the cluster, regardless of the read and write workload. - -## Does BR back up system tables? During data restoration, do they raise conflicts? - -Before v5.1.0, BR filters out data from the system schemas `mysql.*` during the backup. Since v5.1.0, BR **backs up** all data by default, including the system schemas `mysql.*`. - -The technical implementation of restoring the system tables in `mysql.*` is not complete yet, so the tables in the system schema `mysql` are **not restored** by default, which means no conflicts will be raised. For more details, refer to [Restore tables in the `mysql` schema (experimental)](/br/br-usage-restore.md#restore-tables-in-the-mysql-schema). - -## What should I do to handle the `Permission denied` or `No such file or directory` error, even if I have tried to run BR using root in vain? - -You need to confirm whether TiKV has access to the backup directory. To back up data, confirm whether TiKV has the write permission. To restore data, confirm whether it has the read permission. - -During the backup operation, if the storage medium is the local disk or a network file system (NFS), make sure that the user to start BR and the user to start TiKV are consistent (if BR and TiKV are on different machines, the users' UIDs must be consistent). Otherwise, the `Permission denied` issue might occur. - -Running BR with the root access might fail due to the disk permission, because the backup files (SST files) are saved by TiKV. - -> **Note:** -> -> You might encounter the same problem during data restoration. When the SST files are read for the first time, the read permission is verified. The execution duration of DDL suggests that there might be a long interval between checking the permission and running BR. You might receive the error message `Permission denied` after waiting for a long time. -> -> Therefore, it is recommended to check the permission before data restore according to the following steps: - -1. Run the Linux-native command for process query: - - {{< copyable "shell-regular" >}} - - ```bash - ps aux | grep tikv-server - ``` - - The output of the above command: - - ```shell - tidb_ouo 9235 10.9 3.8 2019248 622776 ? Ssl 08:28 1:12 bin/tikv-server --addr 0.0.0.0:20162 --advertise-addr 172.16.6.118:20162 --status-addr 0.0.0.0:20188 --advertise-status-addr 172.16.6.118:20188 --pd 172.16.6.118:2379 --data-dir /home/user1/tidb-data/tikv-20162 --config conf/tikv.toml --log-file /home/user1/tidb-deploy/tikv-20162/log/tikv.log - tidb_ouo 9236 9.8 3.8 2048940 631136 ? Ssl 08:28 1:05 bin/tikv-server --addr 0.0.0.0:20161 --advertise-addr 172.16.6.118:20161 --status-addr 0.0.0.0:20189 --advertise-status-addr 172.16.6.118:20189 --pd 172.16.6.118:2379 --data-dir /home/user1/tidb-data/tikv-20161 --config conf/tikv.toml --log-file /home/user1/tidb-deploy/tikv-20161/log/tikv.log - ``` - - Or you can run the following command: - - {{< copyable "shell-regular" >}} - - ```bash - ps aux | grep tikv-server | awk '{print $1}' - ``` - - The output of the above command: - - ```shell - tidb_ouo - tidb_ouo - ``` - -2. Query the startup information of the cluster using the TiUP command: - - {{< copyable "shell-regular" >}} - - ```bash - tiup cluster list - ``` - - The output of the above command: - - ```shell - [root@Copy-of-VM-EE-CentOS76-v1 br]# tiup cluster list - Starting component `cluster`: /root/.tiup/components/cluster/v1.5.2/tiup-cluster list - Name User Version Path PrivateKey - ---- ---- ------- ---- ---------- - tidb_cluster tidb_ouo v5.0.2 /root/.tiup/storage/cluster/clusters/tidb_cluster /root/.tiup/storage/cluster/clusters/tidb_cluster/ssh/id_rsa - ``` - -3. Check the permission for the backup directory. For example, `backup` is for backup data storage: - - {{< copyable "shell-regular" >}} - - ```bash - ls -al backup - ``` - - The output of the above command: - - ```shell - [root@Copy-of-VM-EE-CentOS76-v1 user1]# ls -al backup - total 0 - drwxr-xr-x 2 root root 6 Jun 28 17:48 . - drwxr-xr-x 11 root root 310 Jul 4 10:35 .. - ``` - - From the above output, you can find that the `tikv-server` instance is started by the user `tidb_ouo`. But the user `tidb_ouo` does not have the write permission for `backup`. Therefore, the backup fails. - -## What should I do to handle the `Io(Os...)` error? - -Almost all of these problems are system call errors that occur when TiKV writes data to the disk, for example, `Io(Os {code: 13, kind: PermissionDenied...})` or `Io(Os {code: 2, kind: NotFound...})`. - -To address such problems, first check the mounting method and the file system of the backup directory, and try to back up data to another folder or another hard disk. - -For example, you might encounter the `Code: 22(invalid argument)` error when backing up data to the network disk built by `samba`. - -## What should I do to handle the `rpc error: code = Unavailable desc =...` error occurred in BR? - -This error might occur when the capacity of the cluster to restore (using BR) is insufficient. You can further confirm the cause by checking the monitoring metrics of this cluster or the TiKV log. - -To handle this issue, you can try to scale out the cluster resources, reduce the concurrency during restoration, and enable the `RATE_LIMIT` option. - -## Where are the backed up files stored when I use `local` storage? - -When you use `local` storage, `backupmeta` is generated on the node where BR is running, and backup files are generated on the Leader nodes of each Region. - -## How about the size of the backup data? Are there replicas of the backup? - -During data backup, backup files are generated on the Leader nodes of each Region. The size of the backup is equal to the data size, with no redundant replicas. Therefore, the total data size is approximately the total number of TiKV data divided by the number of replicas. - -However, if you want to restore data from local storage, the number of replicas is equal to that of the TiKV nodes, because each TiKV must have access to all backup files. - -## What should I do when BR restores data to the upstream cluster of TiCDC/Drainer? - -+ **The data restored using BR cannot be replicated to the downstream**. This is because BR directly imports SST files but the downstream cluster currently cannot obtain these files from the upstream. - -+ Before v4.0.3, DDL jobs generated during the BR restore might cause unexpected DDL executions in TiCDC/Drainer. Therefore, if you need to perform restore on the upstream cluster of TiCDC/Drainer, add all tables restored using BR to the TiCDC/Drainer block list. - -You can use [`filter.rules`](https://github.com/pingcap/tiflow/blob/7c3c2336f98153326912f3cf6ea2fbb7bcc4a20c/cmd/changefeed.toml#L16) to configure the block list for TiCDC and use [`syncer.ignore-table`](/tidb-binlog/tidb-binlog-configuration-file.md#ignore-table) to configure the block list for Drainer. - -## Does BR back up the `SHARD_ROW_ID_BITS` and `PRE_SPLIT_REGIONS` information of a table? Does the restored table have multiple Regions? - -Yes. BR backs up the [`SHARD_ROW_ID_BITS` and `PRE_SPLIT_REGIONS`](/sql-statements/sql-statement-split-region.md#pre_split_regions) information of a table. The data of the restored table is also split into multiple Regions. - -## What should I do if the restore fails with the error message `the entry too large, the max entry size is 6291456, the size of data is 7690800`? - -You can try to reduce the number of tables to be created in a batch by setting `--ddl-batch-size` to `128` or a smaller value. - -When using BR to restore the backup data with the value of [`--ddl-batch-size`](/br/br-batch-create-table.md#how to use) greater than `1`, TiDB writes a DDL job of table creation to the DDL jobs queue that is maintained by TiKV. At this time, the total size of all tables schema sent by TiDB at one time should not exceed 6 MB, because the maximum value of job messages is `6 MB` by default (it is **not recommended** to modify this value. For details, see [`txn-entry-size-limit`](/tidb-configuration-file.md#txn-entry-size-limit-new-in-v50) and [`raft-entry-max-size`](/tikv-configuration-file.md#raft-entry-max-size)). Therefore, if you set `--ddl-batch-size` to an excessively large value, the schema size of the tables sent by TiDB in a batch at one time exceeds the specified value, which causes BR to report the `entry too large, the max entry size is 6291456, the size of data is 7690800` error. - -## Why is the `region is unavailable` error reported for a SQL query after I use BR to restore the backup data? - -If the cluster backed up using BR has TiFlash, `TableInfo` stores the TiFlash information when BR restores the backup data. If the cluster to be restored does not have TiFlash, the `region is unavailable` error is reported. - -## Does BR support in-place full restoration of some historical backup? - -No. BR does not support in-place full restoration of some historical backup. - -## How can I use BR for incremental backup on Kubernetes? - -To get the `commitTs` field of the last BR backup, run the `kubectl -n ${namespace} get bk ${name}` command using kubectl. You can use the content of this field as `--lastbackupts`. - -## How can I convert BR backupTS to Unix time? - -BR `backupTS` defaults to the latest timestamp obtained from PD before the backup starts. You can use `pd-ctl tso timestamp` to parse the timestamp to obtain an accurate value, or use `backupTS >> 18` to quickly obtain an estimated value. - -## After BR restores the backup data, do I need to execute the `ANALYZE` statement on the table to update the statistics of TiDB on the tables and indexes? - -BR does not back up statistics (except in v4.0.9). Therefore, after restoring the backup data, you need to manually execute `ANALYZE TABLE` or wait for TiDB to automatically execute `ANALYZE`. - -In v4.0.9, BR backs up statistics by default, which consumes too much memory. To ensure that the backup process goes well, the backup for statistics is disabled by default starting from v4.0.10. - -If you do not execute `ANALYZE` on the table, TiDB will fail to select the optimized execution plan due to inaccurate statistics. If query performance is not a key concern, you can ignore `ANALYZE`. - -## Can I use multiple BR processes at the same time to restore the data of a single cluster? - -**It is strongly not recommended** to use multiple BR processes at the same time to restore the data of a single cluster for the following reasons: - -+ When BR restores data, it modifies some global configurations of PD. Therefore, if you use multiple BR processes for data restore at the same time, these configurations might be mistakenly overwritten and cause abnormal cluster status. -+ BR consumes a lot of cluster resources to restore data, so in fact, running BR processes in parallel improves the restore speed only to a limited extent. -+ There has been no test for running multiple BR processes in parallel for data restore, so it is not guaranteed to succeed. - -## What should I do if the backup log reports `key locked Error`? - -Error message in the log: `log - ["backup occur kv error"][error="{\"KvError\":{\"locked\":` - -If a key is locked during the backup process, BR tries to resolve the lock. If this error occurs only occasionally, the correctness of the backup is not affected. - -## What should I do if a backup operation fails? - -Error message in the log: `log - Error: msg:"Io(Custom { kind: AlreadyExists, error: \"[5_5359_42_123_default.sst] is already exists in /dir/backup_local/\" })"` - -If a backup operation fails and the preceding message occurs, perform one of the following operations and then start the backup again: - -- Change the directory for the backup. For example, change `/dir/backup_local/` to `/dir/backup-2020-01-01/`. -- Delete the backup directories of all TiKV nodes and BR nodes. - -## What should I do if the disk usage shown on the monitoring node is inconsistent after BR backup or restoration? - -This inconsistency is caused by the fact that the data compression rate used in backup is different from the default rate used in restoration. If the checksum succeeds, you can ignore this issue. - -## Why does an error occur when I restore placement rules to a cluster? - -Before v6.0.0, BR does not support [placement rules](/placement-rules-in-sql.md). Starting from v6.0.0, BR supports placement rules and introduces a command-line option `--with-tidb-placement-mode=strict/ignore` to control the backup and restore mode of placement rules. With the default value `strict`, BR imports and validates placement rules, but ignores all placement rules when the value is `ignore`. - -## Why does BR report `new_collations_enabled_on_first_bootstrap` mismatch? - -Since TiDB v6.0.0, the default value of [`new_collations_enabled_on_first_bootstrap`](/tidb-configuration-file.md#new_collations_enabled_on_first_bootstrap) has changed from `false` to `true`. BR backs up the `new_collations_enabled_on_first_bootstrap` configuration of the upstream cluster and then checks whether the value of this configuration is consistent between the upstream and downstream clusters. If the value is consistent, BR safely restores the data backed up in the upstream cluster to the downstream cluster. If the value is inconsistent, BR does not perform the data restore and reports an error. - -Suppose that you have backed up the data in a TiDB cluster of an earlier version of v6.0.0, and you want to restore this data to a TiDB cluster of v6.0.0 or later versions. In this situation, you need to manually check whether the value of `new_collations_enabled_on_first_bootstrap` is consistent between the upstream and downstream clusters: - -- If the value is consistent, you can add `--check-requirements=false` to the restoration command to skip this configuration check. -- If the value is inconsistent, and you forcibly perform the restoration, BR reports a data validation error. diff --git a/br/backup-and-restore-overview.md b/br/backup-and-restore-overview.md index 7a7600572151f..be11c15391739 100644 --- a/br/backup-and-restore-overview.md +++ b/br/backup-and-restore-overview.md @@ -1,114 +1,133 @@ --- -title: BR Overview -summary: Learn about the definition and functions of BR. -aliases: ['/docs/dev/br/backup-and-restore-tool/','/docs/dev/reference/tools/br/br/','/docs/dev/how-to/maintain/backup-and-restore/br/','/tidb/dev/backup-and-restore-tool'] +title: TiDB Backup & Restore Overview +summary: Learn about the definition and features of TiDB Backup & Restore. +aliases: ['/docs/dev/br/backup-and-restore-tool/','/docs/dev/reference/tools/br/br/','/docs/dev/how-to/maintain/backup-and-restore/br/','/tidb/dev/backup-and-restore-tool/','/tidb/dev/point-in-time-recovery/'] --- -# BR Overview +# TiDB Backup & Restore Overview -[BR](https://github.com/pingcap/tidb/tree/master/br) (Backup & Restore) is a command-line tool for **distributed backup and restoration** of the TiDB cluster data. In addition to regular backup and restoration, you can also use BR for large-scale data migration as long as compatibility is ensured. +Based on the Raft protocol and a reasonable deployment topology, TiDB realizes high availability of clusters. When a few nodes in the cluster fail, the cluster can still be available. On this basis, to further ensure data safety, TiDB provides the Backup & Restore (BR) feature as the last resort to recover data from natural disasters and misoperations. -This document describes BR's architecture, features, and usage tips. +BR satisfies the following requirements: -## BR architecture +- Back up cluster data to a disaster recovery (DR) system with an RPO of no more than 10 minutes, reducing data loss in disaster scenarios. +- Handle the cases of misoperations from applications by rolling back data to a time point before the error event. +- Perform history data auditing to meet the requirements of judicial supervision. +- Clone the production environment, which is convenient for troubleshooting, performance tuning, and simulation testing. -BR sends a backup or restoration command to each TiKV node. After receiving the command, TiKV performs the corresponding backup or restoration operation. +## Use backup and restore -Each TiKV node has a path in which the backup files generated in the backup operation are stored and from which the stored backup files are read during the restoration. +The way to use BR varies with the deployment method of TiDB. This document introduces how to use the br command-line tool to back up and restore TiDB cluster data in an on-premise deployment. -![br-arch](/media/br-arch.png) +For information about how to use this feature in other deployment scenarios, see the following documents: -For detailed information about the BR design, see [BR Design Principles](/br/backup-and-restore-design.md). +- [Back Up and Restore TiDB Deployed on TiDB Cloud](https://docs.pingcap.com/tidbcloud/backup-and-restore): It is recommended that you create TiDB clusters on [TiDB Cloud](https://www.pingcap.com/tidb-cloud/?from=en). TiDB Cloud offers fully managed databases to let you focus on your applications. +- [Back Up and Restore Data Using TiDB Operator](https://docs.pingcap.com/tidb-in-kubernetes/stable/backup-restore-overview): If you deploy a TiDB cluster using TiDB Operator on Kubernetes, it is recommended to back up and restore data using Kubernetes CustomResourceDefinition (CRD). ## BR features -This section describes BR features and the performance impact. +TiDB BR provides the following features: -### Back up TiDB cluster data +- Back up cluster data: You can back up full data (**full backup**) of the cluster at a certain time point, or back up the data changes in TiDB (**log backup**, in which log means KV changes in TiKV). -- **Back up cluster snapshots**: A snapshot of a TiDB cluster contains transactionally consistent data at a specific time. You can back up snapshot data of a TiDB cluster using BR. For details, see [Back up TiDB cluster snapshots](/br/br-usage-backup.md#back-up-tidb-cluster-snapshots). -- **Back up incremental data**: The incremental data of a TiDB cluster represents changes between the latest snapshot and the previous snapshot. Incremental data is smaller in size compared with full data, and can be used together with snapshot backup, which reduces the volume of backup data. For details, see [Back up incremental data](/br/br-usage-backup.md#back-up-incremental-data). -- **Back up a database or table**: On top of snapshot and incremental data backup, BR supports backing up a specific database or table and filtering out unnecessary data. For details, see [Back up a database or table](/br/br-usage-backup.md#back-up-a-database-or-a-table). -- **Encrypt backup data**: BR supports backup data encryption and Amazon S3 server-side encryption. You can select an encryption method as needed. For details, see [Encrypt backup data](/br/br-usage-backup.md#encrypt-backup-data). +- Restore backup data: -#### Impact on performance + - You can **restore a full backup** or **specific databases or tables** in a full backup. + - Based on backup data (full backup and log backup), you can restore the target cluster to any time point of the backup cluster. This type of restore is called point-in-time recovery, or PITR for short. -The impact of backup on a TiDB cluster is kept below 20%, and this value can be reduced to 10% or less with the proper configuration of the TiDB cluster. The backup speed of a TiKV node is scalable and ranges from 50 MB/s to 100 MB/s. For more information, see [Backup performance and impact](/br/br-usage-backup.md#backup-performance-and-impact). +### Back up cluster data -#### Storage types of backup data +Full backup backs up all data of a cluster at a specific time point. TiDB supports the following way of full backup: -BR supports backing up data to Amazon S3, Google Cloud Storage, Azure Blob Storage, NFS, and other S3-compatible file storage services. For details, see [Back up data to external storages](/br/br-usage-backup.md#back-up-data-to-external-storage). +- Back up cluster snapshots: A snapshot of a TiDB cluster contains transactionally consistent data at a specific time. For details, see [Snapshot backup](/br/br-snapshot-guide.md#back-up-cluster-snapshots). -### Restore TiDB cluster data +Full backup occupies much storage space and contains only cluster data at a specific time point. If you want to choose the restore point as required, that is, to perform point-in-time recovery (PITR), you can use the following two ways of backup at the same time: -- **Restore snapshot backup**: You can restore snapshot backup data to a new cluster. For details, see [Restore TiDB cluster snapshots](/br/br-usage-restore.md#restore-tidb-cluster-snapshots). -- **Restore incremental backup**: You can restore the incremental backup data to a cluster. For details, see [Restore incremental backup](/br/br-usage-restore.md#restore-incremental-data). -- **Restore a database or a table from backup**: You can restore part of a specific database or table. During the process, BR will filter out unnecessary data. For details, see [Restore a database or a table](/br/br-usage-restore.md#restore-a-database-or-a-table). +- Start [log backup](/br/br-pitr-guide.md#start-log-backup). After log backup is started, the task keeps running on all TiKV nodes and backs up TiDB incremental data in small batches to the specified storage periodically. +- Perform snapshot backup regularly. Back up the full cluster data to the backup storage, for example, perform cluster snapshot backup at 0:00 AM every day. -#### Impact on performance +#### Backup performance and impact on TiDB clusters -Data restoration is performed at a scalable speed. Generally, the speed is 100 MB/s per TiKV node. BR only supports restoring data to a new cluster and uses the resources of the target cluster as much as possible. For more details, see [Restoration performance and impact](/br/br-usage-restore.md#restoration-performance-and-impact). +- The impact of backup on a TiDB cluster is kept below 20%, and this value can be reduced to 10% or less with the proper configuration of the TiDB cluster. The backup speed of a TiKV node is scalable and ranges from 50 MB/s to 100 MB/s. For more information, see [Backup performance and impact](/br/br-snapshot-guide.md#performance-and-impact-of-snapshot-backup). +- When there are only log backup tasks, the impact on the cluster is about 5%. Log backup flushes all the changes generated after the last refresh every 5-10 minutes to the backup storage, which can **achieve a Recovery Point Objective (RPO) of no more than ten minutes**. -## Before you use BR +### Restore backup data -Before you use BR, pay attention to its usage restrictions, compatibility, and other considerations. +Corresponding to the backup features, you can perform two types of restore: full restore and PITR. -### Usage restrictions +- Restore a full backup -This section describes usage restrictions of BR. + - Restore cluster snapshot backup: You can restore snapshot backup data to an empty cluster or a cluster that does not have data conflicts (with the same schema or tables). For details, see [Restore snapshot backup](/br/br-snapshot-guide.md#restore-cluster-snapshots). In addition, you can restore specific databases or tables from the backup data and filter out unwanted data. For details, see [Restore specific databases or tables from backup data](/br/br-snapshot-guide.md#restore-a-database-or-a-table). -#### Unsupported scenarios +- Restore data to any point in time (PITR) -When BR restores data to the upstream cluster of TiCDC or TiDB Binlog, TiCDC or TiDB Binlog cannot replicate the restored data to the downstream cluster. + - By running the `br restore point` command, you can restore the latest snapshot backup data before recovery time point and log backup data to a specified time. BR automatically determines the restore scope, accesses backup data, and restores data to the target cluster in turn. -#### Compatibility +#### Restore performance and impact on TiDB clusters -The compatibility issues of BR and a TiDB cluster are as follows: +- Data restore is performed at a scalable speed. Generally, the speed is 100 MiB/s per TiKV node. `br` only supports restoring data to a new cluster and uses the resources of the target cluster as much as possible. For more details, see [Restore performance and impact](/br/br-snapshot-guide.md#performance-and-impact-of-snapshot-restore). +- On each TiKV node, PITR can restore log data at 30 GiB/h. For more details, see [PITR performance and impact](/br/br-pitr-guide.md#performance-and-impact-of-pitr). -- There is a cross-version compatibility issue: +## Backup storage - Before v5.4.0, BR cannot restore tables with `charset=GBK`. At the same time, no version of BR supports restoring `charset=GBK` tables to a TiDB cluster earlier than v5.4.0. +TiDB supports backing up data to Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, NFS, and other S3-compatible file storage services. For details, see the following documents: -- The KV format might change when some features are enabled or disabled. If these features are not consistently enabled or disabled during backup and restoration, compatibility issues might occur. +- [Specify backup storage in URL](/br/backup-and-restore-storages.md#url-format) +- [Configure access privileges to backup storages](/br/backup-and-restore-storages.md#authentication) -These features are as follows: +## Before you use -| Feature | Issue | Solution | -| ---- | ---- | ----- | -| Clustered index | [#565](https://github.com/pingcap/br/issues/565) | Make sure that the value of the `tidb_enable_clustered_index` global variable during restoration is consistent with that during backup. Otherwise, data inconsistency might occur, such as `default not found` and inconsistent data index. | -| New collation | [#352](https://github.com/pingcap/br/issues/352) | Make sure that the value of the `new_collations_enabled_on_first_bootstrap` variable during restoration is consistent with that during backup. Otherwise, inconsistent data index might occur and checksum might fail to pass. | -| Global temporary tables | | Make sure that you are using BR v5.3.0 or a later version to back up and restore data. Otherwise, an error occurs in the definition of the backed global temporary tables. | +This section describes the prerequisites for using TiDB backup and restore, including the usage tips and compatibility issues. -However, even after you have ensured that the preceding features are consistently enabled or disabled during backup and restoration, compatibility issues might still occur due to the inconsistent internal versions or inconsistent interfaces between BR and TiKV/TiDB/PD. To avoid such cases, BR provides a built-in version check. +### Some tips -#### Version check +Snapshot backup: -Before performing backup and restoration, BR compares and checks the TiDB cluster version and the BR version. If there is a major-version mismatch (for example, BR v4.x and TiDB v5.x), BR prompts a reminder to exit. To forcibly skip the version check, you can set `--check-requirements=false`. Note that skipping the version check might introduce incompatibility. +- It is recommended that you perform the backup operation during off-peak hours to minimize the impact on applications. +- It is recommended that you execute multiple backup or restore operations one by one. Running backup operations in parallel leads to low performance. Worse still, lack of collaboration between multiple tasks might result in task failures and affect cluster performance. -The version compatibility mapping between BR and TiDB versions are as follows: +Snapshot restore: -| Backup version (vertical) \ Restoration version (horizontal) | Use BR v5.4 to restore TiDB v5.4 | Use BR v6.0 to restore TiDB v6.0 | Use BR v6.1 to restore TiDB v6.1 | Use BR v6.2 to restore TiDB v6.2 | -| ---- | ---- | ---- | ---- | ---- | -| Use BR v5.4 to back up TiDB v5.4 | Compatible | Incompatible (Before restoration, modify the restoration cluster to use the same [new collation](/tidb-configuration-file.md#new_collations_enabled_on_first_bootstrap) as the backup cluster.) | Incompatible (Before restoration, modify the restoration cluster to use the same [new collation](/tidb-configuration-file.md#new_collations_enabled_on_first_bootstrap) as the backup cluster.) | Incompatible (Before restoration, modify the restoration cluster to use the same [new collation](/tidb-configuration-file.md#new_collations_enabled_on_first_bootstrap) as the backup cluster.) | -| Use BR v6.0 to back up TiDB v6.0 | Incompatible | Compatible | Compatible | Compatible | -| Use BR v6.1 to back up TiDB v6.1 | Incompatible | Compatible (A known issue [#36379](https://github.com/pingcap/tidb/issues/36379): if backup data contains an empty schema, BR might report an error.) | Compatible | Compatible | -| Use BR v6.2 to back up TiDB v6.2 | Incompatible | Compatible (A known issue [#36379](https://github.com/pingcap/tidb/issues/36379): if backup data contains an empty schema, BR might report an error.) | Compatible | Compatible | +- BR uses resources of the target cluster as much as possible. Therefore, it is recommended that you restore data to a new cluster or an offline cluster. Avoid restoring data to a production cluster. Otherwise, your application might be affected. PITR only supports restoring data to an empty cluster. -#### Some tips +PITR: -The following are some recommended operations for using BR: +- You can only perform cluster-level PITR. Database-level and table-level PITR are not supported. +- You cannot restore data in the user tables or the privilege tables. -- It is recommended that you perform the backup operation during off-peak hours to minimize the impact on applications. -- BR only supports restoring data to a new cluster and uses resources of the target cluster as much as possible. Therefore, it is not recommended that you restore data to a production cluster. Otherwise, services might be affected. -- It is recommended that you execute multiple backup or restoration operations one by one. Running backup or restoration operations in parallel reduces performance and also affects online applications. Worse still, lack of collaboration between multiple tasks might result in task failures and affect cluster performance. -- Amazon S3, Google Cloud Storage, and Azure Blob Storage are recommended to store backup data. -- Make sure that the BR and TiKV nodes, and the backup storage system have sufficient network bandwidth to ensure sound write/read performance. Insufficient storage capacity might be the bottleneck for a backup or restoration operation. - -### See also - -- [Back up Data to S3-Compatible Storage Using BR](https://docs.pingcap.com/tidb-in-kubernetes/stable/backup-to-aws-s3-using-br) -- [Restore Data from S3-Compatible Storage Using BR](https://docs.pingcap.com/tidb-in-kubernetes/stable/restore-from-aws-s3-using-br) -- [Back up Data to GCS Using BR](https://docs.pingcap.com/tidb-in-kubernetes/stable/backup-to-gcs-using-br) -- [Restore Data from GCS Using BR](https://docs.pingcap.com/tidb-in-kubernetes/stable/restore-from-gcs-using-br) -- [Back up Data to PV](https://docs.pingcap.com/tidb-in-kubernetes/stable/backup-to-pv-using-br) -- [Restore Data from PV](https://docs.pingcap.com/tidb-in-kubernetes/stable/restore-from-pv-using-br) +Backup storage and network configuration: + +- It is recommended that you store backup data to a storage system that is compatible with Amazon S3, GCS, or Azure Blob Storage. +- You need to ensure that BR, TiKV, and the backup storage system have enough network bandwidth, and the storage system can provide sufficient read and write performance (IOPS). Otherwise, they might become a performance bottleneck during backup and restore. + +### Compatibility + +#### Compatibility with other features + +Backup and restore might go wrong when some TiDB features are enabled or disabled. If these features are not consistently enabled or disabled during backup and restore, compatibility issues might occur. + +| Feature | Issue | Solution | +| ---- | ---- | ----- | +|GBK charset|| BR of versions earlier than v5.4.0 does not support restoring `charset=GBK` tables. No version of BR supports recovering `charset=GBK` tables to TiDB clusters earlier than v5.4.0. | +| Clustered index | [#565](https://github.com/pingcap/br/issues/565) | Make sure that the value of the `tidb_enable_clustered_index` global variable during restore is consistent with that during backup. Otherwise, data inconsistency might occur, such as `default not found` error and inconsistent data index. | +| New collation | [#352](https://github.com/pingcap/br/issues/352) | Make sure that the value of the `new_collations_enabled_on_first_bootstrap` variable during restore is consistent with that during backup. Otherwise, inconsistent data index might occur and checksum might fail to pass. For more information, see [FAQ - Why does BR report `new_collations_enabled_on_first_bootstrap` mismatch?](/faq/backup-and-restore-faq.md#why-is-new_collations_enabled_on_first_bootstrap-mismatch-reported-during-restore). | +| Global temporary tables | | Make sure that you are using v5.3.0 or a later version of BR to back up and restore data. Otherwise, an error occurs in the definition of the backed global temporary tables. | +| TiDB Lightning Physical Import| | If the upstream database uses the physical import mode of TiDB Lightning, data cannot be backed up in log backup. It is recommended to perform a full backup after the data import. For more information, see [When the upstream database imports data using TiDB Lightning in the physical import mode, the log backup feature becomes unavailable. Why?](/faq/backup-and-restore-faq.md#when-the-upstream-database-imports-data-using-tidb-lightning-in-the-physical-import-mode-the-log-backup-feature-becomes-unavailable-why).| + +#### Version compatibility + +Before performing backup and restore, BR compares and checks the TiDB cluster version with its own. If there is a major-version mismatch, BR prompts a reminder to exit. To forcibly skip the version check, you can set `--check-requirements=false`. Note that skipping the version check might introduce incompatibility. + +| Backup version (vertical) \ Restore version (horizontal) | Restore to TiDB v6.0 | Restore to TiDB v6.1 | Restore to TiDB v6.2 | Restore to TiDB v6.3 | +| ---- | ---- | ---- | ---- | ---- | +| TiDB v6.0 snapshot backup | Compatible | Compatible | Compatible | Compatible | +| TiDB v6.1 snapshot backup | Compatible (A known issue [#36379](https://github.com/pingcap/tidb/issues/36379): if backup data contains an empty schema, BR might report an error.) | Compatible | Compatible | Compatible | +| TiDB v6.2 snapshot backup | Compatible (A known issue [#36379](https://github.com/pingcap/tidb/issues/36379): if backup data contains an empty schema, BR might report an error.) | Compatible | Compatible | Compatible | +| TiDB v6.3 snapshot backup | Compatible (A known issue [#36379](https://github.com/pingcap/tidb/issues/36379): if backup data contains an empty schema, BR might report an error.) | Compatible | Compatible | Compatible | +| TiDB v6.3 log backup| N/A | N/A | Incompatible | Compatible | + +## See also + +- [TiDB Snapshot Backup and Restore Guide](/br/br-snapshot-guide.md) +- [TiDB Log Backup and PITR Guide](/br/br-pitr-guide.md) +- [Backup Storages](/br/backup-and-restore-storages.md) diff --git a/br/backup-and-restore-storages.md b/br/backup-and-restore-storages.md index b1a5e09ca8c03..554ef8840ece2 100644 --- a/br/backup-and-restore-storages.md +++ b/br/backup-and-restore-storages.md @@ -1,247 +1,229 @@ --- -title: External Storages -summary: Describes the storage URL format used in BR, TiDB Lightning, and Dumpling. -aliases: ['/docs/dev/br/backup-and-restore-storages/'] +title: Backup Storages +summary: Describes the storage URL format used in TiDB backup and restore. +aliases: ['/docs/dev/br/backup-and-restore-storages/','/tidb/dev/backup-storage-S3/','/tidb/dev/backup-storage-azblob/','/tidb/dev/backup-storage-gcs/'] --- -# External Storages +# Backup Storages -Backup & Restore (BR), TiDB Lightning, and Dumpling support reading and writing data on the local filesystem and on Amazon S3. BR also supports reading and writing data on the [Google Cloud Storage (GCS)](/br/backup-storage-gcs.md) and [Azure Blob Storage (Azblob)](/br/backup-storage-azblob.md). These are distinguished by the URL scheme in the `--storage` parameter passed into BR, in the `-d` parameter passed into TiDB Lightning, and in the `--output` (`-o`) parameter passed into Dumpling. +TiDB supports storing backup data to Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, and NFS. Specifically, you can specify the URL of backup storage in the `--storage` or `-s` parameter of `br` commands. This document introduces the [URL format](#url-format) and [authentication](#authentication) of different external storage services, and [server-side encryption](#server-side-encryption). -## Schemes +## URL format -The following services are supported: +### URL format description -| Service | Schemes | Example URL | -|---------|---------|-------------| -| Local filesystem, distributed on every node | local | `local:///path/to/dest/` | -| Amazon S3 and compatible services | s3 | `s3://bucket-name/prefix/of/dest/` | -| Google Cloud Storage (GCS) | gcs, gs | `gcs://bucket-name/prefix/of/dest/` | -| Azure Blob Storage | azure, azblob | `azure://container-name/prefix/of/dest/` | -| Write to nowhere (for benchmarking only) | noop | `noop://` | +This section describes the URL format of the storage services: -## URL parameters +```shell +[scheme]://[host]/[path]?[parameters] +``` -Cloud storages such as S3, GCS and Azblob sometimes require additional configuration for connection. You can specify parameters for such configuration. For example: + +
-+ Use Dumpling to export data to S3: +- `scheme`: `s3` +- `host`: `bucket name` +- `parameters`: - {{< copyable "shell-regular" >}} + - `access-key`: Specifies the access key. + - `secret-access-key`: Specifies the secret access key. + - `use-accelerate-endpoint`: Specifies whether to use the accelerate endpoint on Amazon S3 (defaults to `false`). + - `endpoint`: Specifies the URL of custom endpoint for S3-compatible services (for example, ``). + - `force-path-style`: Use path style access rather than virtual hosted style access (defaults to `true`). + - `storage-class`: Specifies the storage class of the uploaded objects (for example, `STANDARD` or `STANDARD_IA`). + - `sse`: Specifies the server-side encryption algorithm used to encrypt the uploaded objects (value options: ``, `AES256`, or `aws:kms`). + - `sse-kms-key-id`: Specifies the KMS ID if `sse` is set to `aws:kms`. + - `acl`: Specifies the canned ACL of the uploaded objects (for example, `private` or `authenticated-read`). - ```bash - ./dumpling -u root -h 127.0.0.1 -P 3306 -B mydb -F 256MiB \ - -o 's3://my-bucket/sql-backup' - ``` +
+
-+ Use TiDB Lightning to import data from S3: +- `scheme`: `gcs` or `gs` +- `host`: `bucket name` +- `parameters`: - {{< copyable "shell-regular" >}} + - `credentials-file`: Specifies the path to the credentials JSON file on the migration tool node. + - `storage-class`: Specifies the storage class of the uploaded objects (for example, `STANDARD` or `COLDLINE`) + - `predefined-acl`: Specifies the predefined ACL of the uploaded objects (for example, `private` or `project-private`) - ```bash - ./tidb-lightning --tidb-port=4000 --pd-urls=127.0.0.1:2379 --backend=local --sorted-kv-dir=/tmp/sorted-kvs \ - -d 's3://my-bucket/sql-backup' - ``` +
+
-+ Use TiDB Lightning to import data from S3 (using the path style in the request mode): +- `scheme`: `azure` or `azblob` +- `host`: `container name` +- `parameters`: - {{< copyable "shell-regular" >}} + - `account-name`: Specifies the account name of the storage. + - `account-key`: Specifies the access key. + - `access-tier`: Specifies the access tier of the uploaded objects, for example, `Hot`, `Cool`, or `Archive`. The value is `Hot` by default. - ```bash - ./tidb-lightning --tidb-port=4000 --pd-urls=127.0.0.1:2379 --backend=local --sorted-kv-dir=/tmp/sorted-kvs \ - -d 's3://my-bucket/sql-backup?force-path-style=true&endpoint=http://10.154.10.132:8088' - ``` +
+
-+ Use TiDB Lightning to import data from S3 (access S3 data by using a specific IAM role): +### URL examples - ```bash - ./tidb-lightning --tidb-port=4000 --pd-urls=127.0.0.1:2379 --backend=local --sorted-kv-dir=/tmp/sorted-kvs \ - -d 's3://my-bucket/test-data?role-arn=arn:aws:iam::888888888888:role/my-role' - ``` +This section provides some URL examples by using `external` as the `host` parameter (`bucket name` or `container name` in the preceding sections). -+ Use BR to back up data to GCS: + +
- {{< copyable "shell-regular" >}} +**Back up snapshot data to Amazon S3** - ```bash - ./br backup full -u 127.0.0.1:2379 \ - -s 'gcs://bucket-name/prefix' - ``` +```shell +./br restore full -u "${PD_IP}:2379" \ +--storage "s3://external/backup-20220915?access-key=${access-key}&secret-access-key=${secret-access-key}" +``` -+ Use BR to back up data to Azblob: +**Restore snapshot data from Amazon S3** - {{< copyable "shell-regular" >}} +```shell +./br restore full -u "${PD_IP}:2379" \ +--storage "s3://external/backup-20220915?access-key=${access-key}&secret-access-key=${secret-access-key}" +``` - ```bash - ./br backup full -u 127.0.0.1:2379 \ - -s 'azure://container-name/prefix' - ``` +
+
-### S3 URL parameters +**Back up snapshot data to GCS** -| URL parameter | Description | -|:----------|:---------| -| `access-key` | The access key | -| `secret-access-key` | The secret access key | -| `use-accelerate-endpoint` | Whether to use the accelerate endpoint on Amazon S3 (default to `false`) | -| `endpoint` | URL of custom endpoint for S3-compatible services (for example, `https://s3.example.com/`) | -| `force-path-style` | Use path style access rather than virtual hosted style access (default to `true`) | -| `storage-class` | Storage class of the uploaded objects (for example, `STANDARD`, `STANDARD_IA`) | -| `sse` | Server-side encryption algorithm used to encrypt the upload (empty, `AES256` or `aws:kms`) | -| `sse-kms-key-id` | If `sse` is set to `aws:kms`, specifies the KMS ID | -| `acl` | Canned ACL of the uploaded objects (for example, `private`, `authenticated-read`) | -| `role-arn` | When you need to access Amazon S3 data from a third party using a specified [IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html), you can specify the corresponding [Amazon Resource Name (ARN)](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) of the IAM role with the `role-arn` URL query parameter, such as `arn:aws:iam::888888888888:role/my-role`. For more information about using an IAM role to access Amazon S3 data from a third party, see [AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html). | -| `external-id` | When you access Amazon S3 data from a third party, you might need to specify a correct [external ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) to assume [the IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html). In this case, you can use this `external-id` URL query parameter to specify the external ID. An external ID is an arbitrary string provided by the third party together with the IAM role ARN to access the Amazon S3 data. Providing an external ID is optional when assuming an IAM role, which means if the third party does not specify an external ID for the IAM role, you can assume the role and access the corresponding S3 data without providing this parameter. | +```shell +./br backup full --pd "${PD_IP}:2379" \ +--storage "gcs://external/backup-20220915?credentials-file=${credentials-file-path}" +``` -> **Note:** -> -> It is not recommended to pass in the access key and secret access key directly in the storage URL, because these keys are logged in plain text. +**Restore snapshot data from GCS** -If neither the access key and secret access key nor IAM role ARN (`role-arn`) and external ID (`external-id`) are provided, the migration tools try to infer these keys from the environment in the following order: +```shell +./br restore full --pd "${PD_IP}:2379" \ +--storage "gcs://external/backup-20220915?credentials-file=${credentials-file-path}" +``` -1. `$AWS_ACCESS_KEY_ID` and `$AWS_SECRET_ACCESS_KEY` environment variables -2. `$AWS_ACCESS_KEY` and `$AWS_SECRET_KEY` environment variables -3. Shared credentials file on the tool node at the path specified by the `$AWS_SHARED_CREDENTIALS_FILE` environment variable -4. Shared credentials file on the tool node at `~/.aws/credentials` -5. Current IAM role of the Amazon EC2 container -6. Current IAM role of the Amazon ECS task +
+
-### GCS URL parameters +**Back up snapshot data to Azure Blob Storage** -| URL parameter | Description | -|:----------|:---------| -| `credentials-file` | The path to the credentials JSON file on the tool node | -| `storage-class` | Storage class of the uploaded objects (for example, `STANDARD`, `COLDLINE`) | -| `predefined-acl` | Predefined ACL of the uploaded objects (for example, `private`, `project-private`) | +```shell +./br backup full -u "${PD_IP}:2379" \ +--storage "azure://external/backup-20220915?account-name=${account-name}&account-key=${account-key}" +``` -When `credentials-file` is not specified, the migration tool will try to infer the credentials from the environment, in the following order: +**Restore the `test` database from snapshot backup data in Azure Blob Storage** -1. Content of the file on the tool node at the path specified by the `$GOOGLE_APPLICATION_CREDENTIALS` environment variable -2. Content of the file on the tool node at `~/.config/gcloud/application_default_credentials.json` -3. When running in GCE or GAE, the credentials fetched from the metadata server. +```shell +./br restore db --db test -u "${PD_IP}:2379" \ +--storage "azure://external/backup-20220915account-name=${account-name}&account-key=${account-key}" +``` -### Azblob URL parameters +
+
-| URL parameter | Description | -|:----------|:-----| -| `account-name` | The account name of the storage | -| `account-key` | The access key| -| `access-tier` | Access tier of the uploaded objects (for example, `Hot`, `Cool`, `Archive`). If `access-tier` is not set (the value is empty), the value is `Hot` by default. | +## Authentication -To ensure that TiKV and BR use the same storage account, BR determines the value of `account-name`. That is, `send-credentials-to-tikv = true` is set by default. BR infers these keys from the environment in the following order: +When storing backup data in a cloud storage system, you need to configure authentication parameters depending on the specific cloud service provider. This section describes the authentication methods used by Amazon S3, GCS, and Azure Blob Storage, and how to configure the accounts used to access the corresponding storage service. -1. If both `account-name` **and** `account-key` are specified, the key specified by this parameter is used. -2. If `account-key` is not specified, BR tries to read the related credentials from environment variables on the node of BR. BR reads `$AZURE_CLIENT_ID`, `$AZURE_TENANT_ID`, and `$AZURE_CLIENT_SECRET` first. At the same time, BR allows TiKV to read these three environment variables from the respective nodes and access the variables using Azure AD (Azure Active Directory). -3. If the preceding three environment variables are not configured in the BR node, BR tries to read `$AZURE_STORAGE_KEY` using an access key. + +
-> **Note:** -> -> - When using Azure Blob Storage as the external storage, you should set `send-credentials-to-tikv = true` (which is set by default). Otherwise, the backup task will fail. -> - `$AZURE_CLIENT_ID`, `$AZURE_TENANT_ID`, and `$AZURE_CLIENT_SECRET` respectively refer to the application ID `client_id`, the tenant ID `tenant_id`, and the client password `client_secret` of the Azure application. For details about how to confirm the presence of the three environment variables, or how to configure the environment variables as parameters, see [Configure environment variables](/br/backup-storage-azblob.md#configure-environment-variables). +Before backup, configure the following privileges to access the backup directory on S3. -## Command-line parameters +- Minimum privileges for TiKV and Backup & Restore (BR) to access the backup directories during backup: `s3:ListBucket`, `s3:PutObject`, and `s3:AbortMultipartUpload` +- Minimum privileges for TiKV and BR to access the backup directories during restore: `s3:ListBucket` and `s3:GetObject` -In addition to the URL parameters, BR and Dumpling also support specifying these configurations using command-line parameters. For example: +If you have not yet created a backup directory, refer to [Create a bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html) to create an S3 bucket in the specified region. If necessary, you can also create a folder in the bucket by referring to [Create a folder](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-folders.html). -{{< copyable "shell-regular" >}} +It is recommended that you configure access to S3 using either of the following ways: -```bash -./dumpling -u root -h 127.0.0.1 -P 3306 -B mydb -F 256MiB \ - -o 's3://my-bucket/sql-backup' \ - --s3.role-arn="arn:aws:iam::888888888888:role/my-role" -``` +- Method 1: Specify the access key -The preceding command is equivalent to the following: + If you specify an access key and a secret access key in the URL, authentication is performed using the specified access key and secret access key. Besides specifying the key in the URL, the following methods are also supported: -```bash -./dumpling -u root -h 127.0.0.1 -P 3306 -B mydb -F 256MiB \ - -o 's3://my-bucket/sql-backup&role-arn=arn:aws:iam::888888888888:role/my-role' -``` + - BR reads the environment variables `$AWS_ACCESS_KEY_ID` and `$AWS_SECRET_ACCESS_KEY`. + - BR reads the environment variables `$AWS_ACCESS_KEY` and `$AWS_SECRET_KEY`. + - BR reads the shared credentials file in the path specified by the environment variable `$AWS_SHARED_CREDENTIALS_FILE`. + - BR reads the shared credentials file in the `~/.aws/credentials` path. -If you have specified URL parameters and command-line parameters at the same time, the URL parameters are overwritten by the command-line parameters. +- Method 2: Access based on the IAM role -### S3 command-line parameters + Associate an IAM role that can access S3 with EC2 instances where the TiKV and BR nodes run. After the association, BR can directly access the backup directories in S3 without additional settings. -| Command-line parameter | Description | -|:----------|:------| -| `--s3.endpoint` | The URL of custom endpoint for S3-compatible services. For example, `https://s3.example.com/`. | -| `--s3.storage-class` | The storage class of the upload object. For example, `STANDARD` or `STANDARD_IA`. | -| `--s3.sse` | The server-side encryption algorithm used to encrypt the upload. The value options are empty, `AES256` and `aws:kms`. | -| `--s3.sse-kms-key-id` | If `--s3.sse` is configured as `aws:kms`, this parameter is used to specify the KMS ID. | -| `--s3.acl` | The canned ACL of the upload object. For example, `private` or `authenticated-read`. | -| `--s3.provider` | The type of the S3-compatible service. The supported types are `aws`, `alibaba`, `ceph`, `netease` and `other`. | -| `--s3.role-arn` | When you need to access Amazon S3 data from a third party using a specified [IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html), you can specify the corresponding [Amazon Resource Name (ARN)](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) of the IAM role with the `--s3.role-arn` option, such as `arn:aws:iam::888888888888:role/my-role`. For more information about using an IAM role to access Amazon S3 data from a third party, see [AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html). | -| `--s3.external-id` | When you access Amazon S3 data from a third party, you might need to specify a correct [external ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) to assume [the IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html). In this case, you can use this `--s3.external-id` option to specify the external ID. An external ID is an arbitrary string provided by the third party together with the IAM role ARN to access the Amazon S3 data. Providing an external ID is optional when assuming an IAM role, which means if the third party does not specify an external ID for the IAM role, you can assume the role and access the corresponding S3 data without providing this parameter. | + ```shell + br backup full --pd "${PD_IP}:2379" \ + --storage "s3://${host}/${path}" + ``` -To export data to non-AWS S3 cloud storage, specify the cloud provider and whether to use `virtual-hosted style`. In the following examples, data is exported to the Alibaba Cloud OSS storage: +
+
-+ Export data to Alibaba Cloud OSS using Dumpling: +You can configure the account used to access GCS by specifying the access key. If you specify the `credentials-file` parameter, the authentication is performed using the specified `credentials-file`. Besides specifying the key in the URL, the following methods are also supported: - {{< copyable "shell-regular" >}} +- BR reads the file in the path specified by the environment variable `$GOOGLE_APPLICATION_CREDENTIALS` +- BR reads the file `~/.config/gcloud/application_default_credentials.json`. +- BR obtains the credentials from the metadata server when the cluster is running in GCE or GAE. - ```bash - ./dumpling -h 127.0.0.1 -P 3306 -B mydb -F 256MiB \ - -o "s3://my-bucket/dumpling/" \ - --s3.endpoint="http://oss-cn-hangzhou-internal.aliyuncs.com" \ - --s3.provider="alibaba" \ - -r 200000 -F 256MiB - ``` +
+
-+ Back up data to Alibaba Cloud OSS using BR: +- Method 1: Specify the access key - {{< copyable "shell-regular" >}} + If you specify `account-name` and `account-key` in the URL, the authentication is performed using the specified access key and secret access key. Besides the method of specifying the key in the URL, BR can also read the key from the environment variable `$AZURE_STORAGE_KEY`. - ```bash - ./br backup full --pd "127.0.0.1:2379" \ - --storage "s3://my-bucket/full/" \ - --s3.endpoint="http://oss-cn-hangzhou-internal.aliyuncs.com" \ - --s3.provider="alibaba" \ - --send-credentials-to-tikv=true \ - --ratelimit 128 \ - --log-file backuptable.log - ``` +- Method 2: Use Azure AD for backup and restore -+ Export data to Alibaba Cloud OSS using TiDB Lightning. You need to specify the following content in the YAML-formatted configuration file: + Configure the environment variables `$AZURE_CLIENT_ID`, `$AZURE_TENANT_ID`, and `$AZURE_CLIENT_SECRET` on the node where BR is running. - {{< copyable "" >}} + - When the cluster is started using TiUP, TiKV uses the systemd service. The following example shows how to configure the preceding three environment variables for TiKV: - ``` - [mydumper] - data-source-dir = "s3://my-bucket/dumpling/?endpoint=http://oss-cn-hangzhou-internal.aliyuncs.com&provider=alibaba" - ``` + > **Note:** + > + > If this method is used, you need to restart TiKV in step 3. If your cluster cannot be restarted, use **Method 1: Specify the access key** for backup and restore. -### GCS command-line parameters + 1. Suppose that the TiKV port on this node is `24000`, that is, the name of the systemd service is `tikv-24000`: -| Command-line parameter | Description | -|:----------|:------| -| `--gcs.credentials-file` | The path of the JSON-formatted credential on the tool node | -| `--gcs.storage-class` | The storage type of the upload objects (for example, `STANDARD` or `COLDLINE`) | -| `--gcs.predefined-acl` | The pre-defined ACL of the upload objects (for example, `private` or `project-private`) | + ```shell + systemctl edit tikv-24000 + ``` -### Azblob command-line parameters + 2. Edit the TiKV configuration file to configure the three environment variables: -| Command-line parameter | Description | -| `--azblob.account-name` | The account name of the storage | -| `--azblob.account-key` | The access key | -| `--azblob.access-tier` | Access tier of the uploaded objects (for example, `Hot`, `Cool`, `Archive`). If `access-tier` is not set (the value is empty), the value is `Hot` by default. | + ``` + [Service] + Environment="AZURE_CLIENT_ID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + Environment="AZURE_TENANT_ID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" + Environment="AZURE_CLIENT_SECRET=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ``` -## BR sending credentials to TiKV + 3. Reload the configuration and restart TiKV: -By default, when using S3, GCS, or Azblob destinations, BR will send the credentials to every TiKV node to reduce setup complexity. + ```shell + systemctl daemon-reload + systemctl restart tikv-24000 + ``` -However, this is unsuitable on cloud environment, where every node has their own role and permission. In such cases, you need to disable credentials sending with `--send-credentials-to-tikv=false` (or the short form `-c=0`): + - To configure the Azure AD information for TiKV and BR started with command lines, you only need to check whether the environment variables `$AZURE_CLIENT_ID`, `$AZURE_TENANT_ID`, and `$AZURE_CLIENT_SECRET` are configured in the operating environment by running the following commands: -{{< copyable "shell-regular" >}} + ```shell + echo $AZURE_CLIENT_ID + echo $AZURE_TENANT_ID + echo $AZURE_CLIENT_SECRET + ``` -```bash -./br backup full -c=0 -u pd-service:2379 -s 's3://bucket-name/prefix' -``` + - Use BR to back up data to Azure Blob Storage: -When using SQL statements to [back up](/sql-statements/sql-statement-backup.md) and [restore](/sql-statements/sql-statement-restore.md) data, you can add the `SEND_CREDENTIALS_TO_TIKV = FALSE` option: + ```shell + ./br backup full -u "${PD_IP}:2379" \ + --storage "azure://external/backup-20220915?account-name=${account-name}" + ``` -{{< copyable "sql" >}} +
+
-```sql -BACKUP DATABASE * TO 's3://bucket-name/prefix' SEND_CREDENTIALS_TO_TIKV = FALSE; -``` +## Server-side encryption + +### Amazon S3 server-side encryption + +BR supports server-side encryption when backing up data to Amazon S3. You can also use an AWS KMS key you create for S3 server-side encryption using BR. For details, see [BR S3 server-side encryption](/encryption-at-rest.md#br-s3-server-side-encryption). + +## Other features supported by the storage service -This option is not supported in TiDB Lightning and Dumpling, because the two applications are currently standalone. +BR v6.3.0 supports AWS [S3 Object Lock](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html). You can enable this feature to prevent backup data from being tampered with or deleted. diff --git a/br/backup-and-restore-use-cases.md b/br/backup-and-restore-use-cases.md index dc476d1e4b1e7..4770a7bcd7283 100644 --- a/br/backup-and-restore-use-cases.md +++ b/br/backup-and-restore-use-cases.md @@ -1,475 +1,177 @@ --- -title: BR Use Cases -summary: Learn the use cases of backing up and restoring data using BR. -aliases: ['/docs/dev/br/backup-and-restore-use-cases/','/docs/dev/reference/tools/br/use-cases/'] +title: TiDB Backup and Restore Use Cases +summary: Learn the use cases of backing up and restoring data using br command-line tool. +aliases: ['/docs/dev/br/backup-and-restore-use-cases/','/docs/dev/reference/tools/br/use-cases/','/tidb/dev/backup-and-restore-use-cases-for-maintain/'] --- -# BR Use Cases +# TiDB Backup and Restore Use Cases -[Backup & Restore (BR)](/br/backup-and-restore-overview.md) is a tool for distributed backup and restoration of the TiDB cluster data. +[TiDB Snapshot Backup and Restore Guide](/br/br-snapshot-guide.md) and [TiDB Log Backup and PITR Guide](/br/br-pitr-guide.md) introduce the backup and restore solutions provided by TiDB, namely, snapshot (full) backup and restore, log backup and point-in-time recovery (PITR). This document helps you to quickly get started with the backup and restore solutions of TiDB in specific use cases. -This document describes common backup and restoration scenarios: +Assume that you have deployed a TiDB production cluster on AWS and the business team requests the following requirements: -- [Back up a single table to a network disk (recommended for production environments)](#back-up-a-single-table-to-a-network-disk-recommended-for-production-environments) -- [Restore data from a network disk (recommended for production environments)](#restore-data-from-a-network-disk-recommended-for-production-environments) -- [Back up a single table to a local disk](#back-up-a-single-table-to-a-local-disk-recommended-for-testing-environments) -- [Restore data from a local disk](#restore-data-from-a-local-disk-recommended-for-testing-environments) +- Back up the data changes in a timely manner. When the database encounters a disaster, you can quickly recover the application with minimal data loss (only a few minutes of data loss is tolerable). +- Perform business audits every month at no specific time. When an audit request is received, you must provide a database to query the data at a certain time point of the past month as requested. -This document aims to help you achieve the following goals: +With PITR, you can satisfy the preceding requirements. -- Back up and restore data using a network disk or local disk correctly. -- Get the status of a backup or restoration operation through monitoring metrics. -- Learn how to tune performance during the backup or restoration operation. -- Troubleshoot the possible anomalies during the backup operation. +## Deploy the TiDB cluster and BR -## Audience +To use PITR, you need to deploy a TiDB cluster >= v6.4.0 and update BR to the same version as the TiDB cluster. This document uses v6.4.0 as an example. -You are expected to have a basic understanding of TiDB and [TiKV](https://tikv.org/). +The following table shows the recommended hardware resources for using PITR in a TiDB cluster. -Before reading on, make sure you have read [BR Overview](/br/backup-and-restore-overview.md), especially [Usage Restrictions](/br/backup-and-restore-overview.md#usage-restrictions) and [Some tips](/br/backup-and-restore-overview.md#some-tips). - -## Prerequisites - -This section introduces the recommended method of deploying TiDB, cluster versions, the hardware information of the TiKV cluster, and the cluster configuration for the use case demonstrations. - -You can estimate the performance of your backup or restoration operation based on your own hardware and configuration. It is recommended that you use a network disk to back up and restore data. This spares you from collecting backup files and greatly improves the backup efficiency especially when the TiKV cluster is in a large scale. - -### Deployment method - -It is recommended that you deploy the TiDB cluster using [TiUP](/tiup/tiup-cluster.md) and install BR using TiUP. - -### Cluster versions - -- TiDB: v6.4.0 -- TiKV: v6.4.0 -- PD: v6.4.0 -- BR: v6.4.0 - -> **Note:** -> -> It is recommended that you use the latest version of [TiDB/TiKV/PD/BR](/releases/release-notes.md) and make sure that the BR version is **consistent with** the TiDB version. - -### TiKV hardware information - -- Operating system: CentOS Linux release 7.6.1810 (Core) -- CPU: 16-Core Common KVM processor -- RAM: 32 GB -- Disk: 500 GB SSD * 2 -- NIC: 10 Gigabit network card - -### Cluster configuration - -BR directly sends commands to the TiKV cluster and are not dependent on the TiDB server, so you do not need to configure the TiDB server when using BR. - -- TiKV: default configuration -- PD: default configuration - -### Others - -In addition to the preceding prerequisites, you should also perform the following checks before performing the backup and restoration. - -#### Check before backup - -Before running the [`br backup` command](/br/use-br-command-line-tool.md#br-command-line-description), make sure the following conditions are met: - -- No DDL statements are running on the TiDB cluster. -- The target storage device has required space (no less than 1/3 of the disk space of the backup cluster). - -#### Check before restoration - -Before running the [`br restore` command](/br/use-br-command-line-tool.md#br-command-line-description), check the target cluster to ensure that the table in this cluster does not have a duplicate name. - -## Back up a single table to a network disk (recommended for production environments) - -Run the `br backup` command to back up the single table data `--db batchmark --table order_line` to the specified path `local:///br_data` in the network disk. - -### Backup prerequisites - -- [Check before backup](#check-before-backup) -- Configure a high-performance SSD hard disk host as the NFS server to store data, and all BR nodes, TiKV nodes, and TiFlash nodes as NFS clients. Mount the same path (for example, `/br_data`) to the NFS server for NFS clients to access the server. -- The total transfer rate between the NFS server and all NFS clients must reach at least `the number of TiKV instances * 150MB/s`. Otherwise, the network I/O might become the performance bottleneck. - -> **Note:** -> -> - During data backup, because only the data of leader replicas are backed up, even if there is a TiFlash replica in the cluster, BR can complete the backup without mounting TiFlash nodes. -> - When restoring data, BR will restore the data of all replicas. Also, TiFlash nodes need access to the backup data for BR to complete the restore. Therefore, before the restore, you must mount TiFlash nodes to the NFS server. - -### Topology - -The following diagram shows the typology of BR: - -![img](/media/br/backup-nfs-deploy.png) - -### Backup operation - -Run the `br backup` command: - -{{< copyable "shell-regular" >}} - -```shell -bin/br backup table \ - --db batchmark \ - --table order_line \ - -s local:///br_data \ - --pd ${PD_ADDR}:2379 \ - --log-file backup-nfs.log -``` - -### Monitoring metrics for the backup - -During the backup process, pay attention to the following metrics on the monitoring panels to get the status of the backup process. - -**Backup CPU Utilization**: the CPU usage rate of each working TiKV node in the backup operation (for example, backup-worker and backup-endpoint). - -![img](/media/br/backup-cpu.png) - -**IO Utilization**: the I/O usage rate of each working TiKV node in the backup operation. - -![img](/media/br/backup-io.png) - -**BackupSST Generation Throughput**: the backupSST generation throughput of each working TiKV node in the backup operation, which is normally around 150 MB/s. - -![img](/media/br/backup-throughput.png) - -**One Backup Range Duration**: the duration of backing up a range, which is the total time cost of scanning KVs and storing the range as the backupSST file. - -![img](/media/br/backup-range-duration.png) - -**One Backup Subtask Duration**: the duration of each sub-task into which a backup task is divided. +| Component | CPU | Memory | Disk | AWS instance | Number of instances | +| --- | --- | --- | --- | --- | --- | +| TiDB | 8 core+ | 16 GB+ | SAS | c5.2xlarge | 2 | +| PD | 8 core+ | 16 GB+ | SSD | c5.2xlarge | 3 | +| TiKV | 8 core+ | 32 GB+ | SSD | m5.2xlarge | 3 | +| BR | 8 core+ | 16 GB+ | SAS | c5.2xlarge | 1 | +| Monitor | 8 core+ | 16 GB+ | SAS | c5.2xlarge | 1 | > **Note:** > -> - In this task, the single table to be backed up has three indexes and the task is normally divided into four sub-tasks. -> - The panel in the following image has 20 points on it, 10 blue and 10 yellow, indicating that there are 10 sub-tasks. Region scheduling might occur during the backup process, so a few retries is normal. - -![img](/media/br/backup-subtask-duration.png) - -**Backup Errors**: the errors occurred during the backup process. No error occurs in normal situations. Even if a few errors occur, the backup operation has the retry mechanism which might increase the backup time but does not affect the operation correctness. - -![img](/media/br/backup-errors.png) - -**Checksum Request Duration**: the duration of the admin checksum request in the backup cluster. - -![img](/media/br/checksum-duration.png) - -### Backup results explanation - -When finishing the backup, BR outputs the backup summary to the console. - -In the log specified before running the backup command, you can get the statistical information of the backup operation from this log. Search "summary" in this log, you can see the following information: - -``` -["Full backup Success summary: - total backup ranges: 2, - total success: 2, - total failed: 0, - total take(Full backup time): 31.802912166s, - total take(real time): 49.799662427s, - total size(MB): 5997.49, - avg speed(MB/s): 188.58, - total kv: 120000000"] - ["backup checksum"=17.907153678s] - ["backup fast checksum"=349.333µs] - ["backup total regions"=43] - [BackupTS=422618409346269185] - [Size=826765915] -``` - -The preceding log includes the following information: - -- `total take(Full backup time)`: Backup duration -- `total take(real time)`: Total runtime of the application -- `total size(MB)`: The size of the backup data -- `avg speed(MB/s)`: Backup throughput -- `total kv`: The number of backed-up KV pairs -- `backup checksum`: Backup checksum duration -- `backup fast checksum`: The total duration of calculating the checksum, KV pairs, and bytes of each table -- `backup total regions`: The total number of backup Regions -- `BackupTS`: The snapshot timestamp of the backup data -- `Size`: The actual size of the backup data in the disk after compression +> - When BR runs backup and restore tasks, it needs to access PD and TiKV. Make sure that BR can connect to all PD and TiKV nodes. +> - BR and PD servers must use the same time zone. -From the preceding information, the throughput of a single TiKV instance can be calculated: `avg speed(MB/s)`/`tikv_count` = `62.86`. +Deploy or upgrade a TiDB cluster using TiUP: -### Performance tuning +- To deploy a new TiDB cluster, refer to [Deploy a TiDB cluster](/production-deployment-using-tiup.md). +- If the TiDB cluster is earlier than v6.4.0, upgrade it by referring to [Upgrade a TiDB cluster](/upgrade-tidb-using-tiup.md). -If the resource usage of TiKV does not become an obvious bottleneck during the backup process (for example, in the [Monitoring metrics for the backup](#monitoring-metrics-for-the-backup), the highest CPU usage rate of backup-worker is around `1500%` and the overall I/O usage rate is below `30%`), you can try to increase the value of `--concurrency` (`4` by default) to tune the performance. But this performance tuning method is not suitable for the use cases of many small tables. See the following example: +Install or upgrade BR using TiUP: -{{< copyable "shell-regular" >}} +- Install: -```shell -bin/br backup table \ - --db batchmark \ - --table order_line \ - -s local:///br_data/ \ - --pd ${PD_ADDR}:2379 \ - --log-file backup-nfs.log \ - --concurrency 16 -``` - -![img](/media/br/backup-diff.png) - -![img](/media/br/backup-diff2.png) - -The tuned performance results are as follows (with the same data size): - -- Backup duration (`total take(s)`): reduced from `986.43` to `535.53` -- Backup throughput (`avg speed(MB/s)`): increased from `358.09` to `659.59` -- Throughput of a single TiKV instance (`avg speed(MB/s)/tikv_count`): increased from `89` to `164.89` - -## Restore data from a network disk (recommended for production environments) - -Use the `br restore` command to restore the complete backup data to an offline cluster. Currently, BR does not support restoring data to an online cluster. + ```shell + tiup install br:v6.4.0 + ``` -### Restoration prerequisites +- Upgrade: -- [Check before restore](#check-before-restoration) + ```shell + tiup update br:v6.4.0 + ``` -### Topology - -The following diagram shows the typology of BR: - -![img](/media/br/restore-nfs-deploy.png) - -### Restoration operation - -Run the `br restore` command: - -{{< copyable "shell-regular" >}} - -```shell -bin/br restore table --db batchmark --table order_line -s local:///br_data --pd 172.16.5.198:2379 --log-file restore-nfs.log -``` +## Configure backup storage (Amazon S3) -### Monitoring metrics for the restoration +Before you start a backup task, prepare the backup storage, including the following aspects: -During the restoration process, pay attention to the following metrics on the monitoring panels to get the status of the restoration process. +1. Prepare the S3 bucket and directory that stores the backup data. +2. Configure the permissions to access the S3 bucket. +3. Plan the subdirectory that stores each backup data. -**CPU**: the CPU usage rate of each working TiKV node in the restoration operation. +The detailed steps are as follows: -![img](/media/br/restore-cpu.png) +1. Create a directory in S3 to store the backup data. The directory in this example is `s3://tidb-pitr-bucket/backup-data`. -**IO Utilization**: the I/O usage rate of each working TiKV node in the restoration operation. + 1. Create a bucket. You can choose an existing S3 to store the backup data. If there is none, refer to [AWS documentation: Creating a bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html) and create an S3 bucket. In this example, the bucket name is `tidb-pitr-bucket`. + 2. Create a directory for your backup data. In the bucket (`tidb-pitr-bucket`), create a directory named `backup-data`. For detailed steps, refer to [AWS documentation: Organizing objects in the Amazon S3 console using folders](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-folders.html). -![img](/media/br/restore-io.png) +2. Configure permissions for BR and TiKV to access the S3 directory. It is recommended to grant permissions using the IAM method, which is the most secure way to access the S3 bucket. For detailed steps, refer to [AWS documentation: Controlling access to a bucket with user policies](https://docs.aws.amazon.com/AmazonS3/latest/userguide/walkthrough1.html). The required permissions are as follows: -**Region**: the Region distribution. The more even Regions are distributed, the better the restoration resources are used. + - TiKV and BR in the backup cluster need `s3:ListBucket`, `s3:PutObject`, and `s3:AbortMultipartUpload` permissions of the `s3://tidb-pitr-bucket/backup-data` directory. + - TiKV and BR in the restore cluster need `s3:ListBucket` and `s3:GetObject` permissions of the `s3://tidb-pitr-bucket/backup-data` directory. -![img](/media/br/restore-region.png) +3. Plan the directory structure that stores the backup data, including the snapshot (full) backup and the log backup. -**Process SST Duration**: the delay of processing the SST files. When restoring a table, if `tableID` is changed, you need to rewrite `tableID`. Otherwise, `tableID` is renamed. Generally, the delay of rewriting is longer than that of renaming. + - All snapshot backup data are stored in the `s3://tidb-pitr-bucket/backup-data/snapshot-${date}` directory. `${date}` is the start time of the snapshot backup. For example, a snapshot backup starting at 2022/05/12 00:01:30 is stored in `s3://tidb-pitr-bucket/backup-data/snapshot-20220512000130`. + - Log backup data are stored in the `s3://tidb-pitr-bucket/backup-data/log-backup/` directory. -![img](/media/br/restore-process-sst.png) +## Determine the backup policy -**DownLoad SST Throughput**: the throughput of downloading SST files from External Storage. +To meet the requirements of minimum data loss, quick recovery, and business audits within a month, you can set the backup policy as follows: -![img](/media/br/restore-download-sst.png) +- Run the log backup to continuously back up the data change in the database. +- Run a snapshot backup at 00:00 AM every two days. +- Retain the snapshot backup data and log backup data within 30 days and clean up backup data older than 30 days. -**Restore Errors**: the errors occurred during the restoration process. +## Run log backup -![img](/media/br/restore-errors.png) - -**Checksum Request Duration**: the duration of the admin checksum request. This duration for the restoration is longer than that for the backup. - -![img](/media/br/restore-checksum.png) - -### Restoration results explanation - -In the log specified before running the restoration command, you can get the statistical information of the restoration operation from this log. Search "summary" in this log, you can see the following information: - -``` -["Table Restore summary: - total restore tables: 1, - total success: 1, - total failed: 0, - total take(Full restore time): 17m1.001611365s, - total take(real time): 16m1.371611365s, - total kv: 5659888624, - total size(MB): 353227.18, - avg speed(MB/s): 367.42"] - ["restore files"=9263] - ["restore ranges"=6888] - ["split region"=49.049182743s] - ["restore checksum"=6m34.879439498s] - [Size=48693068713] -``` - -The preceding log includes the following information: - -- `total take(Full restore time)`: The restoration duration -- `total take(real time)`: The total runtime of the application -- `total size(MB)`: The size of the data to be restored -- `total kv`: The number of restored KV pairs -- `avg speed(MB/s)`: The restoration throughput -- `split region`: The Region split duration -- `restore checksum`: The restoration checksum duration -- `Size`: The actual size of the restored data in the disk - -From the preceding information, the following items can be calculated: - -- The throughput of a single TiKV instance: `avg speed(MB/s)`/`tikv_count` = `91.8` -- The average restore speed of a single TiKV instance: `total size(MB)`/(`split time` + `restore time`)/`tikv_count` = `87.4` - -#### Performance tuning - -If the resource usage of TiKV does not become an obvious bottleneck during the restore process, you can increase the value of `--concurrency` (defaults to `128`). See the following example: - -{{< copyable "shell-regular" >}} +After the log backup task is started, the log backup process runs in the TiKV cluster to continuously send the data change in the database to the S3 storage. To start a log backup task, run the following command: ```shell -bin/br restore table --db batchmark --table order_line -s local:///br_data/ --pd 172.16.5.198:2379 --log-file restore-concurrency.log --concurrency 1024 +tiup br log start --task-name=pitr --pd="${PD_IP}:2379" \ +--storage='s3://tidb-pitr-bucket/backup-data/log-backup' ``` -The tuned performance results are as follows (with the same data size): - -- Restoration duration (`total take(s)`): reduced from `961.37` to `443.49` -- Restoration throughput (`avg speed(MB/s)`): increased from `367.42` to `796.47` -- Throughput of a single TiKV instance (`avg speed(MB/s)`/`tikv_count`): increased from `91.8` to `199.1` -- Average restore speed of a single TiKV instance (`total size(MB)`/(`split time` + `restore time`)/`tikv_count`): increased from `87.4` to `162.3` - -## Back up a single table to a local disk (recommended for testing environments) - -Run the `br backup` command to back up a single table `--db batchmark --table order_line` to the specified path `local:///home/tidb/backup_local` in the local disk. - -### Backup prerequisites - -* [Check before backup](#check-before-backup) -* Each TiKV node has a separate disk to store backupSST files. -* The `backup_endpoint` node has a separate disk to store `backupmeta` files. -* TiKV and the `backup_endpoint` node share the same directory (for example, `/home/tidb/backup_local`) for backup. - -### Topology - -The following diagram shows the typology of BR: - -![img](/media/br/backup-local-deploy.png) - -### Backup operation - -Run the `br backup` command: - -{{< copyable "shell-regular" >}} +When the log backup task is running, you can query the backup status: ```shell -bin/br backup table \ - --db batchmark \ - --table order_line \ - -s local:///home/tidb/backup_local/ \ - --pd ${PD_ADDR}:2379 \ - --log-file backup_local.log -``` - -During the backup process, pay attention to the metrics on the monitoring panels to get the status of the backup process. See [Monitoring metrics for the backup](#monitoring-metrics-for-the-backup) for details. - -#### Backup results explanation - -In the log specified before running the backup command, you can get the statistical information of the restoration operation from this log. Search "summary" in this log, you can see the following information: - -``` -["Table backup summary: - total backup ranges: 4, - total success: 4, - total failed: 0, - total take(s): 551.31, - total kv: 5659888624, - total size(MB): 353227.18, - avg speed(MB/s): 640.71"] - ["backup total regions"=6795] - ["backup checksum"=6m33.962719217s] - ["backup fast checksum"=22.995552ms] +tiup br log status --task-name=pitr --pd="${PD_IP}:2379" + +● Total 1 Tasks. +> #1 < + name: pitr + status: ● NORMAL + start: 2022-05-13 11:09:40.7 +0800 + end: 2035-01-01 00:00:00 +0800 + storage: s3://tidb-pitr-bucket/backup-data/log-backup + speed(est.): 0.00 ops/s +checkpoint[global]: 2022-05-13 11:31:47.2 +0800; gap=4m53s ``` -The preceding log includes the following information: +## Run snapshot backup -- `total take(s)`: The backup duration -- `total size(MB)`: The data size -- `avg speed(MB/s)`: The backup throughput -- `backup checksum`: The backup checksum duration +You can run snapshot backup tasks on a regular basis using an automatic tool such as crontab. For example, run a snapshot backup at 00:00 every two days. -From the preceding information, the throughput of a single TiKV instance can be calculated: `avg speed(MB/s)`/`tikv_count` = `160`. +The following are two snapshot backup examples: -## Restore data from a local disk (recommended for testing environments) +- Run a snapshot backup at 2022/05/14 00:00:00 -Run the `br restore` command to restore the complete backup data to an offline cluster. Currently, BR does not support restoring data to an online cluster. + ```shell + tiup br backup full --pd="${PD_IP}:2379" \ + --storage='s3://tidb-pitr-bucket/backup-data/snapshot-20220514000000' \ + --backupts='2022/05/14 00:00:00' + ``` -### Restoration prerequisites +- Run a snapshot backup at 2022/05/16 00:00:00 -- [Check before restore](#check-before-restoration) -- The TiKV cluster and the backup data do not have a duplicate database or table. Currently, BR does not support table route. -- Each TiKV node has a separate disk to store backupSST files. -- The `restore_endpoint` node has a separate disk to store `backupmeta` files. -- TiKV and the `restore_endpoint` node share the same directory (for example, `/home/tidb/backup_local/`) for restoration. + ```shell + tiup br backup full --pd="${PD_IP}:2379" \ + --storage='s3://tidb-pitr-bucket/backup-data/snapshot-20220516000000' \ + --backupts='2022/05/16 00:00:00' + ``` -Before the restoration, follow these steps: +## Run PITR -1. Collect all backupSST files into the same directory. -2. Copy the collected backupSST files to all TiKV nodes of the cluster. -3. Copy the `backupmeta` files to the `restore endpoint` node. +Assume that you need to query the data at 2022/05/15 18:00:00. You can use PITR to restore a cluster to that time point by restoring a snapshot backup taken at 2022/05/14 and the log backup data between the snapshot and 2022/05/15 18:00:00. -### Topology - -The following diagram shows the typology of BR: - -![img](/media/br/restore-local-deploy.png) - -### Restoration operation - -Run the `br restore` command: - -{{< copyable "shell-regular" >}} +The command is as follows: ```shell -bin/br restore table --db batchmark --table order_line -s local:///home/tidb/backup_local/ --pd 172.16.5.198:2379 --log-file restore_local.log +tiup br restore point --pd="${PD_IP}:2379" \ +--storage='s3://tidb-pitr-bucket/backup-data/log-backup' \ +--full-backup-storage='s3://tidb-pitr-bucket/backup-data/snapshot-20220514000000' \ +--restored-ts '2022-05-15 18:00:00+0800' + +Full Restore <--------------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% +[2022/05/29 18:15:39.132 +08:00] [INFO] [collector.go:69] ["Full Restore success summary"] [total-ranges=12] [ranges-succeed=xxx] [ranges-failed=0] [split-region=xxx.xxxµs] [restore-ranges=xxx] [total-take=xxx.xxxs] [restore-data-size(after-compressed)=xxx.xxx] [Size=xxxx] [BackupTS={TS}] [total-kv=xxx] [total-kv-size=xxx] [average-speed=xxx] +Restore Meta Files <--------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% +Restore KV Files <----------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% +[2022/05/29 18:15:39.325 +08:00] [INFO] [collector.go:69] ["restore log success summary"] [total-take=xxx.xx] [restore-from={TS}] [restore-to={TS}] [total-kv-count=xxx] [total-size=xxx] ``` -During the restoration process, pay attention to the metrics on the monitoring panels to get the status of the restoration process. See [Monitoring metrics for the restoration](#monitoring-metrics-for-the-restoration) for details. - -### Restoration results explanation - -In the log specified before running the restoration command, you can get the statistical information of the restoration operation from this log. Search "summary" in this log, you can see the following information: - -``` -["Table Restore summary: - total restore tables: 1, - total success: 1, - total failed: 0, - total take(s): 908.42, - total kv: 5659888624, - total size(MB): 353227.18, - avg speed(MB/s): 388.84"] - ["restore files"=9263] - ["restore ranges"=6888] - ["split region"=58.7885518s] - ["restore checksum"=6m19.349067937s] -``` - -The preceding log includes the following information: - -- `total take(s)`: The restoration duration -- `total size(MB)`: The data size -- `avg speed(MB/s)`: The restoration throughput -- `split region`: The region split duration -- `restore checksum`: The restoration checksum duration - -From the preceding information, the following items can be calculated: - -- The throughput of a single TiKV instance: `avg speed(MB/s)`/`tikv_count` = `97.2` -- The average restoration speed of a single TiKV instance: `total size(MB)`/(`split time` + `restore time`)/`tikv_count` = `92.4` - -## Error handling during backup +## Clean up outdated data -This section introduces the common errors that might occur during the backup process. +You can clean up outdated data every two days using an automatic tool such as crontab. -### `key locked Error` in the backup log +For example, you can run the following commands to clean up outdated data: -Error message in the log: `log - ["backup occur kv error"][error="{\"KvError\":{\"locked\":` +- Delete snapshot data earlier than 2022/05/14 00:00:00 -If a key is locked during the backup process, BR tries to resolve the lock. A small number of this error do not affect the correctness of the backup. + ```shell + rm s3://tidb-pitr-bucket/backup-data/snapshot-20220514000000 + ``` -### Backup failure +- Delete log backup data earlier than 2022/05/14 00:00:00 -Error message in the log: `log - Error: msg:"Io(Custom { kind: AlreadyExists, error: \"[5_5359_42_123_default.sst] is already exists in /dir/backup_local/\" })"` + ```shell + tiup br log truncate --until='2022-05-14 00:00:00 +0800' --storage='s3://tidb-pitr-bucket/backup-data/log-backup' + ``` -If the backup operation fails and the preceding message occurs, perform one of the following operations and then start the backup operation again: +## See also -- Change the directory for the backup. For example, change `/dir/backup-2020-01-01/` to `/dir/backup_local/`. -- Delete the backup directory of all TiKV nodes and BR nodes. +- [Backup Storages](/br/backup-and-restore-storages.md) +- [Snapshot Backup and Restore Command Manual](/br/br-snapshot-manual.md) +- [Log Backup and PITR Command Manual](/br/br-pitr-manual.md) diff --git a/br/backup-storage-S3.md b/br/backup-storage-S3.md deleted file mode 100644 index 38f87f6d22fa7..0000000000000 --- a/br/backup-storage-S3.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: Back Up and Restore Data on Amazon S3 Using BR -summary: Learn how to use BR to back up data to and restore data from Amazon S3 storage. ---- - -# Back Up and Restore Data on Amazon S3 Using BR - -The Backup & Restore (BR) tool supports using Amazon S3 or other Amazon S3-compatible file storages as the external storage for backing up and restoring data. - -> **Note:** -> -> To back up data to an S3 bucket with Object Lock enabled, make sure that your TiDB cluster is v6.3.0 or later. - -## Application scenarios - -By using Amazon S3, you can quickly back up the data of a TiDB cluster deployed on Amazon EC2 to Amazon S3, or quickly restore a TiDB cluster from the backup data in Amazon S3. - -## Configure privileges to access S3 - -Before performing backup or restoration using S3, you need to configure the privileges required to access S3. - -### Configure access to the S3 directory - -Before backup, configure the following privileges to access the backup directory on S3. - -- Minimum privileges for TiKV and BR to access the backup directories of `s3:ListBucket`, `s3:PutObject`, and `s3:AbortMultipartUpload` during backup -- Minimum privileges for TiKV and BR to access the backup directories of `s3:ListBucket` and `s3:GetObject` during restoration - -If you have not yet created a backup directory, refer to [AWS Official Document](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html) to create an S3 bucket in the specified region. If necessary, you can also create a folder in the bucket by referring to [AWS official documentation - Create Folder](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-folders.html). - -### Configure a user to access S3 - -It is recommended that you configure access to S3 using either of the following ways: - -- Associate an IAM role that can access S3 with the EC2 instances where the TiKV and BR nodes run. After the association, BR can access the backup directories of S3. - - {{< copyable "shell-regular" >}} - - ```shell - br backup full --pd "${PDIP}:2379" --storage "s3://${Bucket}/${Folder}" - ``` - -- Configure `access-key` and `secret-access-key` for accessing S3 in the `br` CLI, and set `--send-credentials-to-tikv=true` to pass the access key from BR to each TiKV. - - {{< copyable "shell-regular" >}} - - ```shell - br backup full --pd "${PDIP}:2379" --storage "s3://${Bucket}/${Folder}?access-key=${accessKey}&secret-access-key=${secretAccessKey}" --send-credentials-to-tikv=true - ``` - -Because the access key in a command is vulnerable to leakage, you are recommended to associate an IAM role to EC2 instances to access S3. - -## Back up data to S3 - -{{< copyable "shell-regular" >}} - -```shell -br backup full \ - --pd "${PDIP}:2379" \ - --storage "s3://${Bucket}/${Folder}?access-key=${accessKey}&secret-access-key=${secretAccessKey}" \ - --send-credentials-to-tikv=true \ - --ratelimit 128 \ - --log-file backuptable.log -``` - -In the preceding command: - -- `--send-credentials-to-tikv`: specifies that access key is passed to the TiKV nodes. - -## Restore data from S3 - -```shell -br restore full \ - --pd "${PDIP}:2379" \ - --storage "s3://${Bucket}/${Folder}?access-key=${accessKey}&secret-access-key=${secretAccessKey}" \ - --ratelimit 128 \ - --send-credentials-to-tikv=true \ - --log-file restorefull.log -``` - -## See also - -To know more information about external storages supported by BR, see [External storages](/br/backup-and-restore-storages.md). diff --git a/br/backup-storage-azblob.md b/br/backup-storage-azblob.md deleted file mode 100644 index bcb271cc2afd7..0000000000000 --- a/br/backup-storage-azblob.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: Back up and Restore Data on Azure Blob Storage Using BR -summary: Learn how to use BR to back up and restore data on Azure Blob Storage. -aliases: ['/tidb/dev/backup-and-restore-azblob/'] ---- - -# Back up and Restore Data on Azure Blob Storage Using BR - -The Backup & Restore (BR) tool supports using Azure Blob Storage as the external storage for backing up and restoring data. - -## User scenario - -Azure virtual machines can quickly store large-scale data on Azure Blob Storage. If you are using Azure virtual machines to deploy your cluster, you can back up your data on Azure Blob Storage. - -## Usage - -With BR, you can back up and restore data on Azure Blob Storage by the following two methods: - -- Back up and restore data using Azure AD (Azure Active Directory) -- Back up and restore data using an access key - -In common cases, to avoid exposing the key information (such as `account-key`) in command lines, it is recommended to use Azure AD. - -The following is an example of backup and restoration operations on Azure Blob Storage using the preceding two methods. The purpose of the operations are as follows: - -- Back up: Back up the `test` database to a space in the `container=test` container with `t1` as the path prefix in Azure Blob Storage. -- Restore: Restore data from a space in the `container=test` container with `t1` as the path prefix in Azure Blob Storage to the `test` database. - -> **Note:** -> -> When backing up data to the Azure Blob Storage using Azure AD or an access key, you need to set `send-credentials-to-tikv = true` (which is `true` by default). Otherwise, the backup task will fail. - -### Method 1: Back up and restore data using Azure AD (recommended) - -This section describes how to back up and restore data using Azure AD. Before performing backup or restoration, you need to configure environment variables. - -#### Configure environment variables - -In the operating environment of BR and TiKV, configure the environment variables `$AZURE_CLIENT_ID`, `$AZURE_TENANT_ID`, and `$AZURE_CLIENT_SECRET`. - -- When you start a cluster using TiUP, TiKV uses the "systemd" service. The following example introduces how to configure the preceding three environment variables as parameters for TiKV: - - > **Note:** - > - > You need to restart TiKV in Step 3. If your TiKV cannot be restarted, use [Method 2](#method-2-back-up-and-restore-using-an-access-key-easy) to back up and restore data. - - 1. Suppose that the TiKV port on this node is 24000, that is, the name of the "systemd" service is "tikv-24000": - - ``` - systemctl edit tikv-24000 - ``` - - 2. Fill in the environment variable information: - - ``` - [Service] - Environment="AZURE_CLIENT_ID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" - Environment="AZURE_TENANT_ID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" - Environment="AZURE_CLIENT_SECRET=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ``` - - 3. Reload the configuration and restart TiKV: - - ``` - systemctl daemon-reload - systemctl restart tikv-24000 - ``` - -- To configure the Azure AD information for TiKV and BR started with command lines, you only need to check whether the environment variables `$AZURE_CLIENT_ID`, `$AZURE_TENANT_ID`, and `$AZURE_CLIENT_SECRET` are configured in the operating environment by running the following commands: - - ``` - echo $AZURE_CLIENT_ID - echo $AZURE_TENANT_ID - echo $AZURE_CLIENT_SECRET - ``` - -For more information about the environment variables, see [Azblob URL parameters](/br/backup-and-restore-storages.md#azblob-url-parameters). - -#### Back up - -This section shows backing up data to `cool tier`, that is, the access tier of the uploaded object is `Cool`. You can specify `account-name` and `access-tier` in two ways. The backup operations differ depending on the way you choose: - -- Specify `account-name` and `access-tier` as parameters in URL: - - ``` - tiup br backup db --db test -u 127.0.0.1:2379 -s 'azure://test/t1?account-name=devstoreaccount1&access-tier=Cool' - ``` - - If `access-tier` is not set (the value is empty), the value is `Hot` by default. - -- Specify `account-name` and `access-tier` as command-line parameters: - - ``` - tiup br backup db --db test -u 127.0.0.1:2379 -s 'azure://test/t1?' --azblob.account-name=devstoreaccount1 --azblob.access-tier=Cool - ``` - -#### Restore - -Similar to how `account-name` is specified in [Back up](#back-up), you can restore data either using URLs or command-line parameters: - -- Specify `account-name` as a parameter in URL: - - ``` - tiup br restore db --db test -u 127.0.0.1:2379 -s 'azure://test/t1?account-name=devstoreaccount1' - ``` - -- Specify `account-name` as a command-line parameter: - - ``` - tiup br restore db --db test -u 127.0.0.1:2379 -s 'azure://test/t1?' --azblob.account-name=devstoreaccount1 - ``` - -### Method 2: Back up and restore using an access key (easy) - -Compared with backing up and restoring data using Azure AD, backup and restoration using an access key is easier because you do not need to configure environment variables. Other steps are similar to those of using Azure AD. - -#### Back up - -- Specify `account-name`, `account-key`, and `access-tier` as parameters in URL: - - ``` - tiup br backup db --db test -u 127.0.0.1:2379 -s 'azure://test/t1?account-name=devstoreaccount1&account-key=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==&access-tier=Cool' - ``` - -- Specify `account-name`, `account-key`, and `access-tier` as command-line parameters: - - ``` - tiup br backup db --db test -u 127.0.0.1:2379 -s 'azure://test/t1?' --azblob.account-name=devstoreaccount1 --azblob.account-key=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw== --azblob.access-tier=Cool - ``` - -#### Restore - -- Specify `account-name` and `account-key` as parameters in URL: - - ``` - tiup br restore db --db test -u 127.0.0.1:2379 -s 'azure://test/t1?account-name=devstoreaccount1&account-key=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==' - ``` - -- Specify `account-name` and `account-key` as command-line parameters: - - ``` - tiup br restore db --db test -u 127.0.0.1:2379 -s 'azure://test/t1?' --azblob.account-name=devstoreaccount1 --azblob.account-key=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw== - ``` - -## Compatibility - -This feature is **only compatible** with v5.4.0 and later versions. - -## See also - -- To learn other external storages supported by BR, see [External storages](/br/backup-and-restore-storages.md). -- To learn more about the parameters, see the following documents: - - - [Azblob URL parameters](/br/backup-and-restore-storages.md#azblob-url-parameters) - - [Azblob command-line parameters](/br/backup-and-restore-storages.md#azblob-command-line-parameters) diff --git a/br/backup-storage-gcs.md b/br/backup-storage-gcs.md deleted file mode 100644 index a1c622358298b..0000000000000 --- a/br/backup-storage-gcs.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Back Up and Restore Data on Google Cloud Storage Using BR -summary: Learn how to use BR to back up and restore data on Google Cloud Storage. ---- - -# Back Up and Restore Data on Google Cloud Storage Using BR - -The Backup & Restore (BR) tool supports using Google Cloud Storage (GCS) as the external storage for backing up and restoring data. - -## User scenario - -You can quickly back up the data of a TiDB cluster deployed in Google Compute Engine (GCE) to GCS, or quickly restore a TiDB cluster from the backup data in GCS. - -## Back up data to GCS - -{{< copyable "shell-regular" >}} - -```shell -br backup full --pd "${PDIP}:2379" --Storage 'gcs://bucket-name/prefix?credentials-file=${credentials-file-path}' --send-credentials-to-tikv=true -``` - -When backing up data to GCS, you need to place a credential file in the node where BR is running. The credential file contains the account credentials for accessing GCS. If `--send-credentials-to-tikv` is displayed, it means the account access credentials of GCS will be passed to the TiKV node. - -To obtain the credential files, refer to [CREATE AND DOWNLOAD THE GCS CREDENTIALS FILE](https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/13/html/google_cloud_backup_guide/creds). - -## Restore data from GCS - -{{< copyable "shell-regular" >}} - -```shell -br restore full --pd "${PDIP}:2379" --Storage 'gcs://bucket-name/prefix?credentials-file=${credentials-file-path}' --send-credentials-to-tikv=true -``` - -## See also - -To learn other external storages supported by BR, see [External storages](/br/backup-and-restore-storages.md). diff --git a/br/br-auto-tune.md b/br/br-auto-tune.md index 22567eeee1a6d..643df204a9c25 100644 --- a/br/br-auto-tune.md +++ b/br/br-auto-tune.md @@ -1,17 +1,17 @@ --- -title: BR Auto-Tune -summary: Learn about the auto-feature of BR, which automatically limits the resources used by backups to reduce the impact on the cluster in case of high cluster resource usage. +title: Backup Auto-Tune +summary: Learn about the auto-tune feature of TiDB backup and restore, which automatically limits the resources used by backups to reduce the impact on the cluster in case of high cluster resource usage. --- -# BR Auto-Tune New in v5.4.0 +# Backup Auto-Tune New in v5.4.0 -Before TiDB v5.4.0, when you back up data using BR, the number of threads used for backup makes up 75% of the logical CPU cores. Without a speed limit, the backup process can consume a lot of cluster resources, which has a considerable impact on the performance of the online cluster. Although you can reduce the impact of backup by adjusting the size of the thread pool, it is a tedious task to observe the CPU load and manually adjust the thread pool size. +Before TiDB v5.4.0, when you back up data using Backup & Restore (BR), the number of threads used for backup makes up 75% of the logical CPU cores. Without a speed limit, the backup process can consume a lot of cluster resources, which has a considerable impact on the performance of the online cluster. Although you can reduce the impact of backup by adjusting the size of the thread pool, it is a tedious task to observe the CPU load and manually adjust the thread pool size. -To reduce the impact of backup tasks on the cluster, starting from TiDB v5.4.0, BR introduces the auto-tune feature. When the cluster resource utilization is high, BR automatically limits the resources used by backup tasks and thereby reduces their impact on the cluster. The auto-tune feature is enabled by default. +To reduce the impact of backup tasks on the cluster, TiDB v5.4.0 introduces the auto-tune feature, which is enabled by default. When the cluster resource utilization is high, BR automatically limits the resources used by backup tasks and thereby reduces their impact on the cluster. The auto-tune feature is enabled by default. -## User scenario +## Usage scenario -If you want to reduce the impact of backup tasks on the cluster, you can enable the auto-tune feature. With this feature enabled, BR performs backup tasks as fast as possible without excessively affecting the cluster. +If you want to reduce the impact of backup tasks on the cluster, you can enable the auto-tune feature. With this feature enabled, TiDB performs backup tasks as fast as possible without excessively affecting the cluster. Alternatively, you can limit the backup speed by using the TiKV configuration item [`backup.num-threads`](/tikv-configuration-file.md#num-threads-1) or using the parameter `--ratelimit`. @@ -41,7 +41,7 @@ Auto-tune is a coarse-grained solution for limiting backup speed. It reduces the The auto-tune feature has the following issues and corresponding solutions: -- Issue 1: For **write-heavy clusters**, auto-tune might put the workload and backup tasks into a "positive feedback loop": the backup tasks take up too many resources, which causes the cluster to use fewer resources; at this point, auto-tune might mistakenly assume that the cluster is not under heavy workload and thus allow BR to run faster. In such cases, auto-tune is ineffective. +- Issue 1: For **write-heavy clusters**, auto-tune might put the workload and backup tasks into a "positive feedback loop": the backup tasks take up too many resources, which causes the cluster to use fewer resources; at this point, auto-tune might mistakenly assume that the cluster is not under heavy workload and thus allowing backup to run faster. In such cases, auto-tune is ineffective. - Solution: Manually adjust `backup.num-threads` to a smaller number to limit the number of threads used by backup tasks. The working principle is as follows: @@ -57,7 +57,7 @@ The auto-tune feature has the following issues and corresponding solutions: ## Implementation -Auto-tune adjusts the size of the thread pool used by backup tasks using BR to ensure that the overall CPU utilization of the cluster does not exceed a specific threshold. +Auto-tune adjusts the size of the thread pool used by backup tasks to ensure that the overall CPU utilization of the cluster does not exceed a specific threshold. This feature has two related configuration items not listed in the TiKV configuration file. These two configuration items are only for internal tuning. You do **not** need to configure these two configuration items when you perform backup tasks. diff --git a/br/br-batch-create-table.md b/br/br-batch-create-table.md index 9b380379c527a..7394c3a47ad0c 100644 --- a/br/br-batch-create-table.md +++ b/br/br-batch-create-table.md @@ -5,46 +5,46 @@ summary: Learn how to use the Batch Create Table feature. When restoring data, B # Batch Create Table -When restoring data, Backup & Restore (BR) creates databases and tables in the target TiDB cluster and then restores the backup data to the tables. In versions earlier than TiDB v6.0.0, BR uses the [serial execution](#implementation-principles) implementation to create tables in the restore process. However, when BR restores data with a large number of tables (nearly 50000), this implementation takes much time on creating tables. +When restoring data, Backup & Restore (BR) creates databases and tables in the target TiDB cluster and then restores the backup data to the tables. In versions earlier than TiDB v6.0.0, BR uses the [serial execution](#implementation) implementation to create tables in the restore process. However, when BR restores data with a large number of tables (nearly 50000), this implementation takes much time on creating tables. To speed up the table creation process and reduce the time for restoring data, the Batch Create Table feature is introduced in TiDB v6.0.0. This feature is enabled by default. > **Note:** > > - To use the Batch Create Table feature, both TiDB and BR are expected to be of v6.0.0 or later. If either TiDB or BR is earlier than v6.0.0, BR uses the serial execution implementation. -> - Suppose that you use a cluster management tool (for example, TiUP), and your TiDB and BR are of v6.0.0 or later versions, or your TiDB and BR are upgraded from a version earlier than v6.0.0 to v6.0.0 or later. In this case, BR enables the Batch Create Table feature by default. +> - Suppose that you use a cluster management tool (for example, TiUP), and your TiDB and BR are of v6.0.0 or later versions, or your TiDB and BR are upgraded from a version earlier than v6.0.0 to v6.0.0 or later. ## Usage scenario If you need to restore data with a massive amount of tables, for example, 50000 tables, you can use the Batch Create Table feature to speed up the restore process. -For the detailed effect, see [Test for the Batch Create Table Feature](#test-for-the-batch-create-table-feature). +For the detailed effect, see [Test for the Batch Create Table Feature](#feature-test). -## Use the Batch Create Table feature +## Use Batch Create Table -BR enables the Batch Create Table feature by default, with the default configuration of `--ddl-batch-size=128` in v6.0.0 or later to speed up the restore process. Therefore, you do not need to configure this parameter. `--ddl-batch-size=128` means that BR creates tables in batches, each batch with 128 tables. +BR enables the Batch Create Table feature by default, with the default configuration of `--ddl-batch-size=128` in v6.0.0 or later to speed up the restore process. Therefore, you do not need to configure this parameter. `--ddl-batch-size=128` means creating tables in batches, each batch with 128 tables. To disable this feature, you can set `--ddl-batch-size` to `0`. See the following example command: -{{< copyable "shell-regular" >}} - ```shell -br restore full -s local:///br_data/ --pd 172.16.5.198:2379 --log-file restore.log --ddl-batch-size=0 +br restore full \ +--storage local:///br_data/ --pd "${PD_IP}:2379" --log-file restore.log \ +--ddl-batch-size=0 ``` -After this feature is disabled, BR uses the [serial execution implementation](#implementation-principles) instead. +After this feature is disabled, BR uses the [serial execution implementation](#implementation) instead. -## Implementation principles +## Implementation - Serial execution implementation before v6.0.0: - When restoring data, BR creates databases and tables in the target TiDB cluster and then restores the backup data to the tables. To create tables, BR calls TiDB internal API first, and then processes table creation tasks, which works similarly to executing the `Create Table` statement by BR. The TiDB DDL owner creates tables sequentially. Once the DDL owner creates a table, the DDL schema version changes correspondingly and each version change is synchronized to other TiDB DDL workers (including BR). Therefore, when BR restores a large number of tables, the serial execution implementation is time-consuming. + When restoring data, BR creates databases and tables in the target TiDB cluster and then restores the backup data to the tables. To create tables, BR calls TiDB internal API first, and then processes table creation tasks, which works similarly to executing the `Create Table` statement. The TiDB DDL owner creates tables sequentially. Once the DDL owner creates a table, the DDL schema version changes correspondingly and each version change is synchronized to other TiDB DDL workers (including BR). Therefore, when restoring a large number of tables, the serial execution implementation is time-consuming. - Batch create table implementation since v6.0.0: By default, BR creates tables in multiple batches, and each batch has 128 tables. Using this implementation, when BR creates one batch of tables, the TiDB schema version only changes once. This implementation significantly increases the speed of table creation. -## Test for the Batch Create Table feature +## Feature test This section describes the test information about the Batch Create Table feature. The test environment is as follows: @@ -62,4 +62,4 @@ The test result is as follows: '[2022/03/12 22:37:49.060 +08:00] [INFO] [collector.go:67] ["Full restore success summary"] [total-ranges=751760] [ranges-succeed=751760] [ranges-failed=0] [split-region=1h33m18.078448449s] [restore-ranges=542693] [total-take=1h41m35.471476438s] [restore-data-size(after-compressed)=8.337TB] [Size=8336694965072] [BackupTS=431773933856882690] [total-kv=148015861383] [total-kv-size=16.16TB] [average-speed=2.661GB/s]' ``` -From the test result, you can see that the average speed of restoring one TiKV instance is as high as 181.65 MB/s (which equals to `average-speed`/`tikv_count`). \ No newline at end of file +From the test result, you can see that the average speed of restoring one TiKV instance is as high as 181.65 MB/s (which equals to `average-speed`/`tikv_count`). \ No newline at end of file diff --git a/br/br-deployment.md b/br/br-deployment.md deleted file mode 100644 index 76350eedb4e95..0000000000000 --- a/br/br-deployment.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Deploy and Use BR -summary: Learn how to deploy and use BR. ---- - -# Deploy and Use BR - -This document describes the recommended deployment of Backup & Restore (BR) and how to use BR to back up and restore data. - -## Deploy BR - -Recommended practices when deploying BR: - -- In production environments, deploy BR on a node with at least 8 cores CPU and 16 GB memory. Select an appropriate OS version by following [Linux OS version requirements](/hardware-and-software-requirements.md#os-and-platform-requirements). -- Save backup data to Amazon S3, GCS or Azure Blob Storage. -- Allocate sufficient resources for backup and restoration: - - - BR, TiKV nodes, and the backup storage system should provide network bandwidth that is greater than the backup speed. If the target cluster is particularly large, the threshold of backup and restoration speed is limited by the bandwidth of the backup network. - - The backup storage system should also provide sufficient write/read performance (IOPS). Otherwise, the IOPS might become a performance bottleneck during backup or restoration. - - TiKV nodes need to have at least two additional CPU cores and high performance disks for backups. Otherwise, the backup might have an impact on the services running on the cluster. - -> **Note:** -> -> - If no Network File System (NFS) is mounted to a BR or TiKV node, or if you use external storage that supports Amazon S3, GCS, or Azure Blob Storage protocols, the data backed up by BR is generated at each TiKV node. Because BR only backs up the leader replica, you need to estimate the space reserved on each node based on the leader size. Because TiDB uses the leader count for load balancing by default, leaders can greatly differ in size. This might result in the issue that the backup data is unevenly distributed on each node. -> - **Note that this is not the recommended way to deploy BR**, because the backup data are scattered in the local file system of each node. Collecting the backup data might result in data redundancy and operation and maintenance problems. Meanwhile, if you restore data directly before collecting the backup data, you will encounter the `SST file not found` error. - -## Use BR - -Currently, the following methods are supported to run the BR tool: - -### Use SQL statements - -TiDB supports both [`BACKUP`](/sql-statements/sql-statement-backup.md) and [`RESTORE`](/sql-statements/sql-statement-restore.md) SQL statements. You can monitor the progress of these operations using the statement [`SHOW BACKUPS|RESTORES`](/sql-statements/sql-statement-show-backups.md). - -### Use the command-line tool - -For details, see [Use BR Command-line for Backup and Restoration](/br/use-br-command-line-tool.md). - -### Use BR in the Kubernetes environment - -In a Kubernetes environment, you can use TiDB Operator to back up TiDB cluster data to Amazon S3, GCS or persistent volumes, and restore data from the backup data in such systems. For details, see [Back Up and Restore Data Using TiDB Operator](https://docs.pingcap.com/tidb-in-kubernetes/stable/backup-restore-overview). diff --git a/br/br-incremental-guide.md b/br/br-incremental-guide.md new file mode 100644 index 0000000000000..9ea5c51f9e4a0 --- /dev/null +++ b/br/br-incremental-guide.md @@ -0,0 +1,51 @@ +--- +title: TiDB Incremental Backup and Restore Guide +summary: Learns about how to perform incremental backup and restore in TiDB. +--- + +# TiDB Incremental Backup and Restore Guide + +Incremental data of a TiDB cluster is differentiated data between the starting snapshot and the end snapshot of time period, and the DDLs generated during this period. Compared with full (snapshot) backup data, incremental data is smaller and therefore it is a supplementary to snapshot backup, which reduces the volume of backup data. To perform incremental backup, ensure that MVCC data generated within the specified period is not garbage collected by the [TiDB GC mechanism](/garbage-collection-overview.md). For example, to perform incremental backup hourly, you must set [`tidb_gc_life_time`](/system-variables.md#tidb_gc_life_time-new-in-v50) to a value greater than 1 hour. + +> **Warning:** +> +> Development for this feature has stopped. It is recommended that you use [log backup and PITR](/br/br-pitr-guide.md) as an alternative. + +## Back up incremental data + +To back up incremental data, run the `br backup` command with **the last backup timestamp** `--lastbackupts` specified. In this way, br command-line tool automatically backs up incremental data generated between `lastbackupts` and the current time. To get `--lastbackupts`, run the `validate` command. The following is an example: + +```shell +LAST_BACKUP_TS=`tiup br validate decode --field="end-version" --storage "s3://backup-101/snapshot-202209081330?access-key=${access-key}&secret-access-key=${secret-access-key}"| tail -n1` +``` + +The following command backs up the incremental data between `(LAST_BACKUP_TS, current PD timestamp]` and the DDLs generated during this time period: + +```shell +tiup br backup full --pd "${PD_IP}:2379" \ +--storage "s3://backup-101/snapshot-202209081330/incr?access-key=${access-key}&secret-access-key=${secret-access-key}" \ +--lastbackupts ${LAST_BACKUP_TS} \ +--ratelimit 128 +``` + +- `--lastbackupts`: The last backup timestamp. +- `--ratelimit`: The maximum speed **per TiKV** performing backup tasks (in MiB/s). +- `storage`: The storage path of backup data. You need to save the incremental backup data under a different path from the previous snapshot backup. In the preceding example, incremental backup data is saved in the `incr` directory under the full backup data. For details, see [Backup storage URL configuration](/br/backup-and-restore-storages.md#url-format). + +## Restore incremental data + +When restoring incremental data, make sure that all the data backed up before `LAST_BACKUP_TS` has been restored to the target cluster. Also, because incremental restore updates data, you need to ensure that there are no other writes during the restore. Otherwise, conflicts might occur. + +The following command restores the full backup data stored in the `backup-101/snapshot-202209081330` directory: + +```shell +tiup br restore full --pd "${PD_IP}:2379" \ +--storage "s3://backup-101/snapshot-202209081330?access-key=${access-key}&secret-access-key=${secret-access-key}" +``` + +The following command restores the incremental backup data stored in the `backup-101/snapshot-202209081330/incr` directory: + +```shell +tiup br restore full --pd "${PD_IP}:2379" \ +--storage "s3://backup-101/snapshot-202209081330/incr?access-key=${access-key}&secret-access-key=${secret-access-key}" +``` diff --git a/br/br-log-architecture.md b/br/br-log-architecture.md new file mode 100644 index 0000000000000..c75f3593dc75c --- /dev/null +++ b/br/br-log-architecture.md @@ -0,0 +1,152 @@ +--- +title: TiDB Log Backup and PITR Architecture +summary: Learn about the architecture of TiDB log backup and point-in-time recovery. +--- + +# TiDB Log Backup and PITR Architecture + +This document introduces the architecture and process of TiDB log backup and point-in-time recovery (PITR) using a Backup & Restore (BR) tool as an example. + +## Architecture + +The log backup and PITR architecture is as follows: + +![BR log backup and PITR architecture](/media/br/br-log-arch.png) + +## Process of log backup + +The process of a cluster log backup is as follows: + +![BR log backup process design](/media/br/br-log-backup-ts.png) + +System components and key concepts involved in the log backup process: + +* **local metadata**: indicates the metadata backed up by a single TiKV node, including local checkpoint ts, global checkpoint ts, and backup file information. +* **local checkpoint ts** (in local metadata): indicates that all logs generated before local checkpoint ts in this TiKV node have been backed up to the target storage. +* **global checkpoint ts**: indicates that all logs generated before global checkpoint ts in all TiKV nodes have been backed up to the target storage. TiDB Coordinator calculates this timestamp by collecting local checkpoint ts of all TiKV node and then reports it to PD. +* **TiDB Coordinator**: a TiDB node is elected as the coordinator, which is responsible for collecting and calculating the progress of the entire log backup task (global checkpoint ts). This component is stateless in design, and after its failure, a new Coordinator is elected from the surviving TiDB nodes. +* **TiKV log backup observer**: runs on each TiKV node in the TiDB cluster, which is responsible for backing up log data. If a TiKV node fails, backing up the data range on it will be taken by other TiKV nodes after region re-election, and these nodes will back up data of the failure range starting from global checkpoint ts. + +The complete backup process is as follows: + +1. BR receives the `br log start` command. + + * BR parses the checkpoint ts (the start time of log backup) and storage path of the backup task. + * **Register log backup task**: BR registers a log backup task in PD. + +2. TiKV monitors the creation and update of the log backup task. + + * **Fetch log backup task**: The log backup observer of each TiKV node fetches the log backup task from PD and then backs up the log data in the specified range. + +3. The log backup observer backs up the KV change logs continuously. + + * **Read kv change data**: reads KV change data and then saves the change log to [backup files in custom format](#log-backup-files). + * **Fetch global checkpoint ts**: fetches the global checkpoint ts from PD. + * **Generate local metadata**: generates the local metadata of the backup task, including local checkpoint ts, global checkpoint ts, and backup file information. + * **Upload log data & metadata**: uploads the backup files and local metadata to the target storage periodically. + * **Configure GC**: requests PD to prevent data that have not been backed up (greater than local checkpoint ts) from being recycled by the [TiDB GC mechanism](/garbage-collection-overview.md). + +4. The TiDB Coordinator monitors the progress of the log backup task. + + * **Watch backup progress**: gets the backup progress of each Region (Region checkpoint ts) by polling all TiKV nodes. + * **Report global checkpoint ts**: calculates the progress of the entire log backup task (global checkpoint ts) based on the Region checkpoint ts and then reports the global checkpoint ts to PD. + +5. PD persists the status of the log backup task, and you can view it using `br log status`. + +## Process of PITR + +The process of PITR is as follows: + +![Point-in-time recovery process design](/media/br/pitr-ts.png) + +The complete PITR process is as follows: + +1. BR receives the `br restore point` command. + + * BR parses the full backup data address, log backup data address, and the point-in-time recovery time. + * Queries the restore object (database or table) in the backup data and checks whether the table to be restored exists and meets the restore requirements. + +2. BR restores the full backup data. + + * Restores full backup data. For more details about the process of snapshot backup data restore, refer to [Restore snapshot backup data](/br/br-snapshot-architecture.md#process-of-restore). + +3. BR restores the log backup data. + + * **Read backup data**: reads the log backup data and calculates the log backup data that needs to be restored. + * **Fetch Region info**: fetches all Regions distributions by accessing PD. + * **Request TiKV to restore data**: creates a log restore request and sends it to the corresponding TiKV node. The log restore request contains the log backup data information to be restored. + +4. TiKV accepts the restore request from BR and initiates a log restore worker. + + * The log restore worker gets the log backup data that needs to be restored. + +5. TiKV restores the log backup data. + + * **Download KVs**: the log restore worker downloads the corresponding backup data from the backup storage to a local directory according to the log restore request. + * **Rewrite KVs**: the log restore worker rewrites the KV data of the backup data according to the table ID of the restore cluster table, that is, replace the original table ID in the [Key-Value](/tidb-computing.md#mapping-table-data-to-key-value) with the new table ID. The restore worker also rewrites the index ID in the same way. + * **Apply KVs**: the log restore worker writes the processed KV data to the store (RocksDB) through the raft interface. + * **Report restore result**: the log restore worker returns the restore result to BR. + +6. BR receives the restore result from each TiKV node. + + * If some data fails to be restored due to `RegionNotFound` or `EpochNotMatch`, for example, a TiKV node is down, BR will retry the restore. + * If there is any data fails to be restored and cannot be retried, the restore task fails. + * After all data is restored, the restore task succeeds. + +## Log backup files + +Log backup generates the following types of files: + +- `{min_ts}-{uuid}.log` file: stores the KV change log data of the backup task. The `{min_ts}` is the minimum TSO timestamp of the KV change log data in the file, and the `{uuid}` is generated randomly when the file is created. +- `{checkpoint_ts}-{uuid}.meta` file: is generated every time each TiKV node uploads the log backup data and stores metadata of all log backup data files uploaded this time. The `{checkpoint_ts}` is the log backup checkpoint of the TiKV node, and the global checkpoint is the minimum checkpoint of all TiKV nodes. The `{uuid}` is generated randomly when the file is created. +- `{store_id}.ts` file: this file is updated with global checkpoint ts every time each TiKV node uploads the log backup data. The `{store_id}` is the store ID of the TiKV node. +- `v1_stream_truncate_safepoint.txt` file: stores the timestamp corresponding to the latest backup data in storage that deleted by `br log truncate`. + +### Structure of backup files + +``` +. +├── v1 +│   ├── backupmeta +│   │   ├── {min_restored_ts}-{uuid}.meta +│   │   ├── {checkpoint}-{uuid}.meta +│   ├── global_checkpoint +│   │   ├── {store_id}.ts +│   ├── {date} +│   │   ├── {hour} +│   │   │   ├── {store_id} +│   │   │   │   ├── {min_ts}-{uuid}.log +│   │   │   │   ├── {min_ts}-{uuid}.log +├── v1_stream_truncate_safepoint.txt +``` + +The following is an example: + +``` +. +├── v1 +│   ├── backupmeta +│   │   ├── ... +│   │   ├── 435213818858112001-e2569bda-a75a-4411-88de-f469b49d6256.meta +│   │   ├── 435214043785779202-1780f291-3b8a-455e-a31d-8a1302c43ead.meta +│   │   ├── 435214443785779202-224f1408-fff5-445f-8e41-ca4fcfbd2a67.meta +│   ├── global_checkpoint +│   │   ├── 1.ts +│   │   ├── 2.ts +│   │   ├── 3.ts +│   ├── 20220811 +│   │   ├── 03 +│   │   │   ├── 1 +│   │   │   │   ├── ... +│   │   │   │   ├── 435213866703257604-60fcbdb6-8f55-4098-b3e7-2ce604dafe54.log +│   │   │   │   ├── 435214023989657606-72ce65ff-1fa8-4705-9fd9-cb4a1e803a56.log +│   │   │   ├── 2 +│   │   │   │   ├── ... +│   │   │   │   ├── 435214102632857605-11deba64-beff-4414-bc9c-7a161b6fb22c.log +│   │   │   │   ├── 435214417205657604-e6980303-cbaa-4629-a863-1e745d7b8aed.log +│   │   │   ├── 3 +│   │   │   │   ├── ... +│   │   │   │   ├── 435214495848857605-7bf65e92-8c43-427e-b81e-f0050bd40be0.log +│   │   │   │   ├── 435214574492057604-80d3b15e-3d9f-4b0c-b133-87ed3f6b2697.log +├── v1_stream_truncate_safepoint.txt +``` diff --git a/br/pitr-monitoring-and-alert.md b/br/br-monitoring-and-alert.md similarity index 89% rename from br/pitr-monitoring-and-alert.md rename to br/br-monitoring-and-alert.md index f00eb0233eecd..09332f77f56cc 100644 --- a/br/pitr-monitoring-and-alert.md +++ b/br/br-monitoring-and-alert.md @@ -1,18 +1,27 @@ --- -title: PITR Monitoring and Alert -summary: Learn the monitoring and alert of the PITR feature. +title: Monitoring and Alert for Backup and Restore +summary: Learn the monitoring and alert of the backup and restore feature. --- -# PITR Monitoring and Alert +# Monitoring and Alert for Backup and Restore -PITR supports using [Prometheus](https://prometheus.io/) to collect monitoring metrics. Currently all monitoring metrics are built into TiKV. +This document describes the monitoring and alert of the backup and restore feature, including how to deploy monitoring components, monitoring metrics, and common alerts. -## Monitoring configuration +## Log backup monitoring -- For clusters deployed using TiUP, [Prometheus](https://prometheus.io/) automatically collects monitoring metrics. +Log backup supports using [Prometheus](https://prometheus.io/) to collect monitoring metrics. Currently all monitoring metrics are built into TiKV. + +### Monitoring configuration + +- For clusters deployed using TiUP, Prometheus automatically collects monitoring metrics. - For clusters deployed manually, follow the instructions in [TiDB Cluster Monitoring Deployment](/deploy-monitoring-services.md) to add TiKV-related jobs to the `scrape_configs` section of the Prometheus configuration file. -## Monitoring metrics +### Grafana configuration + +- For clusters deployed using TiUP, the [Grafana](https://grafana.com/) dashboard contains the point-in-time recovery (PITR) panel. The **Backup Log** panel in the TiKV-Details dashboard is the PITR panel. +- For clusters deployed manually, refer to [Import a Grafana dashboard](/deploy-monitoring-services.md#step-2-import-a-grafana-dashboard) and upload the [tikv_details](https://github.com/tikv/tikv/blob/master/metrics/grafana/tikv_details.json) JSON file to Grafana. Then find the **Backup Log** panel in the TiKV-Details dashboard. + +### Monitoring metrics | Metrics | Type | Description | |-------------------------------------------------------|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -38,12 +47,9 @@ PITR supports using [Prometheus](https://prometheus.io/) to collect monitoring m | **tikv_log_backup_task_status** | Gauge | The status of the log backup task. `0` means running. `1` means paused. `2` means error.
`task :: string` | | **tikv_log_backup_pending_initial_scan** | Gauge | Statistics of pending initial scans.
`stage :: {"queuing", "executing"}` | -## Grafana configuration - -- For clusters deployed using TiUP, the [Grafana](https://grafana.com/) dashboard contains the PITR panel. The **Backup Log** panel in the TiKV-Details dashboard is the PITR panel. -- For clusters deployed manually, refer to [Import a Grafana dashboard](/deploy-monitoring-services.md#step-2-import-a-grafana-dashboard) and upload the [tikv_details](https://github.com/tikv/tikv/blob/master/metrics/grafana/tikv_details.json) JSON file to Grafana. Then find the **Backup Log** panel in the TiKV-Details dashboard. +### Log backup alerts -## Alert configuration +#### Alert configuration Currently, PITR does not have built-in alert items. This section introduces how to configure alert items in PITR and recommends some items. @@ -51,11 +57,11 @@ To configure alert items in PITR, follow these steps: 1. Create a configuration file (for example, `pitr.rules.yml`) for the alert rules on the node where Prometheus is located. In the file, fill in the alert rules according to the [Prometheus documentation](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/), the following recommended alert items, and the configuration sample. 2. In the `rule_files` field of the Prometheus configuration file, add the path of the alert rule file. -3. Send `SIGHUP` signal to the Prometheus process (`kill -HUP pid`) or send an HTTP POST request to `http://prometheus-addr/-/reload` (before you send the HTTP request, add the `--web.enable-lifecycle` parameter when starting Prometheus). +3. Send `SIGHUP` signal to the Prometheus process (`kill -HUP pid`) or send an HTTP `POST` request to `http://prometheus-addr/-/reload` (before you send the HTTP request, add the `--web.enable-lifecycle` parameter when starting Prometheus). The recommended alert items are as follows: -### LogBackupRunningRPOMoreThan10m +#### LogBackupRunningRPOMoreThan10m - Alert item: `max(time() - tikv_log_backup_store_checkpoint_ts / 262144000) by (task) / 60 > 10 and max(tikv_log_backup_store_checkpoint_ts) by (task) > 0 and max(tikv_log_backup_task_status) by (task) == 0` - Alert level: warning @@ -76,31 +82,31 @@ groups: message: RPO of the log backup task {{ $labels.task }} is more than 10m ``` -### LogBackupRunningRPOMoreThan30m +#### LogBackupRunningRPOMoreThan30m - Alert item: `max(time() - tikv_log_backup_store_checkpoint_ts / 262144000) by (task) / 60 > 30 and max(tikv_log_backup_store_checkpoint_ts) by (task) > 0 and max(tikv_log_backup_task_status) by (task) == 0` - Alert level: critical - Description: The log data is not persisted to the storage for more than 30 minutes. This alert often indicates anomalies. You can check the TiKV logs to find the cause. -### LogBackupPausingMoreThan2h +#### LogBackupPausingMoreThan2h - Alert item: `max(time() - tikv_log_backup_store_checkpoint_ts / 262144000) by (task) / 3600 > 2 and max(tikv_log_backup_store_checkpoint_ts) by (task) > 0 and max(tikv_log_backup_task_status) by (task) == 1` - Alert level: warning - Description: The log backup task is paused for more than 2 hours. This alert item is a reminder and you are expected to run `br log resume` as soon as possible. -### LogBackupPausingMoreThan12h +#### LogBackupPausingMoreThan12h - Alert item: `max(time() - tikv_log_backup_store_checkpoint_ts / 262144000) by (task) / 3600 > 12 and max(tikv_log_backup_store_checkpoint_ts) by (task) > 0 and max(tikv_log_backup_task_status) by (task) == 1` - Alert level: critical - Description: The log backup task is paused for more than 12 hours. You are expected to run `br log resume` as soon as possible to resume the task. Log tasks paused for too long have the risk of data loss. -### LogBackupFailed +#### LogBackupFailed - Alert item: `max(tikv_log_backup_task_status) by (task) == 2 and max(tikv_log_backup_store_checkpoint_ts) by (task) > 0` - Alert level: critical - Description: The log backup task fails. You need to run `br log status` to see the failure reason. If necessary, you need to further check the TiKV logs. -### LogBackupGCSafePointExceedsCheckpoint +#### LogBackupGCSafePointExceedsCheckpoint - Alert item: `min(tikv_log_backup_store_checkpoint_ts) by (instance) - max(tikv_gcworker_autogc_safe_point) by (instance) < 0` - Alert level: critical diff --git a/br/br-pitr-guide.md b/br/br-pitr-guide.md new file mode 100644 index 0000000000000..cbda106d688e6 --- /dev/null +++ b/br/br-pitr-guide.md @@ -0,0 +1,133 @@ +--- +title: TiDB Log Backup and PITR Guide +summary: Learns about how to perform log backup and PITR in TiDB. +aliases: ['/tidb/dev/pitr-usage'] +--- + +# TiDB Log Backup and PITR Guide + +A full backup (snapshot backup) contains the full cluster data at a certain point, while TiDB log backup can back up data written by applications to a specified storage in a timely manner. If you want to choose the restore point as required, that is, to perform point-in-time recovery (PITR), you can [start log backup](#start-log-backup) and [run full backup regularly](#run-full-backup-regularly). + +Before you back up or restore data using the br command-line tool (hereinafter referred to as `br`), you need to [install `br`](/br/br-use-overview.md#deploy-and-use-br) first. + +## Back up TiDB cluster + +### Start log backup + +To start a log backup, run `br log start`. A cluster can only run one log backup task each time. + +```shell +tiup br log start --task-name=pitr --pd "${PD_IP}:2379" \ +--storage 's3://backup-101/logbackup?access-key=${access-key}&secret-access-key=${secret-access-key}"' +``` + +After the log backup task starts, it runs in the background of the TiDB cluster until you stop it manually. During this process, the TiDB change logs are regularly backed up to the specified storage in small batches. To query the status of the log backup task, run the following command: + +```shell +tiup br log status --task-name=pitr --pd "${PD_IP}:2379" +``` + +Expected output: + +``` +● Total 1 Tasks. +> #1 < + name: pitr + status: ● NORMAL + start: 2022-05-13 11:09:40.7 +0800 + end: 2035-01-01 00:00:00 +0800 + storage: s3://backup-101/log-backup + speed(est.): 0.00 ops/s +checkpoint[global]: 2022-05-13 11:31:47.2 +0800; gap=4m53s +``` + +### Run full backup regularly + +The snapshot backup can be used as a method of full backup. You can run `br backup full` to back up the cluster snapshot to the backup storage according to a fixed schedule (for example, every 2 days). + +```shell +tiup br backup full --pd "${PD_IP}:2379" \ +--storage 's3://backup-101/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}"' +``` + +## Run PITR + +To restore the cluster to any point in time within the backup retention period, you can use `br restore point`. When you run this command, you need to specify the **time point you want to restore**, **the latest snapshot backup data before the time point**, and the **log backup data**. BR will automatically determine and read data needed for the restore, and then restore these data to the specified cluster in order. + +```shell +br restore point --pd "${PD_IP}:2379" \ +--storage='s3://backup-101/logbackup?access-key=${access-key}&secret-access-key=${secret-access-key}"' \ +--full-backup-storage='s3://backup-101/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}"' \ +--restored-ts '2022-05-15 18:00:00+0800' +``` + +During data restore, you can view the progress through the progress bar in the terminal. The restore is divided into two phases, full restore and log restore (restore meta files and restore KV files). After each phase is completed, `br` outputs information such as restore time and data size. + +```shell +Full Restore <--------------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% +*** ["Full Restore success summary"] ****** [total-take=xxx.xxxs] [restore-data-size(after-compressed)=xxx.xxx] [Size=xxxx] [BackupTS={TS}] [total-kv=xxx] [total-kv-size=xxx] [average-speed=xxx] +Restore Meta Files <--------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% +Restore KV Files <----------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% +*** ["restore log success summary"] [total-take=xxx.xx] [restore-from={TS}] [restore-to={TS}] [total-kv-count=xxx] [total-size=xxx] +``` + +## Clean up outdated data + +As described in the [Usage Overview of TiDB Backup and Restore](/br/br-use-overview.md): + +To perform PITR, you need to restore the full backup before the restore point, and the log backup between the full backup point and the restore point. Therefore, for log backups that exceed the backup retention period, you can use `br log truncate` to delete the backup before the specified time point. **It is recommended to only delete the log backup before the full snapshot**. + +The following steps describe how to clean up backup data that exceeds the backup retention period: + +1. Get the **last full backup** outside the backup retention period. +2. Use the `validate` command to get the time point corresponding to the backup. Assume that the backup data before 2022/09/01 needs to be cleaned, you should look for the last full backup before this time point and ensure that it will not be cleaned. + + ```shell + FULL_BACKUP_TS=`tiup br validate decode --field="end-version" --storage "s3://backup-101/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}"| tail -n1` + ``` + +3. Delete log backup data earlier than the snapshot backup `FULL_BACKUP_TS`: + + ```shell + tiup br log truncate --until=${FULL_BACKUP_TS} --storage='s3://backup-101/logbackup?access-key=${access-key}&secret-access-key=${secret-access-key}"' + ``` + +4. Delete snapshot data earlier than the snapshot backup `FULL_BACKUP_TS`: + + ```shell + rm -rf s3://backup-101/snapshot-${date} + ``` + +## Performance and impact of PITR + +### Capabilities + +- On each TiKV node, PITR can restore snapshot data at a speed of 280 GB/h and log data 30 GB/h. +- BR deletes outdated log backup data at a speed of 600 GB/h. + +> **Note:** +> +> The preceding specifications are based on test results from the following two testing scenarios. The actual data might be different. +> +> - Snapshot data restore speed = Snapshot data size / (duration * the number of TiKV nodes) +> - Log data restore speed = Restored log data size / (duration * the number of TiKV nodes) + +Testing scenario 1 (on [TiDB Cloud](https://tidbcloud.com)): + +- The number of TiKV nodes (8 core, 16 GB memory): 21 +- The number of Regions: 183,000 +- New log data created in the cluster: 10 GB/h +- Write (INSERT/UPDATE/DELETE) QPS: 10,000 + +Testing scenario 2 (on-premises): + +- The number of TiKV nodes (8 core, 64 GB memory): 6 +- The number of Regions: 50,000 +- New log data created in the cluster: 10 GB/h +- Write (INSERT/UPDATE/DELETE) QPS: 10,000 + +## See also + +* [TiDB Backup and Restore Use Cases](/br/backup-and-restore-use-cases.md) +* [br Command-line Manual](/br/use-br-command-line-tool.md) +* [Log Backup and PITR Architecture](/br/br-log-architecture.md) diff --git a/br/br-log-command-line.md b/br/br-pitr-manual.md similarity index 64% rename from br/br-log-command-line.md rename to br/br-pitr-manual.md index c44413cd90c09..f695d3f080b33 100644 --- a/br/br-log-command-line.md +++ b/br/br-pitr-manual.md @@ -1,41 +1,21 @@ --- -title: Perform Log Backup and Restoration Using BR -summary: Learn how to perform log backup and restoration from the log backup data using the br log command line tool. +title: TiDB Log Backup and PITR Command Manual +summary: Learn about the commands of TiDB log backup and point-in-time recovery. +aliases: ['/tidb/dev/br-log-command-line/'] --- -# Perform Log Backup and Restoration Using BR +# TiDB Log Backup and PITR Command Manual -You can perform log backup and restoration on a TiDB cluster by using the `br log` command. This document describes the usage of the `br log` command. +This document describes the commands used in TiDB log backup and point-in-time recovery (PITR). -## Prerequisites +For more information about log backup and PITR, refer to: -### Install BR - -Before performing log backup, you need to install Backup & Restore (BR). You can install BR via either of the following methods: - -* [Install BR online using TiUP](/migration-tools.md#install-tools-using-tiup) (recommended) -* [Download the TiDB binary package](/download-ecosystem-tools.md) - -### Enable log backup - -Before you use log backup, ensure that [`log-backup.enable`](/tikv-configuration-file.md#enable-new-in-v620) in the TiKV configuration file is in its default value `true`. For the method to modify configuration, refer to [Modify the configuration](/maintain-tidb-using-tiup.md#modify-the-configuration). +- [Log Backup and PITR Guide](/br/br-pitr-guide.md) +- [Back up and Restore Use Cases](/br/backup-and-restore-use-cases.md) ## Perform log backup -You can perform log backup using the `br log` command. This command has a set of subcommands that help you with the following operations: - -* Start a log backup -* Query the backup status -* Pause and resume the backup -* Stop the backup task and delete the backup data -* Clean up the backup data -* View the metadata - -This section introduces the subcommands of `br log` and gives examples of the command usage. - -### `br log` subcommands - -You can view the `br log` command help information by running the following command: +You can start and manage log backup using the `br log` command. ```shell ./br log --help @@ -89,20 +69,22 @@ Global Flags: --key string Private key path for TLS connection -u, --pd strings PD address (default [127.0.0.1:2379]) -s, --storage string specify the url where backup storage, eg, "s3://bucket/path/prefix" + ``` The example output only shows the common parameters. These parameters are described as follows: -- `--task-name`: specify the task name for the log backup. This name is also used to query, pause, and resume the backup task. -- `--start-ts`: specify the start timestamp for the log backup. If this is not specified, the backup program uses the current time as `start-ts`. -- `--pd`: specify the PD address for the backup cluster. BR needs to access PD to start the log backup task. -- `--ca`, `--cert`, `--key`: specify the mTLS encryption method to communicate with TiKV and PD. -- `--storage`: specify the backup storage address. Currently, BR supports shared file systems, Amazon S3, GCS, or Azure Blob Storage as the storage for log backup. For details, see [Amazon S3 storage](/br/backup-storage-S3.md), [GCS storage](/br/backup-storage-gcs.md), and [Azure blob storage](/br/backup-storage-azblob.md). +- `--start-ts`: specifies the start timestamp for the log backup. If this parameter is not specified, the backup program uses the current time as `start-ts`. +- `task-name`: specifies the task name for the log backup. This name is also used to query, pause, and resume the backup task. +- `--ca`, `--cert`, `--key`: specifies the mTLS encryption method to communicate with TiKV and PD. +- `--pd`: specifies the PD address for the backup cluster. BR needs to access PD to start the log backup task. +- `--storage`: specifies the backup storage address. Currently, BR supports Amazon S3, Google Cloud Storage (GCS), or Azure Blob Storage as the storage for log backup. The preceding command uses Amazon S3 as an example. For details, see [URL format of backup storages](/br/backup-and-restore-storages.md#url-format). Usage example: ```shell -./br log start --task-name=pitr --pd=172.16.102.95:2379 --storage='s3://tidb-pitr-bucket/backup-data/log-backup' +./br log start --task-name=pitr --pd="${PD_IP}:2379" \ +--storage='s3://backup-101/logbackup?access-key=${access-key}&secret-access-key=${secret-access-key}"' ``` ### Query the backup status @@ -128,6 +110,7 @@ Global Flags: --cert string Certificate path for TLS connection --key string Private key path for TLS connection -u, --pd strings PD address (default [127.0.0.1:2379]) + ``` In the example output, `task-name` is used to specify the name of the backup task. The default value is `*`, which means querying the status of all tasks. @@ -135,26 +118,31 @@ In the example output, `task-name` is used to specify the name of the backup tas Usage example: ```shell -./br log status --task-name=pitr --pd=172.16.102.95:2379 +./br log status --task-name=pitr --pd="${PD_IP}:2379" +``` + +Expected output: + +```shell ● Total 1 Tasks. > #1 < name: pitr status: ● NORMAL start: 2022-07-14 20:08:03.268 +0800 end: 2090-11-18 22:07:45.624 +0800 - storage: s3://tmp/store-by-storeid/log1 + storage: s3://backup-101/logbackup speed(est.): 0.82 ops/s checkpoint[global]: 2022-07-25 22:52:15.518 +0800; gap=2m52s ``` The output fields are described as follows: -- `status`: the status of the backup task. The status can be `NORMAL`, `ERROR`, or `PAUSE`. +- `status`: the status of the backup task, which can be `NORMAL`, `ERROR`, or `PAUSE`. - `start`: the start time of the backup task. It is the `start-ts` value specified when the backup task is started. - `storage`: the backup storage address. - `speed`: the total QPS of the backup task. QPS means the number of logs backed per second. -- `checkpoint[global]`: all data before this checkpoint is backed up to the backup storage. This is the latest timestamp available for restoring the backup data. -- `error[store]`: the error the log backup program encounters on the storage node. +- `checkpoint [global]`: all data before this checkpoint is backed up to the backup storage. This is the latest timestamp available for restoring the backup data. +- `error [store]`: the error the log backup program encounters on the storage node. ### Pause and resume a backup task @@ -189,10 +177,10 @@ Global Flags: Usage example: ```shell -./br log pause --task-name=pitr --pd=172.16.102.95:2379 +./br log pause --task-name=pitr --pd="${PD_IP}:2379" ``` -You can run the `br log resume` command to resume the paused backup task. +You can run the `br log resume` command to resume a paused backup task. Run `br log resume --help` to see the help information: @@ -214,12 +202,12 @@ Global Flags: -u, --pd strings PD address (default [127.0.0.1:2379]) ``` -After the backup task is paused for more than 24 hours, running `br log resume` reports an error, and BR prompts that backup data is lost. To handle this error, refer to [Troubleshoot PITR Log Backup](/br/pitr-troubleshoot.md#what-should-i-do-if-the-error-message-errbackupgcsafepointexceeded-is-returned-when-using-the-br-log-resume-command-to-resume-the-suspended-task). +After the backup task is paused for more than 24 hours, running `br log resume` reports an error, and BR prompts that backup data is lost. To handle this error, refer to [Backup & Restore FAQs](/faq/backup-and-restore-faq.md#what-should-i-do-if-the-error-message-errbackupgcsafepointexceeded-is-returned-when-using-the-br-log-resume-command-to-resume-a-suspended-task). Usage example: ```shell -./br log resume --task-name=pitr --pd=172.16.102.95:2379 +./br log resume --task-name=pitr --pd="${PD_IP}:2379" ``` ### Stop and restart a backup task @@ -257,7 +245,7 @@ Global Flags: Usage example: ```shell -./br log stop --task-name=pitr --pd=172.16.102.95:2379 +./br log stop --task-name=pitr --pd="${PD_IP}:2379" ``` #### Restart a backup task @@ -268,7 +256,7 @@ After running the `br log stop` command to stop a log backup task, you can creat - The `--start-ts` does not need to be specified. BR automatically starts the backup from the last backup checkpoint. - If the task is stopped for a long time and multiple versions of the data have been garbage collected, the error `BR:Backup:ErrBackupGCSafepointExceeded` is reported when you attempt to restart the task. In this case, you have to create a new log backup task in another `--storage` directory. -### Clean up the backup data +### Clean up backup data You can run the `br log truncate` command to clean up the outdated or no longer needed log backup data. @@ -287,22 +275,22 @@ Flags: --until string Remove all backup data until this TS.(support TSO or datetime, e.g. '400036290571534337' or '2018-05-11 01:42:23+0800'.) -y, --yes Skip all prompts and always execute the command. + Global Flags: -s, --storage string specify the url where backup storage, eg, "s3://bucket/path/prefix" ``` -This command only accesses the backup storage, but does not access the TiDB cluster. - -Some parameters are described as follows: +This command only accesses the backup storage and does not access the TiDB cluster. Some parameters are described as follows: - `--dry-run`: run the command but do not really delete the files. - `--until`: delete all log backup data before the specified timestamp. -- `--storage`: the backup storage address. Currently, BR supports shared file systems, Amazon S3, GCS, or Azure Blob Storage as the storage for log backup. For details, see [Amazon S3 storage](/br/backup-storage-S3.md), [GCS storage](/br/backup-storage-gcs.md), and [Azure blob storage](/br/backup-storage-azblob.md). +- `--storage`: the backup storage address. Currently, BR supports Amazon S3, GCS, or Azure Blob Storage as the storage for log backup. For details, see [URL format of backup storages](/br/backup-and-restore-storages.md#url-format). Usage example: ```shell -./br log truncate --until='2022-07-26 21:20:00+0800' –-storage='s3://tidb-pitr-bucket/backup-data/log-backup' +./br log truncate --until='2022-07-26 21:20:00+0800' \ +–-storage='s3://backup-101/logbackup?access-key=${access-key}&secret-access-key=${secret-access-key}"' ``` Expected output: @@ -317,7 +305,7 @@ Removing metadata... DONE; take = 24.038962ms ### View the backup metadata -You can run the `br log metadata` command to view the metadata of the log backup in the backup storage, such as the earliest and latest timestamp that can be restored. +You can run the `br log metadata` command to view the backup metadata in the storage system, such as the earliest and latest timestamp that can be restored. Run `br log metadata --help` to see the help information: @@ -335,14 +323,14 @@ Global Flags: -s, --storage string specify the url where backup storage, eg, "s3://bucket/path/prefix" ``` -This command only accesses the backup storage, but does not access the TiDB cluster. +This command only accesses the backup storage and does not access the TiDB cluster. -The `--storage` parameter is used to specify the backup storage address. Currently, BR supports shared file systems, Amazon S3, GCS, or Azure Blob Storage as the storage for log backup. For details, see [Amazon S3 storage](/br/backup-storage-S3.md), [GCS storage](/br/backup-storage-gcs.md), and [Azure blob storage](/br/backup-storage-azblob.md). +The `--storage` parameter is used to specify the backup storage address. Currently, BR supports Amazon S3, GCS, or Azure Blob Storage as the storage for log backup. For details, see [URL format of backup storages](/br/backup-and-restore-storages.md#url-format). Usage example: ```shell -./br log metadata –-storage='s3://tidb-pitr-bucket/backup-data/log-backup' +./br log metadata –-storage='s3://backup-101/logbackup?access-key=${access-key}&secret-access-key=${secret-access-key}"' ``` Expected output: @@ -351,7 +339,7 @@ Expected output: [2022/07/25 23:02:57.236 +08:00] [INFO] [collector.go:69] ["log metadata"] [log-min-ts=434582449885806593] [log-min-date="2022-07-14 20:08:03.268 +0800"] [log-max-ts=434834300106964993] [log-max-date="2022-07-25 23:00:15.618 +0800"] ``` -## Restore the log backup data +## Restore to a specified point in time (PITR) You can run the `br restore point` command to perform a PITR on a new cluster or just restore the log backup data. @@ -370,6 +358,7 @@ Flags: --restored-ts string the point of restore, used for log restore. support TSO or datetime, e.g. '400036290571534337' or '2018-05-11 01:42:23+0800' --start-ts string the start timestamp which log restore from. support TSO or datetime, e.g. '400036290571534337' or '2018-05-11 01:42:23+0800' + Global Flags: --ca string CA certificate path for TLS connection --cert string Certificate path for TLS connection @@ -380,28 +369,28 @@ Global Flags: The example output only shows the common parameters. These parameters are described as follows: -- `--full-backup-storage`: the storage address for the snapshot (full) backup. If you need to use PITR, you must specify this parameter and choose the latest snapshot backup before the restoration timestamp. If you only need to restore log backup data, you can omit this parameter. Currently, BR supports shared file systems, Amazon S3, GCS, or Azure Blob Storage as the storage for log backup. For details, see [Amazon S3 storage](/br/backup-storage-S3.md), [GCS storage](/br/backup-storage-gcs.md), and [Azure blob storage](/br/backup-storage-azblob.md). +- `--full-backup-storage`: the storage address for the snapshot (full) backup. To use PITR, specify this parameter and choose the latest snapshot backup before the restore timestamp. To restore only log backup data, you can omit this parameter. Currently, BR supports Amazon S3, GCS, or Azure Blob Storage as the storage for log backup. For details, see [URL format of backup storages](/br/backup-and-restore-storages.md#url-format). - `--restored-ts`: the timestamp that you want to restore data to. If this parameter is not specified, BR restores data to the latest timestamp available in the log backup, that is, the checkpoint of the backup data. -- `--start-ts`: the start timestamp that you want to restore log backup data from. If you only need to restore log backup data and do not need snapshot backup data, you must specify this parameter. -- `--pd`: the PD address of the restoration cluster. +- `--start-ts`: the start timestamp that you want to restore log backup data from. If you only need to restore log backup data, you must specify this parameter. +- `--pd`: the PD address of the restore cluster. - `--ca`, `--cert`, `--key`: specify the mTLS encryption method to communicate with TiKV and PD. -- `--storage`: the storage address for the log backup. Currently, BR supports shared file systems, Amazon S3, GCS, or Azure Blob Storage as the storage for log backup. For details, see [Amazon S3 storage](/br/backup-storage-S3.md), [GCS storage](/br/backup-storage-gcs.md), and [Azure blob storage](/br/backup-storage-azblob.md). +- `--storage`: the storage address for the log backup. Currently, BR supports Amazon S3, GCS, or Azure Blob Storage as the storage for log backup. For details, see [URL format of backup storages](/br/backup-and-restore-storages.md#url-format). Usage example: ```shell -./br restore point --pd=172.16.102.95:2379 ---storage='s3://tidb-pitr-bucket/backup-data/log-backup' ---full-backup-storage='s3://tidb-pitr-bucket/backup-data/snapshot-20220512000000' +./br restore point --pd="${PD_IP}:2379" +--storage='s3://backup-101/logbackup?access-key=${access-key}&secret-access-key=${secret-access-key}"' +--full-backup-storage='s3://backup-101/snapshot-202205120000?access-key=${access-key}&secret-access-key=${secret-access-key}"' + Full Restore <--------------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% -[2022/07/19 18:15:39.132 +08:00] [INFO] [collector.go:69] ["Full Restore success summary"] [total-ranges=12] [ranges-succeed=12] [ranges-failed=0] [split-region=546.663µs] [restore-ranges=3] [total-take=3.112928252s] [restore-data-size(after-compressed)=5.056kB] [Size=5056] [BackupTS=434693927394607136] [total-kv=4] [total-kv-size=290B] [average-speed=93.16B/s] +*** ***["Full Restore success summary"] ****** [total-take=3.112928252s] [restore-data-size(after-compressed)=5.056kB] [Size=5056] [BackupTS=434693927394607136] [total-kv=4] [total-kv-size=290B] [average-speed=93.16B/s] Restore Meta Files <--------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% Restore KV Files <----------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% -[2022/07/19 18:15:39.325 +08:00] [INFO] [collector.go:69] ["restore log success summary"] [total-take=192.955533ms] [restore-from=434693681289625602] [restore-to=434693753549881345] [total-kv-count=33] [total-size=21551] +"restore log success summary"] [total-take=192.955533ms] [restore-from=434693681289625602] [restore-to=434693753549881345] [total-kv-count=33] [total-size=21551] ``` > **Note:** > -> - It is recommended to use `br restore point` to perform PITR (refer to [PITR Overview](/br/point-in-time-recovery.md)). It is not recommended to restore log data of a time period directly in a cluster. > - You cannot restore the log backup data of a certain time period repeatedly. If you restore the log backup data of a range `[t1=10, t2=20)` repeatedly, the restored data might be inconsistent. -> - When you restore log data of different time periods in multiple batches, you must ensure the log data is restored in a consecutive order. If you restore the log backup data of [t1, t2), [t2, t3) and [t3, t4) in a consecutive order, the restored data is consistent. However, if you restore [t1, t2) and then skip [t2, t3) to restore [t3, t4), the restored data might be inconsistent. +> - When you restore log data of different time periods in multiple batches, ensure that the log data is restored in consecutive order. If you restore the log backup data of `[t1, t2)`, `[t2, t3)`, and `[t3, t4)` in consecutive order, the restored data is consistent. However, if you restore `[t1, t2)` and then skip `[t2, t3)` to restore `[t3, t4)`, the restored data might be inconsistent. diff --git a/br/br-snapshot-architecture.md b/br/br-snapshot-architecture.md new file mode 100644 index 0000000000000..bfedcc8c039d8 --- /dev/null +++ b/br/br-snapshot-architecture.md @@ -0,0 +1,158 @@ +--- +title: TiDB Snapshot Backup and Restore Architecture +summary: Learn about the architecture of TiDB snapshot backup and restore. +--- + +# TiDB Snapshot Backup and Restore Architecture + +This document introduces the architecture and process of TiDB snapshot backup and restore using a Backup & Restore (BR) tool as an example. + +## Architecture + +The TiDB snapshot backup and restore architecture is as follows: + +![BR snapshot backup and restore architecture](/media/br/br-snapshot-arch.png) + +## Process of backup + +The process of a cluster snapshot backup is as follows: + +![snapshot backup process design](/media/br/br-snapshot-backup-ts.png) + +The complete backup process is as follows: + +1. BR receives the `br backup full` command. + + * Gets the backup time point and storage path. + +2. BR schedules the backup data. + + * **Pause GC**: BR configures the TiDB GC time to prevent the backup data from being cleaned up by [TiDB GC mechanism](/garbage-collection-overview.md). + * **Fetch TiKV and Region info**: BR accesses PD to get all TiKV nodes addresses and [Region](/tidb-storage.md#region) distribution of data. + * **Request TiKV to back up data**: BR creates a backup request and sends it to all TiKV nodes. The backup request includes the backup time point, Regions to be backed up, and the storage path. + +3. TiKV accepts the backup request and initiates a backup worker. + +4. TiKV backs up the data. + + * **Scan KVs**: the backup worker reads data corresponding to the backup time point from the Region where the leader locates. + * **Generate SST**: the backup worker saves the data to SST files, which are stored in the memory. + * **Upload SST**: the backup worker uploads the SST files to the storage path. + +5. BR receives the backup result from each TiKV node. + + * If some data fails to be backed up due to Region changes, for example, a TiKV node is down, BR will retry the backup. + * If there is any data fails to be backed up and cannot be retried, the backup task fails. + * After all data is backed up, BR will then back up the metadata. + +6. BR backs up the metadata. + + * **Back up schemas**: BR backs up the table schemas and calculates the checksum of the table data. + * **Upload metadata**: BR generates the backup metadata and uploads it to the storage path. The backup metadata includes the backup timestamp, the table and corresponding backup files, data checksum, and file checksum. + +## Process of restore + +The process of a cluster snapshot restore is as follows: + +![snapshot restore process design](/media/br/br-snapshot-restore-ts.png) + +The complete restore process is as follows: + +1. BR receives the `br restore` command. + + * Gets the data storage path and the database or table to be restored. + * Checks whether the table to be restored exists and whether it meets the requirements for restore. + +2. BR schedules the restore data. + + * **Pause Region schedule**: BR requests PD to pause the automatic Region scheduling during restore. + * **Restore schema**: BR gets the schema of the backup data and the database and table to be restored. Note that the ID of a newly created table might be different from that of the backup data. + * **Split & scatter Region**: BR requests PD to allocate Regions (split Region) based on backup data, and schedules Regions to be evenly distributed to storage nodes (scatter Region). Each Region has a specified data range `[start key, end key)`. + * **Request TiKV to restore data**: BR creates a restore request and sends it to the corresponding TiKV nodes according to the result of Region split. The restore request includes the data to be restored and rewrite rules. + +3. TiKV accepts the restore request and initiates a restore worker. + + * The restore worker calculates the backup data that needs to be read to restore. + +4. TiKV restores the data. + + * **Download SST**: the restore worker downloads corresponding SST files from the storage path to a local directory. + * **Rewrite KVs**: the restore worker rewrites the KV data according to the new table ID, that is, replace the original table ID in the [Key-Value](/tidb-computing.md#mapping-table-data-to-key-value) with the new table ID. The restore worker also rewrites the index ID in the same way. + * **Ingest SST**: the restore worker ingests the processed SST files into RocksDB. + * **Report restore result**: the restore worker reports the restore result to BR. + +5. BR receives the restore result from each TiKV node. + + * If some data fails to be restored due to `RegionNotFound` or `EpochNotMatch`, for example, a TiKV node is down, BR will retry the restore. + * If there is any data fails to be restored and cannot be retried, the restore task fails. + * After all data is restored, the restore task succeeds. + +## Backup files + +### Types of backup files + +Snapshot backup generates the following types of files: + +- `SST` file: stores the data that the TiKV node backs up. The size of an `SST` file equals to that of a Region. +- `backupmeta` file: stores the metadata of a backup task, including the number of all backup files, and the key range, the size, and the Hash (sha256) value of each backup file. +- `backup.lock` file: prevents multiple backup tasks from storing data at the same directory. + +### Naming format of SST files + +When data is backed up to Google Cloud Storage (GCS) or Azure Blob Storage, SST files are named in the format of `storeID_regionID_regionEpoch_keyHash_timestamp_cf`. The fields in the name are explained as follows: + +- `storeID` is the TiKV node ID. +- `regionID` is the Region ID. +- `regionEpoch` is the version number of Region. +- `keyHash` is the Hash (sha256) value of the startKey of a range, which ensures the uniqueness of a file. +- `timestamp` is the Unix timestamp of an SST file when it is generated by TiKV. +- `cf` indicates the Column Family of RocksDB (only restores data whose `cf` is `default` or `write` ). + +When data is backed up to Amazon S3 or a network disk, the SST files are named in the format of `regionID_regionEpoch_keyHash_timestamp_cf`. The fields in the name are explained as follows: + +- `regionID` is the Region ID. +- `regionEpoch` is the version number of Region. +- `keyHash` is the Hash (sha256) value of the startKey of a range, which ensures the uniqueness of a file. +- `timestamp` is the Unix timestamp of an SST file when it is generated by TiKV. +- `cf` indicates the Column Family of RocksDB (only restores data whose `cf` is `default` or `write` ). + +### Storage format of SST files + +- For details about the storage format of SST files, see [RocksDB BlockBasedTable format](https://github.com/facebook/rocksdb/wiki/Rocksdb-BlockBasedTable-Format). +- For details about the encoding format of backup data in SST files, see [mapping of table data to Key-Value](/tidb-computing.md#mapping-table-data-to-key-value). + +### Structure of backup files + +When you back up data to GCS or Azure Blob Storage, the SST files, `backupmeta` files, and `backup.lock` files are stored in the same directory as the following structure: + +``` +. +└── 20220621 + ├── backupmeta + |—— backup.lock + ├── {storeID}-{regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst + ├── {storeID}-{regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst + └── {storeID}-{regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst +``` + +When you back up data to Amazon S3 or a network disk, the SST files are stored in sub-directories based on the `storeID`. The structure is as follows: + +``` +. +└── 20220621 + ├── backupmeta + |—— backup.lock + ├── store1 + │   └── {regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst + ├── store100 + │   └── {regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst + ├── store2 + │   └── {regionID}-{regionEpoch}-{keyHash}-{timestamp}-{cf}.sst + ├── store3 + ├── store4 + └── store5 +``` + +## See also + +- [TiDB snapshot backup and restore guide](/br/br-snapshot-guide.md) diff --git a/br/br-snapshot-guide.md b/br/br-snapshot-guide.md new file mode 100644 index 0000000000000..9b13251568cfc --- /dev/null +++ b/br/br-snapshot-guide.md @@ -0,0 +1,180 @@ +--- +title: Snapshot Backup and Restore Guide +summary: Learn about how to back up and restore TiDB snapshots using the br command-line tool. +aliases: ['/tidb/dev/br-usage-backup/','/tidb/dev/br-usage-restore/','/tidb/dev/br-usage-restore-for-maintain/', '/tidb/dev/br-usage-backup-for-maintain/'] +--- + +# Snapshot Backup and Restore Guide + +This document describes how to back up and restore TiDB snapshots using the br command-line tool (hereinafter referred to as `br`). Before backing up and restoring data, you need to [install the br command-line tool](/br/br-use-overview.md#deploy-and-use-br) first. + +Snapshot backup is an implementation to back up the entire cluster. It is based on [multi-version concurrency control (MVCC)](/tidb-storage.md#mvcc) and backs up all data in the specified snapshot to a target storage. The size of the backup data is approximately the size of the compressed single replica in the cluster. After the backup is completed, you can restore the backup data to an empty cluster or a cluster that does not contain conflict data (with the same schema or same tables), restore the cluster to the time point of the snapshot backup, and restore multiple replicas according to the cluster replica settings. + +Besides basic backup and restore, snapshot backup and restore also provides the following features: + +* [Backup data of a specified time point](#back-up-cluster-snapshots) +* [Restore data of a specified database or table](#restore-a-database-or-a-table) + +## Back up cluster snapshots + +You can back up a TiDB cluster snapshot by running the `br backup full` command. Run `br backup full --help` to see the help information: + +```shell +tiup br backup full --pd "${PD_IP}:2379" \ + --backupts '2022-09-08 13:30:00' \ + --storage "s3://backup-101/snapshot-202209081330?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --ratelimit 128 \ +``` + +In the preceding command: + +- `--backupts`: The time point of the snapshot. The format can be [TSO](/glossary.md#tso) or timestamp, such as `400036290571534337` or `2018-05-11 01:42:23`. If the data of this snapshot is garbage collected, the `br backup` command returns an error and `br` exits. If you leave this parameter unspecified, `br` picks the snapshot corresponding to the backup start time. +- `--storage`: The storage address of the backup data. Snapshot backup supports Amazon S3, Google Cloud Storage, and Azure Blob Storage as backup storage. The preceding command uses Amazon S3 as an example. For more details, see [URL format of backup storages](/br/backup-and-restore-storages.md#url-format). +- `--ratelimit`: The maximum speed **per TiKV** performing backup tasks. The unit is in MiB/s. + +During backup, a progress bar is displayed in the terminal as shown below. When the progress bar advances to 100%, the backup task is completed and statistics such as total backup time, average backup speed, and backup data size are displayed. + +```shell +Full Backup <-------------------------------------------------------------------------------> 100.00% +Checksum <----------------------------------------------------------------------------------> 100.00% +*** ["Full Backup success summary"] *** [backup-checksum=3.597416ms] [backup-fast-checksum=2.36975ms] *** [total-take=4.715509333s] [BackupTS=435844546560000000] [total-kv=1131] [total-kv-size=250kB] [average-speed=53.02kB/s] [backup-data-size(after-compressed)=71.33kB] [Size=71330] +``` + +## Get the backup time point of a snapshot backup + +To manage a lot of backups, if you need to get the physical time of a snapshot backup, you can run the following command: + +```shell +tiup br validate decode --field="end-version" \ +--storage "s3://backup-101/snapshot-202209081330?access-key=${access-key}&secret-access-key=${secret-access-key}" | tail -n1 +``` + +The output is as follows, corresponding to the physical time `2022-09-08 13:30:00 +0800 CST`: + +``` +435844546560000000 +``` + +## Restore cluster snapshots + +You can restore a snapshot backup by running the `br restore full` command. Run `br restore full --help` to see the help information: + +The following example restores the [preceding backup snapshot](#back-up-cluster-snapshots) to a target cluster: + +```shell +tiup br restore full --pd "${PD_IP}:2379" \ +--storage "s3://backup-101/snapshot-202209081330?access-key=${access-key}&secret-access-key=${secret-access-key}" +``` + +During restore, a progress bar is displayed in the terminal as shown below. When the progress bar advances to 100%, the restore task is completed and statistics such as total restore time, average restore speed, and total data size are displayed. + +```shell +Full Restore <------------------------------------------------------------------------------> 100.00% +*** ["Full Restore success summary"] *** [total-take=4.344617542s] [total-kv=5] [total-kv-size=327B] [average-speed=75.27B/s] [restore-data-size(after-compressed)=4.813kB] [Size=4813] [BackupTS=435844901803917314] +``` + +### Restore a database or a table + +BR supports restoring partial data of a specified database or table from backup data. This feature allows you to filter out unwanted data and back up only a specific database or table. + +**Restore a database** + +To restore a database to a cluster, run the `br restore db` command. The following example restores the `test` database from the backup data to the target cluster: + +```shell +tiup br restore db \ +--pd "${PD_IP}:2379" \ +--db "test" \ +--storage "s3://backup-101/snapshot-202209081330?access-key=${access-key}&secret-access-key=${secret-access-key}" +``` + +In the preceding command, `--db` specifies the name of the database to be restored. + +**Restore a table** + +To restore a single table to a cluster, run the `br restore table` command. The following example restores the `test.usertable` table from the backup data to the target cluster: + +```shell +tiup br restore table --pd "${PD_IP}:2379" \ +--db "test" \ +--table "usertable" \ +--storage "s3://backup-101/snapshot-202209081330?access-key=${access-key}&secret-access-key=${secret-access-key}" +``` + +In the preceding command, `--db` specifies the name of the database to be restored, and `--table` specifies the name of the table to be restored. + +**Restore multiple tables with table filter** + +To restore multiple tables with more complex filter rules, run the `br restore full` command and specify the [table filters](/table-filter.md) with `--filter` or `-f`. The following example restores tables that match the `db*.tbl*` filter rule from the backup data to the target cluster: + +```shell +tiup br restore full \ +--pd "${PD_IP}:2379" \ +--filter 'db*.tbl*' \ +--storage "s3://backup-101/snapshot-202209081330?access-key=${access-key}&secret-access-key=${secret-access-key}" +``` + +### Restore tables in the `mysql` schema + +Starting from BR v5.1.0, when you back up snapshots, BR backs up the **system tables** in the `mysql` schema and does not restore them by default. Starting from BR v6.2.0, BR restores **data in some system tables** if you configure `--with-sys-table`. + +**BR can restore data in the following system tables:** + +``` ++----------------------------------+ +| mysql.columns_priv | +| mysql.db | +| mysql.default_roles | +| mysql.global_grants | +| mysql.global_priv | +| mysql.role_edges | +| mysql.tables_priv | +| mysql.user | ++----------------------------------+ +``` + +**BR does not restore the following system tables:** + +- Statistics tables (`mysql.stats_*`) +- System variable tables (`mysql.tidb` and `mysql.global_variables`) +- [Other system tables](https://github.com/pingcap/tidb/blob/master/br/pkg/restore/systable_restore.go#L31) + +When you restore data related to system privilege, note the following: + +- BR does not restore user data with `user` as `cloud_admin` and `host` as `'%'`. This user is reserved for TiDB Cloud. Do not create a user or role named `cloud_admin` in your cluster, because the user privileges related to `cloud_admin` cannot be restored correctly. +- Before restoring data, BR checks whether the system tables in the target cluster are compatible with those in the backup data. "Compatible" means that all the following conditions are met: + + - The target cluster has the same system tables as the backup data. + - The **number of columns** in the system privilege table of the target cluster is the same as that in the backup data. The column order is not important. + - The columns in the system privilege table of the target cluster are compatible with that in the backup data. If the data type of the column is a type with a length (such as integer and string), the length in the target cluster must be >= the length in the backup data. If the data type of the column is an `ENUM` type, the number of `ENUM` values in the target cluster must be a superset of that in the backup data. + +## Performance and impact + +### Performance and impact of snapshot backup + +The backup feature has some impact on cluster performance (transaction latency and QPS). However, you can mitigate the impact by adjusting the number of backup threads [`backup.num-threads`](/tikv-configuration-file.md#num-threads-1) or by adding more clusters. + +To illustrate the impact of backup, this document lists the test conclusions of several snapshot backup tests: + +- (5.3.0 and earlier) When the backup threads of BR on a TiKV node take up 75% of the total CPU of the node, the QPS is reduced by 35% of the original QPS. +- (5.4.0 and later) When there are no more than `8` threads of BR on a TiKV node and the cluster's total CPU utilization does not exceed 80%, the impact of BR tasks on the cluster (write and read) is 20% at most. +- (5.4.0 and later) When there are no more than `8` threads of BR on a TiKV node and the cluster's total CPU utilization does not exceed 75%, the impact of BR tasks on the cluster (write and read) is 10% at most. +- (5.4.0 and later) When there are no more than `8` threads of BR on a TiKV node and the cluster's total CPU utilization does not exceed 60%, BR tasks have little impact on the cluster (write and read). + +You can use the following methods to manually control the impact of backup tasks on cluster performance. However, these two methods also reduce the speed of backup tasks while reducing the impact of backup tasks on the cluster. + +- Use the `--ratelimit` parameter to limit the speed of backup tasks. Note that this parameter limits the speed of **saving backup files to external storage**. When calculating the total size of backup files, use the `backup data size(after compressed)` as a benchmark. +- Adjust the TiKV configuration item [`backup.num-threads`](/tikv-configuration-file.md#num-threads-1) to limit the number of threads used by backup tasks. According to internal tests, when BR uses no more than `8` threads for backup tasks, and the total CPU utilization of the cluster does not exceed 60%, the backup tasks have little impact on the cluster, regardless of the read and write workload. + +The impact of backup on cluster performance can be reduced by limiting the backup threads number, but this affects the backup performance. The preceding tests show that the backup speed is proportional to the number of backup threads. When the number of threads is small, the backup speed is about 20 MiB/thread. For example, 5 backup threads on a single TiKV node can reach a backup speed of 100 MiB/s. + +### Performance and impact of snapshot restore + +- During data restore, TiDB tries to fully utilize the TiKV CPU, disk IO, and network bandwidth resources. Therefore, it is recommended to restore the backup data on an empty cluster to avoid affecting the running applications. +- The speed of restoring backup data is much related with the cluster configuration, deployment, and running applications. In internal tests, the restore speed of a single TiKV node can reach 100 MiB/s. The performance and impact of snapshot restore are varied in different user scenarios and should be tested in actual environments. + +## See also + +* [TiDB Backup and Restore Use Cases](/br/backup-and-restore-use-cases.md) +* [br Command-line Manual](/br/use-br-command-line-tool.md) +* [TiDB Snapshot Backup and Restore Architecture](/br/br-snapshot-architecture.md) diff --git a/br/br-snapshot-manual.md b/br/br-snapshot-manual.md new file mode 100644 index 0000000000000..b56696c6635fc --- /dev/null +++ b/br/br-snapshot-manual.md @@ -0,0 +1,228 @@ +--- +title: TiDB Snapshot Backup and Restore Command Manual +summary: Learn about the commands of TiDB snapshot backup and restore. +--- + +# TiDB Snapshot Backup and Restore Command Manual + +This document describes the commands of TiDB snapshot backup and restore according to the application scenarios, including: + +- [Back up cluster snapshots](#back-up-cluster-snapshots) +- [Back up a database](#back-up-a-database) +- [Back up a table](#back-up-a-table) +- [Back up multiple tables with table filter](#back-up-multiple-tables-with-table-filter) +- [Encrypt the backup data](#encrypt-the-backup-data) +- [Restore cluster snapshots](#restore-cluster-snapshots) +- [Restore a database](#restore-a-database) +- [Restore a table](#restore-a-table) +- [Restore multiple tables with table filter](#restore-multiple-tables-with-table-filter) +- [Restore encrypted snapshots](#restore-encrypted-snapshots) + +For more information about snapshot backup and restore, refer to: + +- [Snapshot Backup and Restore Guide](/br/br-snapshot-guide.md) +- [Backup and Restore Use Cases](/br/backup-and-restore-use-cases.md) + +## Back up cluster snapshots + +You can back up the latest or specified snapshot of the TiDB cluster using the `br backup full` command. For more information about the command, run the `br backup full --help` command. + +```shell +br backup full \ + --pd "${PD_IP}:2379" \ + --backupts '2022-09-08 13:30:00' \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --ratelimit 128 \ + --log-file backupfull.log +``` + +In the preceding command: + +- `--backupts`: The time point of the snapshot. The format can be [TSO](/glossary.md#tso) or timestamp, such as `400036290571534337` or `2018-05-11 01:42:23`. If the data of this snapshot is garbage collected, the `br backup` command returns an error and 'br' exits. If you leave this parameter unspecified, `br` picks the snapshot corresponding to the backup start time. +- `--ratelimit`: The maximum speed **per TiKV** performing backup tasks. The unit is in MiB/s. +- `--log-file`: The target file where `br` log is written. + +During backup, a progress bar is displayed in the terminal, as shown below. When the progress bar advances to 100%, the backup is complete. + +```shell +Full Backup <---------/................................................> 17.12%. +``` + +## Back up a database or a table + +Backup & Restore (BR) supports backing up partial data of a specified database or table from a cluster snapshot or incremental data backup. This feature allows you to filter out unwanted data from snapshot backup and incremental data backup, and back up only business-critical data. + +### Back up a database + +To back up a database in a cluster, run the `br backup db` command. + +The following example backs up the `test` database to Amazon S3: + +```shell +br backup db \ + --pd "${PD_IP}:2379" \ + --db test \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --ratelimit 128 \ + --log-file backuptable.log +``` + +In the preceding command, `--db` specifies the database name, and other parameters are the same as those in [Back up TiDB cluster snapshots](#back-up-cluster-snapshots). + +### Back up a table + +To back up a table in a cluster, run the `br backup table` command. + +The following example backs up the `test.usertable` table to Amazon S3: + +```shell +br backup table \ + --pd "${PD_IP}:2379" \ + --db test \ + --table usertable \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --ratelimit 128 \ + --log-file backuptable.log +``` + +In the preceding command, `--db` and `--table` specify the database name and table name respectively, and other parameters are the same as those in [Back up TiDB cluster snapshots](#back-up-cluster-snapshots). + +### Back up multiple tables with table filter + +To back up multiple tables with more criteria, run the `br backup full` command and specify the [table filters](/table-filter.md) with `--filter` or `-f`. + +The following example backs up tables that match the `db*.tbl*` filter rule to Amazon S3: + +```shell +br backup full \ + --pd "${PD_IP}:2379" \ + --filter 'db*.tbl*' \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --ratelimit 128 \ + --log-file backupfull.log +``` + +## Encrypt the backup data + +> **Warning:** +> +> This is an experimental feature. It is not recommended that you use it in the production environment. + +BR supports encrypting backup data at the backup side and [at the storage side when backing up to Amazon S3](/br/backup-and-restore-storages.md#amazon-s3-server-side-encryption). You can choose either encryption method as required. + +Since TiDB v5.3.0, you can encrypt backup data by configuring the following parameters: + +- `--crypter.method`: Encryption algorithm, which can be `aes128-ctr`, `aes192-ctr`, or `aes256-ctr`. The default value is `plaintext`, indicating that data is not encrypted. +- `--crypter.key`: Encryption key in hexadecimal string format. It is a 128-bit (16 bytes) key for the algorithm `aes128-ctr`, a 24-byte key for the algorithm `aes192-ctr`, and a 32-byte key for the algorithm `aes256-ctr`. +- `--crypter.key-file`: The key file. You can directly pass in the file path where the key is stored as a parameter without passing in the `crypter.key`. + +The following is an example: + +```shell +br backup full\ + --pd ${PD_IP}:2379 \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --crypter.method aes128-ctr \ + --crypter.key 0123456789abcdef0123456789abcdef +``` + +> **Note:** +> +> - If the key is lost, the backup data cannot be restored to the cluster. +> - The encryption feature needs to be used on `br` and TiDB clusters v5.3.0 or later versions. The encrypted backup data cannot be restored on clusters earlier than v5.3.0. + +## Restore cluster snapshots + +You can restore a TiDB cluster snapshot by running the `br restore full` command. + +```shell +br restore full \ + --pd "${PD_IP}:2379" \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --ratelimit 128 \ + --log-file restorefull.log +``` + +In the preceding command: + +- `--ratelimit`: The maximum speed **per TiKV** performing backup tasks. The unit is in MiB/s. +- `--log-file`: The target file where the `br` log is written. + +During restore, a progress bar is displayed in the terminal as shown below. When the progress bar advances to 100%, the restore task is completed. Then `br` will verify the restored data to ensure data security. + +```shell +Full Restore <---------/...............................................> 17.12%. +``` + +## Restore a database or a table + +You can use `br` to restore partial data of a specified database or table from backup data. This feature allows you to filter out data that you do not need during the restore. + +### Restore a database + +To restore a database to a cluster, run the `br restore db` command. + +The following example restores the `test` database from the backup data to the target cluster: + +```shell +br restore db \ + --pd "${PD_IP}:2379" \ + --db "test" \ + --ratelimit 128 \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --log-file restore_db.log +``` + +In the preceding command, `--db` specifies the name of the database to be restored and other parameters are the same as those in [Restore TiDB cluster snapshots](#restore-cluster-snapshots). + +> **Note:** +> +> When you restore the backup data, the database name specified by `--db` must be the same as the one specified by `-- db` in the backup command. Otherwise, the restore fails. This is because the metafile of the backup data (`backupmeta` file) records the database name, and you can only restore data to the database with the same name. The recommended method is to restore the backup data to the database with the same name in another cluster. + +### Restore a table + +To restore a single table to a cluster, run the `br restore table` command. + +The following example restores the `test.usertable` table from Amazon S3 to the target cluster: + +```shell +br restore table \ + --pd "${PD_IP}:2379" \ + --db "test" \ + --table "usertable" \ + --ratelimit 128 \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --log-file restore_table.log +``` + +In the preceding command, `--table` specifies the name of the table to be restored, and other parameters are the same as those in [Restore a database](#restore-a-database). + +### Restore multiple tables with table filter + +To restore multiple tables with more complex filter rules, run the `br restore full` command and specify the [table filters](/table-filter.md) with `--filter` or `-f`. + +The following example restores tables that match the `db*.tbl*` filter rule from Amazon S3 to the target cluster: + +```shell +br restore full \ + --pd "${PD_IP}:2379" \ + --filter 'db*.tbl*' \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --log-file restorefull.log +``` + +## Restore encrypted snapshots + +> **Warning:** +> +> This is an experimental feature. It is not recommended that you use it in the production environment. + +After encrypting the backup data, you need to pass in the corresponding decryption parameters to restore the data. Ensure that the decryption algorithm and key are correct. If the decryption algorithm or key is incorrect, the data cannot be restored. The following is an example: + +```shell +br restore full\ + --pd "${PD_IP}:2379" \ + --storage "s3://${backup_collection_addr}/snapshot-${date}?access-key=${access-key}&secret-access-key=${secret-access-key}" \ + --crypter.method aes128-ctr \ + --crypter.key 0123456789abcdef0123456789abcdef +``` diff --git a/br/br-usage-backup.md b/br/br-usage-backup.md deleted file mode 100644 index 69d7b43f8c595..0000000000000 --- a/br/br-usage-backup.md +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: Use BR to Back Up Cluster Data -summary: Learn how to back up data using BR commands ---- - -# Use BR to Back Up Cluster Data - -This document describes how to back up TiDB cluster data in the following scenarios: - -- [Back up TiDB cluster snapshots](#back-up-tidb-cluster-snapshots) -- [Back up a database](#back-up-a-database) -- [Back up a table](#back-up-a-table) -- [Back up multiple tables with table filter](#back-up-multiple-tables-with-table-filter) -- [Back up data to external storage](#back-up-data-to-external-storage) -- [Back up incremental data](#back-up-incremental-data) -- [Encrypt backup data](#encrypt-backup-data) - -If you are not familiar with the backup and restore tools, it is recommended that you read the following documents to fully understand usage principles and methods of these tools: - -- [BR Overview](/br/backup-and-restore-overview.md) -- [Use BR Command-line for Backup and Restoration](/br/use-br-command-line-tool.md) - -If you need to back up a small amount of data (for example, less than 50 GB) and do not require high backup speed, you can use Dumpling to export data to implement backup. For detailed backup operations, see [Use Dumpling to back up full data](/backup-and-restore-using-dumpling-lightning.md#use-dumpling-to-back-up-full-data). - -## Back up TiDB cluster snapshots - -A snapshot of a TiDB cluster contains only the latest and transactionally consistent data at a specific time. You can back up the latest or specified snapshot data of a TiDB cluster by running the `br backup full` command. To get help on this command, run the `br backup full --help` command. - -Example: Back up the snapshot generated at `2022-01-30 07:42:23` to the `2022-01-30/` directory in the `backup-data` bucket of Amazon S3. - -{{< copyable "shell-regular" >}} - -```shell -br backup full \ - --pd "${PDIP}:2379" \ - --backupts '2022-01-30 07:42:23' \ - --storage "s3://backup-data/2022-01-30/" \ - --ratelimit 128 \ - --log-file backupfull.log -``` - -In the preceding command: - -- `--backupts`: The physical time of the snapshot. If data of this snapshot is processed by Garbage Collection (GC), the `br backup` command will exit with an error. If you leave this parameter unspecified, BR picks the snapshot corresponding to the backup start time. -- `--ratelimit`: The maximum speed **per TiKV** performing backup tasks (in MiB/s). -- `--log-file`: The target file for BR logging. - -During backup, a progress bar is displayed in the terminal, as shown below. When the progress bar advances to 100%, the backup is complete. - -```shell -br backup full \ - --pd "${PDIP}:2379" \ - --storage "s3://backup-data/2022-01-30/" \ - --ratelimit 128 \ - --log-file backupfull.log -Full Backup <---------/................................................> 17.12%. -``` - -After the backup is completed, BR compares the checksum of the backup data with the [admin checksum table](/sql-statements/sql-statement-admin-checksum-table.md) of the cluster to ensure data correctness and security. - -## Back up a database or a table - -BR supports backing up partial data of a specified database or table from a cluster snapshot or incremental data backup. This feature allows you to filter out unwanted data from snapshot backup and incremental data backup, and back up only business-critical data. - -### Back up a database - -To back up a database in a cluster, run the `br backup db` command. To get help on this command, run the `br backup db --help` command. - -Example: Back up the `test` database to the `db-test/2022-01-30/` directory in the `backup-data` bucket of Amazon S3. - -{{< copyable "shell-regular" >}} - -```shell -br backup db \ - --pd "${PDIP}:2379" \ - --db test \ - --storage "s3://backup-data/db-test/2022-01-30/" \ - --ratelimit 128 \ - --log-file backuptable.log -``` - -In the preceding command, `--db` specifies the database name, and other parameters are the same as those in [Back up TiDB cluster snapshots](#back-up-tidb-cluster-snapshots). - -### Back up a table - -To back up a table in a cluster, run the `br backup table` command. To get help on this command, run the `br backup table --help` command. - -Example: Back up `test.usertable` to the `table-db-usertable/2022-01-30/` directory in the `backup-data` bucket of Amazon S3. - -{{< copyable "shell-regular" >}} - -```shell -br backup table \ - --pd "${PDIP}:2379" \ - --db test \ - --table usertable \ - --storage "s3://backup-data/table-db-usertable/2022-01-30/" \ - --ratelimit 128 \ - --log-file backuptable.log -``` - -In the preceding command, `--db` and `--table` specify the database name and table name respectively, and other parameters are the same as those in [Back up TiDB cluster snapshots](#back-up-tidb-cluster-snapshots). - -### Back up multiple tables with table filter - -To back up multiple tables with more criteria, run the `br backup full` command and specify the [table filters](/table-filter.md) with `--filter` or `-f`. - -Example: Back up `db*.tbl*` data of a table to the `table-filter/2022-01-30/` directory in the `backup-data` bucket of Amazon S3. - -{{< copyable "shell-regular" >}} - -```shell -br backup full \ - --pd "${PDIP}:2379" \ - --filter 'db*.tbl*' \ - --storage "s3://backup-data/table-filter/2022-01-30/" \ - --ratelimit 128 \ - --log-file backupfull.log -``` - -## Back up data to external storage - -BR supports backing up data to Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, NFS, or other S3-compatible file storage services. For details, see the following documents: - -- [Back up data on Amazon S3 using BR](/br/backup-storage-S3.md) -- [Back up data on Google Cloud Storage using BR](/br/backup-storage-gcs.md) -- [Back up data on Azure Blob Storage using BR](/br/backup-storage-azblob.md) - -## Back up incremental data - -> **Warning:** -> -> This is still an experimental feature. It is **NOT** recommended that you use it in the production environment. - -Incremental data of a TiDB cluster is differentiated data between the snapshot of a starting point and that of an end point. Compared with snapshot data, incremental data is smaller and therefore it is a supplementary to snapshot backup, which reduces the volume of backup data. - -To back up incremental data, run the `br backup` command with **the last backup timestamp** `--lastbackupts` specified. To get `--lastbackupts`, run the `validate` command. The following is an example: - -{{< copyable "shell-regular" >}} - -```shell -LAST_BACKUP_TS=`br validate decode --field="end-version" -s s3://backup-data/2022-01-30/ | tail -n1` -``` - -> **Note:** -> -> - You need to save the incremental backup data under a different path from the previous snapshot backup. -> - GC safepoint must be prior to `lastbackupts`. The defalt GC lifetime is 10 minutes in TiDB, which means that TiDB only backs up incremental data generated in the last 10 minutes. To back up earlier incremental data, you need to [adjust TiDB GC Lifetime setting](/system-variables.md#tidb_gc_life_time-new-in-v50). - -{{< copyable "shell-regular" >}} - -```shell -br backup full\ - --pd ${PDIP}:2379 \ - --ratelimit 128 \ - --storage "s3://backup-data/2022-01-30/incr" \ - --lastbackupts ${LAST_BACKUP_TS} -``` - -The preceding command backs up the incremental data between `(LAST_BACKUP_TS, current PD timestamp]` and the DDLs generated during this time period. When restoring incremental data, BR restores all DDLs first, and then restores data. - -## Encrypt backup data - -> **Warning:** -> -> This is still an experimental feature. It is **NOT** recommended that you use it in the production environment. - -BR supports encrypting backup data at the backup end and at the storage end when backing up to Amazon S3. You can choose either encryption method as required. - -### Encrypt backup data at the backup end - -Since TiDB v5.3.0, you can encrypt backup data by configuring the following parameters: - -- `--crypter.method`: Encryption algorithm, which can be `aes128-ctr`, `aes192-ctr`, or `aes256-ctr`. The default value is `plaintext`, indicating that data is not encrypted. -- `--crypter.key`: Encryption key in hexadecimal string format. It is a 128-bit (16 bytes) key for the algorithm `aes128-ctr`, 24-byte key for the algorithm `aes192-ctr`, and 32-byte key for the algorithm `aes256-ctr`. -- `--crypter.key-file`: The key file. You can directly pass in the file path where the key is stored as a parameter without passing in "crypter.key". - -Example: Encrypt backup data at the backup end. - -{{< copyable "shell-regular" >}} - -```shell -br backup full\ - --pd ${PDIP}:2379 \ - --storage "s3://backup-data/2022-01-30/" \ - --crypter.method aes128-ctr \ - --crypter.key 0123456789abcdef0123456789abcdef -``` - -> **Note:** -> -> - If the key is lost, the backup data cannot be restored to the cluster. -> - The encryption feature needs to be used on BR tools and TiDB clusters v5.3.0 or later versions. The encrypted backup data cannot be restored on clusters earlier than v5.3.0. - -### Encrypt backup data when backing up to Amazon S3 - -BR supports server-side encryption (SSE) when backing up data to S3. In this scenario, you can use AWS KMS keys you have created to encrypt data. For details, see [BR S3 server-side encryption](/encryption-at-rest.md#br-s3-server-side-encryption). - -## Backup performance and impact - -The backup feature has some impact on cluster performance (transaction latency and QPS). However, you can mitigate the impact by adjusting the number of backup threads [`backup.num-threads`](/tikv-configuration-file.md#num-threads-1) or by adding more clusters. - -To illustrate the impact of backup, this document lists the test conclusions of several snapshot backup tests: - -- (5.3.0 and earlier) When the backup threads of BR on a TiKV node takes up 75% of the total CPU of the node, the QPS is reduced by 30% of the original QPS. -- (5.4.0 and later) When there are no more than `8` threads of BR on a TiKV node and the cluster's total CPU utilization does not exceed 80%, the impact of BR tasks on the cluster (write and read) is 20% at most. -- (5.4.0 and later) When there are no more than `8` threads of BR on a TiKV node and the cluster's total CPU utilization does not exceed 75%, the impact of BR tasks on the cluster (write and read) is 10% at most. -- (5.4.0 and later) When there are no more than `8` threads of BR on a TiKV node and the cluster's total CPU utilization does not exceed 60%, BR tasks has little impact on the cluster (write and read). - -You can mitigate impact on cluster performance by reducing the number of backup threads. However, this might cause backup performance to deteriorate. Based on the preceding test results: (On a single TiKV node) the backup speed is proportional to the number of backup threads. When the number of threads is small, the backup speed is about 20 MB/thread. For example, a single node with 5 backup threads can deliver a backup speed of 100 MB/s. - -> **Note:** -> -> The impact and speed of backup depends much on cluser configuration, deployment, and running services. The preceding test conclusions, based on simulation tests in many scenarios and verified in some customer sites, are worthy of reference. However, the exact impact and performance cap may vary depending on the scenarios. Therefore, you should always run the test and verify the test results. - - Since v5.3.0, BR introduces the auto tunning feature (enabled by default) to adjust the number of backup threads. It can maintain the CPU utilization of the cluster below 80% during backup tasks. For details, see [BR Auto-Tune](/br/br-auto-tune.md). diff --git a/br/br-usage-restore.md b/br/br-usage-restore.md deleted file mode 100644 index 678a1861e8b82..0000000000000 --- a/br/br-usage-restore.md +++ /dev/null @@ -1,234 +0,0 @@ ---- -title: Use BR to Restore Cluster Data -summary: Learn how to restore data using BR commands ---- - -# Use BR to Restore Cluster Data - -This document describes how to restore TiDB cluster data in the following scenarios: - -- [Restore TiDB cluster snapshots](#restore-tidb-cluster-snapshots) -- [Restore a database](#restore-a-database) -- [Restore a table](#restore-a-table) -- [Restore multiple tables with table filter](#restore-multiple-tables-with-table-filter) -- [Restore backup data from external storage](#restore-backup-data-from-external-storage) -- [Restore incremental data](#restore-incremental-data) -- [Restore encrypted backup data](#restore-encrypted-backup-data) -- [Restore tables in the `mysql` schema](#restore-tables-in-the-mysql-schema) - -If you are not familiar with backup and restore tools, it is recommended that you read the following documents to fully understand usage principles and methods of these tools: - -- [BR Overview](/br/backup-and-restore-overview.md) -- [Use BR Command-line for Backup and Restoration](/br/use-br-command-line-tool.md) - -If you need to restore data exported by Dumpling, CSV files, or Apache Parquet files generated by Amazon Aurora, you can use TiDB Lightning to import data to implement restore. For details, see [Use TiDB Lightning to restore full data](/backup-and-restore-using-dumpling-lightning.md#use-tidb-lightning-to-restore-full-data). - -## Restore TiDB cluster snapshots - -BR supports restoring snapshot backup on an empty cluster to restore the target cluster to the latest state when the snapshot is backed up. - -Example: Restore the snapshot generated at `2022-01-30 07:42:23` from the `2022-01-30/` directory in the `backup-data` bucket of Amazon S3 to the target cluster. - -{{< copyable "shell-regular" >}} - -```shell -br restore full \ - --pd "${PDIP}:2379" \ - --storage "s3://backup-data/2022-01-30/" \ - --ratelimit 128 \ - --log-file restorefull.log -``` - -In the preceding command, - -- `--ratelimit`: The maximum speed for **each TiKV** to perform a restoration task (unit: MiB/s) -- `--log-file` The target file for BR logging - -During restoration, a progress bar is displayed in the terminal, as shown below. When the progress bar advances to 100%, the restoration is complete. To ensure data security, BR performs a check on the restored data. - -```shell -br restore full \ - --pd "${PDIP}:2379" \ - --storage "s3://backup-data/2022-01-30/" \ - --ratelimit 128 \ - --log-file restorefull.log -Full Restore <---------/...............................................> 17.12%. -``` - -## Restore a database or a table - -BR supports restoring partial data of a specified database or table from backup data. This feature allows you to filter out unwanted data and back up only a specific database or table. - -### Restore a database - -To restore a database to the cluster, run the `br restore db` command. To get help on this command, run the `br restore db --help` command. - -Example: Restore the `test` database from the `db-test/2022-01-30/` directory in the `backup-data` bucket of Amazon S3 to the target cluster. - -{{< copyable "shell-regular" >}} - -```shell -br restore db \ - --pd "${PDIP}:2379" \ - --db "test" \ - --ratelimit 128 \ - --storage "s3://backup-data/db-test/2022-01-30/" \ - --log-file restore_db.log -``` - -In the preceding command, `--db` specifies the name of the database to be restored, and other parameters are the same as those in [Restore TiDB cluster snapshots](#restore-tidb-cluster-snapshots). - -> **Note:** -> -> When you restore the backup data, the database name specified by `--db` must be the same as the one specified by `-- db` in the backup command. Otherwise, the restoration fails. This is because the metafile of the backup data ( `backupmeta` file) records the database name, and you can only restore data to the database with the same name. The recommended method is to restore the backup data to the database with the same name in another cluster. - -### Restore a table - -To restore a single table to the cluster, run the `br restore table` command. To get help on this command, run the `br restore table --help` command. - -Example: Restore `test`.`usertable` from the `table-db-usertable/2022-01-30/`directory in the `backup-data` bucket of Amazon S3 to the target cluster. - -{{< copyable "shell-regular" >}} - -```shell -br restore table \ - --pd "${PDIP}:2379" \ - --db "test" \ - --table "usertable" \ - --ratelimit 128 \ - --storage "s3://backup-data/table-db-usertable/2022-01-30/" \ - --log-file restore_table.log -``` - -In the preceding command, `--table` specifies the name of the table to be restored, and other parameters are the same as those in [Restore TiDB cluster snapshots](#restore-tidb-cluster-snapshots). - -### Restore multiple tables with table filter - -To restore multiple tables with more criteria, run the `br restore full` command and specify the [table filters](/table-filter.md) with `--filter` or `-f`. - -Example: Restore data matching the `db*.tbl*` table from the `table-filter/2022-01-30/` directory in the `backup-data` bucket of Amazon S3 to the target cluster. - -{{< copyable "shell-regular" >}} - -```shell -br restore full \ - --pd "${PDIP}:2379" \ - --filter 'db*.tbl*' \ - --storage "s3://backup-data/table-filter/2022-01-30/" \ - --log-file restorefull.log -``` - -## Restore backup data from external storage - -BR supports restoring data to Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, NFS, or other S3-compatible file storage services. For details, see the following documents: - -- [Restore data on Amazon S3 using BR](/br/backup-storage-S3.md) -- [Restore data on Google Cloud Storage using BR](/br/backup-storage-gcs.md) -- [Restore data on Azure Blob Storage using BR](/br/backup-storage-azblob.md) - -## Restore incremental data - -> **Warning:** -> -> This is still an experimental feature. It is **NOT** recommended that you use it in the production environment. - -Restoring incremental data is similar to restoring full data using BR. When restoring incremental data, make sure that all the data backed up before `last backup ts` has been restored to the target cluster. Also, because incremental restoration updates ts data, you need to ensure that there are no other writes during the restoration. Otherwise, conflicts might occur. - -```shell -br restore full \ - --pd "${PDIP}:2379" \ - --storage "s3://backup-data/2022-01-30/incr" \ - --ratelimit 128 \ - --log-file restorefull.log -``` - -## Restore encrypted backup data - -> **Warning:** -> -> This is still an experimental feature. It is **NOT** recommended that you use it in the production environment. - -After encrypting the backup data, you need to pass in the corresponding decryption parameters to restore the data. Ensure that the decryption algorithm and key are correct. If the decryption algorithm or key is incorrect, the data cannot be restored. - -{{< copyable "shell-regular" >}} - -```shell -br restore full\ - --pd ${PDIP}:2379 \ - --storage "s3://backup-data/2022-01-30/" \ - --crypter.method aes128-ctr \ - --crypter.key 0123456789abcdef0123456789abcdef -``` - -## Restore tables in the `mysql` schema - -Starting from BR v5.1.0, when you perform a full backup, BR backs up the **system tables**. Before BR v6.2.0, under default configuration, BR only restores user data, but does not restore data in the system tables. Starting from BR v6.2.0, if the backup data contains system tables, and if you configure `--with-sys-table`, BR restores **data in some system tables**. - -BR can restore data in **the following system tables**: - -``` -+----------------------------------+ -| mysql.columns_priv | -| mysql.db | -| mysql.default_roles | -| mysql.global_grants | -| mysql.global_priv | -| mysql.role_edges | -| mysql.tables_priv | -| mysql.user | -+----------------------------------+ -``` - -**BR does not restore the following system tables**: - -- Statistics tables (`mysql.stat_*`) -- System variable tables (`mysql.tidb`, `mysql.global_variables`) -- [Other system tables](https://github.com/pingcap/tidb/blob/master/br/pkg/restore/systable_restore.go#L31) - -When you restore data related to system privileges, note the following: - -- BR does not restore user data with `user` as `cloud_admin` and `host` as `'%'`. This user is reserved for TiDB Cloud. Do not create a user or role named `cloud_admin` in your environment, because the user privileges related to `cloud_admin` cannot be restored correctly. -- Before BR restores data, it checks whether the system tables in the target cluster are compatible with those in the backup data. "Compatible" means that all the following conditions are met: - - - The target cluster has the same system tables as the backup data. - - The **number of columns** in the system privilege table of the target cluster is consistent with that of the backup data. The order of the columns can be different. - - The columns in the system privilege table of the target cluster are compatible with those in the backup data. If the data type of the column is a type with length (for example, int or char), the length in the target cluster must be >= the length in the backup data. If the data type of the column is an enum type, the enum values in the target cluster must be a superset of the enum values in the backup data. - -If the target cluster is not empty or the target cluster is not compatible with the backup data, BR returns the following information. You can remove `--with-sys-table` to skip restoring system tables. - -``` -####################################################################### -# the target cluster is not compatible with the backup data, -# br cannot restore system tables. -# you can remove 'with-sys-table' flag to skip restoring system tables -####################################################################### -``` - -To restore a table created by the user in the `mysql` schema (not system tables), you can explicitly include the table using [table filters](/table-filter.md#syntax). The following example shows how to restore the `mysql.usertable` table when BR performs a normal restoration. - -```shell -br restore full -f '*.*' -f '!mysql.*' -f 'mysql.usertable' -s $external_storage_url --with-sys-table -``` - -In the preceding command, - -- `-f '*.*'` is used to override the default rules -- `-f '!mysql.*'` instructs BR not to restore tables in `mysql` unless otherwise stated. -- `-f 'mysql.usertable'` indicates that `mysql.usertable` should be restored. - -If you only need to restore `mysql.usertable`, run the following command: - -{{< copyable "shell-regular" >}} - -```shell -br restore full -f 'mysql.usertable' -s $external_storage_url --with-sys-table -``` - -## Restoration performance and impact - -- TiDB fully uses TiKV CPU, disk IO, network bandwidth, and other resources when restoring data. Therefore, it is recommended that you restore backup data on an empty cluster to avoid affecting running services. -- The restoration speed depends much on cluser configuration, deployment, and running services. Generally, the restoration speed can reach 100 MB/s (per TiKV node). - -> **Note:** -> -> The preceding test conclusions, based on simulation tests in many scenarios and verified in some customer sites, are worthy of reference. However, the restoration speed may vary depending on the scenarios. Therefore, you should always run the test and verify the test results. diff --git a/br/br-use-overview.md b/br/br-use-overview.md new file mode 100644 index 0000000000000..487549010e6ae --- /dev/null +++ b/br/br-use-overview.md @@ -0,0 +1,101 @@ +--- +title: Usage Overview of TiDB Backup and Restore +summary: Learn about how to deploy the backup and restore tool, and how to use it to back up and restore a TiDB cluster. +aliases: ['/tidb/dev/br-deployment/'] +--- + +# Usage Overview of TiDB Backup and Restore + +This document describes best practices of using TiDB backup and restore features, including how to choose a backup method, how to manage backup data, and how to install and deploy the backup and restore tool. + +## Recommended practices + +Before using TiDB backup and restore features, it is recommended that you understand the recommended backup and restore solutions. + +### How to back up data? + +**TiDB provides two types of backup. Which one should I use?** Full backup contains the full data of a cluster at a certain point in time. Log backup contains the data changes written to TiDB. It is recommended to use both types of backup at the same time: + +- **[Start log backup](/br/br-pitr-guide.md#start-log-backup)**: Run the `br log start` command to start the log backup task. After that, the task keeps running on all TiKV nodes and backs up TiDB data changes to the specified storage in small batches regularly. +- **Perform [snapshot (full) backup](/br/br-snapshot-guide.md#back-up-cluster-snapshots) regularly**: Run the `br backup full` command to back up the snapshot of the cluster to the specified storage. For example, back up the cluster snapshot at 0:00 AM every day. + +### How to manage backup data? + +BR provides only basic backup and restore features, and does not support backup management. Therefore, you need to decide how to manage backup data on your own, which might involve the following questions? + +* Which backup storage system should I choose? +* In which directory should I place the backup data during a backup task? +* In what way should I organize the directory of the full backup data and log backup data? +* How to handle the historical backup data in the storage system? + +The following sections will answer these questions one by one. + +**Choose a backup storage system** + +It is recommended that you store backup data to Amazon S3, Google Cloud Storage (GCS), or Azure Blob Storage. Using these systems, you do not need to worry about the backup capacity and bandwidth allocation. + +If the TiDB cluster is deployed in a self-built data center, the following practices are recommended: + +* Build [MinIO](https://docs.min.io/docs/minio-quickstart-guide.html) as the backup storage system, and use the S3 protocol to back up data to MinIO. +* Mount Network File System (NFS, such as NAS) disks to br command-line tool and all TiKV instances, and use the POSIX file system interface to write backup data to the corresponding NFS directory. + +> **Note:** +> +> If you do not choose NFS or a storage system that supports Amazon S3, GCS, or Azure Blob Storage protocols, the data backed up is generated at each TiKV node. **Note that this is not the recommended way to use BR**, because collecting the backup data might result in data redundancy and operation and maintenance problems. + +**Organize the backup data directory** + +* Store the snapshot backup and log backup in the same directory for unified management, for example, `backup-${cluster-id}`. +* Store each snapshot backup in a directory with the backup date included, for example, `backup-${cluster-id}/fullbackup-202209081330`. +* Store the log backup in a fixed directory, for example, `backup-${cluster-id}/logbackup`. The log backup program creates subdirectories under the `logbackup` directory every day to distinguish the data backed up each day. + +**Handle historical backup data** + +Assume that you need to set the life cycle for each backup data, for example, 7 days. Such a life cycle is called **backup retention period**, which will also be mentioned in backup tutorials. + +* To perform PITR, you need to restore the full backup before the restore point, and the log backup between the full backup and the restore point. Therefore, **It is recommended to only delete the log backup before the full snapshot**. For log backups that exceed the backup retention period, you can use `br log truncate` command to delete the backup before the specified time point. +* For backup data that exceeds the retention period, you can delete or archive the backup directory. + +### How to restore data? + +- To restore only full backup data, you can use `br restore` to perform a full restore of the specified backup. +- If you have started log backup and regularly performed a full backup, you can run the `br restore point` command to restore data to any time point within the backup retention period. + +## Deploy and use BR + +To deploy BR, ensure that the following requirements are met: + +- BR, TiKV nodes, and the backup storage system provide network bandwidth that is greater than the backup speed. If the target cluster is particularly large, the threshold of backup and restore speed is limited by the bandwidth of the backup network. +- The backup storage system provides sufficient read and write performance (IOPS). Otherwise, they might become a performance bottleneck during backup or restore. +- TiKV nodes have at least two additional CPU cores and high performance disks for backups. Otherwise, the backup might have an impact on the services running on the cluster. +- BR runs on a node with more than 8 cores and 16 GiB memory. + +You can use backup and restore features in several ways, such as via the command-line tool, by running SQL commands, and using TiDB Operator. The following sections describe these three methods in detail. + +### Use br command-line tool (recommended) + +TiDB supports backup and restore using br command-line tool. + +* You can run the `tiup install br` command to [install br command-line tool using TiUP online](/migration-tools.md#install-tools-using-tiup). +* For details about how to use `br` commands to back up and restore data, refer to the following documents: + + * [TiDB Snapshot Backup and Restore Guide](/br/br-snapshot-guide.md) + * [TiDB Log Backup and PITR Guide](/br/br-pitr-guide.md) + * [TiDB Backup and Restore Use Cases](/br/backup-and-restore-use-cases.md) + +### Use SQL statements + +TiDB supports full backup and restore using SQL statements: + +- [`BACKUP`](/sql-statements/sql-statement-backup.md): backs up full snapshot data. +- [`RESTORE`](/sql-statements/sql-statement-restore.md): restores snapshot backup data. +- [`SHOW BACKUPS|RESTORES`](/sql-statements/sql-statement-show-backups.md): views the backup and restore progress. + +### Use TiDB Operator on Kubernetes + +On Kubernetes, you can use TiDB Operator to back up TiDB cluster data to Amazon S3, GCS, or Azure Blob Storage, and restore data from the backup data in such systems. For details, see [Back Up and Restore Data Using TiDB Operator](https://docs.pingcap.com/tidb-in-kubernetes/stable/backup-restore-overview). + +## See also + +- [TiDB Backup and Restore Overview](/br/backup-and-restore-overview.md) +- [TiDB Backup and Restore Architecture](/br/backup-and-restore-design.md) diff --git a/br/external-storage.md b/br/external-storage.md new file mode 100644 index 0000000000000..4b10e0dd960d6 --- /dev/null +++ b/br/external-storage.md @@ -0,0 +1,237 @@ +--- +title: External Storages +summary: Describes the storage URL format used in BR, TiDB Lightning, and Dumpling. +--- + +# External Storages + +br command-line tool, TiDB Lightning, and Dumpling support reading and writing data on the local file system and on Amazon S3. br command-line tool also supports reading and writing data on the Google Cloud Storage (GCS) and Azure Blob Storage (Azblob). These are distinguished by the URL scheme in the `--storage` (`-s`) parameter passed into br command-line tool, in the `-d` parameter passed into TiDB Lightning, and in the `--output` (`-o`) parameter passed into Dumpling. + +## Schemes + +The following services are supported: + +| Service | Scheme | Example URL | +|---------|---------|-------------| +| Local file system, distributed on every node | local | `local:///path/to/dest/` | +| Amazon S3 and compatible services | s3 | `s3://bucket-name/prefix/of/dest/` | +| Google Cloud Storage (GCS) | gcs, gs | `gcs://bucket-name/prefix/of/dest/` | +| Azure Blob Storage | azure, azblob | `azure://container-name/prefix/of/dest/` | +| Write to nowhere (for benchmarking only) | noop | `noop://` | + +## URL parameters + +Cloud storages such as S3, GCS and Azblob sometimes require additional configuration for connection. You can specify parameters for such configuration. For example: + ++ Use Dumpling to export data to S3: + + ```bash + ./dumpling -u root -h 127.0.0.1 -P 3306 -B mydb -F 256MiB \ + -o 's3://my-bucket/sql-backup' + ``` + ++ Use TiDB Lightning to import data from S3: + + ```bash + ./tidb-lightning --tidb-port=4000 --pd-urls=127.0.0.1:2379 --backend=local --sorted-kv-dir=/tmp/sorted-kvs \ + -d 's3://my-bucket/sql-backup' + ``` + ++ Use TiDB Lightning to import data from S3 (using the path-style request): + + ```bash + ./tidb-lightning --tidb-port=4000 --pd-urls=127.0.0.1:2379 --backend=local --sorted-kv-dir=/tmp/sorted-kvs \ + -d 's3://my-bucket/sql-backup?force-path-style=true&endpoint=http://10.154.10.132:8088' + ``` + ++ Use TiDB Lightning to import data from S3 (access S3 data by using a specific IAM role): + + ```bash + ./tidb-lightning --tidb-port=4000 --pd-urls=127.0.0.1:2379 --backend=local --sorted-kv-dir=/tmp/sorted-kvs \ + -d 's3://my-bucket/test-data?role-arn=arn:aws:iam::888888888888:role/my-role' + ``` + ++ Use br command-line tool to back up data to GCS: + + ```bash + ./br backup full -u 127.0.0.1:2379 \ + -s 'gcs://bucket-name/prefix' + ``` + ++ Use br command-line tool to back up data to Azblob: + + ```bash + ./br backup full -u 127.0.0.1:2379 \ + -s 'azure://container-name/prefix' + ``` + +### S3 URL parameters + +| URL parameter | Description | +|:----------|:---------| +| `access-key` | The access key | +| `secret-access-key` | The secret access key | +| `use-accelerate-endpoint` | Whether to use the accelerate endpoint on Amazon S3 (default to `false`) | +| `endpoint` | URL of custom endpoint for S3-compatible services (for example, `https://s3.example.com/`) | +| `force-path-style` | Use path-style requests rather than virtual-hosted–style requests (default to `true`) | +| `storage-class` | Storage class of the uploaded objects (for example, `STANDARD`, `STANDARD_IA`) | +| `sse` | Server-side encryption algorithm used to encrypt the upload (empty, `AES256` or `aws:kms`) | +| `sse-kms-key-id` | If `sse` is set to `aws:kms`, specifies the KMS ID | +| `acl` | Canned ACL of the uploaded objects (for example, `private`, `authenticated-read`) | +| `role-arn` | When you need to access Amazon S3 data from a third party using a specified [IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html), you can specify the corresponding [Amazon Resource Name (ARN)](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) of the IAM role with the `role-arn` parameter, such as `arn:aws:iam::888888888888:role/my-role`. For more information, see [Providing access to AWS accounts owned by third parties](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html). | +| `external-id` | When you access Amazon S3 data from a third party, you might need to specify a correct [external ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) to assume [the IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html). In this case, you can use this `external-id` URL query parameter to specify the external ID. An external ID is an arbitrary string provided by the third party together with the IAM role ARN to access the Amazon S3 data. Providing an external ID is optional when assuming an IAM role, which means if the third party does not specify an external ID for the IAM role, you can assume the role and access the corresponding S3 data without providing this parameter. | + +> **Note:** +> +> It is not recommended to pass in the access key and secret access key directly in the storage URL, because these keys are stored as plain text. + +If neither the access key and secret access key nor IAM role ARN (`role-arn`) and external ID (`external-id`) are provided, the migration tools searches for these keys from the environment in the following order: + +1. `$AWS_ACCESS_KEY_ID` and `$AWS_SECRET_ACCESS_KEY` environment variables +2. `$AWS_ACCESS_KEY` and `$AWS_SECRET_KEY` environment variables +3. Shared credentials file on the tool node at the path specified by the `$AWS_SHARED_CREDENTIALS_FILE` environment variable +4. Shared credentials file on the tool node at `~/.aws/credentials` +5. Current IAM role of the Amazon EC2 container +6. Current IAM role of the Amazon ECS task + +### GCS URL parameters + +| URL parameter | Description | +|:----------|:---------| +| `credentials-file` | The path to the credentials JSON file on the tool node | +| `storage-class` | Storage class of the uploaded objects (for example, `STANDARD`, `COLDLINE`) | +| `predefined-acl` | Predefined ACL of the uploaded objects (for example, `private`, `project-private`) | + +When `credentials-file` is not specified, the migration tool searches for the credentials from the environment in the following order: + +1. Content of the file on the tool node at the path specified by the `$GOOGLE_APPLICATION_CREDENTIALS` environment variable +2. Content of the file on the tool node at `~/.config/gcloud/application_default_credentials.json` +3. When running in GCE or GAE, the credentials fetched from the metadata server. + +### Azblob URL parameters + +| URL parameter | Description | +|:----------|:-----| +| `account-name` | The account name of the storage | +| `account-key` | The access key| +| `access-tier` | Access tier of the uploaded objects (for example, `Hot`, `Cool`, `Archive`). If `access-tier` is not set (the value is empty), the value is `Hot` by default. | + +To ensure that TiKV and br use the same storage account, br determines the value of `account-name`. That is, `send-credentials-to-tikv = true` is set by default. br searches for these keys from the environment in the following order: + +1. If both `account-name` **and** `account-key` are specified, the key specified by this parameter is used. +2. If `account-key` is not specified, br tries to read the related credentials from environment variables on the br node. br reads `$AZURE_CLIENT_ID`, `$AZURE_TENANT_ID`, and `$AZURE_CLIENT_SECRET` first. At the same time, br allows TiKV to read these three environment variables from the respective nodes and access the variables using Azure AD (Azure Active Directory). +3. If the preceding three environment variables are not configured in the br node, br tries to read `$AZURE_STORAGE_KEY` using an access key. + +> **Note:** +> +> - When using Azure Blob Storage as the external storage, you should set `send-credentials-to-tikv = true` (which is set by default). Otherwise, the backup task will fail. +> - `$AZURE_CLIENT_ID`, `$AZURE_TENANT_ID`, and `$AZURE_CLIENT_SECRET` respectively refer to the application ID `client_id`, the tenant ID `tenant_id`, and the client password `client_secret` of the Azure application. For details about how to confirm the presence of the three environment variables, or how to configure the environment variables as parameters, see [Authentication](/br/backup-and-restore-storages.md#authentication). + +## Command-line parameters + +In addition to the URL parameters, br and Dumpling also support specifying these configurations using command-line parameters. For example: + +{{< copyable "shell-regular" >}} + +```bash +./dumpling -u root -h 127.0.0.1 -P 3306 -B mydb -F 256MiB \ + -o 's3://my-bucket/sql-backup' \ + --s3.role-arn="arn:aws:iam::888888888888:role/my-role" +``` + +The preceding command is equivalent to the following: + +```bash +./dumpling -u root -h 127.0.0.1 -P 3306 -B mydb -F 256MiB \ + -o 's3://my-bucket/sql-backup&role-arn=arn:aws:iam::888888888888:role/my-role' +``` + +If you have specified URL parameters and command-line parameters at the same time, the URL parameters are overwritten by the command-line parameters. + +### S3 command-line parameters + +| Command-line parameter | Description | +|:----------|:------| +| `--s3.endpoint` | The URL of custom endpoint for S3-compatible services (for example, `https://s3.example.com/`) | +| `--s3.storage-class` | The storage class of the upload object (for example, `STANDARD` or `STANDARD_IA`) | +| `--s3.sse` | The server-side encryption algorithm used to encrypt the upload (value options are empty, `AES256` and `aws:kms`) | +| `--s3.sse-kms-key-id` | If `--s3.sse` is configured as `aws:kms`, this parameter is used to specify the KMS ID. | +| `--s3.acl` | The canned ACL of the upload object (for example, `private` or `authenticated-read`) | +| `--s3.provider` | The type of the S3-compatible service (supported types are `aws`, `alibaba`, `ceph`, `netease` and `other`) | +| `--s3.role-arn` | When you need to access Amazon S3 data from a third party using a specified [IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html), you can specify the corresponding [Amazon Resource Name (ARN)](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) of the IAM role with the `--s3.role-arn` option, such as `arn:aws:iam::888888888888:role/my-role`. For more information, see [AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html). | +| `--s3.external-id` | When you access Amazon S3 data from a third party, you might need to specify a correct [external ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) to assume [the IAM role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html). In this case, you can use this `--s3.external-id` option to specify the external ID. An external ID is an arbitrary string provided by the third party together with the IAM role ARN to access the Amazon S3 data. Providing an external ID is optional when assuming an IAM role, which means if the third party does not specify an external ID for the IAM role, you can assume the role and access the corresponding S3 data without providing this parameter. | + +To export data to non-AWS S3 cloud storage, specify the cloud provider and whether to use `virtual-hosted style`. In the following examples, data is exported to the Alibaba Cloud OSS storage: + ++ Export data to Alibaba Cloud OSS using Dumpling: + + {{< copyable "shell-regular" >}} + + ```bash + ./dumpling -h 127.0.0.1 -P 3306 -B mydb -F 256MiB \ + -o "s3://my-bucket/dumpling/" \ + --s3.endpoint="http://oss-cn-hangzhou-internal.aliyuncs.com" \ + --s3.provider="alibaba" \ + -r 200000 -F 256MiB + ``` + ++ Back up data to Alibaba Cloud OSS using br command-line tool: + + {{< copyable "shell-regular" >}} + + ```bash + ./br backup full --pd "127.0.0.1:2379" \ + --storage "s3://my-bucket/full/" \ + --s3.endpoint="http://oss-cn-hangzhou-internal.aliyuncs.com" \ + --s3.provider="alibaba" \ + --send-credentials-to-tikv=true \ + --ratelimit 128 \ + --log-file backuptable.log + ``` + ++ Export data to Alibaba Cloud OSS using TiDB Lightning. You need to specify the following content in the YAML configuration file: + + {{< copyable "" >}} + + ``` + [mydumper] + data-source-dir = "s3://my-bucket/dumpling/?endpoint=http://oss-cn-hangzhou-internal.aliyuncs.com&provider=alibaba" + ``` + +### GCS command-line parameters + +| Command-line parameter | Description | +|:----------|:------| +| `--gcs.credentials-file` | The path to the credentials JSON file on the tool node | +| `--gcs.storage-class` | The storage class of the upload objects (for example, `STANDARD` or `COLDLINE`) | +| `--gcs.predefined-acl` | Predefined ACL of the uploaded objects (for example, `private` or `project-private`) | + +### Azblob command-line parameters + +| Command-line parameter | Description | +|:----------|:------| +| `--azblob.account-name` | The account name of the storage | +| `--azblob.account-key` | The access key | +| `--azblob.access-tier` | Access tier of the uploaded objects (for example, `Hot`, `Cool`, `Archive`). If `access-tier` is not set (the value is empty), the value is `Hot` by default. | + +## br command-line tool sending credentials to TiKV + +By default, when using S3, GCS, or Azblob destinations, br command-line tool will send the credentials to every TiKV node to reduce setup complexity. + +However, this is unsuitable on cloud environment, where every node has their own role and permission. In such cases, you need to disable credentials sending with `--send-credentials-to-tikv=false` (or the short form `-c=0`): + +{{< copyable "shell-regular" >}} + +```bash +./br backup full -c=0 -u pd-service:2379 -s 's3://bucket-name/prefix' +``` + +When using SQL statements to [back up](/sql-statements/sql-statement-backup.md) and [restore](/sql-statements/sql-statement-restore.md) data, you can add the `SEND_CREDENTIALS_TO_TIKV = FALSE` option: + +{{< copyable "sql" >}} + +```sql +BACKUP DATABASE * TO 's3://bucket-name/prefix' SEND_CREDENTIALS_TO_TIKV = FALSE; +``` + +This option is not supported in TiDB Lightning and Dumpling, because they are currently standalone. diff --git a/br/pitr-known-issues.md b/br/pitr-known-issues.md deleted file mode 100644 index 7ac341effb237..0000000000000 --- a/br/pitr-known-issues.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Known Issues in Log Backup -summary: Learn known issues in log backup. ---- - -# Known Issues in Log Backup - -This document lists the known issues and corresponding workarounds when you use the log backup feature. - -## BR encounters the OOM problem after you run the `br log truncate` command - -Issue: [#36648](https://github.com/pingcap/tidb/issues/36648) - -Consider the following possible causes: - -- The range of logs to be deleted is too large. - - To resolve this issue, reduce the range of logs to be deleted first and delete the target logs in several batches instead of deleting them once. - -- The memory allocation of the node where the BR process is located is too low. - - It is recommended to scale up the node memory configuration to at least 16 GB to ensure that PITR has sufficient memory resources for recovery. - -## The upstream database imports data using TiDB Lightning in the physical import mode, which makes it impossible to use the log backup feature - -Currently, the log backup feature is not fully adapted to TiDB Lightning. Therefore, data imported in the physical mode of TiDB Lightning cannot be backed up to logs. - -In upstream clusters where you create log backup tasks, avoid using the TiDB Lightning physical mode to import data. Instead, you can use TiDB Lightning logical mode. If you do need to use the physical mode, perform a snapshot backup after the import is complete, so that PITR can be restored to the time point after the snapshot backup. - -## The cluster has recovered from the network partition failure, but the checkpoint of the log backup task progress still does not resume - -Issue: [#13126](https://github.com/tikv/tikv/issues/13126) - -After a network partition failure in the cluster, the backup task cannot continue backing up logs. After a certain retry time, the task will be set to `ERROR` state. At this point, the backup task has stopped. - -To resolve this issue, you need to manually execute the `br log resume` command to resume the log backup task. - -## The error `execute over region id` is returned when you perform PITR - -Issue: [#37207](https://github.com/pingcap/tidb/issues/37207) - -This issue usually occurs when you enable log backup during a full data import and afterwards perform a PITR to restore data at a time point during the data import. - -Specifically, there is a probability that this issue occurs if there are a large number of hotspot writes for a long time (such as 24 hours) and if the OPS of each TiKV node is larger than 50k/s (you can view the metrics in Grafana: **TiKV-Details** -> **Backup Log** -> **Handle Event Rate**). - -For the current version, it is recommended that you perform a snapshot backup after the data import and perform PITR based on this snapshot backup. - -## The commit time of a large transaction affects the checkpoint lag of log backup - -Issue: [#13304](https://github.com/tikv/tikv/issues/13304) - -When there is a large transaction, the log checkpoint lag is not updated before the transaction is committed. Therefore, the checkpoint lag is increased by a period of time close to the commit time of the transaction. - -## The acceleration of adding indexes feature is not compatible with PITR - -Issue: [#38045](https://github.com/pingcap/tidb/issues/38045) - -Currently, the [acceleration of adding indexes](/system-variables.md#tidb_ddl_enable_fast_reorg-new-in-v630) feature is not compatible with PITR. When using index acceleration, you need to ensure that there are no PITR log backup tasks running in the background. Otherwise, unexpected behaviors might occur, including: - -- If you start a log backup task first, and then add an index. The adding index process is not accelerated even if index acceleration is enabled. But the index is added in a slow way. -- If you start an index acceleration task first, and then start a log backup task. The log backup task returns an error. But the index acceleration is not affected. -- If you start a log backup task and an index acceleration task at the same time, the two tasks might not be aware of each other. This might result in PITR failing to back up the newly added index. diff --git a/br/pitr-troubleshoot.md b/br/pitr-troubleshoot.md deleted file mode 100644 index 0cef780d6a2bb..0000000000000 --- a/br/pitr-troubleshoot.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Troubleshoot Log Backup -summary: Learn about common problems of log backup and how to fix them. ---- - -# Troubleshoot Log Backup - -This document summarizes common problems during log backup and the solutions. - -## After restoring a downstream cluster using the `br restore point` command, data cannot be accessed from TiFlash. What should I do? - -In v6.2.0, PITR does not support restoring the TiFlash replicas of a cluster. After restoring data, you need to execute the following statement to set the TiFlash replica of the schema or table. - -```sql -ALTER TABLE table_name SET TIFLASH REPLICA @count; -``` - -In v6.3.0 and later versions, after PITR completes data restore, BR automatically executes the `ALTER TABLE SET TIFLASH REPLICA` DDL statement according to the number of TiFlash replicas in the upstream cluster at the corresponding time. You can check the TiFlash replica setting using the following SQL statement: - -``` sql -SELECT * FROM INFORMATION_SCHEMA.tiflash_replica; -``` - -> **Note:** -> -> Currently, PITR does not support writing data directly to TiFlash during the restore phase. Therefore, TiFlash replicas are not available immediately after PITR completes data restore. Instead, you need to wait for a certain period of time for the data to be replicated from TiKV nodes. To check the replication progress, check the `progress` information in the `INFORMATION_SCHEMA.tiflash_replica` table. - -## What should I do if the `status` of a log backup task becomes `ERROR`? - -During a log backup task, the task status becomes `ERROR` if it fails and cannot be recovered after retrying. The following is an example: - -```shell -br log status --pd x.x.x.x:2379 - -● Total 1 Tasks. -> #1 < - name: task1 - status: ○ ERROR - start: 2022-07-25 13:49:02.868 +0000 - end: 2090-11-18 14:07:45.624 +0000 - storage: s3://tmp/br-log-backup0ef49055-5198-4be3-beab-d382a2189efb/Log - speed(est.): 0.00 ops/s - checkpoint[global]: 2022-07-25 14:46:50.118 +0000; gap=11h31m29s - error[store=1]: KV:LogBackup:RaftReq -error-happen-at[store=1]: 2022-07-25 14:54:44.467 +0000; gap=11h23m35s - error-message[store=1]: retry time exceeds: and error failed to get initial snapshot: failed to get the snapshot (region_id = 94812): Error during requesting raftstore: message: "read index not ready, reason can not read index due to merge, region 94812" read_index_not_ready { reason: "can not read index due to merge" region_id: 94812 }: failed to get initial snapshot: failed to get the snapshot (region_id = 94812): Error during requesting raftstore: message: "read index not ready, reason can not read index due to merge, region 94812" read_index_not_ready { reason: "can not read index due to merge" region_id: 94812 }: failed to get initial snapshot: failed to get the snapshot (region_id = 94812): Error during requesting raftstore: message: "read index not ready, reason can not read index due to merge, region 94812" read_index_not_ready { reason: "can not read index due to merge" region_id: 94812 } -``` - -To address this problem, check the error message for the cause and perform as instructed. After the problem is addressed, run the following command to resume the task: - -```shell -br log resume --task-name=task1 --pd x.x.x.x:2379 -``` - -After the backup task is resumed, you can check the status using `br log status`. The backup task continues when the task status becomes `NORMAL`. - -```shell -● Total 1 Tasks. -> #1 < - name: task1 - status: ● NORMAL - start: 2022-07-25 13:49:02.868 +0000 - end: 2090-11-18 14:07:45.624 +0000 - storage: s3://tmp/br-log-backup0ef49055-5198-4be3-beab-d382a2189efb/Log - speed(est.): 15509.75 ops/s -checkpoint[global]: 2022-07-25 14:46:50.118 +0000; gap=6m28s -``` - -> **Note:** -> -> This feature backs up multiple versions of data. When a long backup task fails and the status becomes `ERROR`, the checkpoint data of this task is set as a `safe point`, and the data of the `safe point` will not be garbage collected within 24 hours. Therefore, the backup task continues from the last checkpoint after resuming the error. If the task fails for more than 24 hours and the last checkpoint data has been garbage collected, an error will be reported when you resume the task. In this case, you can only run the `br log stop` command to stop the task first and then start a new backup task. - -## What should I do if the error message `ErrBackupGCSafepointExceeded` is returned when using the `br log resume` command to resume the suspended task? - -```shell -Error: failed to check gc safePoint, checkpoint ts 433177834291200000: GC safepoint 433193092308795392 exceed TS 433177834291200000: [BR:Backup:ErrBackupGCSafepointExceeded]backup GC safepoint exceeded -``` - -After you pause a log backup task, to prevent the MVCC data from being garbage collected, the pausing task program sets the current checkpoint as the service safepoint automatically. This ensures that the MVCC data generated within 24 hours can remain. If the MVCC data of the backup checkpoint has been generated for more than 24 hours, the data of the checkpoint will be garbage collected, and the backup task is unable to resume. - -To address this problem, delete the current task using `br log stop`, and then create a log backup task using `br log start`. At the same time, you can perform a full backup for subsequent PITR. diff --git a/br/pitr-usage.md b/br/pitr-usage.md deleted file mode 100644 index 2b52fc4d21f7a..0000000000000 --- a/br/pitr-usage.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -title: Use PITR -summary: Learn how to use PITR. ---- - -# Use PITR - -This document describe how to deploy the relevant tool and use point-in-time recovery (PITR). It aims to help you get started with this feature. - -Assume that you have deployed a TiDB cluster in the production environment on AWS, and the business team puts forward the following requirements: - -- Back up the data changes in time. When the database encounters an error, you can quickly recover the application data with a minimum data loss (only a few minutes of data loss is tolerable). -- Perform business audits every month at no specific time. When an audit request is received, you must provide a database to query the data at a certain time point in the past month as requested. - -With PITR, you can satisfy the above requirements. - -## Deploy the TiDB cluster and BR - -To use PITR, you need to deploy a TiDB cluster >= v6.2.0 and update BR to the same version as the TiDB cluster. This document uses v6.2.0 as an example. - -The following table shows the recommended hardware resources for using PITR in a TiDB cluster. - -| Component | CPU | Memory | Local storage | AWS instance | Number of instances | -| --- | --- | --- | --- | --- | --- | -| TiDB | 8 core+ | 16 GB+ | SAS | c5.2xlarge | 2 | -| PD | 8 core+ | 16 GB+ | SSD | c5.2xlarge | 3 | -| TiKV | 8 core+ | 32 GB+ | SSD | m5.2xlarge | 3 | -| BR | 8 core+ | 16 GB+ | SAS | c5.2xlarge | 1 | -| Monitor | 8 core+ | 16 GB+ | SAS | c5.2xlarge | 1 | - -> **Note:** -> -> - When BR runs the backup and restoration tasks, it needs to access PD and TiKV. Make sure that BR and all PD and TiKV servers are connected. -> - BR and PD servers must use the same time zone. - -Deploy or upgrade a TiDB cluster using TiUP: - -- To deploy a new TiDB cluster, refer to [Deploy a TiDB cluster](/production-deployment-using-tiup.md). -- To upgrade an existing TiDB cluster, refer to [Upgrade a TiDB cluster](/upgrade-tidb-using-tiup.md). - -Install or upgrade BR using TiUP: - -- Install: run `tiup install br:v6.2.0`. -- Upgrade: run `tiup update br:v6.2.0`. - -## Enable log backup - -Before you use log backup, ensure that [`log-backup.enable`](/tikv-configuration-file.md#enable-new-in-v620) in the TiKV configuration file is in its default value `true`. For the method to modify configuration, refer to [Modify the configuration](/maintain-tidb-using-tiup.md#modify-the-configuration). - -## Configure backup storage (Amazon S3) - -Before you start a backup task, prepare the backup storage, including the following aspects: - -1. Prepare the S3 bucket and directory that stores the backup data. -2. Configure the permissions to access the S3 bucket. -3. Plan the directory that stores the backup data. - -The detailed steps are as follows: - -1. Create a directory in S3 to store the backup data. The directory in this example is `s3://tidb-pitr-bucket/backup-data`. - - 1. Create a bucket. You can choose an existing S3 to store the backup data. If there is none, refer to [AWS documentation - Creating a bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html) and create an S3 bucket. In this example, the bucket name is `tidb-pitr-bucket`. - 2. Create a directory for your backup data. In the bucket (`tidb-pitr-bucket`), create a directory named `backup-data`. For detailed steps, refer to [AWS documentation - Organizing objects in the Amazon S3 console using folders](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-folders.html). - -2. Configure permissions for BR and TiKV to access the S3 directory. It is recommended to grant permissions using the IAM method, which is the most secure way to access the S3 bucket. For detailed steps, refer to [AWS documentation - Controlling access to a bucket with user policies](https://docs.aws.amazon.com/AmazonS3/latest/userguide/walkthrough1.html). The required permissions are as follows: - - - TiKV and BR in the backup cluster need `s3:ListBucket`, `s3:PutObject`, and `s3:AbortMultipartUpload` permissions of the `s3://tidb-pitr-bucket/backup-data` directory. - - TiKV and BR in the restoration cluster need `s3:ListBucket` and `s3:GetObject` permissions of the `s3://tidb-pitr-bucket/backup-data` directory. - -3. Plan the directory structure that stores the backup data, including the snapshot (full) backup and the log backup. - - - All snapshot backup data is stored in the `s3://tidb-pitr-bucket/backup-data/snapshot-${date}` directory. `${date}` is the start time of the snapshot backup. For example, a snapshot backup starting at 2022/05/12 00:01:30 is stored in `s3://tidb-pitr-bucket/backup-data/snapshot-20220512000130`. - - Log backup data is stored in the `s3://tidb-pitr-bucket/backup-data/log-backup/` directory. - -## Determine the backup policy - -To meet the requirements of minimum data loss, quick recovery, and business audits within a month, you can set the backup policy as follows: - -- Run the log backup to continuously back up the data change in the database. -- Run a snapshot backup at 00:00 every two days. -- Retain the snapshot backup data and log backup data within 30 days and clean up backup data older than 30 days. - -## Run log backup - -After the log backup task is started, the log backup process runs in the TiKV cluster to continuously send the data change in the database to the S3 storage. To start a log backup task, run the following command: - -```shell -tiup br log start --task-name=pitr --pd=172.16.102.95:2379 --storage='s3://tidb-pitr-bucket/backup-data/log-backup' -``` - -When the log backup task is running, you can query the backup status: - -```shell -tiup br log status --task-name=pitr --pd=172.16.102.95:2379 - -● Total 1 Tasks. -> #1 < - name: pitr - status: ● NORMAL - start: 2022-05-13 11:09:40.7 +0800 - end: 2035-01-01 00:00:00 +0800 - storage: s3://tidb-pitr-bucket/backup-data/log-backup - speed(est.): 0.00 ops/s -checkpoint[global]: 2022-05-13 11:31:47.2 +0800; gap=4m53s -``` - -## Run snapshot backup - -You can run snapshot backup tasks on a regular basis using an automatic tool such as crontab. For example, run a snapshot backup at 00:00 every two days. - -The following are two snapshot backup examples: - -- Run a snapshot backup at 2022/05/14 00:00:00 - - ```shell - tiup br backup full --pd=172.16.102.95:2379 --storage='s3://tidb-pitr-bucket/backup-data/snapshot-20220514000000' --backupts='2022/05/14 00:00:00' - ``` - -- Run a snapshot backup at 2022/05/16 00:00:00 - - ```shell - tiup br backup full --pd=172.16.102.95:2379 --storage='s3://tidb-pitr-bucket/backup-data/snapshot-20220516000000' --backupts='2022/05/16 00:00:00' - ``` - -## Run PITR - -Assume that you need to query the data at 2022/05/15 18:00:00. You can use PITR to restore a cluster to that timestamp by restoring a snapshot backup taken at 2022/05/14 and a log backup between the snapshot and 2022/05/15 18:00:00. - -The command is as follows: - -```shell -tiup br restore point --pd=172.16.102.95:2379 ---storage='s3://tidb-pitr-bucket/backup-data/log-backup' ---full-backup-storage='s3://tidb-pitr-bucket/backup-data/snapshot-20220514000000' ---restored-ts '2022-05-15 18:00:00+0800' - -Full Restore <--------------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% -[2022/05/29 18:15:39.132 +08:00] [INFO] [collector.go:69] ["Full Restore success summary"] [total-ranges=12] [ranges-succeed=xxx] [ranges-failed=0] [split-region=xxx.xxxµs] [restore-ranges=xxx] [total-take=xxx.xxxs] [restore-data-size(after-compressed)=xxx.xxx] [Size=xxxx] [BackupTS={TS}] [total-kv=xxx] [total-kv-size=xxx] [average-speed=xxx] -Restore Meta Files <--------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% -Restore KV Files <----------------------------------------------------------------------------------------------------------------------------------------------------> 100.00% -[2022/05/29 18:15:39.325 +08:00] [INFO] [collector.go:69] ["restore log success summary"] [total-take=xxx.xx] [restore-from={TS}] [restore-to={TS}] [total-kv-count=xxx] [total-size=xxx] -``` - -## Clean up outdated data - -You can clean up outdated data every two days using an automatic tool such as crontab. - -For example, you can run the following commands to clean up outdated data: - -- Delete snapshot data earlier than 2022/05/14 00:00:00 - - ```shell - rm s3://tidb-pitr-bucket/backup-data/snapshot-20220514000000 - ``` - -- Delete log backup data earlier than 2022/05/14 00:00:00 - - ```shell - tiup br log truncate --until='2022-05-14 00:00:00 +0800' --storage='s3://tidb-pitr-bucket/backup-data/log-backup' - ``` - -## Learn more - -- [Use PITR via CLI](/br/br-log-command-line.md) -- [PITR Overview](/br/point-in-time-recovery.md) diff --git a/br/point-in-time-recovery.md b/br/point-in-time-recovery.md deleted file mode 100644 index f05886f6533a4..0000000000000 --- a/br/point-in-time-recovery.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: Point-in-Time Recovery -summary: Learn the design, capabilities, and architecture of Point-in-Time Recovery (PITR). ---- - -# Point-in-Time Recovery - -Point-in-Time Recovery (PITR) allows you to restore a snapshot of a TiDB cluster to a new cluster from any given time point in the past. In v6.2.0, TiDB introduces PITR in [Backup & Restore](/br/backup-and-restore-overview.md) (BR). - -You can use PITR to meet the following business requirements: - -- Reduce the Recovery Point Objective (RPO) of disaster recovery to less than 20 minutes. -- Handle the cases of incorrect writes from applications by rolling back data to a time point before the error event. -- Perform history data auditing to meet the requirements of laws and regulations. - -This document introduces the design, capabilities, and architecture of PITR. If you need to learn how to use PITR, refer to [PITR Usage Scenarios](/br/pitr-usage.md). - -## Use PITR in your business - -[BR](/br/backup-and-restore-overview.md) provides the PITR feature. With BR, you can perform all operations of PITR, including data backup (snapshot backup and log backup), one-click restoration to a specified time point, and backup data management. - -The following are the procedures of using PITR in your business: - -![Point-in-Time Recovery](/media/br/pitr-usage.png) - -### Back up data - -To achieve PITR, you need to perform the following backup tasks: - -- Start a log backup task. You can run the `br log start` command to start a log backup task. This task runs in the background of your TiDB cluster and automatically backs up the change log of KV storage to the backup storage. -- Perform [snapshot (full) backup](/br/br-usage-backup.md#back-up-tidb-cluster-snapshots) regularly. You can run the `br backup full` command to back up the cluster snapshot to the backup storage at a specified time point, for example, 00:00 every day. - -### Restore data with one click - -To restore data using PITR, you need to run the `br restore point` command to execute the restoration program. The program reads data from snapshot backup and log backup and restores the data of the specified time point to a new cluster. - -When you run the `br restore point` command, you need to specify the latest snapshot backup data before the time point you want to restore and specify the log backup data. BR first restores the snapshot data, and then reads the log backup data between the snapshot time point and the specified restoration time point. - -### Manage backup data - -To manage backup data for PITR, you need to design a backup directory structure to store your backup data and regularly delete outdated or no longer needed backup data. - -- Organize the backup data in the following structure: - - - Store the snapshot backup and log backup in the same directory for unified management. For example, `backup-${cluster-id}`. - - Store each snapshot backup in a directory whose name includes the backup date. For example, `backup-${cluster-id}/snapshot-20220512000130`. - - Store the log backup in a fixed directory. For example, `backup-${cluster-id}/log-backup`. - -- Delete the outdated or no longer needed backup data: - - - When you delete the snapshot backup, you can delete the directory of the snapshot backup. - - To delete the log backup before a specified time point, run the `br log truncate` command. - -## Capabilities - -- PITR log backup has a 5% impact on the cluster. -- When you back up logs and snapshots at the same time, it has a less than 20% impact on the cluster. -- On each TiKV node, PITR can restore snapshot data at 280 GB/h and log data at 30 GB/h. -- With PITR, the RPO of disaster recovery is less than 20 minutes. Depending on the data size to be restored, the Recovery Time Objective (RTO) varies from several minutes to several hours. -- BR deletes outdated log backup data at a speed of 600 GB/h. - -> **Note:** -> -> - The preceding functional specification is based on test results from the following two testing scenarios. The actual data may be different. -> - Snapshot data restoration speed = Snapshot data size / (duration * the number of TiKV nodes) -> - Log data restoration speed = Restored log data size / (duration * the number of TiKV nodes) - -Testing scenario 1 (on [TiDB Cloud](https://tidbcloud.com)): - -- The number of TiKV nodes (8 core, 16 GB memory): 21 -- The number of Regions: 183,000 -- New log created in the cluster: 10 GB/h -- Write (insert/update/delete) QPS: 10,000 - -Testing scenario 2 (on-premises): - -- The number of TiKV nodes (8 core, 64 GB memory): 6 -- The number of Regions: 50,000 -- New log created in the cluster: 10 GB/h -- Write (insert/update/delete) QPS: 10,000 - -## Limitations - -- A single cluster can only run one log backup task. -- You can only restore data to an empty cluster. To avoid impact on the services and data of the cluster, do not perform PITR in-place or on a non-empty cluster. -- You can store backup data to a shared filesystem (such as NFS), Amazon S3, GCS, or Azure Blob Storage. -- You can only perform cluster-level PITR. Database-level and table-level PITR are not supported. -- You cannot restore data in the user tables or the privilege tables. -- If the backup cluster has a TiFlash replica, after you perform PITR, the restoration cluster does not contain the data in the TiFlash replica. Instead, it takes a certain period of time for the data to be replicated from TiKV nodes. For this reason, TiFlash is not immediately available after PITR completes data restore. -- If the upstream database uses TiDB Lightning's physical import mode to import data, the data cannot be backed up in log backup. It is recommended to perform a full backup after the data import. For details, refer to [The upstream database uses TiDB Lightning Physical Mode to import data](/br/pitr-known-issues.md#the-upstream-database-imports-data-using-tidb-lightning-in-the-physical-import-mode-which-makes-it-impossible-to-use-the-log-backup-feature). -- Do not restore the log backup data of a certain time period repeatedly. If you restore the log backup data of a range `[t1=10, t2=20)` repeatedly, the restored data might be inconsistent. -- For other known limitations, refer to [PITR Known Issues](/br/pitr-known-issues.md). - -### Version compatibility check - -In v6.3.0, backup files generated after PITR are compressed in a new method. Small files are merged before being stored (to solve problems caused by too many small files). However, TiDB clusters of the earlier version are not compatible with backup data generated in v6.3 clusters. See the following table: - -| Restore version (horizontal) \ Backup version (vertical) | Use PITR v6.2.0 to restore TiDB v6.2.0 | Use PITR v6.3.0 to restore TiDB v6.3.0 | -| ---- | ---- | ---- | -|Use PITR v6.2.0 to back up TiDB v6.2.0 | Compatible | Compatible | -|Use PITR v6.3.0 to back up TiDB v6.3.0 | Incompatible |Compatible | - -## Architecture - -PITR is used for snapshot backup and restoration *and* log backup and restoration. For snapshot backup and restoration, refer to [BR Design Principles](/br/backup-and-restore-design.md). This section describes the implementation of log backup and restoration. - -Log backup and restoration are implemented as follows: - -![BR log backup and restore architecture](/media/br/br-log-arch.png) - -When a log backup task is performed: - -1. BR receives the `br log start` command. -2. BR registers a log backup task with PD and saves the log backup metadata in PD. -3. The TiKV backup executor module listens on the creation of a log backup task in PD. When it detects the creation of a log backup task, it starts to perform log backup. -4. The TiKV backup executor module reads the KV data changes and writes into the local SST files. -5. The TiKV backup executor module periodically writes the SST files to the backup storage and updates the metadata in the backup storage. - -When a log restoration task is performed: - -1. BR receives the `br log restore` command. -2. BR reads the log backup data from the backup storage, and calculates and filters the log backup data that needs to be restored. -3. BR requests PD to create a region for restoring log backup data (split regions) and schedule the region to the corresponding TiKV node (scatter regions). -4. After PD finishes scheduling, BR sends the restoration request to each TiKV restore executor module. -5. The TiKV restore executor module downloads the log backup data from the backup storage and writes the data to the corresponding region. - -## Learn more - -- [Perform Log Backup and Restoration Using BR](/br/br-log-command-line.md) -- [Use PITR](/br/pitr-usage.md) -- [PITR Monitoring and Alert](/br/pitr-monitoring-and-alert.md) diff --git a/br/rawkv-backup-and-restore.md b/br/rawkv-backup-and-restore.md index 1bd7446b2c961..03340b3f28e0c 100644 --- a/br/rawkv-backup-and-restore.md +++ b/br/rawkv-backup-and-restore.md @@ -43,7 +43,7 @@ In this command, the values of `--start` and `--end` are decoded using the forma > - Where each peer is scattered to during restoration is random. You have no idea in advance which node will read which file. > > - These can be avoided using shared storage, for example, mounting an NFS on the local path, or using S3. With network storage, every node can automatically read every SST file. In this case, the preceding caveats no longer apply. -> - Also, note that you can only run one restoration operation for a single cluster at the same time. Otherwise, unexpected behaviors might occur. For details, see [FAQs](/br/backup-and-restore-faq.md#can-i-use-multiple-br-processes-at-the-same-time-to-restore-the-data-of-a-single-cluster). +> - Also, note that you can only run one restoration operation for a single cluster at the same time. Otherwise, unexpected behaviors might occur. For details, see [FAQs](/faq/backup-and-restore-faq.md#can-i-start-multiple-restore-tasks-at-the-same-time-to-restore-the-data-of-a-single-cluster). ## Restore RawKV diff --git a/br/use-br-command-line-tool.md b/br/use-br-command-line-tool.md index a185e6ec6dc59..793765ddaf463 100644 --- a/br/use-br-command-line-tool.md +++ b/br/use-br-command-line-tool.md @@ -1,86 +1,81 @@ --- -title: Use BR Command-line for Backup and Restoration -summary: Learn how to use the BR command line to back up and restore cluster data. +title: br Command-line Manual +summary: Learn about the description, options, and usage of the br command-line tool. --- -# Use BR Command-line for Backup and Restoration +# br Command-line Manual -This document describes how to back up and restore TiDB cluster data using the BR command line. +This document describes the definition, components, and common options of `br` commands, and how to perform snapshot backup and restore, and log backup and point-in-time recovery (PITR) using `br` commands. -Make sure you have read [BR Tool Overview](/br/backup-and-restore-overview.md), especially [Usage restrictions](/br/backup-and-restore-overview.md#usage-restrictions) and [Some tips](/br/backup-and-restore-overview.md#some-tips). +## `br` command-line description -## BR command-line description +A `br` command consists of sub-commands, options, and parameters. A sub-command is the characters without `-` or `--`. An option is the characters that start with `-` or `--`. A parameter is the characters that immediately follow behind and are passed to the sub-command or the option. -A `br` command consists of sub-commands, options, and parameters. - -* Sub-command: the characters without `-` or `--`. -* Option: the characters that start with `-` or `--`. -* Parameter: the characters that immediately follow behind and are passed to the sub-command or the option. - -This is a complete `br` command: - -{{< copyable "shell-regular" >}} +The following is a complete `br` command: ```shell -`br backup full --pd "${PDIP}:2379" -s "s3://backup-data/2022-01-30/"` +br backup full --pd "${PD_IP}:2379" \ +--storage "s3://backup-data/snapshot-202209081330/" ``` -Explanations for the above command are as follows: +Explanations for the preceding command are as follows: * `backup`: the sub-command of `br`. -* `full`: the sub-command of `backup`. -* `-s` (or `--storage`): the option that specifies the path where the backup files are stored. -* `"s3://backup-data/2022-01-30/"`: the parameter of `-s`, indicating that backup data is stored to the `2022-01-30/` directory in the `backup-data` bucket of Amazon S3. -* `--pd`: the option that specifies the Placement Driver (PD) service address. -* `"${PDIP}:2379"`: the parameter of `--pd`. +* `full`: the sub-command of `br backup`. +* `-s` (or `--storage`): the option that specifies the path where the backup files are stored. `"s3://backup-data/snapshot-202209081330/"` is the parameter of `-s`. +* `--pd`: the option that specifies the PD service address. `"${PD_IP}:2379"` is the parameter of `--pd`. -### Sub-commands +### Commands and sub-commands -A `br` command consists of multiple layers of sub-commands. Currently, BR has the following sub-commands: +A `br` command consists of multiple layers of sub-commands. Currently, br command-line tool has the following sub-commands: * `br backup`: used to back up the data of the TiDB cluster. -* `br restore`: used to restore the data of the TiDB cluster. +* `br log`: used to start and manage log backup tasks. +* `br restore`: used to restore backup data of the TiDB cluster. -Each of the above sub-commands might still include the following sub-commands to specify the scope of an operation: +`br backup` and `br restore` include the following sub-commands: * `full`: used to back up or restore all the cluster data. -* `db`: used to back up or restore the specified database of the cluster. +* `db`: used to back up or restore a specified database of the cluster. * `table`: used to back up or restore a single table in the specified database of the cluster. ### Common options -* `--pd`: used for connection, specifying the PD server address. For example, `"${PDIP}:2379"`. -* `-h` (or `--help`): used to get help on all sub-commands. For example, `br backup --help`. -* `-V` (or `--version`): used to check the version of BR. +* `--pd`: specifies the PD service address. For example, `"${PD_IP}:2379"`. +* `-s` (or `--storage`): specifies the path where the backup files are stored. Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, and NFS are supported to store backup data. For more details, refer to [URL format of backup storages](/br/backup-and-restore-storages.md#url-format). * `--ca`: specifies the path to the trusted CA certificate in the PEM format. * `--cert`: specifies the path to the SSL certificate in the PEM format. * `--key`: specifies the path to the SSL certificate key in the PEM format. -* `--status-addr`: specifies the listening address through which BR provides statistics to Prometheus. - -## Examples of using BR command-line to back up cluster data - -To back up cluster data, run the `br backup` command. You can add the `full` or `table` sub-command to specify the scope of your backup operation: the whole cluster or a single table. - -- [Back up TiDB cluster snapshots](/br/br-usage-backup.md#back-up-tidb-cluster-snapshots) -- [Back up a database](/br/br-usage-backup.md#back-up-a-database) -- [Back up a table](/br/br-usage-backup.md#back-up-a-table) -- [Back up multiple tables with table filter](/br/br-usage-backup.md#back-up-multiple-tables-with-table-filter) -- [Back Up data on Amazon S3 using BR](/br/backup-storage-S3.md) -- [Back up data on Google Cloud Storage using BR](/br/backup-storage-gcs.md) -- [Back up data on Azure Blob Storage using BR](/br/backup-storage-azblob.md) -- [Back up incremental data](/br/br-usage-backup.md#back-up-incremental-data) -- [Encrypt data during backup](/br/br-usage-backup.md#encrypt-backup-data-at-the-backup-end) - -## Examples of using BR command-line to restore cluster data - -To restore cluster data, run the `br restore` command. You can add the `full`, `db` or `table` sub-command to specify the scope of your restoration: the whole cluster, a database or a single table. - -- [Restore TiDB cluster snapshots](/br/br-usage-restore.md#restore-tidb-cluster-snapshots) -- [Restore a database](/br/br-usage-restore.md#restore-a-database) -- [Restore a table](/br/br-usage-restore.md#restore-a-table) -- [Restore multiple tables with table filter](/br/br-usage-restore.md#restore-multiple-tables-with-table-filter) -- [Restore data on Amazon S3 using BR](/br/backup-storage-S3.md) -- [Restore data on Google Cloud Storage using BR](/br/backup-storage-gcs.md) -- [Restore data on Azure Blob Storage using BR](/br/backup-storage-azblob.md) -- [Restore incremental data](/br/br-usage-restore.md#restore-incremental-data) -- [Restore encrypted backup data](/br/br-usage-restore.md#restore-encrypted-backup-data) +* `--status-addr`: specifies the listening address through which `br` provides statistics to Prometheus. + +## Commands of full backup + +To back up cluster data, run the `br backup` command. You can add the `full` or `table` sub-command to specify the scope of your backup operation: the whole cluster (`full`) or a single table (`table`). + +- [Back up TiDB cluster snapshots](/br/br-snapshot-manual.md#back-up-cluster-snapshots) +- [Back up a database](/br/br-snapshot-manual.md#back-up-a-database) +- [Back up a table](/br/br-snapshot-manual.md#back-up-a-table) +- [Back up multiple tables with table filter](/br/br-snapshot-manual.md#back-up-multiple-tables-with-table-filter) +- [Encrypt snapshots](/br/backup-and-restore-storages.md#server-side-encryption) + +## Commands of log backup + +To start log backup and manage log backup tasks, run the `br log` command. + +- [Start a log backup task](/br/br-pitr-manual.md#start-a-backup-task) +- [Query the backup status](/br/br-pitr-manual.md#query-the-backup-status) +- [Pause and resume a log backup task](/br/br-pitr-manual.md#pause-and-resume-a-backup-task) +- [Stop and restart a log backup task](/br/br-pitr-manual.md#stop-and-restart-a-backup-task) +- [Clean up the backup data](/br/br-pitr-manual.md#clean-up-backup-data) +- [View the backup metadata](/br/br-pitr-manual.md#view-the-backup-metadata) + +## Commands of restoring backup data + +To restore cluster data, run the `br restore` command. You can add the `full`, `db`, or `table` sub-command to specify the scope of your restore: the whole cluster (`full`), a single database (`db`), or a single table (`table`). + +- [Point-in-time recovery](/br/br-pitr-manual.md#restore-to-a-specified-point-in-time-pitr) +- [Restore cluster snapshots](/br/br-snapshot-manual.md#restore-cluster-snapshots) +- [Restore a database](/br/br-snapshot-manual.md#restore-a-database) +- [Restore a table](/br/br-snapshot-manual.md#restore-a-table) +- [Restore multiple tables with table filter](/br/br-snapshot-manual.md#restore-multiple-tables-with-table-filter) +- [Restore encrypted snapshots](/br/br-snapshot-manual.md#restore-encrypted-snapshots) diff --git a/ecosystem-tool-user-case.md b/ecosystem-tool-user-case.md index a29d911894fce..00c9cd60cc26e 100644 --- a/ecosystem-tool-user-case.md +++ b/ecosystem-tool-user-case.md @@ -34,7 +34,7 @@ If the full data volume is large (at the TB level), you can first use [Dumpling] If you need to back up a TiDB cluster or restore backed up data to the cluster, use [BR](/br/backup-and-restore-overview.md) (Backup & Restore). -In addition, BR can also be used to perform [incremental backup](/br/br-usage-backup.md#back-up-incremental-data) and [incremental restore](/br/br-usage-restore.md#restore-incremental-data) of TiDB cluster data. +In addition, BR can also be used to perform [incremental backup](/br/br-incremental-guide.md#back-up-incremental-data) and [incremental restore](/br/br-incremental-guide.md#restore-incremental-data) of TiDB cluster data. ## Migrate data to TiDB diff --git a/ecosystem-tool-user-guide.md b/ecosystem-tool-user-guide.md index d460234e16b4f..279959f546d82 100644 --- a/ecosystem-tool-user-guide.md +++ b/ecosystem-tool-user-guide.md @@ -105,7 +105,11 @@ The following are the basics of TiDB Lightning: The following are the basics of BR: -- [Input and output data source](/br/backup-and-restore-design.md#types-of-backup-files): SST + `backupmeta` file +- Input and output data source + + - Snapshot backup and restore: [SST + `backupmeta` file](/br/br-snapshot-architecture.md#backup-files) + - Log backup and PITR: [Log backup files](/br/br-log-architecture.md#log-backup-files) + - Supported TiDB versions: v4.0 and later versions - Kubernetes support: Yes. See [Back up Data to S3-Compatible Storage Using BR](https://docs.pingcap.com/tidb-in-kubernetes/stable/backup-to-aws-s3-using-br) and [Restore Data from S3-Compatible Storage Using BR](https://docs.pingcap.com/tidb-in-kubernetes/stable/restore-from-aws-s3-using-br) for details. diff --git a/faq/backup-and-restore-faq.md b/faq/backup-and-restore-faq.md new file mode 100644 index 0000000000000..2c8624a8268d0 --- /dev/null +++ b/faq/backup-and-restore-faq.md @@ -0,0 +1,337 @@ +--- +title: Backup & Restore FAQs +summary: Learn about Frequently Asked Questions (FAQs) and the solutions of backup and restore. +aliases: ['/docs/dev/br/backup-and-restore-faq/','/tidb/dev/pitr-troubleshoot/','/tidb/dev/pitr-known-issues/'] +--- + +# Backup & Restore FAQs + +This document lists the frequently asked questions (FAQs) and the solutions of TiDB Backup & Restore (BR). + +## Performance issues of backup and restore + +## In TiDB v5.4.0 and later versions, when backup tasks are performed on the cluster under a heavy workload, why does the speed of backup tasks become slow? + +Starting from TiDB v5.4.0, BR introduces the auto-tune feature for backup tasks. For clusters in v5.4.0 or later versions, this feature is enabled by default. When the cluster workload is heavy, the feature limits the resources used by backup tasks to reduce the impact on the online cluster. For more information, refer to [Backup Auto-Tune](/br/br-auto-tune.md). + +TiKV supports [dynamically configuring](/tikv-control.md#modify-the-tikv-configuration-dynamically) the auto-tune feature. You can enable or disable the feature by the following methods without restarting your cluster: + +- Disable auto-tune: Set the TiKV configuration item [`backup.enable-auto-tune`](/tikv-configuration-file.md#enable-auto-tune-new-in-v540) to `false`. +- Enable auto-tune: Set `backup.enable-auto-tune` to `true`. For clusters upgraded from v5.3.x to v5.4.0 or later versions, the auto-tune feature is disabled by default. You need to manually enable it. + +To use `tikv-ctl` to enable or disable auto-tune, refer to [Use auto-tune](/br/br-auto-tune.md#use-auto-tune). + +In addition, auto-tune reduces the default number of threads used by backup tasks. For details, see `backup.num-threads`](/tikv-configuration-file.md#num-threads-1). Therefore, on the Grafana Dashboard, the speed, CPU usage, and I/O resource utilization used by backup tasks are lower than those of versions earlier than v5.4.0. Before v5.4.0, the default value of `backup.num-threads` was `CPU * 0.75`, that is, the number of threads used by backup tasks makes up 75% of the logical CPU cores. The maximum value of it was `32`. Starting from v5.4.0, the default value of this configuration item is `CPU * 0.5`, and its maximum value is `8`. + +When you perform backup tasks on an offline cluster, to speed up the backup, you can modify the value of `backup.num-threads` to a larger number using `tikv-ctl`. + +## PITR issues + +### Why `br` encounters the OOM problem after I run the `br log truncate` command? + +Issue: [#36648](https://github.com/pingcap/tidb/issues/36648) + +Consider the following possible causes: + +- The range of logs to be deleted is too large. + + To resolve this issue, reduce the range of logs to be deleted first and delete the target logs in several batches instead of deleting them once. + +- The memory allocation of the node where the `br` process is located is too low. + + It is recommended to scale up the node memory configuration to at least 16 GB to ensure that PITR has sufficient memory for recovery. + +### When the upstream database imports data using TiDB Lightning in the physical import mode, the log backup feature becomes unavailable. Why? + +Currently, the log backup feature is not fully adapted to TiDB Lightning. Therefore, data imported in the physical mode of TiDB Lightning cannot be backed up into log data + +In upstream clusters where you create log backup tasks, avoid using the TiDB Lightning physical mode to import data. Instead, you can use TiDB Lightning logical mode. If you do need to use the physical mode, perform a snapshot backup after the import is complete, so that PITR can be restored to the time point after the snapshot backup. + +### Why is the acceleration of adding indexes feature incompatible with PITR? + +Issue: [#38045](https://github.com/pingcap/tidb/issues/38045) + +Currently, the [acceleration of adding indexes](/system-variables.md#tidb_ddl_enable_fast_reorg-new-in-v630) feature is not compatible with PITR. When using index acceleration, you need to ensure that there are no PITR log backup tasks running in the background. Otherwise, unexpected behaviors might occur, including: + +- If you start a log backup task first, and then add an index. The adding index process is not accelerated even if index acceleration is enabled. But the index is added in a slow way. +- If you start an index acceleration task first, and then start a log backup task. The log backup task returns an error. But the index acceleration is not affected. +- If you start a log backup task and an index acceleration task at the same time, the two tasks might not be aware of each other. This might result in PITR failing to back up the newly added index. + +### The cluster has recovered from the network partition failure, but the checkpoint of the log backup task progress still does not resume. Why? + +Issue: [#13126](https://github.com/tikv/tikv/issues/13126) + +After a network partition failure in the cluster, the backup task cannot continue backing up logs. After a certain retry time, the task will be set to `ERROR` state. At this point, the backup task has stopped. + +To resolve this issue, you need to manually execute the `br log resume` command to resume the log backup task. + +### What should I do if the error `execute over region id` is returned when I perform PITR? + +Issue: [#37207](https://github.com/pingcap/tidb/issues/37207) + +This issue usually occurs when you enable log backup during a full data import and afterward perform a PITR to restore data at a time point during the data import. + +Specifically, there is a probability that this issue occurs if there are a large number of hotspot writes for a long time (such as 24 hours) and if the OPS of each TiKV node is larger than 50k/s (you can view the metrics in Grafana: **TiKV-Details** -> **Backup Log** -> **Handle Event Rate**). + +It is recommended that you perform a snapshot backup after the data import and perform PITR based on this snapshot backup. + +## After restoring a downstream cluster using the `br restore point` command, data cannot be accessed from TiFlash. What should I do? + +Currently, PITR does not support writing data directly to TiFlash during the restore phase. Instead, br command-line tool executes the `ALTER TABLE table_name SET TIFLASH REPLICA ***` DDL to replicate the data. Therefore, TiFlash replicas are not available immediately after PITR completes data restore. Instead, you need to wait for a certain period of time for the data to be replicated from TiKV nodes. To check the replication progress, check the `progress` information in the `INFORMATION_SCHEMA.tiflash_replica` table. + +### What should I do if the `status` of a log backup task becomes `ERROR`? + +During a log backup task, the task status becomes `ERROR` if it fails and cannot be recovered after retrying. The following is an example: + +```shell +br log status --pd x.x.x.x:2379 + +● Total 1 Tasks. +> #1 < + name: task1 + status: ○ ERROR + start: 2022-07-25 13:49:02.868 +0000 + end: 2090-11-18 14:07:45.624 +0000 + storage: s3://tmp/br-log-backup0ef49055-5198-4be3-beab-d382a2189efb/Log + speed(est.): 0.00 ops/s + checkpoint[global]: 2022-07-25 14:46:50.118 +0000; gap=11h31m29s + error[store=1]: KV:LogBackup:RaftReq +error-happen-at[store=1]: 2022-07-25 14:54:44.467 +0000; gap=11h23m35s + error-message[store=1]: retry time exceeds: and error failed to get initial snapshot: failed to get the snapshot (region_id = 94812): Error during requesting raftstore: message: "read index not ready, reason can not read index due to merge, region 94812" read_index_not_ready { reason: "can not read index due to merge" region_id: 94812 }: failed to get initial snapshot: failed to get the snapshot (region_id = 94812): Error during requesting raftstore: message: "read index not ready, reason can not read index due to merge, region 94812" read_index_not_ready { reason: "can not read index due to merge" region_id: 94812 }: failed to get initial snapshot: failed to get the snapshot (region_id = 94812): Error during requesting raftstore: message: "read index not ready, reason can not read index due to merge, region 94812" read_index_not_ready { reason: "can not read index due to merge" region_id: 94812 } +``` + +To address this problem, check the error message for the cause and perform as instructed. After the problem is addressed, run the following command to resume the task: + +```shell +br log resume --task-name=task1 --pd x.x.x.x:2379 +``` + +After the backup task is resumed, you can check the status using `br log status`. The backup task continues when the task status becomes `NORMAL`. + +```shell +● Total 1 Tasks. +> #1 < + name: task1 + status: ● NORMAL + start: 2022-07-25 13:49:02.868 +0000 + end: 2090-11-18 14:07:45.624 +0000 + storage: s3://tmp/br-log-backup0ef49055-5198-4be3-beab-d382a2189efb/Log + speed(est.): 15509.75 ops/s +checkpoint[global]: 2022-07-25 14:46:50.118 +0000; gap=6m28s +``` + +> **Note:** +> +> This feature backs up multiple versions of data. When a long backup task fails and the status becomes `ERROR`, the checkpoint data of this task is set as a `safe point`, and the data of the `safe point` will not be garbage collected within 24 hours. Therefore, the backup task continues from the last checkpoint after resuming the error. If the task fails for more than 24 hours and the last checkpoint data has been garbage collected, an error will be reported when you resume the task. In this case, you can only run the `br log stop` command to stop the task first and then start a new backup task. + +### What should I do if the error message `ErrBackupGCSafepointExceeded` is returned when using the `br log resume` command to resume a suspended task? + +```shell +Error: failed to check gc safePoint, checkpoint ts 433177834291200000: GC safepoint 433193092308795392 exceed TS 433177834291200000: [BR:Backup:ErrBackupGCSafepointExceeded]backup GC safepoint exceeded +``` + +After you pause a log backup task, to prevent the MVCC data from being garbage collected, the pausing task program sets the current checkpoint as the service safepoint automatically. This ensures that the MVCC data generated within 24 hours can remain. If the MVCC data of the backup checkpoint has been generated for more than 24 hours, the data of the checkpoint will be garbage collected, and the backup task is unable to resume. + +To address this problem, delete the current task using `br log stop`, and then create a log backup task using `br log start`. At the same time, you can perform a full backup for subsequent PITR. + +## Feature compatibility issues + +### Why does data restored using br command-line tool cannot be replicated to the upstream cluster of TiCDC or Drainer? + ++ **The data restored using BR cannot be replicated to the downstream**. This is because BR directly imports SST files but the downstream cluster currently cannot obtain these files from the upstream. + ++ Before v4.0.3, DDL jobs generated during the restore might cause unexpected DDL executions in TiCDC/Drainer. Therefore, if you need to perform restore on the upstream cluster of TiCDC/Drainer, add all tables restored using br command-line tool to the TiCDC/Drainer block list. + +You can use [`filter.rules`](https://github.com/pingcap/tiflow/blob/7c3c2336f98153326912f3cf6ea2fbb7bcc4a20c/cmd/changefeed.toml#L16) to configure the block list for TiCDC and use [`syncer.ignore-table`](/tidb-binlog/tidb-binlog-configuration-file.md#ignore-table) to configure the block list for Drainer. + +### Why is `new_collations_enabled_on_first_bootstrap` mismatch reported during restore? + +Since TiDB v6.0.0, the default value of [`new_collations_enabled_on_first_bootstrap`](/tidb-configuration-file.md#new_collations_enabled_on_first_bootstrap) has changed from `false` to `true`. BR backs up the `new_collations_enabled_on_first_bootstrap` configuration of the upstream cluster and then checks whether the value of this configuration is consistent between the upstream and downstream clusters. If the value is consistent, BR safely restores the data backed up in the upstream cluster to the downstream cluster. If the value is inconsistent, BR does not perform the data restore and reports an error. + +Suppose that you have backed up the data in a TiDB cluster of an earlier version of v6.0.0, and you want to restore this data to a TiDB cluster of v6.0.0 or later versions. In this situation, you need to manually check whether the value of `new_collations_enabled_on_first_bootstrap` is consistent between the upstream and downstream clusters: + +- If the value is consistent, you can add `--check-requirements=false` to the restore command to skip this configuration check. +- If the value is inconsistent, and you forcibly perform the restore, BR reports a data validation error. + +### Why does an error occur when I restore placement rules to a cluster? + +Before v6.0.0, BR does not support [placement rules](/placement-rules-in-sql.md). Starting from v6.0.0, BR supports placement rules and introduces a command-line option `--with-tidb-placement-mode=strict/ignore` to control the backup and restore mode of placement rules. With the default value `strict`, BR imports and validates placement rules, but ignores all placement rules when the value is `ignore`. + +## Data restore issues + +### What should I do to handle the `Io(Os...)` error? + +Almost all of these problems are system call errors that occur when TiKV writes data to the disk, for example, `Io(Os {code: 13, kind: PermissionDenied...})` or `Io(Os {code: 2, kind: NotFound...})`. + +To address such problems, first check the mounting method and the file system of the backup directory, and try to back up data to another folder or another hard disk. + +For example, you might encounter the `Code: 22(invalid argument)` error when backing up data to the network disk built by `samba`. + +### What should I do to handle the `rpc error: code = Unavailable desc =...` error occurred in restore? + +This error might occur when the capacity of the cluster to restore is insufficient. You can further confirm the cause by checking the monitoring metrics of this cluster or the TiKV log. + +To handle this issue, you can try to scale out the cluster resources, reduce the concurrency during restore, and enable the `RATE_LIMIT` option. + +### What should I do if the restore fails with the error message `the entry too large, the max entry size is 6291456, the size of data is 7690800`? + +You can try to reduce the number of tables to be created in a batch by setting `--ddl-batch-size` to `128` or a smaller value. + +When using BR to restore the backup data with the value of [`--ddl-batch-size`](/br/br-batch-create-table.md#how to use) greater than `1`, TiDB writes a DDL job of table creation to the DDL jobs queue that is maintained by TiKV. At this time, the total size of all tables schema sent by TiDB at one time should not exceed 6 MB, because the maximum value of job messages is `6 MB` by default (it is **not recommended** to modify this value. For details, see [`txn-entry-size-limit`](/tidb-configuration-file.md#txn-entry-size-limit-new-in-v50) and [`raft-entry-max-size`](/tikv-configuration-file.md#raft-entry-max-size)). Therefore, if you set `--ddl-batch-size` to an excessively large value, the schema size of the tables sent by TiDB in a batch at one time exceeds the specified value, which causes BR to report the `entry too large, the max entry size is 6291456, the size of data is 7690800` error. + +### Where are the backed up files stored when I use `local` storage? + +> **Note:** +> +> If no Network File System (NFS) is mounted to a BR or TiKV node, or if you use external storage that supports Amazon S3, GCS, or Azure Blob Storage protocols, the data backed up by BR is generated at each TiKV node.**Note that this is not the recommended way to deploy BR**, because the backup data are scattered in the local file system of each node. Collecting the backup data might result in data redundancy and operation and maintenance problems. Meanwhile, if you restore data directly before collecting the backup data, you will encounter the `SST file not found` error. + +When you use local storage, `backupmeta` is generated on the node where BR is running, and backup files are generated on the Leader nodes of each Region. + +### What should I do if the error message `could not read local://...:download sst failed` is returned during data restore? + +When you restore data, each node must have access to **all** backup files (SST files). By default, if `local` storage is used, you cannot restore data because the backup files are scattered among different nodes. Therefore, you have to copy the backup file of each TiKV node to the other TiKV nodes. **It is recommended that you store backup data to Amazon S3, Google Cloud Storage (GCS), Azure Blob Storage, or NFS**. + +### What should I do to handle the `Permission denied` or `No such file or directory` error, even if I have tried to run `br` using root in vain? + +You need to confirm whether TiKV has access to the backup directory. To back up data, confirm whether TiKV has the write permission. To restore data, confirm whether it has the read permission. + +During the backup operation, if the storage medium is the local disk or a network file system (NFS), make sure that the user to start `br` and the user to start TiKV are consistent (if `br` and TiKV are on different machines, the users' UIDs must be consistent). Otherwise, the `Permission denied` issue might occur. + +Running `br` as the `root` user might fail due to the disk permission, because the backup files (SST files) are saved by TiKV. + +> **Note:** +> +> You might encounter the same problem during data restore. When the SST files are read for the first time, the read permission is verified. The execution duration of DDL suggests that there might be a long interval between checking the permission and running `br`. You might receive the error message `Permission denied` after waiting for a long time. + +Therefore, it is recommended to check the permission before data restore according to the following steps: + +1. Run the Linux command for process query: + + {{< copyable "shell-regular" >}} + + ```bash + ps aux | grep tikv-server + ``` + + The output is as follows: + + ```shell + tidb_ouo 9235 10.9 3.8 2019248 622776 ? Ssl 08:28 1:12 bin/tikv-server --addr 0.0.0.0:20162 --advertise-addr 172.16.6.118:20162 --status-addr 0.0.0.0:20188 --advertise-status-addr 172.16.6.118:20188 --pd 172.16.6.118:2379 --data-dir /home/user1/tidb-data/tikv-20162 --config conf/tikv.toml --log-file /home/user1/tidb-deploy/tikv-20162/log/tikv.log + tidb_ouo 9236 9.8 3.8 2048940 631136 ? Ssl 08:28 1:05 bin/tikv-server --addr 0.0.0.0:20161 --advertise-addr 172.16.6.118:20161 --status-addr 0.0.0.0:20189 --advertise-status-addr 172.16.6.118:20189 --pd 172.16.6.118:2379 --data-dir /home/user1/tidb-data/tikv-20161 --config conf/tikv.toml --log-file /home/user1/tidb-deploy/tikv-20161/log/tikv.log + ``` + + Or you can run the following command: + + {{< copyable "shell-regular" >}} + + ```bash + ps aux | grep tikv-server | awk '{print $1}' + ``` + + The output is as follows: + + ```shell + tidb_ouo + tidb_ouo + ``` + +2. Query the startup information of the cluster using the `tiup` command: + + {{< copyable "shell-regular" >}} + + ```bash + tiup cluster list + ``` + + The output is as follows: + + ```shell + [root@Copy-of-VM-EE-CentOS76-v1 br]# tiup cluster list + Starting component `cluster`: /root/.tiup/components/cluster/v1.5.2/tiup-cluster list + Name User Version Path PrivateKey + ---- ---- ------- ---- ---------- + tidb_cluster tidb_ouo v5.0.2 /root/.tiup/storage/cluster/clusters/tidb_cluster /root/.tiup/storage/cluster/clusters/tidb_cluster/ssh/id_rsa + ``` + +3. Check the permission for the backup directory. For example, `backup` is for backup data storage: + + {{< copyable "shell-regular" >}} + + ```bash + ls -al backup + ``` + + The output is as follows: + + ```shell + [root@Copy-of-VM-EE-CentOS76-v1 user1]# ls -al backup + total 0 + drwxr-xr-x 2 root root 6 Jun 28 17:48 . + drwxr-xr-x 11 root root 310 Jul 4 10:35 .. + ``` + + From the output of step 2, you can find that the `tikv-server` instance is started by the user `tidb_ouo`. But the user `tidb_ouo` does not have the write permission for `backup`. Therefore, the backup fails. + +### Why are tables in the `mysql` schema not restored? + +Starting from BR v5.1.0, when you perform a full backup, BR backs up the **tables in the `mysql` schema**. Before BR v6.2.0, under default configuration, BR only restores user data, but does not restore tables in the **`mysql` schema**. + +To restore a table created by the user in the `mysql` schema (not system tables), you can explicitly include the table using [table filters](/table-filter.md#syntax). The following example shows how to restore the `mysql.usertable` table when BR performs a normal restore. + +{{< copyable "shell-regular" >}} + +```shell +br restore full -f '*.*' -f '!mysql.*' -f 'mysql.usertable' -s $external_storage_url --with-sys-table +``` + +In the preceding command, + +- `-f '*.*'` is used to override the default rules +- `-f '!mysql.*'` instructs BR not to restore tables in `mysql` unless otherwise stated. +- `-f 'mysql.usertable'` indicates that `mysql.usertable` should be restored. + +If you only need to restore `mysql.usertable`, run the following command: + +{{< copyable "shell-regular" >}} + +```shell +br restore full -f 'mysql.usertable' -s $external_storage_url --with-sys-table +``` + +Note that even if you configures [table filter](/table-filter.md#syntax), **BR does not restore the following system tables**: + +- Statistics tables (`mysql.stat_*`) +- System variable tables (`mysql.tidb`, `mysql.global_variables`) +- [Other system tables](https://github.com/pingcap/tidb/blob/master/br/pkg/restore/systable_restore.go#L31) + +## Other things you may want to know about backup and restore + +### What is the size of the backup data? Are there replicas of the backup? + +During data backup, backup files are generated on the Leader nodes of each Region. The size of the backup is equal to the data size, with no redundant replicas. Therefore, the total data size is approximately the total number of TiKV data divided by the number of replicas. + +However, if you want to restore data from local storage, the number of replicas is equal to that of the TiKV nodes, because each TiKV must have access to all backup files. + +### Why is the disk usage shown on the monitoring node inconsistent after backup or restore using BR? + +This inconsistency is caused by the fact that the data compression rate used in backup is different from the default rate used in restore. If the checksum succeeds, you can ignore this issue. + +### After BR restores the backup data, do I need to execute the `ANALYZE` statement on the table to update the statistics of TiDB on the tables and indexes? + +BR does not back up statistics (except in v4.0.9). Therefore, after restoring the backup data, you need to manually execute `ANALYZE TABLE` or wait for TiDB to automatically execute `ANALYZE`. + +In v4.0.9, BR backs up statistics by default, which consumes too much memory. To ensure that the backup process goes well, the backup for statistics is disabled by default starting from v4.0.10. + +If you do not execute `ANALYZE` on the table, TiDB will fail to select the optimal execution plan due to inaccurate statistics. If query performance is not a key concern, you can ignore `ANALYZE`. + +### Can I start multiple restore tasks at the same time to restore the data of a single cluster? + +**It is strongly not recommended** to start multiple restore tasks at the same time to restore the data of a single cluster for the following reasons: + +- When BR restores data, it modifies some global configurations of PD. Therefore, if you start multiple restore tasks for data restore at the same time, these configurations might be mistakenly overwritten and cause abnormal cluster status. +- BR consumes a lot of cluster resources to restore data, so in fact, running restore tasks in parallel improves the restore speed only to a limited extent. +- There has been no test for running multiple restore tasks in parallel for data restore, so it is not guaranteed to succeed. + +### Does BR back up the `SHARD_ROW_ID_BITS` and `PRE_SPLIT_REGIONS` information of a table? Does the restored table have multiple Regions? + +Yes. BR backs up the [`SHARD_ROW_ID_BITS` and `PRE_SPLIT_REGIONS`](/sql-statements/sql-statement-split-region.md#pre_split_regions) information of a table. The data of the restored table is also split into multiple Regions. diff --git a/faq/faq-overview.md b/faq/faq-overview.md index 2d86a673b2b86..b1f33bf1ad5c3 100644 --- a/faq/faq-overview.md +++ b/faq/faq-overview.md @@ -12,7 +12,7 @@ This document summarizes frequently asked questions (FAQs) about TiDB. | TiDB architecture and principles | [TiDB Architecture FAQs](/faq/tidb-faq.md) | | Deployment | | | Data migration | | -| Data backup and restore | [Backup & Restore FAQs](/br/backup-and-restore-faq.md) | +| Data backup and restore | [Backup & Restore FAQs](/faq/backup-and-restore-faq.md) | | SQL operations | [SQL FAQs](/faq/sql-faq.md) | | Cluster upgrade | [TiDB Upgrade FAQs](/faq/upgrade-faq.md) | | Cluster management | [Cluster Management FAQs](/faq/manage-cluster-faq.md) | diff --git a/faq/manage-cluster-faq.md b/faq/manage-cluster-faq.md index c639c9816fd58..7b3a0c618df8a 100644 --- a/faq/manage-cluster-faq.md +++ b/faq/manage-cluster-faq.md @@ -444,7 +444,7 @@ This section describes common problems you may encounter during backup and resto Currently, for the backup of a large volume of data (more than 1 TB), the preferred method is using [Backup & Restore (BR)](/br/backup-and-restore-overview.md). Otherwise, the recommended tool is [Dumpling](/dumpling-overview.md). Although the official MySQL tool `mysqldump` is also supported in TiDB to back up and restore data, its performance is no better than BR and it needs much more time to back up and restore large volumes of data. -For more FAQs about BR, see [BR FAQs](/br/backup-and-restore-faq.md). +For more FAQs about BR, see [BR FAQs](/faq/backup-and-restore-faq.md). ### How is the speed of backup and restore? diff --git a/faq/migration-tidb-faq.md b/faq/migration-tidb-faq.md index b8bc8a7d455ba..7d67837b01b9a 100644 --- a/faq/migration-tidb-faq.md +++ b/faq/migration-tidb-faq.md @@ -5,11 +5,11 @@ summary: Learn about the FAQs related to data migration. # Migration FAQs -This document summarizes the frequently asked questions (FAQs) related to TiDB data migration. +This document summarizes the frequently asked questions (FAQs) related to TiDB data migration. For the frequently asked questions about migration-related tools, click the corresponding links in the list below: -- [Backup & Restore FAQs](/br/backup-and-restore-faq.md) +- [Backup & Restore FAQs](/faq/backup-and-restore-faq.md) - [TiDB Binlog FAQ](/tidb-binlog/tidb-binlog-faq.md) - [TiDB Lightning FAQs](/tidb-lightning/tidb-lightning-faq.md) - [TiDB Data Migration (DM) FAQs](/dm/dm-faq.md) diff --git a/media/br/br-log-arch.png b/media/br/br-log-arch.png index 35bb470dd924a30eb3d9bb16ed885b1ca683821a..47c691768a25bf34500660a5aca7631c7845ff57 100644 GIT binary patch literal 83424 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

N;e8h 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

*>+7#na9=F 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 diff --git a/media/br/br-log-backup-ts.png b/media/br/br-log-backup-ts.png new file mode 100644 index 0000000000000000000000000000000000000000..30c848a2325ff190604320fa7ead3975b762121b GIT binary patch literal 38823 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 literal 0 HcmV?d00001 diff --git a/media/br/br-snapshot-arch.png b/media/br/br-snapshot-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..cc9a7114f1dea416ac21e3c66df4da659c97d113 GIT binary patch literal 74071 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

y$lee4 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

@9Z3npV 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 **Note:** > > In production clusters, performing a backup with GC disabled might affect cluster performance. It is recommended that you back up data in off-peak hours, and set `RATE_LIMIT` to a proper value to avoid performance degradation. > -> If the versions of the upstream and downstream clusters are different, you should check [BR compatibility](/br/backup-and-restore-overview.md#before-you-use-br). In this document, we assume that the upstream and downstream clusters are the same version. +> If the versions of the upstream and downstream clusters are different, you should check [BR compatibility](/br/backup-and-restore-overview.md#before-you-use). In this document, we assume that the upstream and downstream clusters are the same version. 1. Disable GC. diff --git a/releases/release-5.0.0-rc.md b/releases/release-5.0.0-rc.md index e381e60d269c8..a8d0f10a91f3d 100644 --- a/releases/release-5.0.0-rc.md +++ b/releases/release-5.0.0-rc.md @@ -158,8 +158,8 @@ In the process of Region membership changes, "adding a member" and "deleting a m ## Backup and restore -+ The Backup & Restore tool (BR) supports backing up data to AWS S3 and Google Cloud GCS. ([User document](/br/backup-storage-S3.md)) -+ The Backup & Restore tool (BR) supports restoring data from AWS S3 and Google Cloud GCS to TiDB. ([User document](/br/backup-storage-S3.md)) ++ The Backup & Restore tool (BR) supports backing up data to AWS S3 and Google Cloud GCS. ([User document](/br/backup-and-restore-storages.md)) ++ The Backup & Restore tool (BR) supports restoring data from AWS S3 and Google Cloud GCS to TiDB. ([User document](/br/backup-and-restore-storages.md)) + Related issue: [#89](https://github.com/pingcap/br/issues/89) ## Data import and export diff --git a/releases/release-5.4.0.md b/releases/release-5.4.0.md index 98c5747ba6664..d68c1ec439f34 100644 --- a/releases/release-5.4.0.md +++ b/releases/release-5.4.0.md @@ -214,7 +214,7 @@ In v5.4, the key new features or improvements are as follows: Backup & Restore (BR) supports Azure Blob Storage as a remote backup storage. If you deploy TiDB in Azure Cloud, now you can back up the cluster data to the Azure Blob Storage service. - [User document](/br/backup-storage-azblob.md) + [User document](/br/backup-and-restore-storages.md) ### Data migration diff --git a/releases/release-6.2.0.md b/releases/release-6.2.0.md index fe6a55251cf4a..e8f17ffd03cd6 100644 --- a/releases/release-6.2.0.md +++ b/releases/release-6.2.0.md @@ -19,9 +19,9 @@ In v6.2.0-DMR, the key new features and improvements are as follows: * The [Fine Grained Shuffle feature](/system-variables.md#tiflash_fine_grained_shuffle_batch_size-new-in-v620) allows parallel execution of window functions in multiple threads. * A [new concurrent DDL framework](/system-variables.md#tidb_enable_concurrent_ddl-new-in-v620): Less DDL statements blocked and higher execution efficiency. * TiKV supports [automatically tuning the CPU usage](/tikv-configuration-file.md#background-quota-limiter), thus ensuring stable and efficient database operations. -* [Point-in-time recovery (PITR)](/br/point-in-time-recovery.md) is introduced to restore a snapshot of a TiDB cluster to a new cluster from any given time point in the past. +* [Point-in-time recovery (PITR)](/br/backup-and-restore-overview.md) is introduced to restore a snapshot of a TiDB cluster to a new cluster from any given time point in the past. * TiDB Lightning supports [importing data to production clusters in the physical import mode](/tidb-lightning/tidb-lightning-physical-import-mode-usage.md#import-data-into-a-cluster-in-production). -* BR supports [restoring user and privilege data](/br/br-usage-restore.md#restore-tables-in-the-mysql-schema), making backup and restore smoother. +* BR supports [restoring user and privilege data](/br/br-snapshot-guide.md#restore-tables-in-the-mysql-schema), making backup and restore smoother. * TiCDC unlocks more data replication scenarios by supporting [filtering specific types of DDL events](/ticdc/manage-ticdc.md). * The [`SAVEPOINT` mechanism](/sql-statements/sql-statement-savepoint.md) is supported, with which you can flexibly control the rollback points within a transaction. * TiDB supports [adding, dropping, and modifying multiple columns or indexes with only one `ALTER TABLE` statement](/sql-statements/sql-statement-alter-table.md). @@ -177,7 +177,7 @@ In v6.2.0-DMR, the key new features and improvements are as follows: BR supports restoring user and privilege data when it performs a normal restoration. You do not need any additional restoration plan to restore user and privilege data. To enable this feature, specify the `--with-sys-table` parameter when you use BR to restore data. - [User document](/br/br-usage-restore.md#restore-tables-in-the-mysql-schema) [#35395](https://github.com/pingcap/tidb/issues/35395) @[D3Hunter](https://github.com/D3Hunter) + [User document](/br/br-snapshot-guide.md#restore-tables-in-the-mysql-schema) [#35395](https://github.com/pingcap/tidb/issues/35395) @[D3Hunter](https://github.com/D3Hunter) * Support point-in-time recovery (PITR) based on backup and restoration of log and snapshot @@ -189,7 +189,7 @@ In v6.2.0-DMR, the key new features and improvements are as follows: This feature has usage limitations. For details, refer to the user document. - [User document](/br/point-in-time-recovery.md) [#29501](https://github.com/pingcap/tidb/issues/29501) @[joccau](https://github.com/joccau) + [User document](/br/backup-and-restore-overview.md) [#29501](https://github.com/pingcap/tidb/issues/29501) @[joccau](https://github.com/joccau) * DM supports continuous data validation (experimental) @@ -298,7 +298,7 @@ In v6.2.0-DMR, the key new features and improvements are as follows: - TiFlash `format_version` cannot be downgraded from `4` to `3`. For details, see [TiFlash v6.2.0 Upgrade Guide](/tiflash-620-upgrade-guide.md). - In v6.2.0 and later versions, it is strongly recommended to keep the default value `false` of `dt_enable_logical_split` and not to change it to `true`. For details, see known issue [#5576](https://github.com/pingcap/tiflash/issues/5576). -- If the backup cluster has a TiFlash replica, after you perform PITR, the restoration cluster does not contain the data in the TiFlash replica. To restore data from the TiFlash replica, you need to manually configure TiFlash replicas. Executing the `exchange partition` DDL statement might result in a failure of PITR. If the upstream database uses TiDB Lightning's physical import mode to import data, the data cannot be backed up in log backup. It is recommended to perform a full backup after the data import. For other compatibility issues of PITR, see [PITR limitations](/br/point-in-time-recovery.md#limitations). +- If the backup cluster has a TiFlash replica, after you perform PITR, the restoration cluster does not contain the data in the TiFlash replica. To restore data from the TiFlash replica, you need to manually configure TiFlash replicas. Executing the `exchange partition` DDL statement might result in a failure of PITR. If the upstream database uses TiDB Lightning's physical import mode to import data, the data cannot be backed up in log backup. It is recommended to perform a full backup after the data import. For other compatibility issues of PITR, see [PITR limitations](/br/backup-and-restore-overview.md#before-you-use). - Since TiDB v6.2.0, you can restore table in `mysql` schema by specifying the parameter `--with-sys-table=true` when restoring data. - When you execute the `ALTER TABLE` statement to add, drop, or modify multiple columns or indexes, TiDB checks table consistency by comparing the table before and after statement execution, regardless of the change in the same DDL statement. The execution order of the DDLs is not fully compatible with MySQL in some scenarios. - If the TiDB component is v6.2.0 or later, the TiKV component should not be earlier than v6.2.0. diff --git a/releases/release-6.3.0.md b/releases/release-6.3.0.md index 902bbb28b39d1..eab4e351d5186 100644 --- a/releases/release-6.3.0.md +++ b/releases/release-6.3.0.md @@ -83,7 +83,7 @@ In v6.3.0-DMR, the key new features and improvements are as follows: In v6.2.0, TiFlash introduces the FastScan feature, which brings expected performance improvements but lacks flexibility in use. Therefore, in v6.3.0, TiFlash changes [the way of using FastScan](/develop/dev-guide-use-fastscan.md): the `ALTER TABLE ... SET TIFLASH MODE ...` syntax to enable or disable FastScan is deprecated. Instead, you can use the system variable [`tiflash_fastscan`](/system-variables.md#tiflash_fastscan-new-in-v630) to easily control whether to enable FastScan. - When you upgrade from v6.2.0 to v6.3.0, all FastScan settings in v6.2.0 will become invalid, but will not affect the normal reading of data. You need to set the variable [`tiflash_fastscan`]. When you upgrade from v6.2.0 or an earlier version to v6.3.0, the FastScan feature is not enabled by default for all sessions to keep data consistency. + When you upgrade from v6.2.0 to v6.3.0, all FastScan settings in v6.2.0 will become invalid, but will not affect the normal reading of data. You need to set the variable `tiflash_fastscan`. When you upgrade from v6.2.0 or an earlier version to v6.3.0, the FastScan feature is not enabled by default for all sessions to keep data consistency. * TiFlash optimizes data scanning performance in scenarios of multiple concurrency tasks [#5376](https://github.com/pingcap/tiflash/issues/5376) @[JinheLin](https://github.com/JinheLin) @@ -165,7 +165,7 @@ In v6.3.0-DMR, the key new features and improvements are as follows: ### Backup and restore -* PITR supports [GCS](/br/backup-storage-gcs.md) and [Azure Blob Storage](/br/backup-storage-azblob.md) as backup storages @[joccau](https://github.com/joccau) +* PITR supports [GCS and Azure Blob Storage](/br/backup-and-restore-storages.md) as backup storages @[joccau](https://github.com/joccau) If your TiDB cluster is deployed on GCP or Azure, you can use the PITR feature after upgrading your cluster to v6.3.0. diff --git a/releases/release-6.4.0.md b/releases/release-6.4.0.md index 13721b4c5c6c3..44370342c5bbe 100644 --- a/releases/release-6.4.0.md +++ b/releases/release-6.4.0.md @@ -304,7 +304,7 @@ In v6.4.0-DMR, the key new features and improvements are as follows: | TiDB | [`tidb_max_reuse_chunk`](/tidb-configuration-file.md#tidb_max_reuse_chunk-new-in-v640) | Newly added | Controls the maximum cached chunk objects of chunk allocation. The default value is `64`.| | TiDB | [`tidb_max_reuse_column`](/tidb-configuration-file.md#tidb_max_reuse_column-new-in-v640) | Newly added | Controls the maximum cached column objects of chunk allocation. The default value is `256`. | | TiKV | [`cdc.raw-min-ts-outlier-threshold`](/tikv-configuration-file.md#raw-min-ts-outlier-threshold-new-in-v620) | Deprecated | This configuration item is no longer effective. | -| TiKV | [`causal-ts.alloc-ahead-buffer`](/tikv-configuration-file.md#alloc-ahead-buffer-new-in-v640) | Newly added | The pre-allocated TSO cache size (in duration). The default value is `3s`。| +| TiKV | [`causal-ts.alloc-ahead-buffer`](/tikv-configuration-file.md#alloc-ahead-buffer-new-in-v640) | Newly added | The pre-allocated TSO cache size (in duration). The default value is `3s`. | | TiKV | [`causal-ts.renew-batch-max-size`](/tikv-configuration-file.md#renew-batch-max-size-new-in-v640)| Newly added | Controls the maximum number of TSOs in a timestamp request. The default value is `8192`. | | TiKV | [`raftstore.apply-yield-write-size`](/tikv-configuration-file.md#apply-yield-write-size-new-in-v640) | Newly added | Controls the maximum number of bytes that the Apply thread can write for one FSM (Finite-state Machine) in one round of poll. The default value is `32KiB`. This is a soft limit. | | PD | [`tso-update-physical-interval`](/pd-configuration-file.md#tso-update-physical-interval) | Newly added | Takes effect starting from v6.4.0 and controls the interval at which PD updates the physical time of TSO. The default value is `50ms`. | @@ -315,7 +315,7 @@ In v6.4.0-DMR, the key new features and improvements are as follows: ### Others -- Starting from v6.4.0, the `mysql.user` table adds two new columns: `User_attributes` and `Token_issuer`. If you [restore system tables in the `mysql` schema](/br/br-usage-restore.md#restore-tables-in-the-mysql-schema) from backup data of earlier TiDB versions to TiDB v6.4.0, BR will report the `column count mismatch` error for the `mysql.user` table. If you do not restore system tables in the `mysql` schema, this error will not be reported. +- Starting from v6.4.0, the `mysql.user` table adds two new columns: `User_attributes` and `Token_issuer`. If you [restore system tables in the `mysql` schema](/br/br-snapshot-guide.md#restore-tables-in-the-mysql-schema) from backup data of earlier TiDB versions to TiDB v6.4.0, BR will report the `column count mismatch` error for the `mysql.user` table. If you do not restore system tables in the `mysql` schema, this error will not be reported. - For files whose names match the [format of Dumpling exported files](/dumpling-overview.md#format-of-exported-files) but end with uncompressed formats (such as `test-schema-create.sql.origin` and `test.table-schema.sql.origin`), the way how TiDB Lightning handles them is changed. Before v6.4.0, if the files to be imported include such files, TiDB Lightning skips importing such files. Starting from v6.4.0, TiDB Lightning assumes that such files use unsupported compression formats, so the import task will fail. - Starting with v6.4.0, only the changefeed with the `SYSTEM_VARIABLES_ADMIN` or `SUPER` privilege can use the TiCDC Syncpoint feature. diff --git a/replicate-between-primary-and-secondary-clusters.md b/replicate-between-primary-and-secondary-clusters.md index db4377fa7bd10..7d78516d2483a 100644 --- a/replicate-between-primary-and-secondary-clusters.md +++ b/replicate-between-primary-and-secondary-clusters.md @@ -68,7 +68,7 @@ To replicate incremental data from a running TiDB cluster to its secondary clust 4. Prepare external storage. - In full data backup, both the upstream and downstream clusters need to access backup files. It is recommended that you use [External storage](/br/backup-and-restore-storages.md#external-storages) to store backup files. In this example, Minio is used to simulate an S3-compatible storage service. + In full data backup, both the upstream and downstream clusters need to access backup files. It is recommended that you use [External storage](/br/backup-and-restore-storages.md) to store backup files. In this example, Minio is used to simulate an S3-compatible storage service. ```shell wget https://dl.min.io/server/minio/release/linux-amd64/minio @@ -99,13 +99,13 @@ To replicate incremental data from a running TiDB cluster to its secondary clust ## Step 2. Migrate full data -After setting up the environment, you can use the backup and restore functions of [BR](https://github.com/pingcap/tidb/tree/master/br)) to migrate full data. BR can be started in [three ways](/br/br-deployment.md#use-br). In this document, we use the SQL statements, `BACKUP` and `RESTORE`. +After setting up the environment, you can use the backup and restore functions of [BR](https://github.com/pingcap/tidb/tree/master/br)) to migrate full data. BR can be started in [three ways](/br/br-use-overview.md#deploy-and-use-br). In this document, we use the SQL statements, `BACKUP` and `RESTORE`. > **Note:** > > - In production clusters, performing a backup with GC disabled might affect cluster performance. It is recommended that you back up data in off-peak hours, and set RATE_LIMIT to a proper value to avoid performance degradation. > -> - If the versions of the upstream and downstream clusters are different, you should check [BR compatibility](/br/backup-and-restore-overview.md#before-you-use-br). In this document, we assume that the upstream and downstream clusters are the same version. +> - If the versions of the upstream and downstream clusters are different, you should check [BR compatibility](/br/backup-and-restore-overview.md#some-tips). In this document, we assume that the upstream and downstream clusters are the same version. 1. Disable GC. diff --git a/sql-statements/sql-statement-recover-table.md b/sql-statements/sql-statement-recover-table.md index 34d9e17894f36..2f18b6fa739d6 100644 --- a/sql-statements/sql-statement-recover-table.md +++ b/sql-statements/sql-statement-recover-table.md @@ -60,7 +60,7 @@ When you use `RECOVER TABLE` in the upstream TiDB during TiDB Binlog replication + Latency occurs during replication between upstream and downstream databases. An error instance: `snapshot is older than GC safe point 2019-07-10 13:45:57 +0800 CST`. -For the above three situations, you can resume data replication from TiDB Binlog with a [full import of the deleted table](/br/br-usage-restore.md#restore-a-table). +For the above three situations, you can resume data replication from TiDB Binlog with a [full import of the deleted table](/ecosystem-tool-user-guide.md#backup-and-restore---backup--restore-br). diff --git a/system-variables.md b/system-variables.md index eb3f29e203321..65b1272ced0df 100644 --- a/system-variables.md +++ b/system-variables.md @@ -1043,7 +1043,7 @@ MPP is a distributed computing framework provided by the TiFlash engine, which a > > Acceleration of `ADD INDEX` and `CREATE INDEX` is an experimental feature. It is not recommended that you use it in production environments. > -> Currently, this feature is not compatible with [PITR (Point-in-time recovery)](/br/point-in-time-recovery.md). When using index acceleration, you need to ensure that there are no PITR log backup tasks running in the background. Otherwise, unexpected behaviors might occur, including: +> Currently, this feature is not compatible with [PITR (Point-in-time recovery)](/br/backup-and-restore-overview.md). When using index acceleration, you need to ensure that there are no PITR log backup tasks running in the background. Otherwise, unexpected behaviors might occur, including: > > - If you start a log backup task first, and then add an index. The adding index process is not accelerated even if index acceleration is enabled. But the index is added in a slow way. Since the log backup task keeps running after being started, it means that the index acceleration feature is disabled in this case. > - If you start an index acceleration task first, and then start a log backup task. The log backup task returns an error. But the index acceleration is not affected. diff --git a/ticdc/ticdc-faq.md b/ticdc/ticdc-faq.md index 21c2b1ad487e3..6d3ee408a5e3b 100644 --- a/ticdc/ticdc-faq.md +++ b/ticdc/ticdc-faq.md @@ -201,9 +201,9 @@ Since v6.2, TiCDC supports splitting a single-table transaction into multiple tr If you still encounter an error above, it is recommended to use BR to restore the incremental data of large transactions. The detailed operations are as follows: -1. Record the `checkpoint-ts` of the changefeed that is terminated due to large transactions, use this TSO as the `--lastbackupts` of the BR incremental backup, and execute [incremental data backup](/br/br-usage-backup.md#back-up-incremental-data). +1. Record the `checkpoint-ts` of the changefeed that is terminated due to large transactions, use this TSO as the `--lastbackupts` of the BR incremental backup, and execute [incremental data backup](/br/br-incremental-guide.md#back-up-incremental-data). 2. After backing up the incremental data, you can find a log record similar to `["Full backup Failed summary : total backup ranges: 0, total success: 0, total failed: 0"] [BackupTS=421758868510212097]` in the BR log output. Record the `BackupTS` in this log. -3. [Restore the incremental data](/br/br-usage-restore.md#restore-incremental-data). +3. [Restore the incremental data](/br/br-incremental-guide.md#restore-incremental-data). 4. Create a new changefeed and start the replication task from `BackupTS`. 5. Delete the old changefeed. diff --git a/tidb-lightning/tidb-lightning-overview.md b/tidb-lightning/tidb-lightning-overview.md index b4c1e84aaa53f..9acdaa793042c 100644 --- a/tidb-lightning/tidb-lightning-overview.md +++ b/tidb-lightning/tidb-lightning-overview.md @@ -17,8 +17,8 @@ TiDB Lightning supports the following file formats: TiDB Lightning can read data from the following sources: - Local -- [Amazon S3](/br/backup-and-restore-storages.md#s3-url-parameters) -- [Google Cloud Storage](/br/backup-and-restore-storages.md#gcs-url-parameters) +- [Amazon S3](/br/backup-and-restore-storages.md#url-format-description) +- [Google Cloud Storage](/br/backup-and-restore-storages.md#url-format-description) ## TiDB Lightning architecture diff --git a/tikv-configuration-file.md b/tikv-configuration-file.md index 36852473958df..4e6493544b2bc 100644 --- a/tikv-configuration-file.md +++ b/tikv-configuration-file.md @@ -1628,7 +1628,7 @@ Configuration items related to BR backup. > **Note:** > -> This configuration is introduced to address backup failures caused by S3 rate limiting. This problem has been fixed by [refining the backup data storage structure](/br/backup-and-restore-design.md#backup-file-structure). Therefore, this configuration is deprecated from v6.1.1 and is no longer recommended. +> This configuration is introduced to address backup failures caused by S3 rate limiting. This problem has been fixed by [refining the backup data storage structure](/br/br-snapshot-architecture.md#structure-of-backup-files). Therefore, this configuration is deprecated from v6.1.1 and is no longer recommended. + The part size used when you perform multipart upload to S3 during backup. You can adjust the value of this configuration to control the number of requests sent to S3. + If data is backed up to S3 and the backup file is larger than the value of this configuration item, [multipart upload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) is automatically enabled. Based on the compression ratio, the backup file generated by a 96-MiB Region is approximately 10 MiB to 30 MiB.

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 B^4b6Z literal 0 HcmV?d00001 diff --git a/media/br/br-snapshot-backup-ts.png b/media/br/br-snapshot-backup-ts.png new file mode 100644 index 0000000000000000000000000000000000000000..e9f1facb8c1d26ecc17788ae97275250e011d2cd GIT binary patch literal 32361 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�f!RoCn3r=U#n!6mYSnlc#pB8)LBqnxnbL<6Eiy&>uX!X5ur5^oMoqP9A*{ee* z-}rIf3hAAO3JoZ5au0zVO@2D{?{czQ-Ow6Q>gU&{dO8TMMEqEH%x7yA8WVpW>mDT>XBKp|zwH z2p!~2@nVrN0HqgDboIIM9K`@Xw*f8G$&Y-o18Q7w z>Xlo5QqldL8G*d?UF@eUcyP8mhA16T+Q4rdpMtaJwH7S!9Yu=wDtp z@u4Z2Jt+p^NJR9+S}1B83fi3#p`ICYk2-#4fiWoq1% zvNJ(+0DoVl%zi-DS|_%w@DMy7{s(^<5rcyjaardU2-jUGe#zoq@1+Gojj5RFNGc&)CE;AbxSXqMp#p+xk5hJo8jN?UX4b&6EO<2X**;%YF zKkz|tRU{-4>-=#ga8&7cD1DIO;?&O&T(TZ)T#NFO3yk8mxx~nrY(3KhVjlD~p&zOk z5*$oUMI}l1>C-1L1?q4B*}*B;fUCfF4|=@uVEK0WQ!lVpr~?UsHm!f%$jC^tP=Pwo z#*-(nLA`RjO!AkVN8XY5GS@W(aSd)e>|DSPl{>}sC5b9rVNwP#Xha!U524$sMF)`1 z6p$M5Byg%ep6<#9rrQrdp$-N&3!qN~7_q3R2p%`P4hM{X8CF{WoI&4Fl0}jMDeIFA z24D#Z&r*kKPco}1;KeQljCG1{WQPGyTV0ai6M0Gq4UmK^i{&Y$^)oBc?AH)J-y-E7 zj|Q5gnwlD29M}ovaXrB|g2~Crbt$)?!$);R&&$`B#9jg&2agE*$$oN|kdMPc)8w24 z4N&3sF>q>*j!xR|M$RK*(qvvjAnb@5f^RESI0vg&A z!^3`|p^SqZ&>OF#fEnCxic}K;;|65ET$%fqG)fsV%}8{KiJf)k74|?f?%FTdf9)o? zM<45;{ppN#`idT5%W$5b_X(1(T35h@1uj?cl$2YJOT%lIm6eU|?nwv4?H@MNmPA6W zf)j@ZK^fxbF9Rd9S=n;1;=y^XktDz*h^)g-Zy$w#jq8$H9s?KGD%5Noe|hz)6Brw; z1~oPH%-kFpucj8qn_*~l9kN$5bj76g^z^{k!h7jbQ&pAQ{{8g<9+hj$5@7Fu$;%x$ ziMi^5YzD0PTkj9EX8D6^udo5^ufl3l9@sGGLq!xen_V5>!?z z9yE4u!~-q>QFt&4;THXDNRRa7NwIaeFJf@^Cz8K6t(fj)oH}|`h$AjGHh%Ngctfbj zsQk#W^})p=^WnYx37pLlytNXbOTST_l<`*oZvTOU*PbmM!LyC6XH7db2ksA>ooyPQ2}0#3^lWMpWYZe?xl81-KKBS!?uV4`k6&JFnE z+^0?X4!}^s5#0O4oLGBK{p%bnp_UG~;kgds*81Dz0PwqoHt$B&4%#vx@~7955kJNb zek9MGro`!&Vrd(-d$VZ2Cr~Mo=m@1dM+N)4UMp>9bHkoV;^G3jGT`lO0uKE>v39*4 zLRS^L;hi4-wXeu`2P63qe`MQ5XW-9S`*6>Xa8{phYs5Q%#(Q_{_coB6{GVMO*Vp=) zPm9?%6;xDk2Oc7X*`~{N2p!i@xyPLFUym<=TAA(Ngn+nlu8f7{ila*x- zdKIX?#-J%fws73jEtbzO?zLyb=igXCeZX{k#@>|FJIgK^_I zKMtYd#v;&qkX;m0m09TM+*61suQHrIeVU(NUA5U1*V=0YkN3aozNI^B*^<23IlISD zk#u{{v$D#3N~{|~Ts!vtn8S?Ck3%M%AP6Hc3(L#=c1v#*Eda+tH*a0RutZ8(Ne>(} z9Th0l&6r~AoSYnkG?=icjm$B+aG0*$7W#UlbOcOpctc{}GX%~U{R@n&1MHt@2kVL4 zEE^B_B%oIhDg0*x5AFhK5J!jw1uKB81Di{|L&Ify5Bzl?nOJNrP5xshMb2F=?$##- zTG}WO<~bgI4tXew1^1w=2MEk+dNKRZc=z`ID}yyG>qF|cngROcNNZIEA0rKndB#* zcc2XqJOUtrhqat?v^zIHe?$QZHO~XKr_X@}_q~1mq5$_+$?|kPvdL1R*Nt8mLmmpb ztmEL|(50|m$O5;Fqe)CiP-0huW|qVm1wAa{$nON`T?P2XO&X@g5B#>;X5KCI;S?4T zIX9~zla)*g&8pa}c=q4En~tlYd=2?kywG?Aiyc&#OBFip56<}G7ZKo2 z?)Q}9QEa;qTUc1QrE`c8ndM6xd{Omm>W<)r01vt#m;k@|IQWvfL@!PTp#SEvF|nKp z0qMB$&e&l;zIRH00D#sfhmKE711#c3?Ley*I(d>bKcJYc?b-=V2RV6p;n8WgeF5ky z|2o|ChsD1fyD+*HNC>%AsmE^`7&Yu7_^JUi*n>k0oZnC!b#r8S{yRbxHx$&=B&gpg zr&BJ+fCqA^qO!7b+JinXxVE-d;W?ln=+ogkmG00lg#$g^#ces(a>lr%p)QaKH`hVt z;OLkn6)KDmcDR#XQS$8o6kyP6dgMsJj2JZKq$^!l1eRJv0_Bu5?ipst%IjfeDNZ3o zzkIKqzw-tZ97{MBrKP3N-pgt}gYoqAT&vhLlnxDI1-r}9C!7;E6hp~cakAH3U-3C5 z1w)S%oFJxH(I9*{h#QdP4^r?OKB_{_ATLjq@`Xf;6aQZG8nX%YB zrjmr%S>bm`cad$rj03^|Bqs0>4B_Z^c4;3GKq3zQUW6K&coJ@0?{;U8#bG}PQ503f*8lL2Kn1_T; z`mcl@^aGKgGf>SU=Kq=WA%Jx{E3}!4*zxh-UH%uQ`M+J3|Bme6^$*y4;3VYj{rmUV z$us}*^5|#H3?Txk{-aughqxJRjgeqK)B@6yvwh*JX`k(fXGh`VENXerG?rmFjcoKc zwf7GQfGG*B40FiJ$%%pIjwKTkJD*$lhIap|^a{|{RLe?8f)tXWmY-r=acD)7CLtjK zrmw)A1=_GJ$co_{5A`zUVcurSg!I@kVQRf^#eE=}PVoT#JHPMCj+@2(aSD=JX=D6F zm6gfKW?{^cU)TONxx@w-Z6R=w&+~tM=KJYAB~FL5ftbPWg zeqLULJqF+%GBjkI34>I;vHaE2!s5%9FF@+_*_@Pxf+oA5z|TU-J9a3FPYh^%(63rd z=#S6G_8a4!66Z%Q{hZh2DaOrfHu=|nv%J0_XSx5F{L;PeuGf{oKc_cQyG}h|RhBQP z#}u+07*VGNejeln?W|P!kEfCE@V=qeZ~3jp5428hm^ho9gmr`3&|R=~Hwb6O1_RCZ z^i3wsLR0GHt#>YXX~eq3cCepOtt+nk54*a#fhhyZvnp0hMkc8YTvrc*8tF*Je$nxg zEg!i6cj#rk`$4<@IO-Cp*w|PYVT(@!aSr@?`n}k1w$v%iH!T2klti5GCzl8M`bkMJ zi~u~_Utl1F+wy`WO`1FOlCtUmD8V-lJn4xcfEJA$Ydbh-e+Seb*#ht)j!Hwf1zZrB zAim?wu}nL4%$ZrhjiIYMkI_j!!Q__O-C^pFgCt{4hF=u zVhFexG8wL135Y#3vphe~aOqOw2F`|>l-Jre3DZ08>3x4u_*Xn4)QeawbjkwJ!jng4 z&?0{*7{BR4Qfm~DY(5w}Yj+_aV`|wgFzS%la3rAfs->|{0~AGi8=89;9Pb?^BMb8P ze_z08e&g1yw-n#qo?Tj7Mv2g$#C6?xb?XA*4MlIM3*9a@AAS#>tENbPX5YQjx!yqM zVGtQc!ak-jgNXjk1WGC&PAX&&2YS<+H_ymGOjeNKyzuEcPNwD233b=4YicrWfAa}6 zSpW>Fee?=rfHn{OGgU!i6Enu1sCxYsgg?-3hzSXedkb)0qT5dUqReYiXH^R4C{tIj* zhC>fhub>~qX%W?Zt2oW%>LCzQNPmbadQ<`U2xlr>2jaSu(~dm?aSOZ4eir_YKwKmK z#}5w;mB(hMoyGqiGE!N#7efU6%NzUWw<7$|H~*JkuYh}~zb*t%VSWnKg};8769GYE zU|^69Rui#5OgwZfVjrSqFQ__Ti1~-Bl>r1%n#=c}({SiV{j~);Cl|bAI4wgXe~eg(5!L~CPI;dNS|?4=>h#8X0t$h z%2>>0^P%fKFlV>0x(apTF?)PNr2OsownBY;2nT(Lr{(3J(KARSp}=u`)13i(I%J_JQf2U*8aJ&tiey0k2#SCgj0CM^an*#1o`_C^;l_ zuf9&`yWuchAysgHDXM@Re*AdbUsSg)&m8CBJS%KxXD2MY zm!+@*?4gidaTOIL+=d1zHDALx)m**yy{U7vvyrb~OVuyJ6`-(0+D#=pZmz&spwIxm zC5yuP?=N0>i2R4M^KnQ|U!LLd$IkiJU)agX9bGPkPlDn70SkO7l2izriwW+&r0ng@ z4D@rmAaAc-j!{rRP_jP|g9%BH7huk)j#!bKQIaN5NAXsbYMmol_wzs8;-lsLUj81v z{P4zlnshi09od>9)7bi6suz@0_LC=?Adh6@L1$B96iD_Ke8+^L4p7202N;oAS}K_< z*I5Qb-0ro2snx?5?gp>4rU>daoTR0tttu-ALyLqxg^_kkv{0ZlObj!k#73FUTp#uF zD&4(M`{XGzcuM`r_a9t$VWKBn?+v!lylH**m;L%W1q1Rt9UV1HI^Xi9gr=yjJID!f zK^#}FUd2X&gM(^T^BRy<^%!Ay2&e2ieBx7Dqk-HL00Nv+-k8a%KfGNa)eA~{v~Dj< z^zu~s`f1(NJ(u@Gp9d3Y=Q#n(ku@1iJKw2g@H5M77`X;SfR`>^0w=Li0j$8qi&Bp|>Dxdi0Iw-I zIk^Pgu>cnR2M=2AM}>xp4?pc${f;Hd0hexWZYq2RZQHqCPW@Y!WGHmQ|mY@P$L*m{Fpw9IHNnyCQS$mUI5c6 z&XLW(jKu;cY=d6Pdm}K8l>T}ryBMbuRb}PRmd*U4W((b~P6snHG5Mp8y&K4R6&&1J z;;{1KSTXbucYyqQ3cEw@4C4z9o`-W5V!RGe^E+x$ar!y|k;A~Wt=e1){j~*-4$T(? z)gdRn{GlS8oZz8zR|qtL;vgSOt_!=-Me(>Gli!?=1L! zU&0D)Wz=D-=;*GC(fXv7b>96+GIV)ldhA#S27RD}VZTBDtm5PfdNC2I6wgmo;2$RK z{ry{#DdPZ?!!U(lWMpJwQl%IVJ;%^kqHk*mlsb^!Ttu?Xl!TZx2AK>tClA@Z>)^Ig zB1G9%VH8O)p~U|uaqypo!2ejZ@*jpzl>T9<`h^OY`P*}XY7%HzIOcEJLqEhWABsOp zjjex~XMO*JBPGq>?ByZ&?Ab>=8X@O3%OB&(Eh{1@sIIO3W`Xw$9u(zE|644@}21shsU!wa6V~qYa z&^E+y`iQ>%Q?sKY8`iCR#TCY-HEQ}v`;fcRsG4MQEy zsF0nms+yr{6fY*vzrC22&A&fgyh%&KZEkW1wM=8WsS~<$=yBeoEDND^yz~qs@TP?R}~dm>)L*apL$F2!WqKA*9d*+?h_J;)M#U> z`y=KbSb@G|xNmE{nV5E`Qh%z8sUy>BCc*|N zy)9v^67o%r{=46(9i5y^JucX(8R`+0ysWGe!@?SX+yo^_SvtTt_kd?X)?Hd-V`Hg2 z#~zKdMZDY!GIutfWpira-^;Roy=wBlNlcd`B_3GnRe2Ek=2G{rGrE4by@vC?!Wlxo z0*S!e0~#4IfHruin7FuhKS7biF70w{^XHzPtXc4stHNm?^}%Lh&&jRNL)VDxC%%jX zARESkaI2rF9xjSp2G6KlYYq!EhOKlPxR-B20{F?d*GH6Fdfn>${Sk620uv5mCdIEC z{nBpRCNeo-^wlM<5%gFOmsL{>2nK_tFN9G)MLY{iTWxJE=CG>b)qW@5++~%BzkLr` z*I+D6m>F