HDFS的edits文件不连续导致NameNode无法启动的恢复方法
NameNode启动时,会访问所有JournalNode去获取edits文件,最终结合JournalNode和本地NameNode所有的edits文件后,发现存在edits文件不连续时,会出现此错误。
There appears to be a gap in the edit log. We expected txid 138, but got txid 145.
还比如以下场景,fsimage的序号为120,但所有JournalNode的edits文件均没有121开头的,因此依然无法启动。
这种情况下,除非借助外部备份恢复机制来恢复,否则环境上应该是找不到缺失的edits文件了。
这种场景下修复很大概率会存在丢失部分数据的风险。
使用HDFS的修复命令修复edits,实际上为自动从头遍历一次edits文件,当不存在时自动跳过,最终生成一份最新的fsimage文件,即可保证namenode正常启动。当edits文件比较多,数据量比较大时,会耗时较长:
|
|
从日志上可以看出流程:
- 读取最新的fsimage
- 读取所有JournalNode的edits文件
- 发现出gap
- -force参数自动选择了c,跳过缺失的edits文件继续回放edits文件
- 如果在其他JournalNode上找到了edits文件,则下载过来使用
- 直到所有edits文件都回放完成
- 生成最新的fsimage文件,并记录seen_txid
随后,我们正常启动NameNode与ZKFC即可。
另一NameNode节点若无法启动,可以使用以下命令,重新获取当前节点的最新的fsimage数据,然后就可以正常启动了。
|
|
如果上诉的hdfs namenode -recover -force
命令不好使,那么只能手动修复能让其成功启动,数据一样会存在丢失的风险。
- 对比主备节点的NameNode数据,在找到连续的最新的edits文件和fsimage,在它之后的edits文件都手动删除。尽可能地保留到最新的数据。
- 在该节点的NameNode中删除
seen_txid
文件 hdfs namenode -initializeSharedEdits -force
将该节点的edits文件覆盖到所有JournalNode- 启动该NameNode与ZKFC
- 另一NameNode节点执行
hdfs namenode -bootstrapStandby -force -skipSharedEditsCheck
重新拉取fsimage - 启动另一NameNode节点与ZKFC
不管哪个方式,启动后,很大概率会出现坏块等情况。使用hdfs fsck /
扫描一下,如果出现了,那么只能删除了,基本没有挽救的余地hdfs fsck / -delete
当前发现HDFS 3.4.0之前的版本,会导致这个edit log出现gap的问题是这个issue HDFS-16689 :Standby NameNode crashes when transitioning to Active with in-progress tailer
启用dfs.ha.tail-edits.in-progress
时,当发生主备倒换时,因网络情况可能会造成这个问题。对于老版本的规避方案是dfs.ha.tail-edits.in-progress
配置为false
或者删除此配置项,保持默认值false
最终合入的PR是:https://github.com/apache/hadoop/pull/4744/files
做法就是在主备倒换过程中的doTailEdits
时,添加特殊场景判断,走回原来的逻辑,不回放in-progress的片段。而对于备机日常的doTailEdits
时,继续保持使用in-progress的片段,得以实现读写分离时能加速备可用的特性。