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

适用版本: 7.17-8.9

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

failed to create new translog file 表示 Elasticsearch 在创建新的 translog writer 文件时抛出了 IOException,随后被包装成 TranslogException。该异常发生在写入链路的最底层——translog 持久化阶段,意味着索引操作无法安全地写入事务日志,通常会直接影响分片的可写性和恢复能力。

常见现象 #

  • 索引写入请求失败,返回 500429 状态码,具体取决于是否触发了熔断或重试逻辑。
  • 分片状态可能变为 REDYELLOW,尤其在分片恢复、滚动重启或磁盘压力较大的场景下。
  • 节点日志中会出现 TranslogException: failed to create new translog file 异常,并伴随 IOException 原因链。
  • 如果问题持续存在,可能会导致分片无法分配、索引无法打开,甚至触发索引级别的只读保护。

典型报错与异常栈 #

该异常在日志中通常表现为以下形式:

org.elasticsearch.index.translog.TranslogException: failed to create new translog file
Caused by: java.io.IOException: No space left on device
    at java.io.FileOutputStream.open0(Native Method)
    at java.io.FileOutputStream.open(FileOutputStream.java:270)
    at org.elasticsearch.index.translog.Translog.createWriter(Translog.java:xxx)

或:

TranslogException[failed to create new translog file]
Caused by: java.nio.file.AccessDeniedException: /var/lib/elasticsearch/nodes/0/indices/xxx/0/translog/translog-xxx.tlog

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

Translog(事务日志)是 Elasticsearch 保证数据可靠性的核心组件。每次索引操作(写入、更新、删除)在写入 Lucene 内存缓冲之前,都会先被记录到 translog 中。当 translog 文件大小达到阈值(默认 512MB)或发生 flush 操作时,Elasticsearch 会创建一个新的 translog 文件来继续接收写入。

如果在创建新 translog 文件的过程中,底层文件系统操作失败,就会抛出此异常。常见原因包括:

  • 磁盘空间不足:数据分区使用率接近 100%,文件系统无法分配新的 inode 或数据块。
  • 磁盘 inode 耗尽:即使磁盘空间尚有剩余,但 inode 数量已用完,同样无法创建新文件。
  • 文件权限异常:Elasticsearch 进程对分片数据目录($ES_PATH_DATA/nodes/0/indices/)没有写权限,常见于目录被手动修改权限或迁移后未正确授权。
  • 文件系统只读挂载:磁盘出现 I/O 错误后被系统自动重新挂载为只读模式(ro),导致所有写操作失败。
  • 文件句柄耗尽:操作系统级别的文件描述符(file descriptor)达到上限,无法打开新文件。
  • 磁盘硬件故障或 I/O 抖动:底层存储出现坏道、I/O 超时或存储驱动异常,导致文件创建操作失败。
  • 分片目录损坏:分片数据目录被外部进程意外修改或删除,导致 translog 目录结构不完整。

3. 如何排查这个异常 #

建议按照"先确认影响范围,再定位根因"的顺序排查:

  1. 确认异常影响范围:检查是个别分片报错,还是整个节点甚至多个节点同时出现。单个分片异常往往指向目录权限或局部磁盘问题;多节点同时报错则更可能是存储系统层面的问题。
  2. 检查磁盘空间与 inode:在节点上执行 df -hdf -i,确认数据分区使用率是否超过 90%,以及 inode 是否耗尽。
  3. 检查文件系统挂载状态:执行 mount | grep <data_path> 确认数据目录所在分区是否为读写模式(rw),而非只读(ro)。
  4. 检查 Elasticsearch 进程权限:确认 $ES_PATH_DATA 目录及其子目录的所有者和权限是否正确,Elasticsearch 进程用户是否拥有写权限。
  5. 检查文件句柄限制:查看 Elasticsearch 日志中是否有 too many open files 相关报错,并对比 ulimit -n 的当前值和配置值。
  6. 查看系统日志:检查 /var/log/syslogdmesg 或硬件监控平台,确认是否有磁盘 I/O 错误、文件系统报错或存储链路告警。
  7. 结合时间窗口分析:确认异常发生前后是否有磁盘迁移、节点重启、索引删除或操作系统补丁变更等操作。

