ฉันจะซ่อมแซมฐานข้อมูล Firefox places.sqlite ที่เสียหายได้อย่างไร


15

ฉันมีปัญหากับ RAM ของฉัน (bluescreen หลายครั้ง, Windows XP) และตอนนี้ฐานข้อมูล Firefox ของฉันเสียหาย Firefox คือการทำงาน แต่ประวัติของฉันหายไปและจะรายงานความไม่สอดคล้องกันหลายและข้อผิดพลาดเมื่อรันpragma integrity_checkบนplaces.sqlite:

อิมเมจของดิสก์ฐานข้อมูลมีรูปแบบไม่ถูกต้อง

ตอนนี้คำถามฉันจะซ่อมแซมฐานข้อมูล SQLite ได้อย่างไร


2
สำหรับการอ้างอิงในอนาคต FEBE (ส่วนขยายการสำรองข้อมูลสภาพแวดล้อม Firefox) อาจมีประโยชน์ในอนาคต คัดลอกโปรไฟล์ทั้งหมดและจัดทำเป็นสำรองข้อมูลเดียว ฉันรู้ว่ามันไม่ได้ตอบคำถามของคุณ แต่มันอาจเป็นประโยชน์ที่จะรู้ในอนาคต bit.ly/aumThw
Urda

แก้ไขเพื่อช่วยชาว Google ค้นหาคำถามนี้
bwDraco

คำตอบ:


22

บันทึก

เนื่องจากต้องปิด Firefox เพื่อทำตามขั้นตอนนี้โปรดเปิดหน้านี้ในเว็บเบราว์เซอร์อื่นหรือพิมพ์ออกมาก่อนดำเนินการต่อ


หลังจากชั่วโมงการทำงานพยายามกู้คืนฐานข้อมูล 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 เพื่อเปิดไฟล์ฐานข้อมูล ( sqlite3 places.sqliteหรือsqlite3 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ในกรณีของตารางที่เสียหายคือ (คำอธิบายของตารางที่พบในฐานข้อมูลสถานที่สามารถพบได้ที่นี่ซึ่งรวมถึงแผนภาพ ER ที่ล้าสมัย) ฉันจะอธิบายวิธีการกู้คืนข้อมูลเพิ่มเติมจากตารางนี้เท่านั้น โพรซีเดอร์ต่อไปนี้อาจไม่สามารถใช้ได้กับตารางอื่นดังนั้นให้ข้ามขั้นตอนย่อยเหล่านี้หากมีตารางอื่นนอกเหนือจากที่moz_placesเกี่ยวข้อง)

    • แต่ละแถวในmoz_placesตารางมี ID แถวจะถูกดัมพ์จากตารางตามลำดับ ID นี้ 1 ID คือค่าแรกหลังวงเล็บเปิดในINSERTคำสั่ง พื้นที่ที่ฐานข้อมูลเสียหายน่าจะเป็นบล็อกแถวเล็ก ๆ ในตารางนี้ แนวคิดที่นี่คือการข้ามพื้นที่ที่เสียหายและกู้คืนข้อมูลให้ได้มากที่สุด พื้นที่เริ่มต้นของบล็อกดังกล่าวจะถูกแสดงในการถ่ายโอนข้อมูลเป็นแถวก่อนที่ERRORความคิดเห็นจะปรากฏขึ้น การใช้ ID สำหรับแถวนี้เราสามารถกำหนดได้ว่าฐานข้อมูลเสียหายที่ไหน เราทำได้โดยใช้SELECTข้อความสั่งที่มี ID เป็นเงื่อนไข กระบวนการนี้ใช้เวลาในการทดลองและข้อผิดพลาด ตัวอย่างเช่นหาก ID สุดท้ายก่อนที่ข้อผิดพลาดคือ 49999 และข้อผิดพลาดตามมาบล็อกที่เสียหายจะเริ่มต้นที่ ID 50000 ใช้คำสั่งเช่น:

    - ระงับเอาต์พุตที่ไม่จำเป็น
    - คำสั่งต่อไปนี้สำหรับระบบ Windows
    - สำหรับ Linux และระบบที่คล้าย Unix และ Unix อื่น ๆ ให้ใช้ .put / dev / null
    .output NUL
    
    เลือก id จาก moz_places WHERE id> = 50100;
    
    • ปรับค่าตามหลังid >=และทำซ้ำSELECTคำสั่งด้านบนจนกว่าคุณจะพบค่าน้อยที่สุดที่ไม่ทำให้ SQLite แสดงผลข้อผิดพลาด นี่คือ ID ที่อ้างถึงแถวที่เราสามารถกู้คืนข้อมูลเพิ่มเติมได้ สมมติว่า ID นี้คือ 50200 ในการดัมพ์ข้อมูลนี้ให้ป้อน:

    .output dump2.sql
    .mode แทรก
    SELECT * จาก moz_places WHERE id> = 50200;
    
    - เรียกคืนพฤติกรรมการส่งออกปกติ
    .output stdout
    .mode รายการ
    
    • โปรดทราบว่าINSERTงบในdump2.sqlไฟล์เริ่มต้นด้วยเพื่อใช้ค้นหาและแทนที่คุณลักษณะในการแก้ไขข้อความของคุณที่จะเปลี่ยนทุกกรณีของสายนี้ด้วยINSERT INTO table VALUESINSERT INTO moz_places VALUES
    • คัดลอกเนื้อหาทั้งหมดของdump2.sqlไฟล์และวางลงในdump.sqlไฟล์ที่ERRORความคิดเห็นปรากฏขึ้น
  • แทนที่ในตอนท้ายของไฟล์ที่มีROLLBACK; -- due to errorsCOMMIT;
  • เพิ่มรหัสต่อไปนี้ที่ด้านบนของdump.sqlไฟล์ แทนที่<version>ด้วยค่าที่ถูกต้องซึ่งเป็นสิ่งจำเป็นสำหรับ Firefox เพื่อกำหนดเวอร์ชันสกีมาฐานข้อมูลตามเวอร์ชันของ Firefox ดังนี้ (สามารถพบได้ในไฟล์ต้นฉบับของ Firefox toolkit/components/places/Database.cpp):
    • Firefox 52: schema เวอร์ชั่น 35
    • Firefox 53: schema เวอร์ชั่น 36
    • Firefox 57: สกีมาเวอร์ชัน 39
    • Firefox 58: schema เวอร์ชัน 41
    • Firefox 60: schema เวอร์ชั่น 43
    • Firefox 61: schema เวอร์ชั่น 47
    • Firefox 62: schema รุ่น 52
    • Firefox 69: schema เวอร์ชั่น 53

