适用版本: 6.8-7.7+
1. 错误异常的基本描述 #
aborted 是 Elasticsearch 在操作执行过程中抛出的中止错误。当快照、恢复、分片分配或集群管理操作在执行过程中被强制中止时,就会触发此错误。这可能是用户手动取消、超时、资源不足或底层存储问题导致的。
常见现象 #
- Elasticsearch 返回 HTTP
500 Internal Server Error或409 Conflict状态码。 - 快照、恢复、分片重平衡等操作失败,状态为
ABORTED或FAILED。 - 在 Elasticsearch 服务端日志中会记录
IndexShardSnapshotFailedException或ElasticsearchException: Aborted。 - 如果是通过定时任务(SLM)或自动化脚本执行操作,会导致后续操作失败或阻塞。
- 可能导致集群状态不一致,影响后续的运维操作。
典型报错与异常栈 #
该异常的典型日志形态如下:
IndexShardSnapshotFailedException: [shard_id] aborted
at org.elasticsearch.snapshots.SnapshotsService.updateIndexShardSnapshotStatus(SnapshotsService.java:...)
at org.elasticsearch.snapshots.SnapshotsService.snapshotShardFailed(SnapshotsService.java:...)
at org.elasticsearch.snapshots.SnapshotShardsService.processAborted(SnapshotShardsService.java:...)
通过 API 请求的响应通常如下:
{
"error": {
"root_cause": [
{
"type": "snapshot_creation_exception",
"reason": "[shard_id] aborted"
}
],
"type": "snapshot_creation_exception",
"reason": "[shard_id] aborted",
"status": 500
}
}
另一种常见形态(恢复操作被中止):
ElasticsearchException: Aborted
at org.elasticsearch.indices.recovery.RecoverySourceHandler.abortRecovery(RecoverySourceHandler.java:...)
at org.elasticsearch.indices.recovery.RecoveryTargetHandler.lambda$handlAttention$15(RecoveryTargetHandler.java:...)
2. 为什么会发生这个错误 #
Elasticsearch 的许多长时间运行的操作(如快照、恢复、分片重平衡等)都支持中止机制。源码中的逻辑是:
if (snapshotStatus.isAborted()) {
logger.debug("[{}] [{}] Aborted on the file [{}]; exiting", shardId, snapshotId, fileName);
throw new IndexShardSnapshotFailedException(shardId, "Aborted");
}
常见原因包括:
- 用户手动取消:通过 API 或管理界面手动取消了正在执行的操作。
- 超时中止:操作执行时间超过预设的超时时间。
- 资源不足:磁盘空间不足、内存压力、CPU 饱和导致操作被强制中止。
- 存储问题:仓库不可写、文件系统错误、网络存储访问失败。
- 主节点变更:在操作执行期间发生主节点切换,导致操作被中止。
- 并发冲突:同一资源的多个操作相互冲突,后一个操作导致前一个被中止。
3. 如何排查和解决这个异常和解决这个异常 #
排查步骤 #
建议按以下顺序进行排查:
第一步:查看操作状态和详细错误 #
# 查看快照状态(如果是快照操作)
curl -X GET "localhost:9200/_snapshot/my_repo/_all?pretty" | jq '.snapshots[] | select(.state == "ABORTED")'
# 查看恢复状态(如果是恢复操作)
curl -X GET "localhost:9200/_recovery?active_only=true&pretty"
# 查看操作失败原因
curl -X GET "localhost:9200/_snapshot/my_repo/snapshot_name?pretty" | jq '.snapshots[0].reason'
第二步:检查集群和节点状态 #
# 查看集群健康状态
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"
# 检查是否有主节点变更
grep "master_change" /var/log/elasticsearch/elasticsearch.log
# 检查资源使用情况
curl -X GET "localhost:9200/_nodes/stats?pretty" | jq '.nodes[] | .os.cpu.percent, .jvm.mem.heap_used_percent'
第四步:在测试环境验证 #
# 在测试环境重新执行相同操作,观察是否复现
curl -X PUT "localhost:9200/_snapshot/test_repo/test_snapshot" -H 'Content-Type: application/json' -d '
{
"indices": "test_index",
"ignore_unavailable": true
}'
排查时需要注意的问题_ #
- 区分中止原因:确认是用户手动取消、超时、还是系统强制中止。
- 检查时间线:确认操作失败时是否有主节点变更、节点重启等操作。
- 查看资源瓶颈:磁盘、内存、CPU 等是否成为操作执行的障碍。
- 检查并发操作:确认是否有多个操作同时操作同一资源。
4. 如何解决这个错误 #
常用修复思路 #
方案一:删除中止的操作并重新执行(推荐) #
# 如果是快照被中止,先删除
curl -X DELETE "localhost:9200/_snapshot/my_repo/aborted_snapshot"
# 确认删除成功
curl -X GET "localhost:9200/_snapshot/my_repo/aborted_snapshot?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
}'
方案二:检查并修复资源问题 #
# 检查磁盘空间
df -h /path/to/elasticsearch/data
df -h /path/to/snapshot/repo/
# 检查内存使用
curl -X GET "localhost:9200/_nodes/stats/jvm?pretty" | jq '.nodes[] | .jvm.mem'
# 必要时扩容节点或清理空间
方案三:调整超时设置 #
// 如果是因为超时导致中止,增加超时时间
{
"indices": "my_index*",
"ignore_unavailable": true,
"include_global_state": false
}
// 或者通过集群设置调整全局超时
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d '
{
"persistent": {
"index.snapshot.interval": "120s"
}
}'
方案四:使用 API 取消并重新执行 #
# 如果操作卡住,可以手动取消(某些操作支持)
# 然后重新执行
curl -X PUT "localhost:9200/_snapshot/my_repo/new_snapshot" -H 'Content-Type: application/json' -d @snapshot.json
后续注意事项与推荐建议_ #
- 建立操作监控:监控长时间运行的操作(快照、恢复、重平衡)的状态和耗时。
- 避免并发冲突:对于同一资源(如同一索引、同一仓库)的操作,错开执行时间。
- 检查资源充足:确保磁盘、内存、CPU 等资源充足,避免操作被强制中止。
- 设置合理的超时:根据操作复杂度设置合理的超时时间,避免过早超时。
- 定期清理中止的操作:对于已经中止的操作,及时清理,避免影响后续操作。
借助 INFINI 产品提升排障效率_ #
INFINI Console 提供集群操作的可视化监控界面,可以直观地查看、管理和调试快照、恢复等操作。通过 Console 的操作管理功能,可以快速发现中止的操作、查看失败原因,并直接删除后重建。
INFINI Gateway 可以作为 Elasticsearch API 的代理层,在操作请求到达 Elasticsearch 之前进行拦截和检查。Gateway 可以自动检测长时间运行的操作,并根据预定义的策略(如自动取消、重新排队、转发到备用集群等)进行处理。
对于依赖 Elasticsearch 运维操作的团队,建议结合 INFINI Console 的操作监控功能和 INFINI Gateway 的请求治理能力,建立从操作执行、监控、到故障恢复的完整自动化流程,减少因操作中止导致的运维中断。
5. 小结_ #
aborted 是一个典型的操作中止错误,根源在于长时间运行的操作被强制中断。虽然报错信息比较底层,但解决思路需要根据具体情况来决定:是删除后重建、修复资源问题,还是调整超时设置。
在实际工作中,为避免此类问题,建议建立操作监控体系、错开并发操作时间、并确保资源充足。更重要的是,考虑使用 INFINI Console 来实现可视化的操作管理,使用 INFINI Gateway 来拦截和预处理操作请求,从源头减少操作中止的发生。
相关错误_ #
- a-snapshot-is-already-running:快照正在运行
- aborted-on-initialization:初始化中止
- aborted-by-user:用户中止操作
- recovery-was-canceled-reason-reason:恢复被取消
- failed-to-perform-snapshot-index-files:快照执行失败
参考文档_ #
附:日志上下文_ #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
for (String fileName : fileNames) {
if (snapshotStatus.isAborted()) {
logger.debug("[{}] [{}] Aborted on the file [{}]; exiting", shardId, snapshotId, fileName);
throw new IndexShardSnapshotFailedException(shardId, "Aborted");
}
logger.trace("[{}] [{}] Processing [{}]", shardId, snapshotId, fileName);
final StoreFileMetaData md = metadataFromStore.get(fileName);
BlobStoreIndexShardSnapshot.FileInfo existingFileInfo = null;





