--- title: "创建 Rollup 索引失败 - 如何解决此 Elasticsearch 异常" date: 2026-04-04 lastmod: 2026-04-04 description: "Failed to create rollup index [rollupIndexName] 表示 Rollup 作业在创建目标索引时没有得到成功确认,排查应聚焦目标索引创建流程及其后续补偿删除逻辑。" tags: ["rollup", "index", "ElasticsearchException"] summary: "适用版本: 7.17-8.9 1. 错误异常的基本描述 # Failed to create rollup index [rollupIndexName] 表示 Elasticsearch 在执行 Rollup 作业时,尝试为目标 Rollup 数据创建索引,但索引创建请求未收到成功确认,导致整个 Rollup 任务失败。 Rollup 是 Elasticsearch 中用于将数据从原始索引按时间粒度聚合后写入新索引的功能,常用于降低存储成本、保留历史趋势数据。该异常发生在 Rollup 作业执行流程的索引创建阶段,而非后续的聚合计算阶段。 常见现象 # Rollup 作业状态变为 failed,任务无法正常完成。 目标 Rollup 索引可能不存在,或存在但数据不完整。 Elasticsearch 日志中出现 Failed to create rollup index [xxx] 异常信息。 如果触发了补偿逻辑,可能会看到后续的 deleteRollupIndex 相关日志。 在 Kibana 的 Rollup Jobs 管理界面中,对应作业显示为失败状态。 典型报错与异常栈 # ElasticsearchException: Failed to create rollup index [rollup-logs-2026-06] Caused by: ElasticsearchException: Unable to index into rollup index [rollup-logs-2026-06] at org." --- > **适用版本:** 7.17-8.9 ## 1. 错误异常的基本描述 `Failed to create rollup index [rollupIndexName]` 表示 Elasticsearch 在执行 Rollup 作业时,尝试为目标 Rollup 数据创建索引,但索引创建请求未收到成功确认,导致整个 Rollup 任务失败。 Rollup 是 Elasticsearch 中用于将数据从原始索引按时间粒度聚合后写入新索引的功能,常用于降低存储成本、保留历史趋势数据。该异常发生在 Rollup 作业执行流程的**索引创建阶段**,而非后续的聚合计算阶段。 ### 常见现象 - Rollup 作业状态变为 `failed`,任务无法正常完成。 - 目标 Rollup 索引可能不存在,或存在但数据不完整。 - Elasticsearch 日志中出现 `Failed to create rollup index [xxx]` 异常信息。 - 如果触发了补偿逻辑,可能会看到后续的 `deleteRollupIndex` 相关日志。 - 在 Kibana 的 Rollup Jobs 管理界面中,对应作业显示为失败状态。 ### 典型报错与异常栈 ```text ElasticsearchException: Failed to create rollup index [rollup-logs-2026-06] Caused by: ElasticsearchException: Unable to index into rollup index [rollup-logs-2026-06] at org.elasticsearch.xpack.rollup.action.RollupIndexer.lambda$createRollupIndex$... ``` ## 2. 为什么会发生这个错误 Rollup 索引创建是一个多步骤流程:先创建目标索引,再执行数据写入。如果其中任何一步失败,都会触发该异常。结合源码逻辑,常见原因包括: ### 索引创建阶段失败 - **索引名冲突**:目标 Rollup 索引已存在,且可能与现有索引的 mapping 不兼容。 - **权限不足**:执行 Rollup 作业的用户没有创建索引的权限(`create_index` 权限)。 - **模板不兼容**:索引模板中定义的 mapping 与 Rollup 预期写入的字段类型冲突。 - **磁盘空间不足**:目标节点磁盘水位达到 `cluster.routing.allocation.disk.watermark` 阈值,导致分片无法分配。 - **分片分配失败**:没有可用节点满足分片分配条件(如节点属性过滤、机架感知配置等)。 ### 索引创建后写入阶段失败 - **Mapping 冲突**:Rollup 聚合结果中的字段类型与目标索引 mapping 不匹配。 - **索引被意外删除**:在创建成功之后、写入完成之前,索引被外部操作删除,触发补偿删除逻辑。 - **写入权限问题**:索引创建成功但后续写入时权限被回收或角色变更。 - **索引处于只读状态**:目标索引被设置为 `index.blocks.write: true`,导致无法写入。 ### 补偿逻辑触发的连锁问题 从源码可以看出,Rollup 设计了补偿机制:如果索引创建成功但后续写入失败,会主动调用 `deleteRollupIndex` 删除已创建的索引。这意味着即使索引创建本身成功,只要后续写入失败,最终也会表现为"创建失败"。 ## 3. 如何排查这个异常 建议按以下顺序进行排查: ### 第一步:确认失败发生的具体阶段 查看 Elasticsearch 日志,确认异常发生在索引创建确认阶段,还是创建后的首次写入阶段: ```bash # 搜索相关日志 grep -E "Failed to create rollup index|Unable to index into rollup index|deleteRollupIndex" /var/log/elasticsearch/elasticsearch.log ``` ### 第二步:检查目标索引状态 ```bash # 检查目标索引是否存在 curl -X GET "localhost:9200/rollup-logs-2026-06?pretty" # 检查索引是否为只读状态 curl -X GET "localhost:9200/rollup-logs-2026-06/_settings?pretty" # 检查索引 mapping curl -X GET "localhost:9200/rollup-logs-2026-06/_mapping?pretty" ``` ### 第三步:检查索引模板和权限 ```bash # 查看是否有相关索引模板 curl -X GET "localhost:9200/_index_template?pretty" # 查看用户权限(通过 Kibana 或 Elasticsearch 安全 API) curl -X GET "localhost:9200/_security/user/?pretty" ``` ### 第四步:检查集群健康状态和磁盘空间 ```bash # 查看集群健康状态 curl -X GET "localhost:9200/_cluster/health?pretty" # 查看磁盘使用情况 curl -X GET "localhost:9200/_cat/allocation?v" # 查看分片分配详情 curl -X GET "localhost:9200/_cluster/allocation/explain?pretty" ``` ### 排查时需要注意的问题 - 不要只看最终报错,要关注日志中是否有 `Unable to index into rollup index` 等前置错误。 - 如果系统进行了自动删除回滚,需要核对删除前后索引状态,避免重复创建带来残留问题。 - Rollup 作业可能是定时触发的,需要确认失败时间点是否有集群维护、重启或配置变更。 ## 4. 如何解决这个错误 ### 常用修复思路 **1. 手动验证目标索引能否独立创建** 先尝试手动创建目标索引,确认索引创建本身没有问题: ```bash curl -X PUT "localhost:9200/rollup-logs-2026-06" -H 'Content-Type: application/json' -d ' { "settings": { "number_of_shards": 1, "number_of_replicas": 0 } } ' ``` **2. 检查并修正索引模板冲突** 如果索引模板导致 mapping 冲突,需要更新或删除冲突的模板: ```bash # 查看具体模板内容 curl -X GET "localhost:9200/_index_template/rollup-template?pretty" # 删除冲突的模板(谨慎操作) curl -X DELETE "localhost:9200/_index_template/rollup-template" ``` **3. 确保磁盘空间充足** ```bash # 清理旧索引或扩大磁盘 curl -X DELETE "localhost:9200/old-index-*" # 临时调整磁盘水位线(不推荐长期使用) curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d ' { "transient": { "cluster.routing.allocation.disk.watermark.low": "90%", "cluster.routing.allocation.disk.watermark.high": "95%" } } ' ``` **4. 检查并修正索引只读状态** ```bash # 解除索引只读状态 curl -X PUT "localhost:9200/rollup-logs-2026-06/_settings" -H 'Content-Type: application/json' -d ' { "index.blocks.write": false } ' ``` **5. 重新启动 Rollup 作业** ```bash # 查看 Rollup 作业状态 curl -X GET "localhost:9200/_rollup/job?pretty" # 停止失败的作业 curl -X POST "localhost:9200/_rollup/job//_stop" # 重新启动作业 curl -X POST "localhost:9200/_rollup/job//_start" ``` ### 后续注意事项与推荐建议 - 在创建 Rollup 作业前,先手动验证目标索引的创建和写入流程是否正常。 - 为 Rollup 目标索引使用独立的索引模板,避免与其他业务索引模板冲突。 - 监控磁盘空间,设置合理的磁盘水位线告警,避免因磁盘问题导致 Rollup 失败。 - 对 Rollup 作业配置合理的重试策略,避免因偶发问题导致作业持续失败。 - 保留完整的作业日志,方便区分创建失败与写入失败,缩短排障时间。 ### 借助 INFINI 产品提升排障效率 - [INFINI Console](https://docs.infinilabs.com/console/main/) 适合查看集群健康度、节点指标、索引状态、Rollup 作业执行历史和错误趋势,帮助快速判断异常是局部问题还是系统性问题。 - [INFINI Gateway](https://docs.infinilabs.com/gateway/main/) 适合部署在 Elasticsearch 前面做请求观测、限流和流量治理,尤其适合定位 Rollup 作业触发的高频写入请求和异常重试。 - 建议将 Rollup 作业的执行状态、失败原因和索引创建情况统一接入监控面板,实现主动告警和快速响应。 ## 5. 小结 `Failed to create rollup index [rollupIndexName]` 异常的核心是 Rollup 目标索引创建链路没有闭环成功。修复时需要同时关注"创建是否确认"和"创建后首次写入是否成功"两个阶段。大多数情况下,问题根源在于索引模板冲突、权限不足、磁盘空间不足或分片分配失败,通过系统性的排查和验证可以快速定位并解决。 ## 相关错误 - [创建安全索引失败](/knowledge-base/elasticsearch_error/failed-to-create-security-index-how-to-solve-this-elasticsearch-exception/) - [为解析别名创建临时索引失败](/knowledge-base/elasticsearch_error/failed-to-create-temporary-index-for-parsing-the-alias-how-to-solve-this-elasticsearch-exception/) - [创建 Repository 失败](/knowledge-base/elasticsearch_error/failed-to-create-repository-how-to-solve-this-elasticsearch-exception/) ## 附:日志上下文 下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题: ```java new ElasticsearchException("Unable to index into rollup index [" + rollupIndexName + "]") ); } }; e -> deleteRollupIndex(sourceIndexName; rollupIndexName; parentTask; listener; e))); } else { listener.onFailure(new ElasticsearchException("Failed to create rollup index [" + rollupIndexName + "]")); } }; listener::onFailure)); }; listener::onFailure)); } ```