Come faccio a riparare un database places.sqlite di Firefox danneggiato?


15

Ho avuto alcuni problemi con la mia RAM (più volte blu-screen, Windows XP) e ora i miei database di Firefox sono danneggiati. Firefox funziona, ma la mia cronologia è sparita e segnala diverse incoerenze ed errori durante l'esecuzione pragma integrity_checksu places.sqlite:

l'immagine del disco del database non è corretta

Ora la domanda, come posso riparare i database SQLite?


2
Per riferimento futuro, FEBE (Firefox Backup Backup Extension) potrebbe essere utile in futuro. Copia l'intero profilo e lo impacchetta come un singolo backup. So che non risponde alla tua domanda, ma potrebbe essere utile saperlo in futuro. bit.ly/aumThw
Urda,

Modificato per aiutare i googler a trovare questa domanda.
bwDraco,

Risposte:


22

Nota

Poiché Firefox deve essere chiuso per eseguire questa procedura, assicurarsi di aprire questa pagina in un altro browser Web o stamparlo prima di procedere.


Dopo ore di lavoro nel tentativo di recuperare il database di Places, anche leggendo il codice sorgente di Firefox, sono riuscito ad avere successo. Ecco come l'ho fatto:

  • Scarica l'ultima versione della shell SQLite ed estraila nella cartella del tuo profilo. Su Windows Vista e Windows 7, è nella C:\Users\<username>\AppData\Roaming\Mozilla\Firefox\Profiles\<code>.defaultcartella.
  • Chiudi Firefox se è in esecuzione.
  • Il database di Places è nel places.sqlitefile. Se il file è stato sostituito a causa di corruzione, utilizzare il places.sqlite.corruptfile per il recupero. Creare una copia di backup del file, denominata places.sqlite.bako places.sqlite.corrupt.bak.
  • Utilizzare la shell SQLite per aprire il file di database ( sqlite3 places.sqliteo sqlite3 places.sqlite.corrupt), quindi immettere:
.output dump.sql    -- sends output to file dump.sql
.dump               -- dumps database to file
  • Poiché il database è danneggiato, il dump del database risultante non è completo e non sono stati recuperati tutti i dati recuperabili. Per determinare dove si è verificato l'errore, cerca la parola ERROR(tutto maiuscolo) in un commento SQL all'interno del file di dump dump.sql(ho usato Notepad ++ per farlo) e leggi il INSERTcomando SQL sopra di esso per determinare la tabella in questione. Nel mio caso, la tabella danneggiata è moz_places. (Una descrizione delle tabelle trovate nel database di Places è disponibile qui , che include un diagramma ER non aggiornato.) Spiegherò come recuperare dati aggiuntivi solo da questa tabella; la seguente procedura probabilmente non è applicabile per le altre tabelle, quindi salta questi passaggi secondari se moz_placesè coinvolta una tabella diversa da quella ).

    • Ogni riga nella moz_placestabella ha un ID. Le righe vengono scaricate dalla tabella seguendo l'ordine di questo ID. 1 L'ID è il primo valore che segue la parentesi aperta nell'istruzione INSERT. L'area in cui il database è danneggiato è probabilmente un piccolo blocco di righe in questa tabella; l'idea qui è di saltare quest'area danneggiata e recuperare quanti più dati possibili. L'area iniziale di tale blocco è rappresentata nel dump come la riga prima che ERRORappaia il commento. Usando l'ID per questa riga, possiamo determinare dove il database è danneggiato. Lo facciamo usando le SELECTistruzioni con l'ID come condizione; questo processo richiede alcuni tentativi ed errori. Ad esempio, se l'ultimo ID prima dell'errore era 49999 e l'errore segue, il blocco danneggiato inizia da ID 50000. Utilizzare istruzioni come:

    - elimina l'output non necessario
    - il seguente comando è per i sistemi Windows
    - per Linux e altri sistemi simili a Unix e Unix, utilizzare .output / dev / null
    .output NUL
    
    SELEZIONA id DA moz_places DOVE id> = 50100;
    
    • Regola il valore seguendo il comando id >=e ripeti il SELECTcomando sopra finché non trovi il valore più piccolo che non causa un errore in SQLite. Questo è l'ID che si riferisce alla riga a partire dalla quale possiamo recuperare dati aggiuntivi. Supponiamo che questo ID sia 50200. Per scaricare questi dati, inserisci:

    .output dump2.sql
    .mode insert
    SELEZIONA * DA moz_places DOVE id> = 50200;
    
    - ripristinare il normale comportamento di uscita
    .output stdout
    Elenco .mode
    
    • Nota che le INSERTistruzioni nel dump2.sqlfile iniziano con INSERT INTO table VALUES, quindi usa la funzione trova e sostituisci nel tuo editor di testo per sostituire tutte le istanze di questa stringa INSERT INTO moz_places VALUES.
    • Copia l'intero contenuto del dump2.sqlfile e incollalo nel dump.sqlfile in cui ERRORappare il commento.
  • Sostituisci ROLLBACK; -- due to errorsalla fine del file con COMMIT;.
  • Aggiungi il seguente codice all'inizio del dump.sqlfile. Sostituisci <version>con il valore corretto, necessario per Firefox per determinare la versione dello schema del database in base alla versione di Firefox, come indicato di seguito (è disponibile nel file di origine di Firefox toolkit/components/places/Database.cpp):
    • Firefox 52: schema versione 35
    • Firefox 53: schema versione 36
    • Firefox 57: schema versione 39
    • Firefox 58: schema versione 41
    • Firefox 60: schema versione 43
    • Firefox 61: schema versione 47
    • Firefox 62: schema versione 52
    • Firefox 69: schema versione 53

