Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checking the DB file integrity #3

Open
renewboy opened this issue Jul 13, 2020 · 5 comments
Open

Checking the DB file integrity #3

renewboy opened this issue Jul 13, 2020 · 5 comments

Comments

@renewboy
Copy link

Thanks for the great work!
The DB may corrupted in the error-prone environment(external interrupt or unexpected power off, etc.) occasionally. Is it possible to check the DB file integrity and do some basic recovery when it corrupted?

@zhouxingtuan
Copy link
Owner

zhouxingtuan commented Jul 15, 2020

我前一阵子解决过发现过几个运行时的Bug,对key索引操作出现的错误,会导致key互相覆盖,你可以看看提交日志(2019年提交)。我需要更多信息:你使用的是最新的代码吗?你是在初始化出现崩溃,还是在运行(操作数据库)的过程中出现崩溃?按照你所说,由于断电,导致数据存储失败。实际上,这个存储写入的过程是这样的,数据和索引分开,先写入数据、再写入索引。其中任何一步失败、只会导致数据丢失,而不会导致数据出错。所以我怀疑是由于前面的Bug引起的,也可能还有未知情况的Bug。需要更多信息来判断

@zhouxingtuan
Copy link
Owner

zhouxingtuan commented Jul 15, 2020

Thanks for the great work!
The DB may corrupted in the error-prone environment(external interrupt or unexpected power off, etc.) occasionally. Is it possible to check the DB file integrity and do some basic recovery when it corrupted?

这个是很久以前写的一个,用于手机客户端的简单KV存储,其中对key做了不定长处理,导致出现的这些Bug。我后来写的一些存储都是定长key存储了,绕过了这些复杂的合并控制。key相对来说占用空间很小,使用定长后复杂度变低,Bug就很容易控制了。这个项目我也没打算花时间改成定长存储,你要是愿意可以自己试试,代码量也不多。这里面也有定长数字key存储的就是index.hpp。至于数据存储丢失恢复,在服务器端都是使用前置写日志,成功写入则删除日志、不成功就从日志恢复继续写。我觉得前端要求没这个高吧。

@renewboy
Copy link
Author

感谢回复!你说的key覆盖的bug,我踩过这个坑,自己修复了,后来发现和你改的地方一样。现在的问题是断电的时候数据有可能损坏,key和value都遇到过损坏的情况

@zhouxingtuan
Copy link
Owner

zhouxingtuan commented Jul 16, 2020

感谢回复!你说的key覆盖的bug,我踩过这个坑,自己修复了,后来发现和你改的地方一样。现在的问题是断电的时候数据有可能损坏,key和value都遇到过损坏的情况

在设计的时候考虑过这方面的东西,比如,key索引里面只保存偏移和总的块数量,value文件里面才(开头)存储真实的长度。按照存储顺序:存储value->存储key索引->成功。那么出现问题的就是key出错。由于key是不定长的,而且前一个key决定了下一个key的长度。关键就是这里了,前面的一个key错乱就会导致后面的key读取出错。这个设计确实不好,我自己后面都改成了定长key。某个key损毁不会导致后面的key不能用,只是自己数据索引丢失。有两种方案:一种是增加一个更复杂的机制,可以去恢复后面的key;另一种是直接改成定长key,当然前后数据不兼容。第二种改两个地方,一个是设置key时分配固定大小,二个是初始化解析的时候,去掉前后key的长度依赖。第一种复杂机制,我建议就算了,简单好维护才是王道,这点空间浪费可以接受的。

@zhouxingtuan
Copy link
Owner

感谢回复!你说的key覆盖的bug,我踩过这个坑,自己修复了,后来发现和你改的地方一样。现在的问题是断电的时候数据有可能损坏,key和value都遇到过损坏的情况

你说的value损坏,但是key没有损坏的情况。这个可能是带有缓存的操作系统,并且操作系统写入磁盘顺序是不按照提交顺序的,就会存在这种情况。一种方法是校验码,就是key和value中都保存最后一次存储的校验码,比如现在value的开头是length,校验码。每次读取数据对比一下两边的这个码,相同就说明都成功了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants