记录一下那天晚上的排查过程。一台三节点 Elasticsearch 7.10 集群,日志索引每天涨一百多 G,某天写入全部报 cluster_block_exception,索引的 read_only_allow_delete 被自动置成 true。

刚开始盯着「副本分片数设成 1,实际占用是主分片的两倍,容量估算漏算」,折腾了半个多小时,排掉了。

排查方向其实有限,先把可能性排一排。磁盘使用率超过 high watermark 后,集群自动给索引加只读块保护数据。还有一种是索引生命周期策略没配删除阶段,历史索引只增不减。

另外,集群只剩一个节点有空间,分片无法迁移,水位一直下不来。

上来先查看各节点磁盘水位与索引状态

curl -s 'localhost:9200/_cat/allocation?v&h=node,disk.percent,disk.avail'

随后删除过期索引释放空间

curl -XDELETE 'localhost:9200/logstash-2026.08.*'

解除只读块并确认写入恢复

curl -XPUT 'localhost:9200/_all/_settings' -H 'Content-Type: application/json' -d '{"index.blocks.read_only_allow_delete":null}'

补上生命周期删除阶段,避免再次写满

curl -XPUT 'localhost:9200/_ilm/policy/logs-30d' -H 'Content-Type: application/json' -d '{"policy":{"phases":{"delete":{"min_age":"30d","actions":{"delete":{}}}}}}'

怎么算真的好了,看的是同一批现象。cat allocation 里所有节点 disk.percent 低于 85,索引 settings 中 read_only_allow_delete 为 false,写入请求返回 200 且队列不再堆积。

容易忽略的是,只读块是保护不是故障,先腾空间再解锁,否则解完很快又会被置回去;水位数值在 8.x 已改为可动态调整,升级后要重新核对。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189