使用快照和事务日志复制数据库

时间:2016-02-04 10:37:05

标签: database database-replication transactional-replication

出于学习目的,我想编写自己的数据库,能够自我复制。我已经取得了一些进展,但现在我遇到了一个我无法解决的问题。假设我有一个数据库(让我们调用这个来源)我想复制到另一个数据库(让我们调用这个目标)。

基本原则很简单:在源代码中,您不存储实际的表,而是存储事务日志。通过事务日志发送到目标很容易,然后数据库会重建自己。如果要更新目标,只需请求从那时起已更改的事务日志部分。基本上这就是几乎每个数据库所做的事情。

虽然这有效但它有一个主要缺点:如果一个表已经存在了很长时间,那么事务日志很长,因此复制表需要很多时间......

为避免这种情况,您也可以存储当前状态。这意味着您拥有可以快速复制的最新快照。此外,目标必须订阅源的事务日志。一旦它包含其他条目,目标就会将它们应用于其复制的表。这也很有效,而且在性能和传输量方面也更好。

但是现在我遇到了一个问题:假设快照很大,那么可能会在交付时对其进行更改。这意味着复制的快照包含一些旧数据和一些新数据。现在,如何使目标数据库处于一致状态?即使我知道从哪里开始事务日志,我要么必须应用已经应用于某些记录的更改,要么我必须将其删除,但是然后根本不会对其他记录应用更改

当然我可以使用隔离级别顺序,但随后性能下降。当然我可以做什么,例如CouchDB会记住每条记录中的当前表修订版,并保留每个修订版的每条记录的副本。但随后所需空间大大增加。

那么,我该怎么办?

我能在网上找到的所有内容总是依赖于重播整个事务日志的想法,或者使用CouchDB中占用大量空间的进程。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您的快照需要保持一致,您需要知道它在何时(就tx日志而言)是一致的。然后,您可以应用自此时开始提交的所有事务。

可以使用独占锁定来获取一致的快照,这可能会延迟其他事务的提交或使用行版本(MVCC)。

祝你的项目好运。