Doris学习笔记之备份与恢复

简要原理说明

Doris支持将当前数据以文件的形式,通过broker备份到远程存储系统中,之后可以通过恢复命令,从远程存储系统中将数据恢复到任意Doris集群。通过这个功能,Doris支持将数据进行定期快照备份,并且在不同集群间进行数据迁移,不过需要Doris版本0.8.2+。
使用该功能,需要部署对应的远程存储broker,如HDFS、BOS等,可以通过show broker查看当前部署的broker。

备份

备份操作是将指定表或分区的数据,直接以Doris存储的文件的形式,上传到远端仓库中进行存储。当用户提交Backup请求后,系统内部会做如下操作:

快照及快照上传

快照阶段会对指定的表或分区数据文件进行快照,在快照之后,对表进行的更改、导入等操作都不再影响备份的结果。快照只是对当前数据文件产生一个硬链,耗时很少。快照完成后,会开始对这些快照文件进行逐一上传,快照上传由各个Backend并发完成。

元数据准备及上传

数据文件快照上传完成后,Frontend会首先将对应元数据写成本地文件,然后通过broker将本地元数据文件上传到远端仓库,完成最终备份作业。

恢复

恢复操作需要指定一个远端仓库中已存在的备份,然后将这个备份的内容恢复到本地集群中。当用户提交Restore请求后,系统内部会做如下操作:

在本地创建对应的元数据

这一步首先会在本地集群中,创建恢复对应的表分区等结构。创建完成后,该表可见,但是不可访问。

本地snapshot

这一步是将上一步创建的表做一个快照。这其实是一个空快照(因为刚创建的表是没有数据的),其目的主要是在Backend上产生对应的快照目录,用于之后接收从远端仓库下载的快照文件。

下载快照

远端仓库中的快照文件,会被下载到对应的上一步生成的快照目录中,这一步由各个Backend并发完成。

生效快照

快照下载完成后,我们要将各个快照映射为当前本地表的元数据。然后重新加载这些快照,使之生效,完成最终的恢复作业。

最佳实践

备份

当前我们支持最小分区(Partition)粒度的全量备份(增量备份有可能在未来版本支持)。如果需要对数据进行定期备份,首先需要在建表时,合理的规划表的分区及分桶,比如按时间进行分区。然后在之后的运行过程中,按照分区粒度进行定期的数据备份。

数据迁移

用户可以先将数据备份到远端仓库,再通过远端仓库将数据恢复到另一个集群,完成数据迁移。因为数据备份是通过快照的形式完成的,所以,在备份作业的快照阶段之后的新的导入数据,是不会备份的。因此,在快照完成后,到恢复作业完成这期间,在原集群上导入的数据,都需要在新集群上同样导入一遍。建议在迁移完成后,对新旧两个集群并行导入一段时间。完成数据和业务正确性校验后,再将业务迁移到新的集群。

重点说明

  • 备份恢复相关的操作目前只允许拥有ADMIN权限的用户执行。
  • 一个Database 内,只允许有一个正在执行的备份或恢复作业。
  • 备份和恢复都支持最小分区(Partition)级别的操作,当表的数据量很大时,建议按分区分别执行,以降低失败重试的代价。
  • 因为备份恢复操作,操作的都是实际的数据文件。所以当一个表的分片过多,或者一个分片有过多的小版本时,可能即使总数据量很小,依然需要备份或恢复很长时间。用户可以通过SHOW PARTITIONS FROM table_name;SHOW TABLET FROM table_name;来查看各个分区的分片数量,以及各个分片的文件版本数量,来预估作业执行时间。文件数量对作业执行的时间影响非常大,所以建议在建表时,合理规划分区分桶,以避免过多的分片。
  • 当通过SHOW BACKUP或者SHOW RESTORE命令查看作业状态时,有可能会在TaskErrMsg一列中看到错误信息。但只要State列不为CANCELLED,则说明作业依然在继续。这些Task有可能会重试成功,当然,有些Task错误,也会直接导致作业失败。
  • 如果恢复作业是一次覆盖操作(指定恢复数据到已经存在的表或分区中),那么从恢复作业的COMMIT阶段开始,当前集群上被覆盖的数据有可能不能再被还原。此时如果恢复作业失败或被取消,有可能造成之前的数据已损坏且无法访问。这种情况下,只能通过再次执行恢复操作,并等待作业完成。因此,我们建议,如无必要,尽量不要使用覆盖的方式恢复数据,除非确认当前数据已不再使用。

