Como faço para reparar um banco de dados do Firefox places.sqlite corrompido?

15

Eu tive alguns problemas com minha RAM (tela azul várias vezes, Windows XP) e agora meus bancos de dados do Firefox estão danificados. Firefox está funcionando, mas a minha história se foi e ele está relatando várias inconsistências e erros quando execução pragma integrity_checkem places.sqlite:

imagem de disco do banco de dados está malformada

Agora a pergunta, como faço para reparar bancos de dados SQLite?

Bobby
fonte
2
Para referência futura, o FEBE (Firefox Environment Backup Extension) pode ser útil no futuro. Copia o perfil inteiro e o empacota como um único backup. Sei que não responde à sua pergunta, mas pode ser útil saber no futuro. bit.ly/aumThw
Urda
Editado para ajudar os Googlers a encontrar esta pergunta.
bwDraco - Reinstala Monica

Respostas:

22

Nota

Como o Firefox deve estar fechado para executar este procedimento, abra esta página em outro navegador da Web ou imprima-a antes de continuar.


Depois de horas de trabalho tentando recuperar o banco de dados do Places, mesmo lendo o código-fonte do Firefox, consegui obter sucesso. Aqui está como eu fiz isso:

  • Baixe a versão mais recente do shell SQLite e extraia-a na sua pasta de perfil. No Windows Vista e Windows 7, está na C:\Users\<username>\AppData\Roaming\Mozilla\Firefox\Profiles\<code>.defaultpasta
  • Feche o Firefox se estiver em execução.
  • O banco de dados do Places está no places.sqlitearquivo Se o arquivo foi substituído devido a corrupção, use o places.sqlite.corruptarquivo para recuperação. Crie uma cópia de backup do arquivo, nomeada places.sqlite.bakou places.sqlite.corrupt.bak.
  • Use o shell SQLite para abrir o arquivo de banco de dados ( sqlite3 places.sqliteou sqlite3 places.sqlite.corrupt) e digite:
.output dump.sql    -- sends output to file dump.sql
.dump               -- dumps database to file
  • Como o banco de dados está corrompido, o despejo de banco de dados resultante não está completo e nem todos os dados recuperáveis ​​foram recuperados. Para determinar onde ocorreu o erro, procure a palavra ERROR(todas em maiúsculas) em um comentário SQL dentro do arquivo de despejodump.sql (usei o Notepad ++ para fazer isso) e leia o INSERTcomando SQL acima para determinar a tabela em questão. No meu caso, a mesa danificada é moz_places. (Uma descrição das tabelas encontradas no banco de dados do Places pode ser encontrada aqui , que inclui um diagrama de ER desatualizado.) Explicarei como recuperar dados adicionais somente dessa tabela; o procedimento a seguir provavelmente não é aplicável para as outras tabelas; portanto, pule estas sub-etapas se uma tabela que não moz_placesestiver envolvida.)

    • Cada linha no moz_places tabela possui um ID. As linhas são despejadas da tabela, seguindo a ordem desse ID. 1 O ID é o primeiro valor após o parêntese de abertura na INSERTinstrução. A área em que o banco de dados está danificado provavelmente será um pequeno bloco de linhas nesta tabela; a idéia aqui é pular essa área danificada e recuperar o máximo de dados possível. A área inicial de um bloco desse tipo é representada no despejo como a linha antes do ERRORcomentário aparecer. Usando o ID para esta linha, podemos determinar onde o banco de dados está danificado. Fazemos isso usando SELECTinstruções com o ID como uma condição; esse processo leva algumas tentativas e erros. Por exemplo, se o último ID antes do erro for 49999 e o erro a seguir, o bloco danificado será iniciado no ID 50000. Use instruções como:

    - suprimir saída desnecessária
    - o comando a seguir é para sistemas Windows
    - para Linux e outros sistemas Unix e Unix-like, use .output / dev / null
    .output NUL
    
    SELECT id FROM moz_places WHERE id> = 50100;
    
    • Ajuste o valor após o id >=e repita o SELECTcomando acima até encontrar o menor valor que não faz com que o SQLite produza um erro. Esse é o ID que se refere à linha a partir da qual podemos recuperar dados adicionais. Vamos supor que esse ID seja 50200. Para despejar esses dados, digite:

    .output dump2.sql
    inserção de modo
    SELECT * FROM moz_places WHERE id> = 50200;
    
    - restaurar o comportamento normal da saída
    .output stdout
    .mode list
    
    • Observe que as INSERTinstruções no dump2.sqlarquivo começam com INSERT INTO table VALUES, portanto, use o recurso localizar e substituir no seu editor de texto para substituir todas as instâncias dessa sequência por INSERT INTO moz_places VALUES.
    • Copie todo o conteúdo do dump2.sqlarquivo e cole-o no dump.sqlarquivo em que o ERRORcomentário aparece.
  • Substitua ROLLBACK; -- due to errorsno final do arquivo por COMMIT;.
  • Adicione o seguinte código ao topo do dump.sqlarquivo. Substitua <version>pelo valor correto, necessário para o Firefox determinar a versão do esquema do banco de dados com base na versão do Firefox, conforme a seguir (isso pode ser encontrado no arquivo de origem do Firefox toolkit/components/places/Database.cpp):
    • Firefox 52: versão do esquema 35
    • Firefox 53: versão do esquema 36
    • Firefox 57: versão do esquema 39
    • Firefox 58: versão de esquema 41
    • Firefox 60: versão do esquema 43
    • Firefox 61: versão de esquema 47
    • Firefox 62: versão do esquema 52
    • Firefox 69: versão de esquema 53

