如何增量备份 SQLite 数据库?

iur*_*adz 6 sqlite backup

我想高频率备份数据库,但是全量备份的成本是不能接受的。SQLite 似乎没有 API 可以直接进行增量备份。但我发现有一个数据更改通知回调似乎很有帮助。 https://www.sqlite.org/c3ref/update_hook.html 回调的参数是操作类型、数据库名称、表名称和行 ID。但是,我不知道是否可以通过这些信息生成该行日期的备份信息(例如SQL语句),而无需了解表的详细信息。这意味着,对于不同结构的表,是否有一种通用的方法可以为该操作生成备份?我知道有一些例外情况不会调用回调,如果我定期进行完整备份,我认为这是可以接受的。

use*_*988 10

我\xe2\x80\x99一直在思考这个想法,它\xe2\x80\x99并未得到SQLite的正式认可,但理论上它听起来很合理。

\n\n

SQLite 备份 API 本质上可以让您获取实时数据库文件的工作快照。类似地,VACCUM INTO 让\xe2\x80\x99s 您更新现有的备份数据库文件。https://www.sqlite.org/lang_vacuum.html#vacuuminto

\n\n

这只是很好的 ol\xe2\x80\x99 备份,我们想要增量备份(有点像 git)

\n\n

假设我们想每小时备份一次数据库,而它\xe2\x80\x99是一个1GB的数据库,写入相对较少,每天存储24GB听起来有点大材小用。

\n\n

我们可以利用 SQLite 文件格式,它本质上是固定的 100 字节标头 + (page_size * num_pages)。SQLite 将始终围绕页边界写入。page_size 和 num_pages 存储在 100 字节标头中。请参阅存储规范https://www.sqlite.org/fileformat.html

\n\n

所以我们可以做的是创建一个参考文件,它只是一个带有哈希列表的文件。假设我们使用 sha256 (这是新的 git 版本使用的),所以它将是一个文件(例如 backups/2020-02-22-19-12-00.txt)

\n\n
sha256(header)\nsha256(page1)\nsha256(page2)\nsha256(page3)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我们将相应的页面存储为单独的文件,就像 git 在对象目录中所做的那样。

\n\n

例如对象/ab/cdef12343..

\n\n

前两个字母用作目录名称,因此目录中不会有太多文件。

\n\n

或者,您可以将页面文件上传到任何云存储提供商,例如 GCS、S3、Azure Blob、DO 空间。这可以提供多区域备份。

\n\n

由于我们\xe2\x80\x99不存储页面的重复副本,因此与database_size * num_backups相比,所有备份的总文件大小非常小。

\n\n

您甚至可以使用哈希文件作为同步/恢复 SQLite 文件的方式。这就是 Dropbox/rsync 同步文件的方式。哈希文件告诉我们哪些页面发生了更改,我们只下载更改的对象并更新文件中的这些范围。

\n