备份

创建一个远程仓库路径

CREATE REPOSITORY `hdfs_ods_dw_backup`
WITH BROKER `broker_name`
ON LOCATION "hdfs://scentos:8020/tmp/doris_backup"
PROPERTIES (
    "username" = "",
    "password" = ""
);

执行备份

语法:

BACKUP SNAPSHOT [db_name].{snapshot_name}
TO `repository_name`
ON (
    `table_name` [PARTITION (`p1`, ...)],
    ...
)
PROPERTIES ("key"="value", ...);

示例:

BACKUP SNAPSHOT test.backup1
TO hdfs_ods_dw_backup
ON
(
    table1
);

查看备份任务

语法:

show backup [from db_name];

示例:

mysql> show backup;
+-------+--------------+--------+----------+-------------------------------+---------------------+----------------------+---------------------+---------------------+-----------------+----------+------------+--------+---------+
| JobId | SnapshotName | DbName | State    | BackupObjs                    | CreateTime          | SnapshotFinishedTime | UploadFinishedTime  | FinishedTime        | UnfinishedTasks | Progress | TaskErrMsg | Status | Timeout |
+-------+--------------+--------+----------+-------------------------------+---------------------+----------------------+---------------------+---------------------+-----------------+----------+------------+--------+---------+
| 14289 | backup1      | test   | FINISHED | [default_cluster:test.table1] | 2022-05-17 16:23:00 | 2022-05-17 16:23:03  | 2022-05-17 16:23:12 | 2022-05-17 16:23:19 |                 |          |            | [OK]   | 86400   |
+-------+--------------+--------+----------+-------------------------------+---------------------+----------------------+---------------------+---------------------+-----------------+----------+------------+--------+---------+
1 row in set (0.01 sec)

查看远程仓库镜像

语法:

SHOW SNAPSHOT ON `repo_name` [WHERE SNAPSHOT = "snapshot" [AND TIMESTAMP = "backup_timestamp"]];

示例1,查看仓库hdfs_ods_dw_backup中已有备份:

mysql> SHOW SNAPSHOT ON hdfs_ods_dw_backup;
+----------+---------------------+--------+
| Snapshot | Timestamp           | Status |
+----------+---------------------+--------+
| backup1  | 2022-05-17-16-23-00 | OK     |
+----------+---------------------+--------+
1 row in set (0.02 sec)

示例2,查看仓库hdfs_ods_dw_backup中名称为backup1的备份:

mysql> SHOW SNAPSHOT ON hdfs_ods_dw_backup where snapshot = 'backup1';
+----------+---------------------+--------+
| Snapshot | Timestamp           | Status |
+----------+---------------------+--------+
| backup1  | 2022-05-17-16-23-00 | OK     |
+----------+---------------------+--------+
1 row in set (0.26 sec)

取消备份

前提是备份作业正在进行,语法:

CANCEL BACKUP FROM db_name;

示例:

CANCEL BACKUP FROM test;

恢复

将之前通过BACKUP命令备份的数据,恢复到指定数据库下。该命令为异步操作。提交成功后,需通过SHOW RESTORE命令查看进度。

  • 仅支持恢复 OLAP 类型的表
  • 支持一次恢复多张表,这个需要和你对应的备份里的表一致。

使用语法

RESTORE SNAPSHOT [db_name].{snapshot_name}
FROM `repository_name`
ON (
    `table_name` [PARTITION (`p1`, ...)] [AS `tbl_alias`],
    ...
)
PROPERTIES ("key"="value", ...);

