Advertisement

Unable to load database on disk The current epoch, *, is older than the last zxid

阅读量:

背景

Zookeeper服务正常运行期间,随机断电后,重启设备后,概率性的无法启动zookeeper服务,启动日志报错

Unable to load database on disk The current epoch, *, is older than the last zxid,

原因分析

Zookeeper的ZAB协议实现里,数据持久化会保存acceptedEpoch、currentEpoch和snapshot.x三种重要文件。acceptedEpoch和 currentEpoch文件是记录当前选举周期值,同时快照文件里zxid也保存着当前周期值,其中currentEpoch和最新的snapshot.x要保持一致。

按照ZAB一致性协议,其认为持久化动作是原子性的,原子操作持久化失败或者成功都不影响数据一致性。但实际实现是无法确保持久化动作原子性,会出现部分持久化成功的情况,导致本地数据异常, zookeeper就会启动失败。

该问题本质是,currentEpoch 与最新的snapshot.x周期值不一致。(为什么要保存相同的周期值到多份文件?详情请看官方考虑https://issues.apache.org/jira/browse/ZOOKEEPER-335?focusedCommentId=16975961&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-16975961)。

follower节点接收到leader节点的更新信息后,会触发持久化操作。follower节点持久化流程是,先完成snapshot.x文件持久化,再持久化currentEpoch文件。若在完成快照持久化和持久化周期值前的这段时间内,发生意外终止(断电),则本地数据就会异常,将影响下次启动。

解决方案

异常检测

增加外部异常检测程序,如脚本或者守护。

外部检测程序启动zookeeper,并检测其运行状态。若检测到启动失败退出,则记录并匹配最新的日志信息,判断是否是已知异常情况(即周期值不一致),如果是,则执行自动修复方法,并尝试再次重启。若重试到一定次数都失败,则需要通告人工介入定位。

基于3.5.4版本,匹配日志规则,其中‘*’表示通配符:

[main:QuorumPeerConfig@133][] - Reading configuration from: *

ERROR [main:QuorumPeer@955][] - Unable to load database on disk

The current epoch, *, is older than the last zxid, *

异常修复

异常原因是currentEpoch与snapshot.x不一致,可通过删除currentEpoch文件实现恢复。根据zookeeper的实现流程,若currentEpoch文件不存在时,则会采用最新snapshot.x的周期值参与选举,并同步重新生成,因此删除currentEpoch不影响其快照一致性。

同时,保存currentEpoch期间, 会生成临时缓存文件currentEpoch.tmp,断电可能会造成没有及时删除,若存在则一起删除。

删除后,再次重启zookeeper服务。

文件路径:*/data/version-2/currentEpoch

*/data/version-2/currentEpoch.tmp

全部评论 (0)

还没有任何评论哟~