Apache Doris 副本故障排查与修复实战指南

Apache Doris 副本故障排查与修复实战指南

前言

在使用 Apache Doris 作为时序数据存储时,生产环境偶发以下报错:

复制代码
java.sql.SQLException: errCode = 2, detailMessage = Failed to get scan range, 
no queryable replica found in tablet: 8935003. 
Reason: Visible Replicas:Visible version: 53409, 
Replicas: [replicaId=8935004, backendId=10004, backendAlive=true, 
version=53409, lastFailedVersion=53410, lastSuccessVersion=53409, 
lastFailedTimestamp=1773297614783, state=NORMAL]

本文系统梳理该报错的根因分析、排查流程与修复方案。


一、错误解读

拆解错误信息中的关键字段:

字段 含义
tablet 8935003 问题 Tablet ID
backendAlive true BE 节点存活
version 53409 副本当前版本
lastSuccessVersion 53409 最后一次成功同步版本
lastFailedVersion 53410 在 53410 版本同步失败
lastFailedTimestamp 1773297614783 失败时间戳
state NORMAL 副本状态标记为正常

核心矛盾:

version == lastSuccessVersion < lastFailedVersion

副本在版本 53410 的数据写入失败,且未能自动修复。虽然 backendAlive=truestate=NORMAL,但 Doris FE 判定该副本不可查询,导致整个 Tablet 无可用副本,查询直接报错。


二、根因分析

2.1 常见触发场景

复制代码
数据写入 → Tablet 53410 版本刷盘 → BE 磁盘 IO 异常 / 内存不足
                                    → Compaction 失败
                                    → 网络抖动导致副本同步中断
                                    → BE 进程重启,WAL 未完整回放

2.2 副本版本落后的影响链

复制代码
lastFailedVersion > version
        ↓
FE 标记副本不可查询(non-queryable)
        ↓
Tablet 无 queryable replica
        ↓
查询报 "no queryable replica found"
        ↓
业务查询全部失败

2.3 为何 ADMIN REPAIR 不一定立即生效

Doris 的副本修复依赖后台 TabletChecker 线程周期性扫描,默认检查间隔为 5 分钟。触发修复后需等待:

  1. FE 检测到副本异常
  2. 生成 Clone 任务,从健康副本复制数据
  3. 版本追平,重新标记为 queryable

三、排查流程

Step 1:定位问题 Tablet 详情

sql 复制代码
-- 查看 Tablet 所在表、分区、副本详情
SHOW TABLET 8935003;

返回结果关注:

  • DbName / TableName / PartitionName --- 定位问题范围
  • State --- 副本状态
  • LstFailedVer --- 失败版本号

Step 2:检查 BE 节点状态

sql 复制代码
-- 查看所有 BE 节点健康状态
SHOW BACKENDS;

重点关注:

  • Alive 是否为 true
  • TabletNum 是否异常偏高
  • LastStartTime --- 是否近期有重启

Step 3:检查表的副本分布

sql 复制代码
-- 查看表的 Tablet 整体状态
SHOW TABLET FROM huazhiqiao_db.plc_point_data;

-- 过滤出不健康副本
SELECT * FROM information_schema.tablets 
WHERE TABLE_NAME = 'plc_point_data' 
  AND tablet_state != 'NORMAL';

Step 4:查看 FE/BE 日志

bash 复制代码
# FE 日志 --- 查找副本修复相关
grep "8935003\|TabletChecker\|replica.*failed" fe/log/fe.log | tail -50

# BE 日志 --- 查找 Compaction / IO 错误
grep "8935003\|compaction.*failed\|disk.*error" be/log/be.WARNING | tail -50

四、修复方案

方案一:触发系统自动修复(推荐首选)

sql 复制代码
-- 触发 FE 对指定表分区的副本修复
ADMIN REPAIR TABLE huazhiqiao_db.plc_point_data 
PARTITION p20250511;

-- 5 分钟后验证副本是否追平
SHOW TABLET 8935003;
-- 期望:lastFailedVersion = -1,version 追上最新

方案二:删除损坏分区(数据可丢弃时)

适用于时序场景下历史分区数据已过期、无需保留的情况。

sql 复制代码
-- Step 1:关闭动态分区(防止操作期间自动建分区干扰)
ALTER TABLE huazhiqiao_db.plc_point_data 
SET ("dynamic_partition.enable" = "false");

-- Step 2:确认分区名称
SHOW PARTITIONS FROM huazhiqiao_db.plc_point_data;

-- Step 3:删除问题分区
ALTER TABLE huazhiqiao_db.plc_point_data 
DROP PARTITION p20250511;

-- Step 4:重新启用动态分区
ALTER TABLE huazhiqiao_db.plc_point_data 
SET ("dynamic_partition.enable" = "true");

方案三:删除前先备份(数据需保留时)