说明:

  1. 同一数据库下只能有一个正在执行的BACKUP或RESTORE任务。
  2. ON子句中标识需要恢复的表和分区。如果不指定分区,则默认恢复该表的所有分区。所指定的表和分区必须已存在于仓库备份中
  3. 可以通过AS语句将仓库中备份的表名恢复为新的表,但新表名不能已存在于数据库中。分区名称不能修改。
  4. 可以将仓库中备份的表恢复替换数据库中已有的同名表,但须保证两张表的表结构完全一致。表结构包括:表名、列、分区、Rollup等等。
  5. 可以指定恢复表的部分分区,系统会检查分区Range或者List是否能够匹配。
  6. PROPERTIES目前支持以下属性:
    • "backup_timestamp" = "2018-05-04-16-45-08":指定了恢复对应备份的哪个时间版本,必填。该信息可以通过SHOW SNAPSHOT ON repo;语句获得。
    • "replication_num" = "3":指定恢复的表或分区的副本数。默认为 3。若恢复已存在的表或分区,则副本数必须和已存在表或分区的副本数相同。同时,必须有足够的host容纳多个副本。
    • "timeout" = "3600":任务超时时间,默认为一天。单位秒。
    • "meta_version" = 40:使用指定的meta_version来读取之前备份的元数据。注意,该参数作为临时方案,仅用于恢复老版本Doris备份的数据。最新版本的备份数据中已经包含meta version,无需再指定。

使用示例

示例1

从hdfs_ods_dw_backup中恢复备份backup1里的表table1到数据库example,时间版本为2022-05-17-16-23-00:

RESTORE SNAPSHOT example.`backup1`
FROM `hdfs_ods_dw_backup` 
ON ( `table1` )
PROPERTIES
(
"backup_timestamp"="2022-05-17-16-23-00",
"replication_num" = "1"
);

运行结果:

mysql> create database example;
Query OK, 0 rows affected (0.00 sec)

mysql> RESTORE SNAPSHOT example.`backup1`
    -> FROM `hdfs_ods_dw_backup`
    -> ON ( `table1` )
    -> PROPERTIES
    -> (
    -> "backup_timestamp"="2022-05-17-16-23-00",
    -> "replication_num" = "1"
    -> );
Query OK, 0 rows affected (0.54 sec)

示例2

从hdfs_ods_dw_backup中恢复备份backup1里的表table1到数据库example,并重命名为table_r,时间版本为2022-05-17-16-23-00:

RESTORE SNAPSHOT example.`backup1`
FROM `hdfs_ods_dw_backup`
ON ( `table1` AS `table_r` )
PROPERTIES
(
"backup_timestamp"="2022-05-17-16-23-00",
"replication_num" = "1"
);

运行结果:

mysql> RESTORE SNAPSHOT example.`backup1`
    -> FROM `hdfs_ods_dw_backup`
    -> ON ( `table1` AS `table_r` )
    -> PROPERTIES
    -> (
    -> "backup_timestamp"="2022-05-17-16-23-00",
    -> "replication_num" = "1"
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> select * from example.table_r;
+--------+----------+--------------+------+
| siteid | citycode | username     | pv   |
+--------+----------+--------------+------+
|      3 |        2 | tom          |    2 |
|      4 |        3 | bush         |    3 |
|     99 |       99 | haha         |    5 |
|      2 |        1 | grace        |    2 |
|     11 |        3 | hehe         |    9 |
|     11 |        3 | heihei       |   10 |
|     11 |       21 | szc          |    2 |
|     11 |       23 | haha         |    8 |
|      5 |        3 | helen        |    3 |
|      1 |        1 | jim          |    2 |
|     22 |     NULL | wuyanzu      |    3 |
|     33 |        3 | flink-stream |    3 |
+--------+----------+--------------+------+
12 rows in set (0.10 sec)

查看恢复任务

语法:

show restore [from db_name];

取消恢复

取消一个正在执行的数据恢复作业:

cancel restore from db_name;

当取消处于commit或之后阶段的恢复作业时,可能导致被恢复的表无法访问,此时只能再次执行恢复作业进行数据恢复。

删除远程仓库

删除一个已创建的远程仓库,只有doris里的root或superuser才能执行:

drop repository `repo_name`;

注意,这里的删除仓库只是删除该仓库再doris中的映射,不会删除实际的仓库数据。删除后,可以再次通过指定相同的broker和location映射到该仓库。

示例,删除hdfs_ods_dw_backup仓库:

mysql> DROP REPOSITORY `hdfs_ods_dw_backup`;
Query OK, 0 rows affected (0.01 sec)
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值