如何恢复损坏的SQLite3数据库?


Answers:


127

更新:现在有一个自动方法内置到SQLite中:.recover

有时,损坏仅或主要发生在索引中,在这种情况下,可以通过尝试使用来转储整个数据库.dump并使用这些命令来创建新数据库来获取部分或大部分记录:

$ sqlite3 mydata.db ".dump" | sqlite3 new.db

但是,这并不总是可能的。

最简单,最可靠的方法是从备份中还原数据库文件。


3
这实际上对我有用。“ .dump”从我的完整性检查失败的损坏文件中生成了可接受的SQL。
BrandonLWhite 2014年

3
非常感谢您的回复!在几分钟之内修复了我的数据库;)但是,值得注意的是,所有包含格式错误数据的条目都将不会被复制,并且新数据库将包含所有可以从旧数据库中恢复的条目。只需看一下.dump的输出,您就会看到数据库的工作方式以及哪些条目会产生错误;)
LukeLR 2015年

我只是尝试了一个类似的问题,它给了我一个空文件,没有反馈。没有“ | sqlite3 new.db”部分,它会给我反馈,但没有文件。帮助任何人?
Ne Mo

@NeMo阅读答案的最后两句话。
CL。

1
@NeMo CL编写的命令分为2部分。第一部分创建整个数据库(.dump)的SQL脚本。后半部分将其写入新的数据库。但是,因为它正在将一个命令的输出传递到另一个命令,所以您永远不会获得实际的文件。如果将第一个命令的输出通过管道传输到文件,则可以对其进行编辑。因此,如果您改为运行,sqlite3 mydata.db ".dump" > db_script.sql您将获得一个SQL脚本,您可以对其进行编辑,并确保最后没有像ROLLBACK这样的陌生内容。然后,您可以使用sqlite3 recovered.db < db_script.sql
RobbZ '19

25

对于Sqlite 3.29.0.recover,CLI引入了一个新命令:

添加“ .recover”命令,该命令尝试从损坏的数据库文件中恢复尽可能多的内容。

sqlite3 broken.db ".recover" | sqlite3 new.db

该命令不起作用,它显示“ SQL错误:数据库磁盘映像格式错误” ..我知道它已损坏,我正在尝试恢复
SubqueryCrunch

@SubqueryCrunch我分享了我遇到的事情。希望SQLite的人能看到您的消息。当我的第一页本身损坏时,我遇到了这个“格式错误”的错误。
阿伦

3
这对我有用(尽管我内存不足)。我曾经用过sqlite3 broken.db ".recover" | sqlite3 new.db
卢卡

1
“ .recover”对我来说> 1Gb数据库。恢复数据库只用了1分钟,因此它比我以前尝试过的任何商用SQLite恢复工具都效率更高(其中一些工具甚至无法恢复数据库,而其他工具则花费了近一个小时的时间)。非常感谢SQLite开发人员团队的这一非常有用的功能
Thomas Bernard

20

我有一个损坏的sqlite文件,它会显示这样的症状。

select count(*) from corruptTable;
return:38000;

但是当我尝试用

select * from corruptTable;

它只会返回7条记录。

我尝试了几件事,但是这些步骤是最成功的。

在Mac上,打开终端并在损坏的数据库上运行这些命令。(这些是sqlite3命令,因此您应该能够使用其他sqlite3编辑器或其他系统中的类似命令)。

1 sqlite3 dbWithCorruptTable.sqlite (Obviously replace "dbWithCorruptTable" to your sqlite3 file that has the corrupt table)
2 .mode insert
3 .output dump_all.sql
4 .dump
5 .exit
6 Manually edit the dump_all.sql file in a text editor and remove the transaction statements. Usually there is a "BEGIN TRANSACTION" statement on the 2nd line of the file and a "ROLLBACK" statement on the last line. Remove these and save the file

这些步骤来自以下网站:http://www.dosomethinghere.com/2013/02/20/fixing-the-sqlite-error-the-database-disk-image-is-malformed/


4
注意:如果文件很大(例如500Mb),则无法轻松编辑SQL文件。然后,您应该使用以下命令行:-> cat dump_all_last.sql | grep -v TRANSACTION | grep -v ROLLBACK> dump_all_last_notrans.sql
Nadir

1
Good Point Nadir,谢谢您添加评论。
johnrechd 2015年

您是否知道如何将其放入Automator应用程序?
callisto '16

1
这种方法对于小型数据库可能很好,但是在8.5GB的数据库上,它可以产生约15GB的SQL代码。甚至Visual Studio编辑器也无法打开此文件在我的计算机上进行编辑。
三月

