[tinykv project2c] 求助:节点重启后读取持久化日志小概率丢失1~2条日志

共同点是这些丢失的日志被持久化之后,紧接着节点收到snapshot消息并且应用,随后节点重启,就无法读到部分日志。

比如某个节点日志为{index:898,term:18}, {index:899 term:18}, stabledIndex=899
收到的snapshot.TruncatedIndex=897,并且附带了index 898之后的日志{index:898,term:18}, {index:899 term:18}, {index:900,term:18},{index:901, term:22}… 因为898、899两条本来已经有了,所以节点从900开始追加日志并持久化和提交。

然后重启之后节点初始化时就只能读到900之后的日志,898和899不见了。

我反复跑了很多次,每次出错的时候日志基本都是上面描述的过程,而且通常这些丢失的日志都是好几个term之前的。最开始猜想会不会是应用snapshot的时候删除了日志,但是去看region_task.go applySnap函数,里面应该只删了engines.KV的数据,没有对engines.Raft进行操作;然后我想有没有可能是持久化日志的时候没有成功,但是在write_batch里打印显示持久化应该是成功了。实在没有头绪了。

哪部分的操作可能导致已经持久化的日志丢失,有什么建议吗

1赞

希望不是真的这么薄脆

1赞

我也遇到了类似的问题,分享一下我找到的bug原因。 我的raft在发送snapshot的时候,会立刻将next设置为snap.meta+1,导致leader会立刻发送了接下来的日志。所以follower会同时收到这些日志的时候,会一起处理。由于snapshot的apply是异步的,在处理put请求的时候,同时也在applySnapshot。但是applySnapshot会清空当前region的所有数据,所以如果put请求先写入,会导致这个请求的数据丢失。

1赞