我想要以高频率备份数据库,但是不能接受完全备份的成本。 似乎SQLite没有API直接进行增量备份。但我发现有一个数据更改通知回调似乎有帮助。 https://www.sqlite.org/c3ref/update_hook.html 回调的参数是操作类型,数据库名称,表名和rowID。但是,我不知道是否可以通过这些信息为这一行日期生成备份信息(例如,SQL语句),而不知道表的详细信息。这意味着,是否有一种通用的方法为具有不同结构的表生成此操作的备份? 我知道有一些例外情况是回调不会被调用,我认为如果我定期进行完全备份,这是可以接受的。
答案 0 :(得分:2)
我一直在考虑这个想法,它并未得到SQLite的正式认可,但从理论上讲,这听起来很合理。
SQLite备份api本质上使您可以获得实时数据库文件的有效快照。同样,使用VACCUM INTO,您可以更新现有的备份数据库文件。 https://www.sqlite.org/lang_vacuum.html#vacuuminto
这是很好的备份,我们需要增量备份(有点像git)
假设我们想每小时备份一次数据库,而它的1GB数据库写的次数相对较少,每天存储24GB听起来太过分了。
我们可以利用SQLite文件格式,该格式本质上是固定的100字节标题+(page_size * num_pages)。 SQLite将始终围绕页面边界进行写操作。 page_size和num_pages存储在100字节的标头中。请参阅存储规范https://www.sqlite.org/fileformat.html
因此,我们可以做的是创建一个参考文件,该文件只是具有哈希列表的文件。假设我们使用sha256(新git版本使用的是sha256),那么它将成为文件(例如backups / 2020-02-22-19-12-00.txt)
sha256(header)
sha256(page1)
sha256(page2)
sha256(page3)
我们将相应的页面作为单独的文件存储,就像git在对象目录中一样。
例如objects / ab / cdef12343 ..
前两个字母用作目录名称,因此目录中没有太多文件。
或者,您可以仅将页面文件上传到任何云存储提供商,例如GCS,S3,Azure Blob,DO空间。这样可以进行多区域备份。
由于我们不存储页面的重复副本,因此与database_size * num_backups相比,所有备份的文件总大小非常小。
您甚至可以使用哈希文件来同步/还原SQLite文件。这就是Dropbox / rsync同步文件的方式。哈希文件告诉我们哪些页面已更改,我们仅下载更改的对象并更新文件中的这些范围。