Elasticsearch 的副本不是备份,副本只能应对节点故障,无法恢复误删和逻辑损坏。快照是增量的,多个快照之间共享 segment,快照仓库必须独立于集群数据盘,并且不能被手工清理。快照不保证所有索引的写入严格同时刻;需要强一致时先停止写入并确认刷新。
恢复前要明确 RPO:能接受回到哪一次成功快照。快照之后的写入不会自动补回,需要从上游数据、事务日志或消息队列另行补偿。
明确恢复范围。列出要恢复的索引、别名、模板、ILM 和 pipeline,并确认是恢复到原集群、新集群,还是先做隔离验证。
确认快照仓库和快照可用:
curl -s 'http://es:9200/_snapshot?pretty'
curl -s 'http://es:9200/_cat/snapshots/<repo>?v'
curl -s 'http://es:9200/_snapshot/<repo>/<snap>?pretty'
curl -s 'http://es:9200/_snapshot/<repo>/<snap>/_status?pretty'
curl -s -X POST 'http://es:9200/_snapshot/<repo>/_verify?pretty'
重点看快照的 state、起止时间、包含的索引、成功和失败的分片数。SUCCESS 且失败分片为 0 才适合直接恢复;PARTIAL 或存在失败分片时,先判断缺的是否是关键索引,不要默认它可用。_verify 只验证仓库访问和基本可用性,不等于每个分片都可读,仍要结合 _status 和恢复日志。
检查仓库类型和凭据。fs 仓库要求所有节点配置相同的 path.repo 并有读写权限;对象存储仓库要确认桶、前缀、凭据、网络和生命周期规则。快照仓库不能和集群数据放在同一块盘上,否则磁盘故障会同时丢失生产和备份。仓库对象不要手工删除,多个快照共享 segment。
检查目标集群。确认版本兼容,节点数、磁盘空间、分片上限、watermark 和副本规划能容纳恢复后的索引。空间不足时索引可能恢复成功但副本长期未分配。
curl -s 'http://es:9200/_cluster/health?pretty'
curl -s 'http://es:9200/_cat/nodes?v'
curl -s 'http://es:9200/_cat/allocation?v'
curl -s 'http://es:9200/_cat/indices?v'
curl -s 'http://es:9200/_cat/indices?v' > indices-before.txt
curl -s 'http://es:9200/_cat/aliases?v' > aliases-before.txt
curl -s 'http://es:9200/_index_template?pretty' > templates-before.json
curl -s 'http://es:9200/_ilm/policy?pretty' > ilm-before.json
curl -s 'http://es:9200/_ingest/pipeline?pretty' > pipelines-before.json
curl -s -X POST 'http://es:9200/_ilm/stop?pretty'
curl -s -X POST 'http://es:9200/_slm/stop?pretty'
如果集群启用了 transform、CCR 或 rollup,也要暂停,避免它们在恢复窗口继续写索引。
只恢复数据索引时,保持 include_global_state 为 false,避免把旧模板、旧 ILM 策略和旧集群设置覆盖到当前集群。需要同时恢复模板、pipeline、ILM 等集群级元数据时,再评估是否使用 include_global_state=true;它可能覆盖目标端较新的配置,恢复后要逐项对比。
恢复部分索引时,用 indices 指定名称或通配符,并设置 ignore_unavailable=true,避免快照中缺少某个索引导致整个请求失败。不要用 partial=true 作为常规选项,它只恢复可用分片,可能留下缺少主分片的索引。
优先使用重命名,把快照中的索引恢复到新名称,验证通过后再切换别名:
curl -s -X POST 'http://es:9200/_snapshot/<repo>/<snap>/_restore?wait_for_completion=false&pretty' \
-H 'Content-Type: application/json' \
-d '{
"indices": "orders-*",
"ignore_unavailable": true,
"include_global_state": false,
"include_aliases": false,
"rename_pattern": "(.+)",
"rename_replacement": "restored-$1"
}'
恢复请求默认异步执行,返回 accepted 只表示任务已提交。持续观察恢复进度和集群状态:
curl -s 'http://es:9200/_cat/recovery?v&active_only=true'
curl -s 'http://es:9200/_snapshot/<repo>/<snap>/_status?pretty'
curl -s 'http://es:9200/_cluster/health?pretty'
curl -s 'http://es:9200/_cat/shards?v' | grep -E 'UNASSIGNED|INITIALIZING'
如果目标集群磁盘接近 watermark,先清理空间或扩容;否则分片可能无法分配。恢复并发过高时,可调整 cluster.routing.allocation.node_concurrent_recoveries 和 indices.recovery.max_bytes_per_sec,但不要为了追求速度把节点压垮。
同名索引处于 open 状态时,直接恢复通常会因索引已存在而失败。可选做法只有两类:先关闭或删除旧索引再恢复,或恢复到临时名称后用别名切换。删除前必须确认已有可用快照和回滚路径,不能用“删了再试”处理生产索引。
如果新索引的 mapping 与旧索引不兼容,不能原地修改已有字段类型。应恢复到临时索引,确认新 mapping 后用 _reindex 重建,或让应用写新索引;_reindex 会额外占用磁盘和时间,数据量大时要先评估。
需要恢复模板、ILM、pipeline 时,先确认目标端是否有更新的版本。可以把快照恢复到隔离集群导出配置,再逐项对比后写入生产,而不是直接打开 include_global_state 覆盖。恢复顺序通常是:组件模板和索引模板、ILM 策略、ingest pipeline、索引数据、别名。
用户、角色、API key、TLS 证书等安全配置不要只依赖索引快照,应单独备份并在目标集群验证。快照中的数据可能包含敏感信息,仓库要启用加密和最小权限访问。
验证完成后,用别名原子切换。下面把读流量从旧索引切到恢复索引,旧索引先保留,确认无误后再删除:
curl -s -X POST 'http://es:9200/_aliases?pretty' \
-H 'Content-Type: application/json' \
-d '{
"actions": [
{"remove": {"index": "orders-current", "alias": "orders"}},
{"add": {"index": "restored-orders-current", "alias": "orders"}}
]
}'
切换前确认写别名只指向一个索引,避免双写;如果应用直接写具体索引名而不是别名,要先改配置或重建索引名。切换后恢复 ILM/SLM 和采集端,观察写入、刷新、段合并和副本分配,再补拍一份新快照:
curl -s -X POST 'http://es:9200/_ilm/start?pretty'
curl -s -X POST 'http://es:9200/_slm/start?pretty'
curl -s -X PUT 'http://es:9200/_snapshot/<repo>/post-restore-<date>?wait_for_completion=false&pretty'
_cat/recovery 没有持续 active 的分片,_cluster/health 达到预期状态。快照不存在或仓库不可访问。 先检查仓库注册、凭据、网络和对象存储生命周期,确认快照没有被清理。不要反复重建仓库指向同一个错误路径;换一个已知可用的快照验证仓库本身。
快照分片失败或状态为 PARTIAL。 先确认缺失的分片是否属于关键索引。能重新拍摄就重拍;不能重拍时,评估是否接受部分数据,并把缺失范围写进事故记录。不要把 partial=true 的结果当成完整恢复。
版本或插件不兼容。 目标集群版本不能低于快照来源,跨大版本要先在隔离环境验证。快照格式不兼容时,只能升级目标集群或从兼容的来源重建,不能通过改配置强行读取。
恢复卡住或分片长时间 INITIALIZING。 查看 _cat/recovery、_cluster/allocation/explain、磁盘 watermark、节点容量和仓库吞吐。先解决分配阻塞,再调整恢复并发;不要靠重启所有节点“碰运气”。
mapping 冲突。 已有字段类型不能原地修改。恢复到新索引后用 _reindex 重建,或在应用层做字段转换;不要删除生产索引来强行套用旧 mapping。
ILM 删除了恢复出的索引。 立即停止 ILM,确认策略匹配和索引生命周期状态,必要时从快照重新恢复。恢复前暂停 ILM 是避免该问题的前置条件,不是恢复后的补救措施。
需要回滚。 保留旧索引、旧别名和恢复前的快照;如果新索引已经接受写入,先停止写入,评估差异后再切回。不能简单把别名切回旧索引而忽略新写入,否则会丢数据或造成两份不一致的数据。
合上页面,先回答,再展开对照。
include_global_state=true 有什么风险,恢复前应怎样处理 ILM 和 SLM?
小程序版
微信扫码,随时查命令