【问题标题】:SQLite Backup StrategySQLite 备份策略
【发布时间】:2013-04-19 13:22:37
【问题描述】:

我正在尝试从每隔 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​​ 包装器 - 没有机会 ;(

【问题讨论】:

    标签: sqlite backup database-backups


    【解决方案1】:

    如果您想在查询运行时进行备份,则需要使用备份 API。 The documentation 有一个正在运行的数据库的在线备份示例(示例 2)。我不了解 Ruby 参考,您可以将其集成到您的程序中,或者将其作为一个在实际应用程序之外运行的小型 C 程序来执行——我都做过。

    对备份进行显式完整性检查是多余的。备份 API 保证目标数据库是一致的和最新的。 (硬币的另一面是,如果您在备份运行时过于频繁地更新数据库,备份可能永远不会完成。)

    可以使用“cp”进行备份,但不能备份正在运行的数据库。您需要在整个备份期间拥有一个独占锁,因此它并不是真正的“实时”。您还需要小心复制所有 sqlite 的临时文件以及主数据库。

    我希望 sqlite3 ".backup" 命令使用备份 API。

    【讨论】:

      【解决方案2】:

      如果您无法使用备份 API,则必须使用另一种机制来防止在复制数据库文件时对其进行修改。

      BEGIN IMMEDIATE开始一个事务:

      在 BEGIN IMMEDIATE 之后,没有其他数据库连接能够写入数据库或执行 BEGIN IMMEDIATE 或 BEGIN EXCLUSIVE。但是,其他进程可以继续从数据库中读取数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-07
        • 2019-09-11
        • 1970-01-01
        • 1970-01-01
        • 2010-10-19
        相关资源
        最近更新 更多