我有一个应用程序,它在本地文件系统上的文件上使用QSQLITE驱动程序和QSqlDatabse。我想写一个备份函数,它将保存数据库的快照。
简单地复制文件似乎是一种明显,简单的方法,但我不确定这样做是否安全。
应用程序在定义明确的点修改数据库。每次都会创建,使用并立即销毁新的QSqlQuery对象。明确锁定/刷新是一种可接受的解决方案,但Qt API似乎没有公开这一点。
我无法找到有关Qt何时将数据库提交到磁盘的文档。我想QSqlDatabase析构函数会这样做,但即便如此,我也不知道(在Windows或Linux上)复制文件是否会导致最近的更改被复制(相反,仅限于此)那些已经在文件系统期刊中完成的更改)。有人可以确认或否认吗?如果在执行复制之前关闭写文件句柄会有什么不同吗?
也许唯一安全的方法是online copy,但我已经在使用Qt API并且不知道这将如何互动。
任何建议都将受到赞赏。
答案 0 :(得分:5)
复制SQLite数据库是微不足道的,但以不会破坏它的方式执行此操作并不是一件容易的事。这将为您提供一个很好的干净备份,确保处于正确的状态,因为在复制过程的中途写入数据库是不可能的。
QSqlQuery qry(db);
qry.prepare( "BEGIN IMMEDIATE;");
qry.exec();
QFile::copy(databaseName, destination);
qry.prepare( "ROLLBACK;");
qry.exec();
在BEGIN IMMEDIATE之后,没有其他数据库连接可以写入数据库或执行BEGIN IMMEDIATE或BEGIN EXCLUSIVE。
答案 1 :(得分:1)
这与Qt几乎没有关系。它与数据库有关。此过程适用于任何符合ACID的数据库,SQLite就是其中之一。
来自http://www.sqlite.org/transactional.html
SQLite是Transactional
事务数据库是所有更改和查询的数据库 似乎是Atomic,Consistent,Isolated和Durable(ACID)。 SQLite的 实现原子化,一致的可序列化事务 孤立的,持久的,即使交易被中断了 程序崩溃,操作系统崩溃或电源故障 计算机。
这并不意味着您可以复制文件并且它将保持一致。在复制之前,您应该使用块级快照。如果您使用的是Linux,请阅读
http://tldp.org/HOWTO/LVM-HOWTO/snapshotintro.html
程序将是,
快照是文件系统的全局“冻结”,由于ACID,它是一致的。文件复制是线性操作,如果不在复制期间暂停所有数据库操作,则无法保证一致。这意味着直接复制对于在线数据库(通常)来说是不安全的。