📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 7.8-7.17

1. 错误异常的基本描述 #

aborted on initialization 是 Elasticsearch 在执行快照过程中抛出的异常。当快照任务在初始化阶段失败时,Elasticsearch 会中止该快照并将其标记为失败。这通常发生在快照刚开始执行时,遇到了无法恢复的问题,如仓库不可用、主节点变更、分片分配失败等。

常见现象 #

  • Elasticsearch 返回 HTTP 500 Internal Server Error409 Conflict 状态码。
  • 创建快照的请求(PUT _snapshot/<repo>/<snapshot>)失败,快照状态为 FAILED
  • 在 Elasticsearch 服务端日志中会记录 SnapshotException 和 “Aborted on initialization” 信息。
  • 如果是通过定时任务(SLM)或自动化脚本创建快照,会导致后续快照任务失败或仓库状态异常。
  • 可能导致集群状态不一致,影响后续的快照和恢复操作。

典型报错与异常栈 #

该异常的典型日志形态如下:

SnapshotException: [snapshot_name] aborted on initialization
    at org.elasticsearch.snapshots.SnapshotsService.createSnapshot(SnapshotsService.java:...)
    at org.elasticsearch.action.admin.cluster.SnapshotsStatusTransportAction.shardOperation(SnapshotsStatusTransportAction.java:...)
    at org.elasticsearch.action.TransportActionNodeProxy.lambda$execute$0(TransportActionNodeProxy.java:...)

通过 API 请求的响应通常如下:

{
  "error": {
    "root_cause": [
      {
        "type": "snapshot_creation_exception",
        "reason": "[repo:snapshot_name] aborted on initialization"
      }
    ],
    "type": "snapshot_creation_exception",
    "reason": "[repo:snapshot_name] aborted on initialization",
    "status": 500
  }
}

查看快照状态:

GET /_snapshot/my_repo/snapshot_name

{
  "snapshots": [
    {
      "snapshot": "snapshot_name",
      "state": "FAILED",
      "reason": "aborted on initialization",
      ...
    }
  ]
}

2. 为什么会发生这个错误 #

Elasticsearch 的快照过程分为多个阶段:初始化、启动、分片快照、完成。如果在初始化阶段(准备阶段)遇到问题,快照就会被中止。

源码中的逻辑是:

if (entry.repositoryStateId() == RepositoryData.UNKNOWN_REPO_GEN) {
    logger.debug("[{}] was aborted before starting", snapshot);
    removeFailedSnapshotFromClusterState(
        entry.snapshot(),
        new SnapshotException(snapshot, "Aborted on initialization"),
        repositoryData,
        null
    );
    return;
}

常见原因包括:

  • 仓库不可用:快照仓库(文件系统、S3、Azure 等)无法访问或配置错误。
  • 主节点变更:在快照初始化期间,主节点发生变更,导致快照操作被中止。
  • 分片分配失败:目标索引的分片无法分配或处于不可用状态。
  • 资源不足:磁盘空间不足、内存压力、线程池饱和等。
  • 并发快照冲突:同一仓库已经有正在执行的快照。
  • 版本不兼容:集群升级或版本不一致导致快照格式不兼容。
  • 仓库状态异常:仓库的元数据损坏或状态不一致。

3. 如何排查和解决这个异常和解决这个异常 #

排查步骤 #

建议按以下顺序进行排查:

第一步:查看快照状态和详细错误 #

# 查看快照状态
curl -X GET "localhost:9200/_snapshot/my_repo/snapshot_name?pretty"

# 查看所有失败的快照
curl -X GET "localhost:9200/_snapshot/my_repo/_all?pretty" | jq '.snapshots[] | select(.state == "FAILED")'

# 查看快照状态详情
curl -X GET "localhost:9200/_snapshot/my_repo/_status?pretty"

第二步:检查仓库状态 #

# 验证仓库配置
curl -X GET "localhost:9200/_snapshot/my_repo?pretty"

# 执行仓库验证
curl -X POST "localhost:9200/_snapshot/my_repo/_verify?pretty"

# 检查仓库是否可写
ls -ld /path/to/snapshot/repo/  # 文件系统仓库

第三步:检查集群和分片状态 #

# 查看集群健康状态
curl -X GET "localhost:9200/_cluster/health?pretty"

# 查看分片分配
curl -X GET "localhost:9200/_cat/shards?v"

# 使用 allocation explain 查看分片未分配原因
curl -X GET "localhost:9200/_cluster/allocation/explain?pretty"

第四步:查看日志和监控 #

# 查看 Elasticsearch 日志中的详细错误
tail -n 500 /var/log/elasticsearch/elasticsearch.log | grep -A 30 "aborted on initialization"

