开门见山,能不能修?
Doris 的 Tablet 损坏了,到底能不能修呢?数据会不会丢?
这玩意还真不好说?
哎,怎么又不好说了呢?
这个主要是因为下面的原因:
Doris 数据的高可用是基于多副本的,也就是说你在建表的时候,如果指定了3副本,类似下面的参数
// 指定3副本
"replication_allocation" = "tag.location.default: 3"
//或者
"replication_num"="3"
那如果你损坏了一个副本,这时候,基本用户是不会感知的,Doris会有自动修复功能。
但是如果你损坏了两个副本,这时候你这个表应该就是没有办法读写了,这时候就需要手动去修复了。
但是这些都是基于高可用的情况,那如果就一个副本该怎么办呢?
Doris 默认是三副本的,即建表不指定也是三副本,除非用户单独指定了1副本,才会出现上述情况(但是有时候基于成本考虑,或者测试场景,确实会有单副本的情况)
怎么判断Tablet是否损坏?
一般情况下,当查询时候出现下面的报错
Failed to get scan range, no queryable replica found in tablet: xxxx
或者下面的情况
Failed to initialize storage reader, ..., fail to Find path in version_graph
注:下面这种情况的发生原因:迁移副本过程可能丢version,在2.0.3修复了。(老版本还是推荐大家尽快升级呀)
这时候查询对应表里面的某些Tablet就属于不正常的状态了,那就需要根据下面章节的方法进行修复了。
坏了的Tablet怎么修复?
当出现上面的情况时,对应的报错,会带有tablet_id的一串数字。假设tablet_id 是606202,那就可以按照下面的方式进行修复了。(具体实施时候,替换成自己损坏的tablet_id)。
查询失败情况
1.Show tablet xxxx (这里是606202), 拿到detail cmd
2.执行detail cmd的输出,找出该BE 所在的副本(compact status url中包含有该BE的ip)
3.执行curl <步骤3的compact status url>, 该例子是"curl http://be_ip:http_port/api/compaction/show?tablet_id=606202"
查看该副本的rowset 和 missing_rowset ,重点看rowset 的最大版本(这里是34)和 missing_rowsets,从这里可以看出该副本的rowset 为 0 ~ 34, 且中间不缺version(missing_rowsets为空)。
注意:这里的special version 实际就是partition 的visible version。 它也可以通过 show partitions from where PartitionName = ‘’ 来查看到;
而查询语句中是 special version 是 [0, 35], 而该BE 不含version 35。
所以需要给该BE 补上version 35。
如果在3的结果里面missing version不为空,比如下面的例子
这时候就表示有些版本确实丢失了,这时候如果是三副本的话,可以看看其他的be上是不是也是这种情况。如果都是丢失,而且对应的be上日志里有下面的信息
那就说明,确实这三个副本都损坏了。这种情况说明确实丢数据了,最保险的办法就是对应分区重新导入数据了。
如果实在认为这数据丢了一点就丢了一点,不耽误后面的使用,那就可以参考下面章节的内容修复
4. 先确认能否自动修复
如果是多副本,查看是否存在健康副本。副本健康,是指 version >= special version && last failed version = -1 && isBad = false, 且curl 它的 compaction status, missing rowsets 为空。
如果存在这样的副本,把查询报错的副本set bad。参考命令:https://doris.apache.org/zh-CN/docs/sql-manual/sql-statements/table-and-view/data-and-status-management/SET-REPLICA-STATUS
等待一会(可能需要一两分钟),再执行步骤2的detail cmd,如果副本都健康了(version >= special version && last failed version = -1 && isBad = false),且cur 它的compact status, missing rowsets为空,说明修补OK了。且执行select count (*) from table 是否OK。
如果没问题,就自动修复ok了,不用往下看。如果还是有问题,接着往下看。
5. 添补空rowset的方法
如果是三副本都损坏了,或者单副本的情况,那就可以进行补空rowset的方式进行修复了。
这个例子中修补的url中 start_version = 35, end_version = 35;
这个例子只是缺一个rowset, 实际中可能缺多个(missing rowset、最大version + 1 ~ special version ),缺多少个rowset,就调用多少次修补的方法;
参考命令:https://doris.apache.org/zh-CN/docs/admin-manual/open-api/be-http/pad-rowset
这种缺version 可以通过上面的方式让数据可查,但是这部分的数据是没有了,会有少数据的情况
6. 修补完,判断是否需要修改last fail version
修复完之后,再执行下show tablet xxx, 该副本last fail version 是否等于 -1,如果它的version都补上了,但是last fail version = version + 1, 还需要手工执行把last fail version 改成 -1。
参考命令: https://doris.apache.org/zh-CN/docs/sql-manual/sql-statements/table-and-view/data-and-status-management/SET-REPLICA-VERSION
低版本的doris可能不含这个SQL, 如果不支持这个SQL且是单副本的或多副本都损坏了,那救不回来了。
如果没问题,使用 select count(*) from table_xx 查看是否可读,可读则正常了。
特殊场景应对
如果是日志场景,使用单副本存储,但是出现某个tablet损坏了,少数据就少数据,能查就行,也不需要单独修复,该怎么做呢?
通过设置变量skip_missing_version 和 skip_bad_tablet 为true就行了,默认是false。
总结
好了,上面就是比较常见的解决办法了,还搞不好,或者不会搞怎么办?
这就要学会主动出击了,找Doris社区的同学,他们都是嘎嘎热心的人!
如果自己通过上面的方式修复了,但是感觉还是不合理,为什么会出现Tablet损坏的情况呢?这时候也是可以带着对应的日志去找社区的同学,让他们辅助分析一波。