适用版本: 7.x-8.x
1. 错误异常的基本描述 #
failed to find existing translog files 表示 Elasticsearch 在处理损坏分片或恢复分片时,尝试读取 translogPath 目录中的现有 translog 文件,但在列目录阶段就抛出了 IOException。
这不是查询层错误,而是分片存储层错误。异常通常出现在 translog 工具、损坏分片清理或底层恢复流程中。
常见现象 #
- 分片恢复、节点启动或损坏分片清理失败,Elasticsearch 日志中出现
failed to find existing translog files异常。 - 服务端日志里同时出现
IOException、路径访问失败、权限错误或文件系统报错。 - 同一分片可能伴随
all shards failed、索引不可恢复或 translog 损坏类报错。 - 使用
elasticsearch-shard工具执行remove-corrupted-data时,命令执行失败并输出该异常。
典型报错与异常栈 #
org.elasticsearch.ElasticsearchException: failed to find existing translog files
Caused by: java.io.IOException: No such file or directory
at java.io.UnixFileSystem.list(Native Method)
at org.elasticsearch.index.translog.Translog.filesInDirectory(Translog.java:XXX)
org.elasticsearch.ElasticsearchException: failed to find existing translog files
Caused by: java.nio.file.AccessDeniedException: /var/lib/elasticsearch/nodes/0/indices/XXX/0/translog
2. 为什么会发生这个错误 #
从源码看,异常直接包裹在 filesInDirectory(translogPath) 外层。也就是说,真正失败点不是"没找到某个 translog 条目",而是 Elasticsearch 连 translog 目录都无法正常枚举。
Translog 是 Elasticsearch 保障数据可靠性的核心机制:每次写入操作先写入 translog 再写入 Lucene 索引,节点重启时通过重放 translog 恢复未刷盘的数据。如果 translog 目录本身无法访问,分片恢复流程将直接中断。
常见原因包括:
- 分片目录缺失或不完整:分片目录被手工删除、迁移不完整,或挂载卷未正确挂载,导致 translog 目录物理上不存在。
- 权限问题:Elasticsearch 进程对 translog 目录没有读取或执行权限,常见于目录权限被误改或数据目录被其他用户重新创建。
- 磁盘或文件系统故障:磁盘故障、文件系统损坏、只读挂载(
read-only)或底层 I/O 错误导致目录访问失败。 - 运维误操作:运维脚本在节点运行期间误删了 translog 文件或上层目录,例如直接清理
data/目录下的文件。 - 节点异常退出后的残留状态:节点被
kill -9强制终止后,数据目录状态不一致,重启时触发恢复逻辑但 translog 目录已损坏。
3. 如何排查这个异常 #
建议按以下顺序排查:
- 定位分片路径:根据日志中的索引名、分片号和节点路径,定位实际的
translog目录,默认路径类似:# 路径格式 $ES_DATA_DIR/nodes/0/indices/<index_uuid>/<shard_id>/translog - 检查目录是否存在:在节点上执行:
ls -la /var/lib/elasticsearch/nodes/0/indices/<index_uuid>/<shard_id>/translog如果目录不存在,说明分片数据已丢失或被误删。
- 检查目录权限:确认目录的属主和权限是否正确:
ls -ld /var/lib/elasticsearch/nodes/0/indices/<index_uuid>/<shard_id>/translog # 应归属于运行 Elasticsearch 的用户(如 elasticsearch) - 检查磁盘和文件系统状态:
# 检查磁盘是否只读 mount | grep "read-only" # 检查磁盘空间 df -h /var/lib/elasticsearch # 检查文件系统错误(需要 umount) dmesg | grep -i "error\|readonly\|I/O" - 查看系统日志:确认是否存在磁盘 I/O、文件系统只读或设备异常:
journalctl -xe | grep -i "read-only\|io error\|ext4\|xfs" - 确认分片是否有副本或快照:如果这是恢复或修复流程的一部分,先确认该分片是否已有可用副本或快照,避免盲目删除数据。
排查时需要注意的问题 #
- 不要直接在运行中的 Elasticsearch 节点上删除或修改
data/目录下的文件,这会导致分片状态不一致。 - 如果节点以
readonly模式挂载了数据盘,Elasticsearch 可能无法枚举目录内容,此时IOException是正常现象。 - 多个分片同时报错时,优先考虑磁盘或挂载点问题,而非单个分片的问题。
- 使用
elasticsearch-shard工具前,务必先停止目标节点上的 Elasticsearch 进程,避免数据进一步损坏。
4. 如何解决这个错误 #
常用修复思路 #
方案一:修复目录访问问题(目录存在但无法访问)
# 修复权限
chown -R elasticsearch:elasticsearch /var/lib/elasticsearch/nodes/0/indices/<index_uuid>/<shard_id>/translog
chmod 755 /var/lib/elasticsearch/nodes/0/indices/<index_uuid>/<shard_id>/translog
# 如果磁盘只读,重新挂载为可写
mount -o remount,rw /var/lib/elasticsearch
方案二:从副本自动恢复(推荐)
如果索引配置了副本(number_of_replicas >= 1),将当前节点移出集群后重新加入,Elasticsearch 会从其他副本自动恢复分片:
# 临时将节点排除出集群(在集群中任意正常节点执行)
curl -X PUT "localhost:9200/_cluster/settings" -H "Content-Type: application/json" -d'
{
"transient": {
"cluster.routing.allocation.exclude._name": "<故障节点名>"
}
}'
# 修复后取消排除
curl -X PUT "localhost:9200/_cluster/settings" -H "Content-Type: application/json" -d'
{
"transient": {
"cluster.routing.allocation.exclude._name": null
}
}'
方案三:使用 shard 工具删除损坏数据(无副本时慎用)
# 停止 Elasticsearch 进程后执行
sudo -u elasticsearch bin/elasticsearch-shard remove-corrupted-data \
--index <index_name> \
--shard-id 0
# 注意:此操作会丢失 translog 中未刷盘的数据
方案四:从快照恢复
# 关闭索引
curl -X POST "localhost:9200/<index_name>/_close"
# 从快照恢复
curl -X POST "localhost:9200/_snapshot/<repo_name>/<snapshot_name>/_restore" \
-H "Content-Type: application/json" -d'
{
"indices": "<index_name>",
"include_global_state": false
}'
后续注意事项与推荐建议 #
- 为索引设置至少 1 个副本(
number_of_replicas: 1),确保单节点故障时数据可恢复。 - 定期执行快照备份,验证快照完整性,避免数据丢失后无备份可用。
- 监控磁盘使用率、inode 使用率和文件系统只读状态,设置告警阈值。
- 禁止在 Elasticsearch 运行时对
data/目录执行任何手工删除或移动操作。
借助 INFINI 产品提升排障效率 #
- INFINI Console 适合查看集群健康度、节点指标、索引状态、分片分配情况和磁盘使用趋势,帮助快速判断异常是局部问题还是系统性问题。
- INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测、限流和流量治理,减少因写入风暴导致的节点异常和 translog 堆积。
- 建议将节点磁盘、JVM、分片状态和恢复进度统一接入监控面板,在分片恢复失败前提前预警。
5. 小结 #
failed to find existing translog files 的核心含义是"存储层无法读取 translog 目录",不是普通字段或请求错误。排查重点应放在分片数据路径、权限、磁盘和文件系统,而不是 DSL 或客户端请求。
只要把磁盘监控、副本策略和快照备份结合起来,大多数 translog 相关的分片恢复问题都可以快速定位并修复,也更容易通过 INFINI Console 和 INFINI Gateway 实现持续预警与防护。
相关错误 #
- all-shards-failed:所有分片失败
- index-not-found-in-repository:仓库中未找到索引
- could-not-read-repository-data:无法读取仓库数据
附:日志上下文 #
// Hold the lock open for the duration of the tool running
Set translogFiles;
try {
translogFiles = filesInDirectory(translogPath);
} catch (IOException e) {
throw new ElasticsearchException("failed to find existing translog files", e);
}
final String details = deletingFilesDetails(translogPath, translogFiles);
return Tuple.tuple(RemoveCorruptedShardDataCommand.CleanStatus.CORRUPTED, details);





