elasticsearch集群red恢复损坏的索引

发布时间 2024-01-05 17:49:44作者: 赛博朋克V

背景

客户磁盘损坏,修复磁盘后,重启机器,发现elasticsearch启动成功,ES状态正常green,但是历史数据都没有加载进,查看ES存储数据目录,发现数据还在。

解决方案

  1. 首先,需要确认indices目录下的lucene 索引正常。需要关闭ES(实际操作索引处于close状态也可以)。
# 检测lucene 索引数据是否正常
java -cp /usr/share/elasticsearch/lib/*:/usr/share/elasticsearch/lib/elasticsearch-*.jar -ea:org.apache.lucene... org.apache.lucene.index.CheckIndex    文件路径

如果返回java异常报错,注意文件路径,需要到index分片目录下,例如:

/data/elasticsearch/data/nodes/0/indices/LV3R8lK_RU6RJyQlYIx6Tw/0/index/

如果CheckIndex检测到问题并且其修复建议看起来很明智,使用 -exorcise 命令修复

# 修复lucene数据
java -cp /usr/share/elasticsearch/lib/*:/usr/share/elasticsearch/lib/elasticsearch-*.jar -ea:org.apache.lucene... org.apache.lucene.index.CheckIndex -exorcise  文件路径
  1. 其次,查看索引分片具体的失败原因

使用如下API查看

# 查看分片分配失败原因
curl -XGET IP:9200/_cluster/allocation/explain?pretty

或者,查看es的日志,也会打印出堆栈信息,分片分配失败原因。

  1. 如果,报错_state目录下的.st文件损坏 则删除这个问题,然后重新分配

    3.1 手动重新分配

# 手动重新分配
curl -XPOST IP:9200/_cluster/reroute?retry_failed=true

3.2 手动分配陈腐的分片

# 手动分配陈腐的分片
curl -H "Content-Type:application/json" -XPOST "localhost:9200/_cluster/reroute?pretty" -d '
{
  "commands": [
    {
      "allocate_stale_primary": {
      "index": "{索引名称}",
      "shard": "{分片ID}",
      "node": "{节点名称}",
      "accept_data_loss": true
      }
    }
  ]
}'

需要从步骤2 查看分片分配失败原因的返回结果中,选取index 、shard、node信息

  1. 如果报错translog-*.tlog日志文件损坏,那么需要移走这个tlog日志文件,然后重试3.2步骤,手动分配陈腐的分片。

    此种情况会丢失损坏的tlog文件中的数据。但相对整个索引丢失,已经是最好的情况了

  2. 如果在索引的分片数据目录,出现corrupt开头的文件,则需要清理掉这个文件。corrupt开头的文件是记录文件损坏的位置,不移除这个文件,分配stale是无法恢复,移除了这个文件才能恢复。清理完corrupt文件之后,再重试 3.2 手动分配陈腐的分片

  3. 如果尝试以上种种,都不能恢复分片数据。那么为了保证当前索引的正常业务的读写以及ES正常的状态。只能重建索引。丢失的数据不要了(最糟糕的情况)。

# 丢弃分片,保留索引
curl -H "Content-Type:application/json" -XPOST "IP:9200/_cluster/reroute?pretty" -d '
{
  "commands": [
    {
      "allocate_empty_primary": {
      "index": "{索引名称}",
      "shard": "{分片ID}",
      "node": "{节点名称}",
      "accept_data_loss": true
      }
    }
  ]
}'

批量修复分片,不要数据了