我该如何修复损坏的Firefox place.sqlite数据库?


15

我的RAM出现了一些问题(多次蓝屏,Windows XP),现在Firefox数据库已损坏。Firefox的工作,但我的历史已经一去不复返了,它的报告数的不一致和执行时错误pragma integrity_checkplaces.sqlite

数据库磁盘映像格式错误

现在的问题是,如何修复SQLite数据库?


2
供将来参考,FEBE(Firefox环境备份扩展)将来可能会有所帮助。复制整个配置文件,并将其打包为单个备份。我知道它不能回答您的问题,但是将来了解它可能会有所帮助。bit.ly/aumThw
Urda 2010年

编辑以帮助Google员工查找此问题。
bwDraco 2014年

Answers:


22

注意

由于必须关闭Firefox才能执行此过程,因此请确保在其他Web浏览器中打开此页面或将其打印出来,然后再继续。


经过数小时的工作,尝试恢复Places数据库,甚至阅读Firefox源代码,我都成功了。这是我的操作方式:

  • 下载最新版本的SQLite Shell,并将其解压缩到您的配置文件文件夹中。在Windows Vista和Windows 7上,它位于C:\Users\<username>\AppData\Roaming\Mozilla\Firefox\Profiles\<code>.default文件夹中。
  • 如果正在运行,请关闭Firefox。
  • 位置数据库在places.sqlite文件中。如果由于损坏而替换了文件,请使用该places.sqlite.corrupt文件进行恢复。创建文件的备份副本,命名为places.sqlite.bakplaces.sqlite.corrupt.bak
  • 使用SQLite Shell打开数据库文件(sqlite3 places.sqlitesqlite3 places.sqlite.corrupt),然后输入:
.output dump.sql    -- sends output to file dump.sql
.dump               -- dumps database to file
  • 由于数据库已损坏,因此导致的数据库转储未完成,并且未检索到所有可恢复的数据。若要确定错误发生的位置,请ERROR在转储文件中的SQL注释中搜索单词(全部大写)dump.sql(我使用Notepad ++进行此操作),然后阅读其INSERT上方的SQL 命令以确定所涉及的表。就我而言,损坏的桌子是moz_places。(可以在此处找到对在Places数据库中找到的表的描述,其中包括过时的ER图。)我将仅说明如何从该表中恢复其他数据。以下过程可能不适用于其他表,因此,如果moz_places所涉及的表不是该表,请跳过这些子步骤。)

    • moz_places表中的每一行都有一个ID。按照该ID的顺序从表中转储行。1 ID是INSERT语句中左括号后面的第一个值。数据库损坏的区域可能是该表中的一小排行;这里的想法是跳过这个损坏的区域并恢复尽可能多的数据。这样的块的开始区域在转储中表示为ERROR注释出现前的行。使用该行的ID,我们可以确定数据库损坏的位置。为此,我们使用SELECTID为条件的语句;此过程需要一些反复试验。例如,如果错误之前的最后一个ID是49999,并且随后出现错误,则损坏的块将从ID 50000开始。使用如下语句:

    -抑制不必要的输出
    -以下命令适用于Windows系统
    -对于Linux和其他Unix及类似Unix的系统,请使用.output / dev / null
    。输出NUL
    
    SELECT ID来自moz_places,其中id> = 50100;
    
    • 调整之后的值,id >=并重复上述SELECT命令,直到找到不会导致SQLite输出错误的最小值。这是引用行的ID,我们可以从该行开始恢复其他数据。假设此ID为50200。要转储​​此数据,请输入:

    .output dump2.sql
    .mode插入
    选择*从moz_places,其中id> = 50200;
    
    -恢复正常的输出行为
    .output标准输出
    。模式列表
    
    • 请注意,文件中的INSERT语句以dump2.sql开头INSERT INTO table VALUES,因此请使用文本编辑器中的“查找和替换”功能以将该字符串的所有实例替换为INSERT INTO moz_places VALUES
    • 复制dump2.sql文件的全部内容,并将其粘贴到出现注释的dump.sql文件中ERROR
  • ROLLBACK; -- due to errors文件末尾的替换为COMMIT;
  • 将以下代码添加到dump.sql文件顶部。替换<version>为正确的值,这是Firefox根据Firefox的版本确定数据库架构版本所必需的,如下所示(可在Firefox源文件中找到toolkit/components/places/Database.cpp):
    • Firefox 52:架构版本35
    • Firefox 53:架构版本36
    • Firefox 57:架构版本39
    • Firefox 58:架构版本41
    • Firefox 60:架构版本43
    • Firefox 61:架构版本47
    • Firefox 62:架构版本52
    • Firefox 69:架构版本53

PRAGMA user_version = <版本>;
PRAGMA journal_mode =截断;
PRAGMA page_size = 32768;
真空;
PRAGMA journal_mode = wal;
  • 退出SQLite Shell,删除places.sqlite,然后使用启动SQLite Shell创建一个空places.sqlite数据库sqlite3 places.sqlite。键入.read dump.sql以将SQL转储加载到数据库中。
  • 启动Firefox并确认您的历史记录和位置栏是否按预期运行。确认一切正常后,从配置文件文件夹中删除数据库转储文件和SQLite Shell可执行文件。

可在以下页面上找到更多相关信息:

