¿Cómo reparo una base de datos incorrecta de Firefox places.sqlite?

15

Tuve algunos problemas con mi RAM (pantalla azul varias veces, Windows XP) y ahora están dañadas las bases de datos de Firefox. Firefox está funcionando, pero mi historial se ha ido y está reportando varias inconsistencias y errores al ejecutar pragma integrity_check en places.sqlite:

La imagen del disco de la base de datos tiene un formato incorrecto

Ahora la pregunta, ¿cómo puedo reparar bases de datos SQLite?

Bobby
fuente
2
Para futuras referencias, la FEBE (Firefox Environment Backup Extension) puede ser útil en el futuro. Copia todo el perfil y lo empaqueta como una sola copia de seguridad. Sé que no responde a su pregunta, pero puede ser útil saberlo en el futuro. bit.ly/aumThw
Urda
Editado para ayudar a los Googlers a encontrar esta pregunta.
bwDraco

Respuestas:

22

Nota

Debido a que Firefox debe estar cerrado para realizar este procedimiento, asegúrese de abrir esta página en otro navegador web o imprimirla antes de continuar.


Después de horas de trabajo intentando recuperar la base de datos de Places, incluso leyendo el código fuente de Firefox, logré hacerlo. Así es como lo hice:

  • Descarga la última versión del shell SQLite y extraerlo en su carpeta de perfil. En Windows Vista y Windows 7, está en el C:\Users\<username>\AppData\Roaming\Mozilla\Firefox\Profiles\<code>.default carpeta.
  • Cierre Firefox si se está ejecutando.
  • La base de datos de Lugares está en el places.sqlite expediente. Si el archivo fue reemplazado debido a un daño, use la places.sqlite.corrupt archivo para la recuperación. Crear una copia de seguridad del archivo, llamado places.sqlite.bak o places.sqlite.corrupt.bak.
  • Utilice el shell de SQLite para abrir el archivo de base de datos ( sqlite3 places.sqlite o sqlite3 places.sqlite.corrupt ), luego ingrese:
.output dump.sql    -- sends output to file dump.sql
.dump               -- dumps database to file
  • Debido a que la base de datos está dañada, el volcado de la base de datos resultante no está completo y no se han recuperado todos los datos recuperables. Para determinar dónde ocurrió el error, busque la palabra ERROR (todo mayúsculas) en un comentario SQL dentro del archivo de volcado dump.sql (Solía Bloc de notas ++ para hacer esto), y leer el SQL INSERT Comando arriba para determinar la tabla en cuestión. En mi caso, la mesa dañada es moz_places. (Se puede encontrar una descripción de las tablas encontradas en la base de datos de Lugares aquí ; Se puede encontrar un diagrama ER bastante desactualizado aquí . Explicaré cómo recuperar datos adicionales de esta tabla solamente; es probable que el siguiente procedimiento no sea aplicable para las otras tablas, por lo que debe omitir estos pasos secundarios si la tabla no es moz_places esta involucrado.)

    • Cada fila en el moz_places La tabla tiene una identificación. Las filas se vuelcan de la tabla siguiendo el orden de este ID. 1 El ID es el primer valor después del paréntesis de apertura en el INSERT declaración. El área donde la base de datos está dañada probablemente sea un pequeño bloque de filas en esta tabla; La idea aquí es saltarse esta área dañada y recuperar la mayor cantidad de datos posible. El área de inicio de dicho bloque se representa en el volcado como la fila antes de la ERROR aparece el comentario. Usando la ID para esta fila, podemos determinar dónde está dañada la base de datos. Lo hacemos usando SELECT declaraciones con el ID como condición; Este proceso requiere un poco de prueba y error. Por ejemplo, si el último ID anterior al error fue 49999, y el error aparece a continuación, el bloque dañado comienza en el ID 50000. Use declaraciones como:

    -- suppress unnecessary output
    -- the following command is for Windows systems
    -- for Linux and other Unix and Unix-like systems, use .output /dev/null
    .output NUL
    
    SELECT id FROM moz_places WHERE id >= 50100;
    
    • Ajustar el valor siguiendo el id >= y repite lo anterior SELECT hasta que encuentre el valor más pequeño que no haga que SQLite genere un error. Este es el ID que se refiere a la fila a partir de la cual podemos recuperar datos adicionales. Asumamos que esta ID es 50200. Para volcar estos datos, ingrese:

    .output dump2.sql
    .mode insert
    SELECT * FROM moz_places WHERE id >= 50200;
    
    -- restore normal output behavior
    .output stdout
    .mode list
    
    • Tenga en cuenta que el INSERT declaraciones en el dump2.sql el archivo comienza con INSERT INTO table VALUES, entonces use la función de buscar y reemplazar en su editor de texto para reemplazar todas las instancias de esta cadena con INSERT INTO moz_places VALUES.
    • Copiar todo el contenido de la dump2.sql archívalo y pégalo en el dump.sql archivo donde el ERROR aparece el comentario.
  • Reemplace la ROLLBACK; -- due to errors al final del archivo con COMMIT;.
  • Agregue el siguiente código en la parte superior de la dump.sql expediente. Reemplazar <version> con el valor correcto, que se requiere para que Firefox determine la versión del esquema de la base de datos según la versión de Firefox, como se muestra a continuación (se puede encontrar en el archivo fuente de Firefox) toolkit/components/places/Database.cpp ):
    • Firefox 50: esquema de la versión 33
    • Firefox 51: esquema de la versión 34
    • Firefox 52: versión de esquema 35
    • Firefox 53: versión de esquema 36
    • Firefox 57: versión de esquema 39
    • Firefox 58: esquema de la versión 41
    • Firefox 60: esquema de la versión 43
    • Firefox 61: esquema de la versión 47

