87

这是之前回答的帖子的后续问题:是否有用于在 Linux 中验证 SQLite 数据库的命令行实用程序?

如果数据库产生以下错误:

$ sqlite3 mydata.db "PRAGMA integrity_check"
Error: database disk image is malformed

是否可以进行任何清理处理以将数据库恢复到可用状态?即使可能丢失一些损坏的记录?

谢谢

4

13 回答 13

140

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

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

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

然而,这并不总是可能的。

最简单、最可靠的方法是从备份中恢复数据库文件。

于 2013-08-15T19:52:19.180 回答
38

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

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

sqlite3 broken.db ".recover" | sqlite3 new.db
于 2019-09-10T13:47:34.127 回答
23

我有一个损坏的 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/

于 2015-05-20T18:30:03.097 回答
12

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

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

它可能.dump比文件更可取,然后使用文本编辑器删除有问题的行。ERROR在转储文件中搜索。

于 2014-10-24T13:58:01.867 回答
10

我的方法类似,防止错误回滚脚本:

sqlite3 database.db ".dump" | sed -e 's|^ROLLBACK;\( -- due to errors\)*$|COMMIT;|g' | sqlite3 database.new
于 2019-05-09T22:23:01.770 回答
8

我能够通过这种方式修复我的 Chrome 历史文件(这是一个 sqlite3 数据库文件):

sqlite3.exe History ".backup History-new"
于 2017-01-12T08:02:18.777 回答
6

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

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

file is encrypted or is not a database

有效的方法如下:

  1. 备份了旧的 db 文件
  2. 让 kodi 创建一个新的 db 文件
  3. 在此站点上检查了 sqlite 文件的标头格式
  4. 使用十六进制编辑器(祝福)打开两个文件并检查前 96 个字节
  5. 前 40 个字节不同,所以我将前 40 个字节从新 db 文件复制到旧 db 文件
  6. 这样做之后,我的数据库文件又工作了!!!
于 2015-04-04T12:20:47.650 回答
4

pragmawritable_schema禁用了一些完整性检查,因此这两个命令也可以解决问题,保持 db 自定义到位:

PRAGMA writable_schema=ON;
VACUUM;
于 2019-01-07T14:24:24.113 回答
2

这对我有用:

从这里下载 sqlite3 工具包并将其放入任何文件夹。将损坏的数据库放在同一个文件夹中。

打开命令提示符。

键入以下内容:

sqlite3.exe

(按回车)

NAME_OF_YOUR_CORRUPTED_DATABASE> ".dump" | sqlite3 new.db

(按回车)

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

于 2017-05-27T15:47:38.727 回答
2

我已经通过这些步骤修复了由于缺少索引而导致的数据库损坏,并且它们对我有用。

  1. DROP Index:sqlite 删除索引命令

  2. 运行真空Sqlite 真空命令

  3. 再次重新创建索引:Sqlite 创建索引

于 2019-06-03T11:47:04.373 回答
1

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

我在使用我的一张表时收到“数据库磁盘映像格式错误”错误消息,因此我运行 [PRAGMA integrity_check] 返回

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

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

页面 16988 从未使用过

页面 46637 从未使用过

索引 indexname1 中缺少第 4493 行

索引 indexname2 中缺少第 4493 行

索引 indexname3 中缺少第 4493 行

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

于 2018-06-16T06:16:24.950 回答
1

在我什至无法通过 sql 语句删除单个损坏的行之后,我通过以下步骤修复了它,只有全部。

  1. 使用sqlite 浏览器和 PRAGMA 完整性检查打开 *.db ;表示损坏的表。
  2. 通过 sqlite 浏览器将此表导出为 csv
  3. 删除表中的所有内容。从 [表名]删除
  4. 使用 sqlite 浏览器导入 csv 并在导入设置 -> 高级 -> 冲突策略 -> 忽略行中选择
  5. 之后我的完整性检查就OK了
于 2020-11-02T13:38:29.007 回答
1

如果错误PRAGMA integrity_check类似于“索引 sqlite_autoindex_XXX 中缺少行 NNN”,则可以使用命令修复索引REINDEX

于 2021-06-01T05:58:35.203 回答