我正在尝试从一个以5分钟为间隔运行的cronjob备份我的sqlite数据库。数据库是“实时”的,因此在我想要执行备份时会有运行的查询。
我想确定,当我备份数据库时,数据库状态良好,以便我可以依赖备份。
我目前的策略(伪代码):
function backup()
{
#try to acquire the lock for 2 seconds, then check the database integrity
sqlite3 mydb.sqlite '.timeout 2000' 'PRAGMA integrity_check;'
if (integrity is ok and database was not locked)
{
#perform the backup to backup.sqlite
sqlite3 mydb.sqlite '.timeout 2000' '.backup backup.sqlite'
if (backup could be performed)
{
#Check the consistency of the backup database
sqlite3 backup.sqlite 'PRAGMA integrity_check;'
if (ok)
{
return true;
}
}
}
return false;
}
现在,我的策略存在一些问题:
PRAGMA integrity_check;
和备份之间出现问题,我就会知道。有什么想法吗?顺便说一句,sqlite3 .backup
和一个好的cp mydb.sqlite mybackup.sqlite
之间有什么区别?
[edit] 我在嵌入式系统上运行nodejs,所以如果有人建议sqlite online backup api使用一些ruby包装器 - 没有机会;(
答案 0 :(得分:3)
如果要在查询运行时进行备份,则需要使用备份API。 The documentation有一个运行数据库在线备份的例子(例2)。我不理解Ruby参考,你可以将它集成到你的程序中,或者作为一个小的C程序运行,除了真正的应用程序之外 - 我已经完成了两个。
备份上的显式integrity_check是过度的。备份API可确保目标数据库保持一致且是最新的。 (该硬币的另一面是,如果在备份运行时经常更新数据库,则备份可能永远不会完成。)
可以使用'cp'进行备份,但不能使用正在运行的数据库。您需要在整个备份期间拥有一个独占锁,因此它并不是真正的“实时”。您还需要小心复制所有sqlite的临时文件以及主数据库。
我希望sqlite3“.backup”命令能够使用备份API。
答案 1 :(得分:2)
如果您无法使用备份API,则必须使用其他机制来防止在复制数据库文件时修改该数据库文件。
使用BEGIN IMMEDIATE开始交易:
在BEGIN IMMEDIATE之后,没有其他数据库连接可以写入数据库或执行BEGIN IMMEDIATE或BEGIN EXCLUSIVE。但是,其他进程可以继续从数据库中读取。