排查时需要注意的问题 #

  • 不要只关注 translog 报错本身,磁盘问题往往会同时触发多种异常(如 engine 启动失败translog 损坏segment 文件写入失败 等),需要综合研判。
  • 如果节点已被标记为磁盘水位超限(high disk watermark),Elasticsearch 会自动将该节点上的分片迁走,此时 translog 创建失败可能是迁移过程中的连带问题。
  • 在容器化部署(Docker/K8s)场景下,还需确认宿主机磁盘和容器存储卷的映射关系是否正确,以及是否有存储卷容量限制(PVC quota)。

4. 如何解决这个错误 #

常用修复思路 #

  • 磁盘空间不足:清理过期数据、删除不需要的索引、扩容磁盘,或临时调高磁盘水位线(cluster.routing.allocation.disk.watermark)以恢复写入。
  • inode 耗尽:查找并清理大量小文件(常见于 translog 或 segment 文件堆积),必要时重新格式化文件系统时指定更大的 inode 数量。
  • 权限问题:修正数据目录权限,例如执行 chown -R elasticsearch:elasticsearch $ES_PATH_DATAchmod -R 750 $ES_PATH_DATA
  • 文件系统只读:先排查磁盘硬件健康状态,确认无硬件故障后,尝试重新以读写模式挂载分区:mount -o remount,rw <device> <mount_point>
  • 文件句柄耗尽:修改系统限制,在 /etc/security/limits.conf 中增加 elasticsearch soft nofile 65536elasticsearch hard nofile 65536,然后重启 Elasticsearch。
  • 分片目录损坏:如果确认目录结构损坏且无法修复,可以考虑从副本分片恢复,或通过快照(snapshot)重建索引。

紧急恢复步骤 #

如果业务写入受到严重影响,可以按以下顺序快速止血:

# 1. 临时关闭索引的只读保护(仅在确认磁盘问题已修复后执行)
PUT /<index_name>/_settings
{
  "index.blocks.read_only_allow_delete": null
}

# 2. 如果磁盘空间紧张,临时调高磁盘水位线(恢复后记得改回)
PUT _cluster/settings
{
  "transient": {
    "cluster.routing.allocation.disk.watermark.low": "90%",
    "cluster.routing.allocation.disk.watermark.high": "95%"
  }
}

# 3. 尝试手动分配因 translog 问题而未被分配的分片
POST /_cluster/reroute?retry_failed=true

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

  • 为磁盘使用率、inode 使用率、文件句柄数和 I/O 延迟设置监控告警,在问题影响业务之前提前介入。
  • 定期清理过期索引和旧的 translog 文件,避免磁盘空间被缓慢耗尽。
  • 对关键索引保持至少一个副本,确保单节点磁盘故障时可以快速从副本恢复。
  • 定期备份数据到远程快照仓库,确保极端情况下可以从快照恢复,而不是依赖可能已损坏的本地 translog。

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

  • INFINI Console 适合查看集群健康度、节点磁盘使用率、分片分配状态和异常趋势,帮助快速判断 translog 异常是局部磁盘问题还是系统性问题。
  • INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测、限流和熔断,在磁盘异常期间减少写入压力,避免更多 translog 相关错误被连锁触发。
  • 建议将磁盘告警、分片未分配事件和 translog 异常日志统一接入监控面板,缩短从"发现问题"到"定位根因"的时间。

5. 小结 #

failed to create new translog file 的本质是 translog 新文件创建失败,根因几乎总是落在磁盘、文件系统或操作系统层面的资源限制上,而不是 Elasticsearch 本身的代码缺陷。排查时应优先关注分片本地目录的可写性、磁盘 I/O 健康状态以及操作系统资源限制,而不是请求参数或索引 mapping。只要把磁盘监控、权限管理和容量规划固定下来,这类异常可以在很大程度上被提前预防。

相关错误 #

附:日志上下文 #

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

bigArrays;
diskIoBufferPool;
operationListener
);
} catch (final IOException e) {
throw new TranslogException(shardId; "failed to create new translog file"; e);
}
return newWriter;
}