命名空间和友元冲突
今天遇到一个问题,需要跨namespace定义友元,这种情况比较常见的是测试类需要访问源码类,gtest据说有个FRIEND_TEST宏,以前用过好像有问题。这里我们直接用友元:
namespace oceanbase
{
namespace election
{
class ObElectionServer : public ObSingleServer
{
friend class ObElectionTester;
...
}
}
}
namespace oceanbase
{
namespace tests
{
namespace election
{
c...
两阶段提交协议的异常处理
两阶段提交的协议大家都比较熟悉了,解释一下每个阶段的异常处理。首先,我们需要持久化协议过程中的状态,这样如果server宕机,那么恢复的时候还能通过日志知道宕机前处于那个阶段。同时,所有对数据的修改都会先写write ahead log,保证宕机重启的之后数据也不会丢失。写日志的顺序假定为:写write ahead log-修改缓冲区-写commit/abort log。
在这个前提下,我们根据如下的时序图来讨论异常情况和处理方法。
过程a没有成功,即协调者没有收到部分参与者的回应。超时后,协调者发送abort消息给参与者取消事务。参与者存在两种情况:
- 过程1失败,网络问题导致参与者没有收到vote request消息或者此时参与者宕机。参与者重启恢复后无需...
undo 日志和redo 日志
具体的可以看这里,解释几个作者没解释清楚的问题:
只用REDO日志为什么数据修改要每次修改刷盘
如果不刷盘,不会导致数据不一致,但是数据修改过程相当于写redo日志-修改内存-写commit日志(修改内存的顺序也无所谓了),这个过程结束已经应答用户了,但是修改没有刷下去断电恢复的话也无法通过redolog恢复到当前状态,所以会丢失修改。
修改数据和写redo/undo log/commit log之间的关系是什么
任何对磁盘的数据修改落实之前都需要先写log,无论是redo还是undo。undo保证了一旦数据写了一半(脏数据)能够回滚,redo保证了写了日志的事务能够回放出来。
只使用undo的时候commit日志要等...
关于备份文件管理
最近在写一个备份的工作,备份线程每次会把需要备份的数据写到文件,同时需要保存一定数量的旧文件。
首先为了写失败的时候不会损坏之前的旧备份文件,我们需要写一个临时文件然后覆盖回去。同时,为了保存旧文件,需要每次写一个不同的文件,同时维护一个当前的最新文件,然后删除超过了一定期限的文件,假定临时文件名是file.bin.2014xxxx,最新文件名是file.bin,有如下三个方法:
每次写临时文件,同时写一个内容一样的file.bin。造成空间浪费。
每次写临时文件,同时更新软链接file.bin。不兼容非linux系统。
写manifest,文件内容是当前最新文件名。比较麻烦。
最后还是按2方案实现的,代码如下:
跟事务相关的一些文章
主要纪录一下跟事务相关的一些文章。主要是博客,有论文加论文。顺便纪念下女神订婚。图是转载。
参考文献:
[1] 数据库事务隔离级别和锁实现机制, http://comedsh.iteye.com/blog/698733
[2] 数据库事务的实现(一) 故障恢复 (undo日志), http://www.cnblogs.com/clam/archive/2012/08/27/2657943.html
[3] 数据库事务的实现-故障恢复(二)(undo日志检查点), http://www.cnblogs.com/clam/archive/2012/08/27/2657944.html
[4] 为 Key-Value 数据库实现MVCC 事务, http://juliashin...
506 post articles, 64 pages.