PRAGMA user_version = <versão>;
PRAGMA journal_mode = truncar;
PRAGMA page_size = 32768;
VÁCUO;
PRAGMA journal_mode = wal;
  • Saia do shell do SQLite, exclua places.sqlitee inicie o shell do SQLite criando um places.sqlitebanco de dados vazio usando sqlite3 places.sqlite. Digite .read dump.sqlpara carregar o dump SQL no banco de dados.
  • Inicie o Firefox e confirme se seu histórico e barra de localização estão funcionando conforme o esperado. Depois de confirmar que tudo está OK, remova os arquivos de despejo do banco de dados e o shell SQLite executável da pasta de perfil.

Informações mais relevantes podem ser encontradas nas seguintes páginas:

Um procedimento simplificado é descrito neste artigo MDN, mas eu não o testei. No entanto, eu incorporei PRAGMAcomandos atualizados desse artigo.


1 O SQL normalmente não garante que a saída do banco de dados seja fornecida em qualquer ordem, a menos que você use a ORDER BYcláusula. No entanto, ORDER BYprovavelmente falhará ao produzir qualquer saída em um banco de dados corrompido (como o SQLite precisará ler a tabela inteira antes que possa produzir qualquer saída). Até onde eu sei, o Firefox sempre grava moz_placesentradas de tabela com IDs seqüenciais, para que possamos assumir que toda a saída seja ordenada por ID.

bwDraco - Restabelecer Monica
fonte
3
Isso é pura grandiosidade. Me ajudou a recuperar quase toda a história de um places.sqlite corrompido. Muito obrigado!!
Ashutosh Jindal
Ajudou, com duas modificações: 1) adicione um ";" na linha user_version; 2) por algum motivo, meu arquivo "corrompido" tinha uma versão do esquema "um a menos" do que o esperado. Depois que seu método não funcionou inicialmente, tentei importar o despejo para o novo banco de dados de 10 MB e falhei porque a tabela antiga tinha uma coluna a menos. Uma olhada no link do código-fonte me fez entender o que estava acontecendo. Awesome post !!!
Tilman Hausherr
@TilmanHausherr: endereçado. Para evitar o problema de alteração da coluna, siga as etapas nesta resposta assim que detectar corrupção e antes de atualizar o Firefox, para que o esquema do banco de dados não seja alterado. Você também pode tentar definir uma versão mais antiga do esquema - o Firefox atualizará para a nova versão quando você restaurar o banco de dados.
bwDraco - Reinstala Monica
Definir a versão anterior do esquema foi o que eu havia feito ao escrever meu primeiro comentário, ou seja, eu já tinha sucesso :-) Sim, eu suspeito que não havia notado a corrupção imediatamente, normalmente só noto ao inserir caracteres que devem fazer uma alteração. "URL antigo" aparece e nada acontece.
Tilman Hausherr
Excelente trabalho! Que bom que você o atualizou, o que o colocou de volta nas perguntas ativas em que eu o vi.
fixer1234
4

Bem, dependendo de como está danificado, o reparo pode não ser possível. Sua melhor aposta é provavelmente tentar despejar o banco de dados usando sqlitee ver o que você pode recuperar.

Se isso falhar, você provavelmente precisará restaurar a partir do backup.

Para despejar e recriar um banco de dados, use o comando .dump:

sqlite places.sqlite .dump | sqlite places-new.sqlite
sleske
fonte
11
Obrigado. A publicação do SO não foi útil, pois não funcionou, mas a solução mencionada no link funcionou d:\sqlite3.exe d:\idimager.cat.db .dump | d:\sqlite3.exe d:\newdb.cat.db. Todos os favicons agora se foram, mas eu eles estão reconstruindo enquanto visito os sites. Obrigado novamente!
Bobby
O link stackoverflow.com/questions/2255305/… na pergunta acima foi removido voluntariamente por seu autor. A resposta abaixo pode ser útil.
user66001
@ user66001: Sim, o OP excluiu sua pergunta. Eu copiei o comando relevante.
sleske 25/09
Isso não funcionou para mim e acabei com um places.sqlite.corruptarquivo. Postei outra resposta com uma solução que funcionou para mim.
Daniel
2

Como sempre, ao executar um reparo como esse, recomendo que você faça primeiro pelo menos uma cópia de backup do seu arquivo places.sqlite localizado no diretório do seu perfil. Ter um backup permite que você tente várias coisas diferentes para reparar esses problemas, sabendo que, se a tentativa de reparo piorar as coisas, você sempre poderá fazer outra cópia do backup para tentar novamente.

Dependendo do que está corrompido e de quanto está corrompido, pode ser possível corrigir os problemas com a extensão Manutenção de Locais . Acabei com um arquivo places.sqlite corrompido em algumas ocasiões. A Manutenção de Locais conseguiu resolver o problema toda vez executando várias verificações / correções que ele fornece como operações em sua caixa de diálogo de opções. As várias verificações e / ou relatórios diferentes devem levar apenas alguns minutos a minutos.

Se isso não funcionar, seguir o caminho de corrigi-lo manualmente de maneira semelhante ao que o DragonLord descreve acima pode ser o necessário.

Makyen
fonte
1

Esse processo descrito no MDN me ajudou a resolver um problema em que novas páginas que visitei não foram registradas no histórico do navegador. Eu não tinha um arquivo places.sqlite.corrupt(ou places.sqlite-corrupt), mas a verificação da integridade do meu places.sqlitearquivo revelou que a imagem do disco do banco de dados está com um erro de formato.

Saia do Firefox e faça um backup do seu perfil do Firefox antes de prosseguir aqui.

$ 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

Inicie o Firefox. A história deve estar funcionando novamente.

Estou em um Mac com Firefox 60.0.1. Pode ser necessário ajustar os comandos para sua plataforma.

Daniel
fonte
Obrigado Daniel, sempre útil para ver o procedimento de comando real
not2qubit 26/09/18