磁盤故障導致索引無法恢復處理流程
ES集羣版本:V_5.4.2
translog 損壞
如因磁盤故障,導致索引translog
損壞而無法恢復,此時可通過清空索引translog
的方式恢復索引,但translog
中未刷盤的數據會丟失(索引歷史數據不會丟失,一般來說,至多隻會丟失當天數據)。
查看未分配分片原因
// 按照state狀態正序排序,state一致時按照 prirep 正序排序
// 獲取到未分配主分片(p)的 index,shard,prirep 信息
GET _cat/shards?v&s=state,prirep
// 使用explain命令查看未分配的原因
// index 填寫未分配主分片的索引名稱;shard 填寫未分配主分片的分片編號;primary爲true表示是主分片,填false表示查看副本未分配的原因
GET /_cluster/allocation/explain
{
"index": "test_index",
"shard": 1,
"primary": true
}
如果返回結果中,有 [failed to recover from translog] 字樣,如:
“explanation” : “shard has exceeded the maximum number of retries [5] on failed allocation attempts - manually call [/_cluster/reroute?retry_failed=true] to retry, [unassigned_info[[reason=ALLOCATION_FAILED], at[2018-07-30T11:28:21.654Z], failed_attempts[5], delayed=false, details[failed shard on node [_wtZ2Gq7TvWoKsII2yCN6Q]: shard failure, reason [failed to recover from translog], failure EngineException[failed to recover from translog]; nested: TranslogCorruptedException[operation size must be at least 4 but was: 0]; ], allocation_status[deciders_no]]]”
或者在es集羣日誌中,有 [failed to recover from translog] 如:
則表示是因爲 translog 損壞,導致分片無法恢復,此時只能清空translog,會導致translog裏的數據丟失(通知用戶,會丟失當天的數據)。
通知用戶
清空 translog 日誌
通知用戶後,開始清空未分配分片的translog 日誌,在第一步查看未分配分片的原因時,通過explain命令,已經獲取到了未分配分片所在節點:
查看 explain 命令返回結果,找出所有帶 [failed to recover from translog] 的對應的 node_name 的名稱(可能有多個節點),假設在 es01 和 es02 兩個節點上都找到了,則需要去 es01 和 es02 兩個節點上去清空 translog 日誌。
知道 索引名稱index、未分配分片的編號shard,以及目標節點node_name後,需要去獲取 index 的 UUID:
// 獲取 index 的 UUID
GET _cat/indices/test_index?v
獲取到 UUID 後,即可開始清空 損壞的 translog 了,到目標節點 node_name 的es安裝包的 bin 目錄下,執行:
bin/elasticsearch-translog truncate -d /data00/clusterName/nodes/0/indices/UUID/shard/translog/
命令解析:
bin/elasticsearch-translog truncate –d : 固定不變
/data00/clusterName/nodes/0/indices/UUID/shard/translog/ :
data0*:磁盤(注意,節點上每一塊磁盤,都需要清理)
clusterName:集羣名稱
UUID:索引的UUID
shard:未分配分片的編號
其餘保持不變
/data00/clusterName/nodes/0 /indices 其實就是 es 的數據目錄
手動分配分片
translog 清空後,即可手動分配分片了,使用 reroute 命令:
// 使用 allocate_stale_primary 命令手動分配分片
POST _cluster/reroute
{
"commands": [
{
"allocate_stale_primary": {
"index": "test_index",
"shard": 0,
"node": "one_of_node_name",
"accept_data_loss": true
}
}
]
}
命令解析:
index : 索引名稱
shard : 未分配的分片的編號
node : 分配到哪一臺節點上,填節點的名稱,如 es-node1 【如果不確定節點名稱,可以通過 GET _cat/nodes?v
命令,查看節點名稱】注意,填寫的節點名稱,必須是清空 translog 的那個節點,如果有多個節點,隨便選一個即可。
手動分配後,可以通過 GET _cat/shards/indexname?v
命令查看,是否未分配的分片狀態,還是 UNASSIGNED
,如果不是,則流程結束,等待恢復;如果是,則 通過 explain
命令,查看原因。
index 文件損壞
如果是索引文件損壞,explain 或 集羣日誌中,有 input/output error 類似的字樣,則表示無法恢復此分片的數據了,只能強制分配一個空主分片,原先分片裏的數據會全部丟失。
手動分配分片到集羣中任意一個節點上:
POST _cluster/reroute
{
"commands": [
{
"allocate_empty_primary": {
"index": "test_index",
"shard": 0,
"node": "one_of_cluster_node ",
"accept_data_loss": true
}
}
]
}
命令解析:
index : 索引名稱
shard : 未分配的分片的編號
node : 集羣任意一臺正常的節點名稱