Bob*_*bby 17 firefox data-recovery database sqlite places.sqlite
我的 RAM 出现了一些问题(蓝屏几次,Windows XP),现在我的 Firefox 数据库已损坏。Firefox的工作,但我的历史消失了,它的报告执行时数不一致和错误pragma integrity_check
的places.sqlite
:
数据库磁盘映像格式错误
现在的问题是,如何修复 SQLite 数据库?
bwD*_*aco 26
由于必须关闭 Firefox 才能执行此过程,因此请务必在其他 Web 浏览器中打开此页面或将其打印出来,然后再继续。
经过几个小时的工作试图恢复 Places 数据库,甚至阅读了 Firefox 源代码,我已经成功了。这是我如何做到的:
C:\Users\<username>\AppData\Roaming\Mozilla\Firefox\Profiles\<code>.default
文件夹中。places.sqlite
文件中。如果文件因损坏而被替换,请使用该places.sqlite.corrupt
文件进行恢复。创建文件的备份副本,命名为places.sqlite.bak
或places.sqlite.corrupt.bak
。sqlite3 places.sqlite
或sqlite3 places.sqlite.corrupt
),然后输入:.output dump.sql -- sends output to file dump.sql
.dump -- dumps database to file
Run Code Online (Sandbox Code Playgroud)
由于数据库已损坏,因此生成的数据库转储不完整,并且未检索到所有可恢复数据。要确定错误发生的位置,请ERROR
在转储文件内的 SQL 注释中搜索单词(全部大写)dump.sql
(我使用Notepad++来执行此操作),并读取其INSERT
上方的 SQL命令以确定有问题的表。就我而言,损坏的表是moz_places
. (可以在此处找到对 Places 数据库中的表的描述,其中包括过时的 ER 图。)我将仅说明如何从该表中恢复其他数据;以下过程可能不适用于其他表格,因此如果涉及的表格不是其他表格,请跳过这些子步骤moz_places
。)
moz_places
表中的每一行都有一个 ID。按照此 ID 的顺序从表中转储行。1 ID 是INSERT
语句中左括号后面的第一个值。数据库损坏的区域很可能是这个表中的一小块行;这里的想法是跳过这个损坏的区域并尽可能多地恢复数据。此类块的起始区域在转储中表示为ERROR
注释出现之前的行。使用该行的 ID,我们可以确定数据库损坏的位置。我们通过使用SELECT
带有 ID 作为条件的语句来实现;这个过程需要一些反复试验。例如,如果错误之前的最后一个 ID 是 49999,并且错误随之而来,则损坏的块从 ID 50000 开始。使用如下语句:-- 抑制不必要的输出 -- 以下命令适用于Windows系统 -- 对于 Linux 和其他 Unix 和类 Unix 系统,使用 .output /dev/null .输出空 SELECT id FROM moz_places WHERE id >= 50100;
id >=
,重复上面的SELECT
命令,直到找到不导致SQLite输出错误的最小值。这是指从我们可以恢复额外数据的行开始的 ID。假设此 ID 为 50200。要转储此数据,请输入:.output dump2.sql .mode 插入 SELECT * FROM moz_places WHERE id >= 50200; -- 恢复正常输出行为 .输出标准输出 .mode 列表
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
):
PRAGMA user_version=<版本>; PRAGMA journal_mode = truncate; PRAGMA page_size = 32768; 真空; PRAGMA journal_mode = wal;
places.sqlite
,然后启动 SQLite shell,places.sqlite
使用sqlite3 places.sqlite
. 键入.read dump.sql
以将 SQL 转储加载到数据库中。更多相关信息可在以下页面找到:
此 MDN 文章中描述了一个简化的过程,但我尚未对其进行测试。尽管如此,我已经合并PRAGMA
了那篇文章中的更新命令。
1 SQL 通常不保证以任何顺序给出数据库输出,除非您使用该ORDER BY
子句。但是,ORDER BY
可能无法在损坏的数据库上生成任何输出(因为 SQLite 需要读取整个表才能生成任何输出)。据我所知,Firefox 总是moz_places
使用顺序 ID写入表条目,因此我们可以假设所有输出都是按 ID 排序的。
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
Run Code Online (Sandbox Code Playgroud)
启动火狐浏览器。历史应该再次发挥作用。
我使用的是装有 Firefox 60.0.1 的 Mac。您可能需要针对您的平台调整命令。
归档时间: |
|
查看次数: |
28158 次 |
最近记录: |