# 检查主节点变更日志
grep "master_change" /var/log/elasticsearch/elasticsearch.log

排查时需要注意的问题 #

  • 区分初始化失败和执行失败aborted on initialization 是初始化阶段失败,不是执行阶段失败。
  • 检查时间线:确认快照失败时是否有主节点变更、节点重启等操作。
  • 查看仓库类型:文件系统、S3、Azure 等不同仓库类型的问题排查方式不同。
  • 检查并发快照:确认同一仓库是否有其他正在运行的快照。

4. 如何解决这个错误 #

常用修复思路 #

方案一:删除失败的快照并重新创建 #

# 删除失败的快照
curl -X DELETE "localhost:9200/_snapshot/my_repo/snapshot_name"

# 确认删除成功
curl -X GET "localhost:9200/_snapshot/my_repo/snapshot_name?pretty"
# 应该返回 404 Not Found

# 重新创建快照
curl -X PUT "localhost:9200/_snapshot/my_repo/new_snapshot" -H 'Content-Type: application/json' -d '
{
  "indices": "my_index*",
  "ignore_unavailable": true,
  "include_global_state": false
}'

方案二:检查并修复仓库配置 #

# 文件系统仓库:检查磁盘空间和权限
df -h /path/to/snapshot/repo/
ls -la /path/to/snapshot/repo/

# S3 仓库:检查凭证和 endpoint
# 测试 S3 访问
aws s3 ls s3://my-bucket/snapshot/path/

# Azure 仓库:检查连接字符串和凭证
# 查看仓库配置
curl -X GET "localhost:9200/_snapshot/my_repo?pretty" | jq '.settings'

方案三:等待主节点稳定后重试 #

# 如果是因为主节点变更导致的,等待集群稳定
curl -X GET "localhost:9200/_cluster/health?wait_for_status=yellow&timeout=60s"

# 然后重试快照
curl -X PUT "localhost:9200/_snapshot/my_repo/new_snapshot" -H 'Content-Type: application/json' -d @snapshot.json

方案四:调整快照配置减少初始化负担 #

// 减少索引范围,避免一次性快照过多索引
{
  "indices": "critical_index*",  // 而不是 "*"
  "ignore_unavailable": true,
  "include_global_state": false  // 不包含全局状态,减少初始化工作
}

后续注意事项与推荐建议 #

  • 建立快照监控:监控快照执行状态、耗时和成功率,及时发现初始化失败。
  • 错开定时任务:确保 SLM 策略、外部备份任务的时间窗口不重叠。
  • 检查仓库健康:定期执行 _verify 检查仓库可用性。
  • 设置合理的重试:在自动化脚本中,快照失败后等待一段时间再重试,避免立即重试加剧问题。
  • 监控集群状态:在主节点变更、节点重启期间,可以暂停定时快照任务。

借助 INFINI 产品提升排障效率 #

  • INFINI Console 提供快照状态的可视化监控界面,可以直观地查看、管理和调试快照任务。通过 Console 的快照管理功能,可以快速发现初始化失败的快照、查看失败原因,并直接删除后重建。

  • INFINI Gateway 可以作为 Elasticsearch API 的代理层,在快照创建请求到达 Elasticsearch 之前进行拦截和检查。Gateway 可以自动检测仓库状态,并根据预定义的策略(如排队等待、返回友好错误、转发到备用仓库等)进行处理。

  • 对于依赖快照进行数据备份的团队,建议结合 INFINI Console 的快照监控功能和 INFINI Gateway 的请求治理能力,建立从快照创建、监控、到恢复的完整自动化流程,减少因初始化失败导致的备份中断。

5. 小结 #

aborted on initialization 是一个典型的快照初始化失败错误,根源在于快照在准备阶段遇到了无法恢复的问题。虽然报错信息直接指向初始化中止,但解决思路需要根据具体情况来决定:是仓库问题、主节点变更、还是资源不足。

在实际工作中,为避免此类问题,建议建立快照监控体系、错开定时任务时间、并在自动化脚本中增加状态检查逻辑。更重要的是,考虑使用 INFINI Console 来实现可视化的快照管理,使用 INFINI Gateway 来拦截和预处理快照创建请求,从源头减少初始化失败的发生。

相关错误 #

参考文档 #

附:日志上下文 #

下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:

final boolean newFinalization = endingSnapshots.add(snapshot);
if (entry.repositoryStateId() == RepositoryData.UNKNOWN_REPO_GEN) {
    logger.debug("[{}] was aborted before starting", snapshot);
    removeFailedSnapshotFromClusterState(
        entry.snapshot(),
        new SnapshotException(snapshot, "Aborted on initialization"),
        repositoryData,
        null
    );
    return;
}