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

Replicate a database using snapshots and transaction logs

出于学习目的,我想编写自己的数据库,能够自我复制。我取得了一些进步,但现在我面临着一个我无法解决的问题。假设我有一个数据库(我们称之为源),我想将其复制到另一个数据库(我们称之为目标)。

基本原理很简单:在源代码中,您不存储实际的 table,而是存储交易日志。将事务日志发送到目标很容易,然后数据库会在目标中重建自身。如果你想更新目标,你只需请求事务日志中自那以后发生变化的部分。基本上这就是几乎每个数据库所做的。

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

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

但是我现在面临一个问题:假设快照很大,那么可能会在发送的时候对它进行修改。这意味着复制的快照包含一些旧数据和一些新数据。现在,如何使目标数据库处于一致状态?即使我知道从哪里开始事务日志,我也必须应用已经应用到某些记录的更改,或者我必须将其保留,但更改根本不会应用到其他一些记录.

当然我可以使用顺序隔离级别,但性能会下降。当然我可以做CouchDB 会记住每条记录中的当前 table 修订版,并为每个修订版保留每条记录的副本。但随后所需的 space 会大幅增长。

那么,我该怎么办?

我在网上找到的所有东西总是要么依赖于重放整个事务日志的想法,要么使用 CouchDB 中占用大量 space 的进程。

有什么想法吗?

您的快照需要保持一致并且您需要知道它在什么时间(关于 tx 日志)是一致的。然后应用自此时起已提交的所有事务。

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

祝你项目顺利。