跳到主要内容

数据操作问题

本文档主要用于记录 Doris 使用过程中的数据操作常见问题。会不定期更新。

Q1. 使用 Stream Load 访问 FE 的公网地址导入数据,被重定向到内网 IP?

当 stream load 的连接目标为 FE 的 http 端口时,FE 仅会随机选择一台 BE 节点做 http 307 redirect 操作,因此用户的请求实际是发送给 FE 指派的某一个 BE 的。而 redirect 返回的是 BE 的 ip,也即内网 IP。所以如果你是通过 FE 的公网 IP 发送的请求,很有可能因为 redirect 到内网地址而无法连接。

通常的做法,一种是确保自己能够访问内网 IP 地址,或者是给所有 BE 上层架设一个负载均衡,然后直接将 stream load 请求发送到负载均衡器上,由负载均衡将请求透传到 BE 节点。

Q2. Doris 是否支持修改列名?

在 1.2.0 版本之后,开启 "light_schema_change"="true" 选项时,可以支持修改列名。

在 1.2.0 版本之前或未开启 "light_schema_change"="true" 选项时,不支持修改列名,原因如下:

Doris 支持修改数据库名、表名、分区名、物化视图(Rollup)名称,以及列的类型、注释、默认值等等。但遗憾的是,目前不支持修改列名。

因为一些历史原因,目前列名称是直接写入到数据文件中的。Doris 在查询时,也是通过列名查找到对应的列的。所以修改列名不仅是简单的元数据修改,还会涉及到数据的重写,是一个非常重的操作。

我们不排除后续通过一些兼容手段来支持轻量化的列名修改操作。

Q3. Unique Key 模型的表是否支持创建物化视图?

不支持。

Unique Key 模型的表是一个对业务比较友好的表,因为其特有的按照主键去重的功能,能够很方便的同步数据频繁变更的业务数据库。因此,很多用户在将数据接入到 Doris 时,会首先考虑使用 Unique Key 模型。

但遗憾的是,Unique Key 模型的表是无法建立物化视图的。原因在于,物化视图的本质,是通过预计算来将数据“预先算好”,这样在查询时直接返回已经计算好的数据,来加速查询。在物化视图中,“预计算”的数据通常是一些聚合指标,比如求和、求 count。这时,如果数据发生变更,如 update 或 delete,因为预计算的数据已经丢失了明细信息,因此无法同步的进行更新。比如一个求和值 5,可能是 1+4,也可能是 2+3。因为明细信息的丢失,我们无法区分这个求和值是如何计算出来的,因此也就无法满足更新的需求。

Q4. tablet writer write failed, tablet_id=27306172, txn_id=28573520, err=-235 or -238

这个错误通常发生在数据导入操作中。错误码为 -235。这个错误的含义是,对应 tablet 的数据版本超过了最大限制(默认 500,由 BE 参数 max_tablet_version_num 控制),后续写入将被拒绝。比如问题中这个错误,即表示 27306172 这个 tablet 的数据版本超过了限制。

这个错误通常是因为导入的频率过高,大于后台数据的 compaction 速度,导致版本堆积并最终超过了限制。此时,我们可以先通过 show tablet 27306172 语句,然后执行结果中的 show proc 语句,查看 tablet 各个副本的情况。结果中的 versionCount 即表示版本数量。如果发现某个副本的版本数量过多,则需要降低导入频率或停止导入,并观察版本数是否有下降。如果停止导入后,版本数依然没有下降,则需要去对应的 BE 节点查看 be.INFO 日志,搜索 tablet id 以及 compaction 关键词,检查 compaction 是否正常运行。关于 compaction 调优相关,可以参阅 ApacheDoris 公众号文章:Doris 最佳实践-Compaction 调优 (3)

-238 错误通常出现在同一批导入数据量过大的情况,从而导致某一个 tablet 的 Segment 文件过多(默认是 200,由 BE 参数 max_segment_num_per_rowset 控制)。此时建议减少一批次导入的数据量,或者适当提高 BE 配置参数值来解决。在 2.0 版本及以后,可以通过打开 segment compaction 功能来减少 Segment 文件数量 (BE config 中 enable_segcompaction=true)。