PRAGMA user_version = <versione>;
PRAGMA journal_mode = troncato;
PRAGMA page_size = 32768;
VUOTO;
PRAGMA journal_mode = wal;
  • Esci dalla shell SQLite, elimina places.sqlite, quindi avvia la shell SQLite creando un places.sqlitedatabase vuoto usando sqlite3 places.sqlite. Digitare .read dump.sqlper caricare il dump SQL nel database.
  • Avvia Firefox e conferma che la cronologia e la barra della posizione funzionano come previsto. Dopo aver verificato che tutto è OK, rimuovere i file di dump del database e l'eseguibile della shell SQLite dalla cartella del profilo.

Informazioni più pertinenti sono disponibili nelle seguenti pagine:

Una procedura semplificata è descritta in questo articolo MDN ma non l'ho testata. Tuttavia, ho incorporato i PRAGMAcomandi aggiornati da quell'articolo.


1 SQL normalmente non garantisce che l'output del database venga fornito in qualsiasi ordine a meno che non si utilizzi la ORDER BYclausola. Tuttavia, ORDER BYprobabilmente non riuscirà a produrre alcun output su un database danneggiato (poiché SQLite dovrà leggere l'intera tabella prima di poter produrre qualsiasi output). Per quanto ne so, Firefox scrive sempre le moz_placesvoci della tabella con ID sequenziali, quindi possiamo supporre che tutto l'output sia ordinato per ID.


3
Questa è pura meraviglia. Mi ha aiutato a recuperare quasi tutta la storia da un posto danneggiato. Molte grazie!!
Ashutosh Jindal,

Ha aiutato, con due modifiche: 1) aggiungere un ";" nella riga user_version; 2) per qualche motivo, il mio file "corrotto" aveva una versione dello schema che era "uno in meno" del previsto. Dopo che il tuo metodo non ha funzionato inizialmente, ho provato a importare il dump nel nuovo database da 10 MB e ho fallito perché la vecchia tabella aveva una colonna in meno. Uno sguardo al link del codice sorgente mi ha fatto capire cosa stava succedendo. Post fantastico !!!
Tilman Hausherr,