此MDN文章中介绍了简化的过程,但我尚未对其进行测试。尽管如此,我已经合并PRAGMA了该文章中的更新命令。


1 SQL通常不保证数据库输出将以任何顺序给出,除非您使用该ORDER BY子句。但是,ORDER BY可能不会在损坏的数据库上产生任何输出(因为SQLite必须先读取整个表才能产生任何输出)。据我所知,Firefox总是moz_places使用顺序ID 编写表条目,因此我们可以假定所有输出均按ID排序。


3
这真是太棒了。帮助我从一个损坏的places.sqlite恢复了几乎所有历史记录。非常感谢!!
2014年

它确实有所帮助,但有两个修改:1)添加“;” 在user_version行中;2)由于某种原因,我的“损坏”文件的架构版本比预期的“少”。在您的方法最初无效后,我尝试将转储导入10MB新数据库中,但由于旧表少了一列而失败。看一下源代码链接使我了解发生了什么。很棒的帖子!!!
Tilman Hausherr 2014年

@TilmanHausherr:致辞。为避免列更改问题,请确保在发现损坏后并在更新Firefox之前立即执行此答案中的步骤,以使数据库架构不变。您也可以尝试设置较旧的架构版本-还原数据库时,Firefox会将其更新为新版本。
bwDraco

设置先前的架构版本是我在编写第一个注释时所做的,即我已经成功了:-)是的,我怀疑我没有立即注意到损坏,我通常只在输入应该使出现“旧URL”,但没有任何反应。
Tilman Hausherr 2014年

优秀作品!很高兴您进行了更新,这使它重新回到了我发现它的活跃问题中。
fixer1234年

4

好吧,根据损坏程度的不同,可能无法修复。最好的选择可能是尝试使用来转储数据库sqlite,然后看看您可以挽救什么。

如果失败,则可能必须从备份中还原。

要转储并重新创建数据库,请使用以下命令.dump

sqlite places.sqlite .dump | sqlite places-new.sqlite

1
谢谢。SO帖子没有用,因为它没有用,但是链接中引用的解决方案确实有用d:\sqlite3.exe d:\idimager.cat.db .dump | d:\sqlite3.exe d:\newdb.cat.db。现在所有图标都消失了,但是当我访问这些站点时,它们正在重建。再次感谢!
鲍比,2010年

上述问题中的stackoverflow.com/questions/2255305/…链接已被其作者自愿删除。下面的答案可能会有所帮助。
2013年

@ user66001:是的,OP删除了他们的问题。我复制了相关命令。
sleske

这对我不起作用,我最终得到了一个places.sqlite.corrupt文件。我发布了另一个答案,给出了适合我的解决方案。
丹尼尔(Daniel)

2

与以往一样,建议您首先对个人资料目录中的places.sqlite文件进行至少一个备份。拥有备份可以让您尝试各种不同的方法来修复此类问题,同时知道如果尝试进行的修复会使情况变得更糟,则始终可以制作另一个备份副本,然后在该副本上再次尝试。

根据损坏的内容以及损坏的严重程度,可能可以通过扩展Places Maintenance修复问题。在某些情况下,我最终遇到了损坏的places.sqlite文件。地方信息维护每次都能通过运行其选项对话框中提供的各种检查/修复来解决问题。各种不同的检查和/或报告应仅花费几分钟到几分钟。

如果这不起作用,则可能需要采用类似于DragonLord上面描述的方式进行手动修复的方法。


1

MDN上描述的过程可帮助我解决一个问题,即我访问的新页面未记录在浏览器历史记录中。我没有一个places.sqlite.corrupt(或places.sqlite-corrupt)文件,但是检查我places.sqlite文件的完整性后发现数据库磁盘映像格式错误。

退出Firefox并备份Firefox配置文件,然后再继续操作。

$ cd /Users/<username>/Library/Application\ Support/Firefox/Profiles/<profile_dir>/
$ cp places.sqlite places.sqlite.bak  # for safety

$ sqlite3 places.sqlite
sqlite> PRAGMA integrity_check;
*** in database main ***
On tree page 2 cell 131: Rowid 20884 out of order
...
Error: database disk image is malformed
sqlite> .clone places-clone.sqlite
moz_places... done
moz_historyvisits... done
... more output like above plus a few errors (which I ignored) like
sqlite_sequence... Error: object name reserved for internal use: sqlite_sequence
SQL: [CREATE TABLE sqlite_sequence(name,seq)]
done
...
sqlite> PRAGMA user_version;
43  <----- TAKE NOTE OF THIS VALUE it may be different for you
sqlite> .exit

$ sqlite3 places-clone.sqlite
sqlite> PRAGMA integrity_check;
ok
sqlite> PRAGMA user_version = 43;  -- use the number you got from PRAGMA user_version; above
sqlite> PRAGMA journal_mode = truncate;
truncate
sqlite> PRAGMA page_size = 32768;
sqlite> VACUUM;
sqlite> PRAGMA journal_mode = wal;
wal
sqlite> .exit

$ mv places-clone.sqlite places.sqlite

启动Firefox。历史应该再次发挥作用。

我在装有Firefox 60.0.1的Mac上。您可能需要针对您的平台调整命令。


感谢Daniel,始终能帮助您查看实际的命令过程
not2qubit
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.