PRAGMA page_size=4096;
PRAGMA user_version=<version>;
  • Salir del shell SQLite, eliminar places.sqlite, luego inicie el shell SQLite creando un vacío places.sqlite base de datos utilizando sqlite3 places.sqlite. Tipo .read dump.sql para cargar el volcado de SQL en la base de datos.
  • Inicie Firefox y confirme que su historial y la barra de ubicación funcionan correctamente. Una vez que haya confirmado que todo está bien, elimine los archivos de volcado de la base de datos y el ejecutable del shell SQLite de la carpeta del perfil.

Más información relevante se puede encontrar en las siguientes páginas:


1 Normalmente, SQL no garantiza que la salida de la base de datos se dará en ningún orden a menos que use el ORDER BY cláusula. Sin embargo, ORDER BY es probable que no produzca ningún resultado en una base de datos dañada (ya que SQLite necesitará leer la tabla completa antes de que pueda generar cualquier resultado) Por lo que yo sé, Firefox siempre escribe moz_places entradas de tabla con ID secuenciales, por lo que podemos suponer que todas las salidas están ordenadas por ID.

bwDraco
fuente
3
Esto es pura maravilla. Me ayudó a recuperar casi toda la historia de un lugar corrupto.sqlite. ¡¡Muchas gracias!!
Ashutosh Jindal
Ayudó, con dos modificaciones: 1) agregar un ";" en la línea user_version; 2) por alguna razón, mi archivo "corrupto" tenía una versión de esquema que era "una menos" de lo esperado. Después de que su método no funcionó inicialmente, intenté importar el volcado en la nueva base de datos de 10MB y falló porque la tabla anterior tenía una columna menos. Una mirada al enlace del código fuente me hizo entender lo que estaba pasando. Post impresionante !!!
Tilman Hausherr
@TilmanHausherr: Dirigido. Para evitar el problema de cambio de columna, asegúrese de seguir los pasos de esta respuesta tan pronto como note daños y antes de actualizar Firefox, para que no se cambie el esquema de la base de datos. También puede intentar configurar una versión anterior del esquema: Firefox lo actualizará a la nueva versión cuando restaure la base de datos.
bwDraco
Establecer la versión del esquema anterior es lo que había hecho al escribir mi primer comentario, es decir, ya tenía éxito :-) Sí, sospecho que no había notado la corrupción de inmediato, por lo general me doy cuenta de que solo al ingresar caracteres que deberían hacer una Aparece "antigua URL" y no pasa nada.
Tilman Hausherr
¡Excelente trabajo! Me alegro de que lo haya actualizado, lo que lo puso de nuevo en las preguntas activas donde lo descubrí.
fixer1234
4

Bueno, dependiendo de lo dañado que esté, la reparación podría no ser posible. Su mejor apuesta es probablemente tratar de volcar el db usando sqlite, entonces ve lo que puedes salvar.

Si eso falla, probablemente tendrás que restaurar desde la copia de seguridad.

Para volcar y volver a crear una base de datos, use el comando .dump:

sqlite places.sqlite .dump | sqlite places-new.sqlite
sleske
fuente
1
Gracias. La publicación SO no fue útil porque no funcionó, pero la solución a la que se hace referencia en el enlace funcionó d:\sqlite3.exe d:\idimager.cat.db .dump | d:\sqlite3.exe d:\newdb.cat.db. Todos los favicons se han ido, pero se están reconstruyendo a medida que visito los sitios. ¡Gracias de nuevo!
Bobby
stackoverflow.com/questions/2255305/… enlace en la pregunta anterior, fue eliminado voluntariamente por su autor. La respuesta abajo puede ser de ayuda
user66001
@ user66001: Sí, el OP eliminó su pregunta. Copié el comando correspondiente.
sleske
Esto no funcionó para mí, y terminé con un places.sqlite.corrupt expediente. publiqué otra respuesta Con una solución que me funcionó.
Daniel
2

Como siempre al realizar una reparación como esta, le recomiendo que primero haga al menos una copia de respaldo de su archivo places.sqlite ubicado en su directorio de perfil. Tener una copia de seguridad le permite probar varias cosas diferentes para reparar tales problemas y saber que si la reparación intentada empeora las cosas, siempre puede hacer otra copia de la copia de seguridad en la que vuelva a intentarlo.

Dependiendo de lo que esté dañado y de lo mal que esté, puede ser posible solucionar los problemas con la extensión Mantenimiento de lugares . He terminado con un archivo places.sqlite dañado en algunas ocasiones. Mantenimiento de lugares ha podido solucionar el problema cada vez ejecutando varios de los controles / correcciones que proporciona como operaciones en su diálogo de opciones. Los distintos controles y / o informes diferentes deben tomar solo unos minutos o minutos.

Si esto no funciona, entonces lo que se necesita es seguir la ruta de reparación manual de una manera similar a lo que DragonLord describe anteriormente.

Makyen
fuente
1

Esta proceso descrito en MDN me ayudó a resolver un problema donde las nuevas páginas que visité no se registraron en el historial del navegador. No tuve un places.sqlite.corrupt (o places.sqlite-corrupt ), pero comprobando la integridad de mi places.sqlite archivo reveló el La imagen del disco de la base de datos tiene un formato incorrecto error.

Salga de Firefox y haga una copia de seguridad de su perfil de Firefox antes de continuar aquí.

$ 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

Inicia Firefox. La historia debería estar funcionando de nuevo.

Estoy en una Mac con Firefox 60.0.1. Es posible que necesite ajustar los comandos para su plataforma.

Daniel
fuente
Gracias Daniel, siempre útil para ver el procedimiento de comando real
not2qubit