PRAGMA user_version = <version>;
PRAGMA journal_mode = truncate;
PRAGMA page_size = 32768;
เครื่องดูดฝุ่น;
PRAGMA journal_mode = wal;
  • ออกจาก SQLite เปลือกลบplaces.sqliteแล้วเริ่มต้นเปลือกของ SQLite การสร้างที่ว่างเปล่าฐานข้อมูลโดยใช้places.sqlite sqlite3 places.sqliteพิมพ์.read dump.sqlเพื่อโหลด SQL dump ลงในฐานข้อมูล
  • เริ่ม Firefox และยืนยันว่าประวัติและแถบตำแหน่งของคุณทำงานได้ตามที่ต้องการ เมื่อคุณยืนยันว่าทุกอย่างเรียบร้อยแล้วให้ลบไฟล์ดัมพ์ฐานข้อมูลและเชลล์ SQLite ที่สามารถเรียกทำงานได้จากโฟลเดอร์โปรไฟล์

ข้อมูลที่เกี่ยวข้องเพิ่มเติมสามารถพบได้ในหน้าต่อไปนี้:

ขั้นตอนง่ายอธิบายไว้ในบทความ MDN นี้แต่ฉันยังไม่ได้ทดสอบ อย่างไรก็ตามฉันได้รวมPRAGMAคำสั่งที่อัปเดตจากบทความนั้นแล้ว


1โดยปกติ SQL จะไม่รับประกันว่าจะให้เอาต์พุตฐานข้อมูลในลำดับใด ๆ เว้นแต่ว่าคุณจะใช้ORDER BYคำสั่งย่อย อย่างไรก็ตามORDER BYมีแนวโน้มที่จะล้มเหลวในการสร้างเอาต์พุตใด ๆ บนฐานข้อมูลที่เสียหาย (เนื่องจาก SQLite จะต้องอ่านตารางทั้งหมดก่อนที่จะสามารถสร้างเอาต์พุตใด ๆ ) เท่าที่ฉันรู้ Firefox จะเขียนmoz_placesรายการตารางที่มี ID ตามลำดับเสมอดังนั้นเราจึงสามารถสันนิษฐานได้ว่าเอาท์พุททั้งหมดเรียงลำดับตาม ID


3
นี่คือสุดยอดที่บริสุทธิ์ ช่วยฉันกู้คืนประวัติเกือบทั้งหมดจากสถานที่ที่เสียหาย sqlite ขอบคุณมาก!!
Ashutosh Jindal

