SQLite备份策略

时间:2013-04-19 13:22:38

标签: sqlite backup database-backups

我正在尝试从一个以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包装器 - 没有机会;(

2 个答案:

答案 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。但是,其他进程可以继续从数据库中读取。