- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我们有一个数据库,该数据库由使用 sqlite3 模块的 Python 编写的程序写入。数据库上执行了大量插入语句,但事务从未因提交而结束。
结果是我们有两个文件:
Size Time Name
855117824 2010-12-14 15:27 db
1665240 2010-12-14 15:27 db-journal
数据库文件很大,但大部分数据未提交,所以当我们从数据库中选择时,我们只得到几行。当我们执行 sql 命令 'VACUUM' 时,数据库缩小到大约 3MB。
有什么方法可以取回数据吗?
最佳答案
我使用 sqlite3
shell 程序进行了一些测试。
假设 sqlite3 Python 模块以相同的方式运行,似乎没有办法可靠地恢复未提交的事务。
对于相对较少的语句,未提交的事务似乎只保留在应用程序内存中,没有数据写入文件系统。一旦数据库连接关闭或应用程序终止,这些插入将完全丢失。
对于较大的事务 block ,数据被写入文件系统,但一旦数据库连接关闭或(如果应用程序崩溃)下次打开数据库时,数据就会被清除。简而言之,为未提交的事务分配新的 DB 页面,但如果未提交事务,它们将被视为可用空间,这就是 VACUUM
减小 DB 大小的原因。这些页面将在下次写入 DB 文件时被写入(并且它们的数据丢失)。如果它们位于数据库文件的末尾,则文件会在清理时被截断。
您可能能够从执行的最后一个未提交的事务中恢复一些数据,只要之后没有执行其他写入事务。从你的问题的措辞方式来看,听起来好像整个数据库都是在单个程序运行和单个事务中创建和填充的(尽管 VACUUM
那时不会产生这么大的文件)。在那种情况下,事情可能会更容易一些。
这在很大程度上取决于异常程序的终止方式。如果您允许它优雅地终止,它可能有时间进行清理,在这种情况下这是不可取的。既然你有 DB 日志,我会假设它有一个更暴力的结局。
无论如何,您至少必须深入研究 sqlite3 DB 文件格式并修改库代码以解析未提交的数据。您仍然会丢失保留在应用程序内存中的那些交易部分。
如果 DB 文件中有空闲页面(例如来自 DELETE
语句),则可能还有旧事务的片段,尽管解释这些片段是另一回事。
在我看来,整个行动将偏离(如果不是完全进入)计算机取证和数据恢复领域,以及所有相关问题。除非您拥有无法通过任何其他方式获得的非常重要的数据,否则我怀疑它是否足够简单,值得您为此付出努力。
关于sql - 从未提交的事务中恢复数据库行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4445366/
背景 我最近在 merge 期间遇到了一个意外未 merge 的文档文件的问题。 无论出于何种原因,我搞砸了 merge 并有效地删除了文件(和其他几个文件),因为我忘记了它们的存在。 现在我想查看我
我在我的网站上使用旧的 mysql 版本和 php 版本 4。 我的表结构: | orders_status_history_id | orders_id | orders_status_id |
我是一名优秀的程序员,十分优秀!