มันช่วยได้ด้วยการแก้ไขสองแบบ: 1) เพิ่ม ";" ในบรรทัด user_version; 2) ด้วยเหตุผลบางอย่างไฟล์ "เสียหาย" ของฉันมีรุ่นสคีมาที่ "น้อยกว่าที่คาด" หลังจากวิธีการของคุณใช้งานไม่ได้ในตอนแรกฉันพยายามนำเข้าดัมพ์ไปยังฐานข้อมูลใหม่ 10MB และล้มเหลวเนื่องจากตารางเก่ามีหนึ่งคอลัมน์น้อยลง การดูลิงก์ซอร์สโค้ดทำให้ฉันเข้าใจว่าเกิดอะไรขึ้น โพสต์ที่น่ากลัว !!!
Tilman Hausherr

@TilmanHausherr: ที่อยู่ เพื่อหลีกเลี่ยงปัญหาการเปลี่ยนแปลงคอลัมน์โปรดปฏิบัติตามขั้นตอนในคำตอบนี้ทันทีที่คุณสังเกตเห็นความเสียหายและก่อนที่จะอัปเดต Firefox เพื่อให้สคีมาฐานข้อมูลไม่เปลี่ยนแปลง คุณสามารถลองตั้งค่าสคีมาที่เก่ากว่าได้ - Firefox จะอัปเดตเป็นเวอร์ชันใหม่เมื่อคุณกู้คืนฐานข้อมูล
bwDraco

การตั้งค่าเวอร์ชันสกีมาก่อนหน้านี้เป็นสิ่งที่ฉันได้ทำเมื่อเขียนความคิดเห็นแรกของฉันคือฉันประสบความสำเร็จแล้ว :-) ใช่ฉันสงสัยว่าฉันไม่ได้สังเกตเห็นความเสียหายทันทีฉันมักจะสังเกตเห็นเฉพาะเมื่อป้อนอักขระที่ควรทำ "URL เก่า" ปรากฏขึ้นและไม่มีอะไรเกิดขึ้น
Tilman Hausherr

เยี่ยมมาก! ดีใจที่คุณอัปเดตซึ่งใส่กลับไปในคำถามที่ใช้งานอยู่ที่ฉันเห็น
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ได้ ตอนนี้ทุกคนหายไปแล้ว แต่ฉันกำลังสร้างใหม่เมื่อฉันเยี่ยมชมเว็บไซต์ ขอบคุณอีกครั้ง!
Bobby

stackoverflow.com/questions/2255305/…ลิงก์ในคำถามข้างต้นถูกลบโดยสมัครใจโดยผู้เขียน คำตอบด้านล่างอาจช่วยได้
user66001

@ user66001: ใช่ OP ลบคำถามของพวกเขา ฉันคัดลอกคำสั่งที่เกี่ยวข้อง
sleske

สิ่งนี้ไม่ได้ผลสำหรับฉันและฉันลงเอยด้วยplaces.sqlite.corruptไฟล์ ฉันโพสต์คำตอบอื่นด้วยโซลูชันที่เหมาะกับฉัน
Daniel

2

เช่นเคยกับการซ่อมแซมเช่นนี้ฉันขอแนะนำให้คุณทำสำเนาสำรองอย่างน้อยหนึ่งไฟล์ของ places.sqlite ของคุณซึ่งอยู่ในไดเรกทอรีโปรไฟล์ของคุณ การมีการสำรองข้อมูลช่วยให้คุณลองทำสิ่งต่าง ๆ เพื่อซ่อมแซมปัญหาดังกล่าวโดยที่รู้ว่าหากการซ่อมแซมที่พยายามทำนั้นแย่ลงคุณสามารถทำสำเนาสำรองอีกครั้งหนึ่งซึ่งจะลองอีกครั้ง

ทั้งนี้ขึ้นอยู่กับสิ่งที่ได้รับความเสียหายและวิธีการที่ไม่ดีมันเสียหายก็อาจจะเป็นไปได้ที่จะแก้ไขปัญหากับส่วนขยายสถานที่การบำรุงรักษา ฉันลงเอยด้วยไฟล์ 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 ประวัติควรจะทำงานอีกครั้ง

ฉันใช้ Mac ด้วย Firefox 60.0.1 คุณอาจต้องปรับคำสั่งสำหรับแพลตฟอร์มของคุณ


ขอบคุณ Daniel ที่เป็นประโยชน์เสมอในการดูขั้นตอนคำสั่งจริง
not2qubit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.