Q5. tablet 110309738 has few replicas: 1, alive backends: [10003]

这个错误可能发生在查询或者导入操作中。通常意味着对应 tablet 的副本出现了异常。

此时,可以先通过 show backends 命令检查 BE 节点是否有宕机,如 isAlive 字段为 false,或者 LastStartTime 是最近的某个时间(表示最近重启过)。如果 BE 有宕机,则需要去 BE 对应的节点,查看 be.out 日志。如果 BE 是因为异常原因宕机,通常 be.out 中会打印异常堆栈,帮助排查问题。如果 be.out 中没有错误堆栈。则可以通过 linux 命令 dmesg -T 检查是否是因为 OOM 导致进程被系统 kill 掉。

如果没有 BE 节点宕机,则需要通过 show tablet 110309738 语句,然后执行结果中的 show proc 语句,查看 tablet 各个副本的情况,进一步排查。

Q6. disk xxxxx on backend xxx exceed limit usage

通常出现在导入、Alter 等操作中。这个错误意味着对应 BE 的对应磁盘的使用量超过了阈值(默认 95%)此时可以先通过 show backends 命令,其中 MaxDiskUsedPct 展示的是对应 BE 上,使用率最高的那块磁盘的使用率,如果超过 95%,则会报这个错误。

此时需要前往对应 BE 节点,查看数据目录下的使用量情况。其中 trash 目录和 snapshot 目录可以手动清理以释放空间。如果是 data 目录占用较大,则需要考虑删除部分数据以释放空间了。具体可以参阅磁盘空间管理

Q7. 通过 Java 程序调用 stream load 导入数据,在一批次数据量较大时,可能会报错 Broken Pipe

除了 Broken Pipe 外,还可能出现一些其他的奇怪的错误。

这个情况通常出现在开启 httpv2 后。因为 httpv2 是使用 spring boot 实现的 http 服务,并且使用 tomcat 作为默认内置容器。但是 tomcat 对 307 转发的处理似乎有些问题,所以后面将内置容器修改为了 jetty。此外,在 java 程序中的 apache http client 的版本需要使用 4.5.13 以后的版本。之前的版本,对转发的处理也存在一些问题。

所以这个问题可以有两种解决方式:

  1. 关闭 httpv2

    在 fe.conf 中添加 enable_http_server_v2=false 后重启 FE。但是这样无法再使用新版 UI 界面,并且之后的一些基于 httpv2 的新接口也无法使用。(正常的导入查询不受影响)。

  2. 升级

    可以升级到 Doris 0.15 及之后的版本,已修复这个问题。

Q8. 执行导入、查询时报错 -214

在执行导入、查询等操作时,可能会遇到如下错误:

failed to initialize storage reader. tablet=63416.1050661139.aa4d304e7a7aff9c-f0fa7579928c85a0, res=-214, backend=192.168.100.10

-214 错误意味着对应 tablet 的数据版本缺失。比如如上错误,表示 tablet 63416 在 192.168.100.10 这个 BE 上的副本的数据版本有缺失。(可能还有其他类似错误码,都可以用如下方式进行排查和修复)。

通常情况下,如果你的数据是多副本的,那么系统会自动修复这些有问题的副本。可以通过以下步骤进行排查:

首先通过 show tablet 63416 语句并执行结果中的 show proc xxx 语句来查看对应 tablet 的各个副本情况。通常我们需要关心 Version 这一列的数据。

正常情况下,一个 tablet 的多个副本的 Version 应该是相同的。并且和对应分区的 VisibleVersion 版本相同。

你可以通过 show partitions from tblx 来查看对应的分区版本(tablet 对应的分区可以在 show tablet 语句中获取。)

同时,你也可以访问 show proc 语句中的 CompactionStatus 列中的 URL(在浏览器打开即可)来查看更具体的版本信息,来检查具体丢失的是哪些版本。

如果长时间没有自动修复,则需要通过 show proc "/cluster_balance" 语句,查看当前系统正在执行的 tablet 修复和调度任务。可能是因为有大量的 tablet 在等待被调度,导致修复时间较长。可以关注 pending_tabletsrunning_tablets 中的记录。