sql 复制代码
-- Step 1:备份问题分区数据
CREATE TABLE plc_point_data_backup_p20250511
AS SELECT * FROM huazhiqiao_db.plc_point_data 
PARTITION (p20250511);

-- Step 2:确认备份行数
SELECT COUNT(*) FROM plc_point_data_backup_p20250511;

-- Step 3:再执行方案二的删除流程

方案四:手动设置副本状态(高级操作,谨慎使用)

sql 复制代码
-- 将问题副本标记为 bad,触发重新 Clone
ADMIN SET REPLICA STATUS 
PROPERTIES(
  "tablet_id" = "8935003", 
  "backend_id" = "10004", 
  "status" = "bad"
);

注意: 此操作会触发副本重建,期间该副本不可用,确保集群有其他健康副本再执行。


五、修复验证

sql 复制代码
-- 1. 检查 Tablet 副本版本是否追平
SHOW TABLET 8935003;
-- 期望:lastFailedVersion = -1

-- 2. 检查表查询是否恢复
SELECT COUNT(*) 
FROM huazhiqiao_db.plc_point_data 
WHERE ts >= '2025-05-11 00:00:00' 
  AND ts < '2025-05-12 00:00:00';

-- 3. 查看集群整体不健康 Tablet 数量
SHOW PROC '/statistic';
-- 关注 UnhealthyTabletNum 是否归零

六、预防措施

6.1 动态分区合理配置

针对时序场景,建议限制历史分区保留数量,避免分区过多导致 Tablet 数量膨胀:

sql 复制代码
ALTER TABLE huazhiqiao_db.plc_point_data SET (
  "dynamic_partition.enable"          = "true",
  "dynamic_partition.time_unit"       = "DAY",
  "dynamic_partition.start"           = "-30",   -- 保留近 30 天
  "dynamic_partition.end"             = "3",      -- 提前建 3 天
  "dynamic_partition.prefix"          = "p",
  "dynamic_partition.buckets"         = "8",
  "dynamic_partition.replication_num" = "3"       -- 3 副本保障可用性
);

6.2 副本数建议

场景 推荐副本数 原因
生产时序数据 3 允许 1 副本故障仍可读写
历史冷数据 2 降低存储成本
单机测试 1 节省资源

6.3 监控告警配置

建议对以下指标配置告警:

sql 复制代码
-- 定期巡检不健康 Tablet
SELECT 
  TABLE_SCHEMA,
  TABLE_NAME,
  COUNT(*) AS unhealthy_tablet_count
FROM information_schema.tablets
WHERE tablet_state != 'NORMAL'
GROUP BY TABLE_SCHEMA, TABLE_NAME
HAVING COUNT(*) > 0;

将上述 SQL 接入定时任务(如每 10 分钟执行一次),发现 unhealthy_tablet_count > 0 立即告警。


七、总结

场景 推荐方案
单个 Tablet 版本落后,BE 存活 ADMIN REPAIR TABLE + 等待自动修复
时序历史分区,数据已过期 直接 DROP PARTITION
数据需保留,分区异常 备份后删除分区,重新导入
多副本均异常,BE 磁盘故障 先修复 BE,再触发副本修复
紧急恢复查询可用性 临时降低副本要求 + 删除异常分区

核心结论:

lastFailedVersion > lastSuccessVersion 是 Doris 副本不可查询的直接原因。优先通过 ADMIN REPAIR 触发自动修复;时序场景下过期分区可直接删除,以最低成本恢复服务。

相关推荐
一个天蝎座 白勺 程序猿9 小时前
Apache IoTDB(18):IoTDB时序数据库的数据同步之Pipe机制与插件同步指南
数据库·apache·时序数据库·iotdb
老徐电商数据笔记12 小时前
一个典型的基于 Apache Paimon 的湖仓一体架构图
apache·湖仓一体·paimon·湖仓
pangares1 天前
防火墙安全策略(基本配置)
服务器·php·apache
Hello.Reader1 天前
Apache Flink 2.2.0 源码编译从环境准备到 PyFlink 打包一次讲清
大数据·flink·apache
青衫客361 天前
浅谈 Apache POI:XSSFWorkbook 的原理与实践(Java 操作 Excel 实践指南)
java·apache·excel
DolphinScheduler社区1 天前
Apache DolphinScheduler 3.4.1 发布,新增任务分发超时检测
java·数据库·开源·apache·海豚调度·大数据工作流调度
吴声子夜歌1 天前
小程序——开放接口(登录和用户信息)详解
小程序·apache
倔强的石头1062 天前
工业平台选型指南:权限、审计与多租户治理——用 Apache IoTDB 把“数据可用”升级为“数据可控”
人工智能·apache·iotdb
SeaTunnel2 天前
Apache SeaTunnel 2.3.13 版本前瞻:核心引擎变化和 AI ETL 趋势值得关注
数据仓库·人工智能·apache·etl·seatunnel·数据同步