对于那些数据库太大而无法读入编辑器的人来说,这只是一个建议。只需编写一个简单的文件解析程序即可读取文件并查找事务语句并将其删除(或将每一行写入新文件并排除其中)。实施应该不是最糟糕的事情。
johnrechd

11

如果数据库严重损坏,.dump将包含错误,并且某些数据可能会丢失。

对于更复杂的数据模式,这将意味着孤立的记录和/或部分记录,这可能会使应用程序感到困惑。

最好是.dump使用文件,然后使用文本编辑器删除有问题的行。ERROR在转储文件中搜索。


将转储直接传递到sqlite3不能单独工作,删除临时转储中的错误行将其修复。
亚历山德拉·拉沃

8

我可以通过以下方式修复我的Chrome历史记录文件(这是sqlite3数据库文件):

sqlite3.exe History ".backup History-new"

2
太好了!我一直使用.dump,然后将其加载到新数据库中。您的方法有一个好处,那就是它可以用于使用自定义归类等不使用.dump的数据库。
mz2

7

我的方法很相似,可以防止错误回滚脚本:

sqlite3 database.db ".dump" | sed -e 's|^ROLLBACK;\( -- due to errors\)*$|COMMIT;|g' | sqlite3 database.new

1
这是允许我修复nextcloud sqlite db方案的唯一方法,因此我可以还原备份(这需要运行主脚本,这会避免早期的模式错误)。
TauPan

这使我得以恢复AWS CLI的历史记录,由于损坏的history db经常错误地发出database disk image is malformed
阿舒托什·金达尔

6

我知道这是一个老问题,但是我仍然想分享我的解决方案。我的问题是kodi(xbmc)的sqlite3数据库已损坏。

.dump在我的情况下不起作用

file is encrypted or is not a database

起作用的是以下内容:

  1. 备份了旧的db文件
  2. 让Kodi创建一个新的数据库文件
  3. 检查这个站点了sqlite文件的头格式
  4. 使用十六进制编辑器(bless)打开两个文件,并检查前96个字节
  5. 前40个字节不同,因此我将前40个字节从新的db文件复制到了旧的db文件
  6. 完成此操作后,我的数据库文件再次工作!

1
好一个。完成此操作后,您可能应该立即重建数据库,例如在其他答案中使用.dump/ .repair,以确保文件具有完整的完整性。
mwfearnley '20

4

编译指示writable_schema禁用某些完整性检查,因此这两个命令也可以解决问题,从而使数据库自定义保持在适当的位置:

PRAGMA writable_schema=ON;
VACUUM;

这使我能够恢复非常损坏的数据库!干杯!
SubqueryCrunch

2

这为我工作:

此处下载sqlite3工具包,并将其放在任何文件夹中。将损坏的数据库放在同一文件夹中。

打开命令提示符。

输入以下内容:

sqlite3.exe

(按Enter)

NAME_OF_YOUR_CORRUPTED_DATABASE>“ .dump” | sqlite3 new.db

(按Enter)

所有其他解决方案都不适用于我。


1
这看起来像是已接受答案的交互式版本?(尽管显然是Windows特定的。。)
mwfearnley '20


1

以下修复程序可以在不运行任何命令行工具的情况下修复我的数据库。

当我使用其中一个表时,出现“数据库磁盘映像格式错误”错误消息,因此我运行了[PRAGMA完整性_检查],该返回

主空闲列表:标题中的空闲页面数太少

在第16198页的树上的单元格1:第14190页的第二次引用

从未使用过的页面16988

从未使用过的页面46637

索引indexname1中缺少第4493行

索引indexname2中缺少第4493行

索引indexname3中缺少第4493行

我首先用错误的索引保存了表的架构,以便重新创建这些索引。然后,我使用[drop index _]命令删除了索引名称1、2和3的索引。我将表一一导出到JSON文件,然后将每个表都截断。此时运行完整性检查已成功。然后,我使用[create index _]命令重新添加了三个索引,并从其JSON文件导出中导入了每个表的记录。运行完整性检查命令仍返回“ ok”,并还原所有记录。


0

我什至无法通过sql语句仅删除所有损坏的行后,通过以下步骤修复了该问题。

  1. 使用sqlite浏览器和PRAGMA完整性检查打开* .db ; 指示损坏的表。
  2. 通过sqlite浏览器将此表导出为csv
  3. 删除表中的所有内容。从[表名]删除
  4. 使用sqlite浏览器导入csv并选择导入设置->高级->冲突策略->忽略行
  5. 之后,我的完整性检查正常
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.