file - usuarios - sqlite ventajas y desventajas pdf
La base de datos SQLite3 o el disco están llenos/la imagen del disco de la base de datos está mal formada (7)
Algunas cosas a considerar:
Los archivos SQLite3 DB crecen aproximadamente en múltiplos del tamaño de la página DB y no se reducen a menos que use
VACUUM
. Si elimina algunas filas, el espacio liberado se marca internamente y se reutiliza en inserciones posteriores. Por lo tanto, una inserción a menudo no causará un cambio en el tamaño del archivo DB de respaldo.No debe usar herramientas de copia de seguridad tradicionales para SQLite (o cualquier otra base de datos, para el caso), ya que no tienen en cuenta la información de estado de la base de datos que es fundamental para garantizar una base de datos no corrupta. Especialmente, copiar los archivos DB en el medio de una transacción de inserción es una receta para el desastre ...
SQLite3 tiene una API específicamente para realizar copias de seguridad o copiar bases de datos que están en uso.
Y sí, parece que tus archivos DB están corrupted . Podría ser un error de hardware / sistema de archivos. ¿O quizás los copiaste mientras estaban en uso? ¿O quizás restauró una copia de seguridad que no se tomó correctamente?
Mi base de datos es de aproximadamente 25 MB y he verificado que el nombre de usuario que accede a ella, así como los permisos de archivo no han cambiado en meses. Tengo un problema donde las consultas fallan debido a que "la base de datos o el disco está lleno" y, a veces, el problema de "la imagen de disco de la base de datos está mal formada".
A menos que esté leyendo esto mal, mi disco no está casi lleno (este es un servidor de Ubuntu, 9.10, si hace alguna diferencia)
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 19610300 2389596 16224560 13% /
udev 10240 128 10112 2% /dev
none 254136 0 254136 0% /dev/shm
none 254136 36 254100 1% /var/run
none 254136 0 254136 0% /var/lock
none 254136 0 254136 0% /lib/init/rw
Como prueba, simplemente hice una acción que agregó un nuevo registro, y está bien. Estoy tratando de averiguar si hay un conjunto específico de acciones que están fallando. Sin embargo, después de la inserción (y verificar que está allí), el número de bytes en el disco para la base de datos no ha cambiado (ni hacia arriba ni hacia abajo).
El uso de la utilidad de línea de comandos da como resultado lo siguiente, que falla espectacularmente :)
SQLite version 3.6.12
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> pragma integrity_check;
*** in database main ***
On tree page 2 cell 0: 2nd reference to page 26416
On tree page 2 cell 1: 2nd reference to page 26417
On tree page 2 cell 2: 2nd reference to page 26434
On tree page 2 cell 3: 2nd reference to page 26449
On tree page 2 cell 4: 2nd reference to page 26464
On tree page 2 cell 5: 2nd reference to page 26358
On tree page 2 cell 6: 2nd reference to page 26494
On tree page 2 cell 7: Child page depth differs
On tree page 2 cell 8: 2nd reference to page 26190
On tree page 2 cell 8: Child page depth differs
... etc., etc. ...
¿Alguna idea de dónde debería estar mirando después? ¿Hay algún problema con la cantidad máxima de filas en una tabla o algo así? Leí un poco sobre los valores máximos de SQLite3, y nada en mi base de datos es algo cercano a ellos, por lo que puedo ver.
Luego eché un vistazo a mis copias de seguridad diarias, y veo que la copia de seguridad de la base de datos no ha cambiado en el tamaño del archivo durante 3-4 días, muy extraño. Restauré una copia de seguridad de la base de datos antes de que no cambiara el tamaño del archivo y aún recibía problemas extraños.
Estoy pensando que voy a tener que (1) restaurar desde una copia de seguridad anterior, y (2) volver a ejecutar mis migraciones de Rails para corregirlo.
Durante el desarrollo de la aplicación, descubrí que los mensajes proceden de las frecuentes y masivas operaciones INSERT y UPDATE. Asegúrese de INSERTAR y ACTUALIZAR múltiples filas o datos en una sola operación.
var updateStatementString : String! = ""
for item in cardids {
let newstring = "UPDATE "+TABLE_NAME+" SET pendingImages = ''/(pendingImage)/' WHERE cardId = ''/(item)/';"
updateStatementString.append(newstring)
}
print(updateStatementString)
let results = dbManager.sharedInstance.update(updateStatementString: updateStatementString)
return Int64(results)
He visto esto suceder cuando la base de datos se corrompe, ¿ha intentado clonarla en una nueva?
Copia de forma segura una base de datos SQLite
Es trivialmente fácil copiar una base de datos SQLite. Es menos trivial hacer esto de una manera que no lo corrompa. Así es cómo:
shell$ sqlite3 some.db sqlite> begin immediate; <press CTRL+Z> shell$ cp some.db some.db.backup shell$ exit sqlite> rollback;
Esto le proporcionará una buena copia de seguridad limpia que seguramente estará en un estado apropiado, ya que escribir en la base de datos a mitad de su proceso de copia es imposible.
Para evitar obtener "base de datos o disco lleno" en primer lugar, intente esto si tiene mucha RAM:
sqlite> pragma temp_store = 2;
Eso le dice a SQLite que ponga archivos temporales en la memoria. (El mensaje "la base de datos o el disco está lleno" no significa que la base de datos esté llena o que el disco esté lleno. Significa que el directorio temporal está lleno). Tengo 256G de RAM pero solo 2G de / tmp, así que esto funciona genial para mi Cuanta más memoria RAM tenga, más archivos db con los que pueda trabajar.
Si no tienes mucha ram, prueba esto:
sqlite> pragma temp_store = 1;
sqlite> pragma temp_store_directory = ''/directory/with/lots/of/space'';
temp_store_directory está en desuso (lo cual es una tontería, ya que temp_store no está en desuso y requiere temp_store_directory), así que tenga cuidado de usar esto en el código.
Para reparar una base de datos corrupta, puede usar la utilidad de línea de comandos sqlite3. Escriba los siguientes comandos en un shell después de configurar las variables de entorno:
cd $DATABASE_LOCATION
echo ''.dump''|sqlite3 $DB_NAME|sqlite3 repaired_$DB_NAME
mv $DB_NAME corrupt_$DB_NAME
mv repaired_$DB_NAME $DB_NAME
Este código me ayudó a recuperar una base de datos SQLite que uso como almacén persistente para Core Data y que produjo el siguiente error al guardar:
No se pudo guardar: NSError 259 en el dominio NSCocoaErrorDomain {NSFilePath = mydata.db NSUnderlyingException = Error grave. La base de datos en mydata.db está dañada. Código de error SQLite: 11, ''la imagen del disco de la base de datos está mal formada''}
Uso la siguiente secuencia de comandos para reparar archivos sqlite mal formados:
#!/bin/bash
cat <( sqlite3 "$1" .dump | grep "^ROLLBACK" -v ) <( echo "COMMIT;" ) | sqlite3 "fix_$1"
La mayoría de las veces, cuando una base de datos sqlite está mal formada, todavía es posible hacer un volcado. Este vuelco es básicamente una gran cantidad de sentencias SQL que reconstruyen la base de datos.
Algunas filas pueden faltar en el volcado (probablemente porque están dañadas). Si este es el caso, las instrucciones INSERT de las filas faltantes se reemplazarán con algunos comentarios y el script finalizará con una TRANSACCIÓN ROLLBACK.
Entonces, lo que hacemos aquí es hacer el volcado (las filas mal formadas son excluidas) y reemplazamos el ROLLBACK con un COMPROMISO para que todo el guión de volcado sea cometido en lugar de retrotraerlo.
Este método me salvó la vida unas 100 veces ya / o /
mientras usaba Google App Engine, tuve este problema. Por alguna razón lo hice desde entonces, Google App Engine nunca comenzó.
$ echo '''' > /tmp/appengine.apprtc.root/*.db
Para solucionarlo, debo hacerlo manualmente:
$ sqlite3 datastore.db
sqlite> begin immediate;
<press CTRL+Z>
$ cp datastore.db logs.db
Y luego ejecuta Google App Engine con bandera:
$ dev_appserver.py --clear_datastore --clear_search_index
después de eso finalmente funcionó.