更进一步的,可以通过 admin repair 语句来指定优先修复某个表或分区,具体可以参阅 help admin repair;

如果依然无法修复,那么在多副本的情况下,我们使用 admin set replica status 命令强制将有问题的副本下线。具体可参阅 help admin set replica status 中将副本状态置为 bad 的示例。(置为 bad 后,副本将不会再被访问。并且会后续自动修复。但在操作前,应先确保其他副本是正常的)

Q9. Not connected to 192.168.100.1:8060 yet, server_id=384

在导入或者查询时,我们可能遇到这个错误。如果你去对应的 BE 日志中查看,也可能会找到类似错误。

这是一个 RPC 错误,通常有两种可能:1. 对应的 BE 节点宕机。2. rpc 拥塞或其他错误。

如果是 BE 节点宕机,则需要查看具体的宕机原因。这里只讨论 rpc 拥塞的问题。

一种情况是 OVERCROWDED,即表示 rpc 源端有大量未发送的数据超过了阈值。BE 有两个参数与之相关:

  1. brpc_socket_max_unwritten_bytes:默认 1GB,如果未发送数据超过这个值,则会报错。可以适当修改这个值以避免 OVERCROWDED 错误。(但这个治标不治本,本质上还是有拥塞发生)。
  2. tablet_writer_ignore_eovercrowded:默认为 false。如果设为 true,则 Doris 会忽略导入过程中出现的 OVERCROWDED 错误。这个参数主要为了避免导入失败,以提高导入的稳定性。

第二种是 rpc 的包大小超过 max_body_size。如果查询中带有超大 String 类型,或者 bitmap 类型时,可能出现这个问题。可以通过修改以下 BE 参数规避:

brpc_max_body_size:默认 3GB.

Q10. [ Broker load ] org.apache.thrift.transport.TTransportException: java.net.SocketException: Broken pipe

出现这个问题的原因可能是到从外部存储(例如 HDFS)导入数据的时候,因为目录下文件太多,列出文件目录的时间太长,这里 Broker RPC Timeout 默认是 10 秒,这里需要适当调整超时时间。

修改 fe.conf 配置文件,添加下面的参数:

broker_timeout_ms = 10000
##这里默认是10秒,需要适当加大这个参数

这里添加参数,需要重启 FE 服务。

Q11.[ Routine load ] ReasonOfStateChanged: ErrorReason{code=errCode = 104, msg='be 10004 abort task with reason: fetch failed due to requested offset not available on the broker: Broker: Offset out of range'}

出现这个问题的原因是因为 kafka 的清理策略默认为 7 天,当某个 routine load 任务因为某种原因导致任务暂停,长时间没有恢复,当重新恢复任务的时候 routine load 记录了消费的 offset,而 kafka 的清理策略已经清理了对应的 offset,就会出现这个问题

所以这个问题可以用 alter routine load 解决方式:

查看 kafka 最小的 offset ,使用 ALTER ROUTINE LOAD 命令修改 offset,重新恢复任务即可

ALTER ROUTINE LOAD FOR db.tb
FROM kafka
(
"kafka_partitions" = "0",
"kafka_offsets" = "xxx",
"property.group.id" = "xxx"
);

Q12. ERROR 1105 (HY000): errCode = 2, detailMessage = (192.168.90.91)[CANCELLED][INTERNAL_ERROR]error setting certificate verify locations: CAfile: /etc/ssl/certs/ca-certificates.crt CApath: none

yum install -y ca-certificates
ln -s /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt /etc/ssl/certs/ca-certificates.crt

Q13. create partition failed. partition numbers will exceed limit variable max_auto_partition_num

对自动分区表导入数据时,为防止意外创建过多分区,我们使用了 FE 配置项max_auto_partition_num管控此类表自动创建时的最大分区数。如果确需创建更多分区,请修改 FE master 节点的该配置项。

Q14. Doris 在使用 Select Into Outfile 导出文件到本地时,是否可以导出到指定 BE 所在服务器?

不可以。使用 Select Into Outfile 导出文件到本地时,会随机导出到某个本地路径,不支持导出到指定路径。更多关于 Select Into Outfile 的信息,可参考 Select Into Outfile