@TilmanHausherr: indirizzato. Per evitare il problema di modifica della colonna, assicurarsi di seguire i passaggi in questa risposta non appena si nota la corruzione e prima di aggiornare Firefox, in modo che lo schema del database non venga modificato. Puoi anche provare a impostare una versione di schema precedente: Firefox la aggiornerà alla nuova versione quando ripristini il database.
bwDraco,

L'impostazione della versione precedente dello schema è ciò che avevo fatto quando ho scritto il mio primo commento, ovvero ho già avuto successo :-) Sì, sospetto di non aver notato immediatamente la corruzione, di solito lo noto solo quando inserisco i caratteri che dovrebbero creare un Viene visualizzato "vecchio URL" e non accade nulla.
Tilman Hausherr,

Lavoro eccellente! Sono contento di averlo aggiornato, che lo ha reinserito nelle domande attive in cui l'ho individuato.
fixer1234

4

Bene, a seconda di quanto sia danneggiato, la riparazione potrebbe non essere possibile. La tua scommessa migliore è probabilmente provare a scaricare il db usando sqlite, quindi vedere cosa puoi salvare.

Se fallisce, probabilmente dovrai ripristinare dal backup.

Per scaricare e ricreare un database, utilizzare il comando .dump:

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

1
Grazie. Il post SO non è stato utile poiché non ha funzionato, ma la soluzione a cui si fa riferimento nel collegamento ha funzionato d:\sqlite3.exe d:\idimager.cat.db .dump | d:\sqlite3.exe d:\newdb.cat.db. Ora tutti i favicon sono spariti, ma sto ricostruendo mentre visito i siti. Grazie ancora!
Bobby,

stackoverflow.com/questions/2255305/… link nella domanda precedente, è stato rimosso volontariamente dall'autore. La risposta di seguito potrebbe essere di aiuto.
user66001,

@ user66001: Sì, l'OP ha eliminato la domanda. Ho copiato il comando pertinente.
sleske,

Questo non ha funzionato per me e ho finito con un places.sqlite.corruptfile. Ho pubblicato un'altra risposta con una soluzione che ha funzionato per me.
Daniel

2

Come sempre quando esegui una riparazione come questa, ti consiglio di fare prima almeno una copia di backup del tuo file places.sqlite che si trova nella directory del tuo profilo. Avere un backup ti consente di provare varie cose diverse per riparare tali problemi pur sapendo che se il tentativo di riparazione peggiora le cose, puoi sempre fare un'altra copia del backup su cui riprovare.

A seconda di ciò che è danneggiato e di quanto gravemente sia corrotto, potrebbe essere possibile risolvere i problemi con l'estensione Places Maintenance . Ho finito con un file places.sqlite danneggiato in alcune occasioni. Places Maintenance è stato in grado di risolvere il problema ogni volta eseguendo vari controlli / correzioni forniti come operazioni nella finestra di dialogo delle opzioni. I vari controlli e / o rapporti diversi dovrebbero richiedere solo pochi minuti o minuti.

Se il problema persiste, seguire la procedura per risolverlo manualmente in modo simile a quanto descritto in precedenza da DragonLord potrebbe essere necessario.


1

Questo processo descritto su MDN mi ha aiutato a risolvere un problema in cui le nuove pagine che ho visitato non sono state registrate nella cronologia del browser. Non avevo un file places.sqlite.corrupt(o places.sqlite-corrupt), ma il controllo dell'integrità del mio places.sqlitefile ha rivelato che l' immagine del disco del database non è corretta.

Esci da Firefox ed esegui un backup del tuo profilo Firefox prima di proseguire oltre.

$ 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

Avvia Firefox. La storia dovrebbe funzionare di nuovo.

Sono su un Mac con Firefox 60.0.1. Potrebbe essere necessario regolare i comandi per la tua piattaforma.


Grazie Daniel, sempre utile vedere l'attuale procedura di comando
not2qubit il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.