wanggx commented on issue #69816:
URL: https://github.com/apache/doris/issues/69816#issuecomment-6791940222
# ANN 索引不一致问题(issue #69816)时间线
本文档记录 Doris 4.1.5 **HNSW 索引多副本不一致致查询负载静默倾斜**(GitHub apache/doris issue
#69816)从数据准备、问题触发、定位、修复到验证的完整时间线,所有时间节点来自
[vectordbbench-768d10m-3be-result.md](vectordbbench-768d10m-3be-result.md)
记录的真实操作时刻 + BE 日志时间戳,精确到分钟/秒。
## 操作机器说明
| 机器 | 角色 | 在本问题中的操作 |
| --- | --- | --- |
| 10.201.1.104 | FE(master,单节点) | 副本调度、元数据、`show tablets`/`SHOW PROC`
查询、fe.log 记录 |
| 10.201.1.110 | BE-1 | 副本之一,索引旧(VersionNum=14),full compaction 修复对象 |
| 10.201.1.131 | BE-2 | 副本之一,索引新(VersionNum=21),独扛查询;LAION-100M 数据集下载位置 |
| 10.201.1.231 | BE-3 | 副本之一,索引旧(VersionNum=12),full compaction 修复对象 |
| 10.201.1.232 | VectorDBBench 压测客户端 | 跑导入/查询压测(`run_1bucket.sh`) |
表:`vdb10m1b.performance768d10m`,1 bucket 3 副本,tablet `1793183900055`,10M
Cohere 768d,HNSW 128/256 + `hnsw_ef_search=100` + cosine。
## 完整时间线
### 第一阶段:数据集导入(1 桶 3 副本对照表)
| 操作 | 实际时间节点 | 操作机器 | 备注 |
| --- | --- | --- | --- |
| 1 桶表分批 INSERT INTO SELECT 启动 | **2026-10-28 23:23** | 客户端 232 → BE
110/131/231 | 20 批 × 50 万,按 id 范围分批,每批 memtable ~1.5GB 避 OOM |
| 1 桶表导入完成(COUNT=1000 万,version 21) | **2026-10-29 01:32** | BE 110/131/231
| 跨度约 2h9min,产 20 个独立 rowset,3 副本全 OK |
| 导入后建图(HNSW 索引随 segment flush 同步构建) | 23:23 → 01:32 期间 | BE 110/131/231 |
建表 DDL 即指定 `INDEX idx_embedding USING ANN`,导入即建图,无需事后 CREATE INDEX |
> **注**:1 桶表(每 BE 常驻全量 50GB HNSW 索引)是为排除 bucket 数差异(官方 1 桶 vs 我们 3
桶)而建的对照表。导入路径此前已踩过两个坑:①单事务 INSERT INTO SELECT 单 BE memtable 集中 OOM;②分批导入后查询
recall=0(实为 ann_search OOM,非索引未生效——见 3be 文档"尝试 2"根因排查)。
### 第二阶段:问题触发(BE 重启)
| 操作 | 实际时间节点 | 操作机器 | 备注 |
| --- | --- | --- | --- |
| 3 BE 重启(模拟运维/升级)——问题触发点 | **2026-10-29 11:11** | BE 110/131/231;FE 104 记录
| fe.log 记录 tablet `REPLICA_MISSING`、110/231 `isAlive=false` |
| 110/231 tablet 子目录最后修改时间 | **10-28 20:53**(重启后无变化) | BE 110/231 | 索引文件
mtime 停在重启前,重启后无 ann_index_writer 日志 |
| 131 重启后 ann_index_writer 持续 rebuild | **11:49 → 12:23** | BE 131 |
cumulative point=3 低,持续 compaction + 重建 HNSW,VersionNum 推进到 21 |
| 110/231 重启后 compaction 双卡死 | 重启后全程 | BE 110/231 | cumulative
`candidate_rowsets is empty`(point=22 > 数据 max version)+ base
`_input_rowsets.size() is 1` |
### 第三阶段:问题定位(根因确认,4 次归因修正)
| 操作 | 实际时间节点 | 操作机器 | 备注 |
| --- | --- | --- | --- |
| 副本选择源码 + 运行时实测(默认随机却全落 131) | **2026-10-29 12:xx** | 客户端 232 → 3 BE |
`use_fix_replica=0/1/2` 全落 131,证 `getQueryableReplicas` 只返 131 |
| 重启实验 + 逐步停 BE 定位 | **2026-10-29 13:xx** | 停 131/231 | 推翻"110/231 不可选" |
| 停 131+231,查询落 110(fragment 执行铁证) | **14:02:59 / 14:03:33 / 14:03:54** | BE
110 | be.INFO 三条 fragment start execution,21s/条成功 |
| 3 BE 全在时段 fragment cancel 回退铁证 | **13:18:08 / 13:19:49 / 13:22:54 /
13:24:35**(231 cancel)+ **13:18:07**(131 执行) | BE 231 / 131 | 231 cancel 的 4 个
query_id 全在 131 be.INFO 有对应执行日志 |
| BUILD INDEX 尝试(0ms 无效) | **14:09** | BE 110/131 | `_input_rowsets is
empty`,只 build 新 rowset 不重建旧索引 |
| `SHOW BUILD INDEX` 显示任务 CANCELLED | 14:09 触发,失败 10 次达阈值 | BE 131 |
`OBTAIN_LOCK_FAILED`(compaction 抢锁),JobId 1793250767903 |
| 索引不一致修复方案 + SHOW PROC 可观测性分析 | **2026-10-29 15:xx** | FE 104 | `SHOW PROC`
下钻 5 层能看到 VersionCount 12/14/21 不一致 |
| 131+231 重启恢复,3 BE 全在仍全落 131 | **14:31 alive** | BE 131/231 | 131
重启后索引也冷(20s/条),但仍被选——因索引完整可用 |
### 第四阶段:full compaction 修复
| 操作 | 实际时间节点 | 操作机器 | 备注 |
| --- | --- | --- | --- |
| 对 110 触发 full compaction(`compact_type=full&force=true`) | **15:09:13 启动**
| BE 110 | `POST /api/compaction/run`,绕过 cumulative/base 分层 |
| 对 231 触发 full compaction | 15:09 同步触发 | BE 231 | — |
| 110 full compaction 完成(25 segment,~90 分钟) | **16:39:53** | BE 110 | 每段
~3.5min,6 线程 faiss_build_idx 满载 |
| 231 full compaction 完成 | **16:46:50** | BE 231 | — |
| 3 副本 VersionCount 全对齐 = 1(`show tablets` 实测) | **16:48** | FE 104 | 修复前
1/14/12 → 修复后 全 1,compaction 状态机分裂修复 |
### 第五阶段:修复后验证 + issue 落盘
| 操作 | 实际时间节点 | 操作机器 | 备注 |
| --- | --- | --- | --- |
| 修复后压测(full1/qB/qC 三轮) | **2026-10-29 17:19-17:41** | 客户端 232 | 参数与 154 QPS
那次完全对齐 |
| BestQPS 154 → **345.19**(翻倍,vs 官方 71.6%) | 17:41 后取 qC 稳态 | 客户端 232 |
recall 98.70% 无损,三 BE 负载均匀分摊 |
| issue 文档首次 git 提交 | **2026-10-29 19:34:04** | 本地 git(commit `189bdee69`) |
docs/千万级/doris-ann-index-consistency-issue.md |
## 因果链闭合
```
10-28 23:23 1桶对照表导入(产 20 rowset,version 21)
10-29 01:32 导入完成,3副本索引一致
10-29 11:11 3 BE 重启 —— 问题触发
│
├─ 131 cumulative point=3 → 持续 compaction + rebuild(11:49-12:23)→ 索引新
VersionNum=21
└─ 110/231 cumulative point=22 > 数据 max version
→ cumulative candidate_rowsets is empty + base
_input_rowsets.size() is 1 双卡死
→ HNSW 索引停滞旧版本(VersionNum=14/12)
│
10-29 12:xx FE 默认 shuffle 却全落 131(use_fix_replica=0/1/2 实测)
10-29 13:18-13:25 231 收到 SELECT fragment 但索引旧执行失败 → cancel → 131 执行成功(铁证)
10-29 14:02-14:03 停 131+231 → 110 能执行(推翻"不可选"),因果链闭合
10-29 14:09 BUILD INDEX 无效(0ms,只 build 新 rowset)
│
└─ 根因:3 副本 HNSW 索引不一致(不是副本选择机制问题)
10-29 15:09 对 110/231 触发 full compaction(绕过分层,合并所有 rowset + 重置 cumulative
point + 重建索引)
10-29 16:39:53 110 full compaction 完成,VersionCount 14 → 1
10-29 16:46:50 231 full compaction 完成,VersionCount 12 → 1
10-29 16:48 3 副本 VersionCount 全对齐 = 1
10-29 17:19-17:41 修复后压测:QPS 154→345 翻倍,三 BE 均匀分摊,因果链闭合
10-29 19:34 issue #69816 文档落盘提交
```
## 关键时间节点速查
| 节点 | 时刻 |
| --- | --- |
| 导入启动 | 10-28 23:23 |
| 导入完成 | 10-29 01:32 |
| BE 重启(触发点) | 10-29 11:11 |
| 131 rebuild | 10-29 11:49-12:23 |
| 回退铁证时段 | 10-29 13:18-13:25 |
| 停 BE 实验 | 10-29 14:02-14:03 |
| BUILD INDEX 尝试 | 10-29 14:09 |
| full compaction 启动 | 10-29 15:09:13 |
| 110 修复完成 | 10-29 16:39:53 |
| 231 修复完成 | 10-29 16:46:50 |
| VersionCount 对齐 | 10-29 16:48 |
| 修复后压测 | 10-29 17:19-17:41 |
| issue 文档提交 | 10-29 19:34:04 |
## 相关文档
-
[doris-ann-index-consistency-issue.md](doris-ann-index-consistency-issue.md) —
issue #69816 正文(复现步骤、证据链、建议)
- [vectordbbench-768d10m-3be-result.md](vectordbbench-768d10m-3be-result.md)
— 3 BE 10M 测试全文(含 4 次归因修正过程、完整实测数据)
## 附件:3 台 BE 完整原始日志(10-28/10-29 两天,public-read)
为便于社区复现/验证,上传 3 台 BE 在 2026-10-28/10-29 两个完整天的 `be.INFO` + `be.WARNING`
原始日志(按日期切分,未做关键字过滤),已上传 KS3 公开可下载:
| 机器 | 对应 issue 中的角色 | 下载链接 | 大小 |
| --- | --- | --- | --- |
| 10.201.1.131 | BE-A(索引新,VersionNum=21) |
http://deploy-dev.ks3-cn-beijing.ksyun.com/pkgs/base/doris-ann-issue-logs/be131_logs.tar.gz
| 96.9 MB |
| 10.201.1.110 | BE-B(索引旧,VersionNum=14) |
http://deploy-dev.ks3-cn-beijing.ksyun.com/pkgs/base/doris-ann-issue-logs/be110_logs.tar.gz
| 94.5 MB |
| 10.201.1.231 | BE-C(索引旧,VersionNum=12) |
http://deploy-dev.ks3-cn-beijing.ksyun.com/pkgs/base/doris-ann-issue-logs/be231_logs.tar.gz
| 84.4 MB |
每个 tar.gz 解压后含 3 个文件:`<be>_raw_1028.log`(10-28 整天
be.INFO)、`<be>_raw_1029.log`(10-29 整天 be.INFO)、`<be>_raw_warn.log`(10-28/10-29
两天 be.WARNING)。日志区间已校验:be.INFO 首尾精确卡在 `00:00:00 → 23:59:5x`,无跨天污染/截断。
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]