pcl net sqlite

net - sqlite xamarin forms



¿Cómo desbloqueo una base de datos SQLite? (30)

Acabo de ocurrirme algo similar: mi aplicación web podía leer desde la base de datos, pero no podía realizar inserciones ni actualizaciones. Un reinicio de Apache resolvió el problema al menos temporalmente.

Sin embargo, sería bueno poder rastrear la causa raíz.

sqlite> DELETE FROM mails WHERE (`id` = 71); SQL error: database is locked

¿Cómo desbloqueo la base de datos para que esto funcione?


Acabo de tener el mismo error. Después de 5 minets de google, encontré que no cerré un shell, que estaba usando la base de datos. Solo ciérralo y vuelve a intentarlo;)


Algunas funciones, como INDEX''ing, pueden llevar mucho tiempo, y bloquean toda la base de datos mientras se ejecuta. En casos como ese, ¡puede que ni siquiera use el archivo de diario!

Por lo tanto, la mejor / única forma de verificar si su base de datos está bloqueada porque un proceso le está ESCRIBIENDO ACTIVAMENTE (y, por lo tanto, debe dejarlo en paz hasta que se complete su operación) es md5 (o md5sum en algunos sistemas) el archivo dos veces . Si obtiene una suma de comprobación diferente, la base de datos se está escribiendo y realmente, REALMENTE, no desea finalizar el proceso con -9 porque puede terminar fácilmente con una tabla / base de datos dañada si lo hace.

Reitero, porque es importante (la solución NO es encontrar el programa de bloqueo y eliminarlo), es buscar si la base de datos tiene un bloqueo de escritura por una buena razón e ir desde allí. A veces la solución correcta es solo un descanso para tomar café.

La única forma de crear esta situación de bloqueo pero no de escritura es si su programa ejecuta BEGIN EXCLUSIVE , porque quería hacer algunas modificaciones de la tabla o algo así, entonces, por alguna razón, nunca envía un END después, y el proceso nunca termina Es muy poco probable que se cumplan las tres condiciones en cualquier código escrito correctamente, y como tal, 99 veces de cada 100 cuando alguien quiere anular el proceso de bloqueo de -9, el proceso de bloqueo en realidad está bloqueando su base de datos por una buena razón. Los programadores normalmente no agregan la condición BEGIN EXCLUSIVE menos que realmente lo necesiten, ya que evita la concurrencia y aumenta las quejas de los usuarios. SQLite solo lo agrega cuando realmente lo necesita (como cuando indexa).

Finalmente, el estado ''bloqueado'' no existe DENTRO del archivo, como lo han indicado varias respuestas: reside en el núcleo del sistema operativo. El proceso que se ejecutó BEGIN EXCLUSIVE ha solicitado que el sistema operativo se coloque un bloqueo en el archivo. Incluso si su proceso exclusivo se ha bloqueado, su sistema operativo podrá averiguar si debería mantener el bloqueo del archivo o no. ¡No es posible terminar con una base de datos que está bloqueada pero ningún proceso la está bloqueando activamente! Cuando se trata de ver qué proceso está bloqueando el archivo, normalmente es mejor usar lsof en lugar de fuser (esta es una buena demostración de por qué: https://unix.stackexchange.com/questions/94316/fuser-vs-lsof-to-check-files-in-use ). Alternativamente, si tiene DTrace (OSX) puede usar iosnoop en el archivo.


Antes de desactivar la opción de reinicio, vale la pena ver si puede encontrar al usuario de la base de datos sqlite.

En Linux, se puede emplear un fuser para este fin:

$ fuser database.db $ fuser database.db-journal

En mi caso obtuve la siguiente respuesta:

philip 3556 4700 0 10:24 pts/3 00:00:01 /usr/bin/python manage.py shell

Lo que demostró que tenía otro programa Python con pid 3556 (manage.py) usando la base de datos.


Como dijo Seun Osewa, a veces un proceso de zombie se sienta en la terminal con un bloqueo adquirido, incluso si no lo crees posible. La secuencia de comandos se ejecuta, se bloquea y regresa al indicador, pero hay un proceso zombie generado en algún lugar por una llamada a la biblioteca, y ese proceso tiene el bloqueo.

El cierre del terminal en el que estaba (en OSX) podría funcionar. El reinicio funcionará. Puedes buscar procesos "python" (por ejemplo) que no están haciendo nada y matarlos.


De tus comentarios anteriores dijiste que un archivo periodístico estaba presente.

Esto podría significar que ha abierto y (¿EXCLUSIVO?) Transacción y aún no ha confirmado los datos. ¿Su programa o algún otro proceso dejó la revista?

Al reiniciar el proceso de sqlite, se verá el archivo de diario, se limpiarán las acciones no confirmadas y se eliminará el archivo periodístico.


Debe ser un problema interno de la base de datos ...
Para mí, se ha manifestado después de intentar explorar la base de datos con "Administrador de SQLite" ...
Por lo tanto, si no puede encontrar otro proceso de conexión a la base de datos y no puede solucionarlo, pruebe esta solución radical:

  1. Proporcionar para exportar sus tablas (puede usar "Administrador de SQLite" en Firefox)
  2. Si la migración altera el esquema de su base de datos, elimine la última migración fallida.
  3. Renombra tu archivo "database.sqlite"
  4. Ejecute "rake db: migrate" para crear una nueva base de datos de trabajo
  5. Proporcionar para dar los permisos adecuados a la base de datos para la importación de tablas
  6. Importe sus tablas de copia de seguridad
  7. Escribe la nueva migración
  8. Ejecutarlo con " rake db:migrate "

Eliminar el archivo periodístico suena como una idea terrible. Está ahí para permitir que sqlite restaure la base de datos a un estado consistente después de un fallo. Si lo elimina mientras la base de datos se encuentra en un estado incoherente, entonces se queda con una base de datos dañada. Citando una página del sitio sqlite :

Si se produce un fallo o pérdida de alimentación y se deja un diario activo en el disco, es esencial que el archivo de la base de datos original y el diario activo permanezcan en el disco con sus nombres originales hasta que otro proceso de SQLite abra el archivo de la base de datos. . [...]

Sospechamos que un modo de falla común para la recuperación de SQLite ocurre así: Se produce una falla de energía. Una vez que se restaura la energía, un usuario o administrador del sistema con buenas intenciones comienza a buscar daños en el disco. Ellos ven su archivo de base de datos llamado "important.data". Este archivo es quizás familiar para ellos. Pero después del accidente, también hay un diario caliente llamado "important.data-journal". Luego, el usuario elimina el diario activo, pensando que están ayudando a limpiar el sistema. No conocemos ninguna otra forma de prevenir esto más que la educación del usuario.

Se supone que la reversión se producirá automáticamente la próxima vez que se abra la base de datos, pero fallará si el proceso no puede bloquear la base de datos. Como han dicho otros, una posible razón para esto es que otro proceso actualmente lo tiene abierto. Otra posibilidad es un bloqueo de NFS obsoleto, si la base de datos está en un volumen NFS. En ese caso, una solución es reemplazar el archivo de base de datos con una copia nueva que no esté bloqueada en el servidor NFS (mv database.db original.db; cp original.db database.db). Tenga en cuenta que las preguntas frecuentes de sqlite recomiendan precaución con respecto al acceso concurrente a bases de datos en volúmenes NFS, debido a implementaciones erróneas de bloqueo de archivos NFS.

No puedo explicar por qué eliminar un archivo periodístico le permitiría bloquear una base de datos que antes no podía. ¿Es eso reproducible?

Por cierto, la presencia de un archivo periodístico no significa necesariamente que haya habido un bloqueo o que haya cambios que se revertirán. Sqlite tiene algunos modos de diario diferentes, y en los modos PERSIST o TRUNCATE siempre deja el archivo diario en su lugar, y cambia el contenido para indicar si hay transacciones parciales para revertir.


En Windows puede probar este programa http://www.nirsoft.net/utils/opened_files_view.html para averiguar si el proceso está manejando el archivo db. Intenta cerrar ese programa para desbloquear la base de datos

En Linux y macOS puede hacer algo similar, por ejemplo, si su archivo bloqueado es development.db:

$ fuser development.db

Este comando mostrará qué proceso está bloqueando el archivo:

> desarrollo.db: 5430

Solo mata el proceso ...

matar -9 5430

... Y tu base de datos estará desbloqueada.


Encontré que la documentation de los diversos estados de bloqueo en SQLite es muy útil. Michael, si puede realizar lecturas pero no puede realizar escrituras en la base de datos, eso significa que un proceso ha obtenido un bloqueo RESERVADO en su base de datos pero aún no ha ejecutado la escritura. Si está utilizando SQLite3, hay un nuevo bloqueo llamado PENDIENTE en el que no se permiten más procesos para conectarse, pero las conexiones existentes aún pueden realizar lecturas, por lo que si este es el problema, debe verlo en su lugar.



Este error se puede lanzar si el archivo está en una carpeta remota, como una carpeta compartida. Cambié la base de datos a un directorio local y funcionó perfectamente.



La página de SQLite wiki DatabaseIsLocked ofrece una buena explicación de este mensaje de error. Establece, en parte, que la fuente de conflicto es interna (al proceso que emite el error).

Lo que esta página no explica es cómo SQLite decide que algo en su proceso tiene un bloqueo y qué condiciones podrían conducir a un falso positivo.


Los archivos db de SQLite son solo archivos, por lo que el primer paso sería asegurarse de que no sea de solo lectura. La otra cosa que debe hacer es asegurarse de que no tiene algún tipo de visor de base de datos SQLite GUI con la base de datos abierta. Podría tener la base de datos abierta en otro shell, o su código podría tener la base de datos abierta. Normalmente, vería esto si un subproceso o aplicación diferente, como el Explorador de bases de datos SQLite, tiene la base de datos abierta para escribir.


Me encontré con este mismo problema en Mac OS X 10.5.7 ejecutando scripts de Python desde una sesión de terminal. A pesar de que había detenido los scripts y la ventana de la terminal se encontraba en el símbolo del sistema, daría este error la próxima vez que se ejecutara. La solución fue cerrar la ventana de la terminal y luego volver a abrirla. No tiene sentido para mí, pero funcionó.


Mi bloqueo se debió a un bloqueo del sistema y no a un proceso de bloqueo. Para resolver esto, simplemente cambié el nombre del archivo y luego lo copié a su nombre y ubicación originales.

Usando un shell de linux que sería ...

mv mydata.db temp.db cp temp.db mydata.db


Recibí este error al usar Delphi con los componentes LiteDAC. Resultó que solo sucedió mientras se ejecutaba mi aplicación desde el IDE de Delphi si la propiedad Conectada se configuraba Verdadero para el componente de conexión SQLite (en este caso, TLiteConnection).


Recibí este error en un escenario un poco diferente de los descritos aquí.

La base de datos SQLite descansaba en un sistema de archivos NFS compartido por 3 servidores. En 2 de los servidores pude realizar consultas en la base de datos con éxito, en el tercero pensé que estaba recibiendo el mensaje "la base de datos está bloqueada".

El problema con esta tercera máquina era que no le quedaba espacio en /var . Cada vez que intentaba ejecutar una consulta en CUALQUIER base de datos SQLite ubicada en este sistema de archivos recibí el mensaje "la base de datos está bloqueada" y también este error en los registros:

8 de agosto 10:33:38 server01 kernel: lockd: no se puede monitorear 172.22.84.87

Y este también:

8 de agosto 10:33:38 server01 rpc.statd [7430]: No se pudo insertar: escribiendo /var/lib/nfs/statd/sm/other.server.name.com: No queda espacio en el dispositivo 8 de agosto 10:33: 38 server01 rpc.statd [7430]: STAT_FAIL al servidor01 para SM_MON de 172.22.84.87

Después de manejar la situación espacial, todo volvió a la normalidad.


Si desea eliminar un error de "la base de datos está bloqueada", siga estos pasos:

  1. Copie su archivo de base de datos a otra ubicación.
  2. Reemplace la base de datos con la base de datos copiada. Esto eliminará todos los procesos que accedieron a su archivo de base de datos.

Si un proceso tiene un bloqueo en una base de datos SQLite y se bloquea, la base de datos permanece bloqueada permanentemente. Ese es el problema. No es que algún otro proceso tenga un candado.


Tengo tal problema dentro de la aplicación, que accedía a SQLite desde 2 conexiones: una era de solo lectura y la segunda para escribir y leer. Parece que esa conexión de solo lectura bloqueó la escritura de la segunda conexión. Finalmente, resulta que es necesario finalizar o, al menos, restablecer las declaraciones preparadas INMEDIATAMENTE después de su uso. Hasta que se abra la declaración preparada, se bloqueó la escritura de la base de datos.

NO OLVIDES LLAMAR

sqlite_reset(xxx);

o

sqlite_finalize(xxx);


Tuve este problema justo ahora, usando una base de datos SQLite en un servidor remoto, almacenado en un montaje NFS. SQLite no pudo obtener un bloqueo después de que la sesión de shell remota que usé se bloqueó mientras la base de datos estaba abierta.

Las recetas para la recuperación sugeridas anteriormente no me funcionaron (incluida la idea de mover primero y luego volver a copiar la base de datos). Pero después de copiarlo en un sistema que no es NFS, la base de datos se volvió utilizable y parece que no se han perdido datos.


Una pregunta antigua, con muchas respuestas, aquí están los pasos que seguí recientemente leyendo las respuestas anteriores, pero en mi caso, el problema se debió al uso compartido de recursos cifs. Este caso no se informó anteriormente, así que espero que ayude a alguien.

  • Comprueba que no queden conexiones abiertas en tu código java.
  • Compruebe que ningún otro proceso está utilizando su archivo db SQLite con lsof.
  • Verifique que el propietario del usuario de su proceso jvm en ejecución tenga permisos r / w sobre el archivo.
  • Intente forzar el modo de bloqueo en la abertura de conexión con

    final SQLiteConfig config = new SQLiteConfig(); config.setReadOnly(false); config.setLockingMode(LockingMode.NORMAL); connection = DriverManager.getConnection(url, config.toProperties());

Si está utilizando su archivo db SQLite sobre una carpeta compartida NFS, verifique este punto de las preguntas frecuentes de SQLite y revise sus opciones de configuración de montaje para asegurarse de evitar bloqueos, como se describe here :

//myserver /mymount cifs username=*****,password=*****,iocharset=utf8,sec=ntlm,file,nolock,file_mode=0700,dir_mode=0700,uid=0500,gid=0500 0 0


Una razón común para obtener esta excepción es cuando intenta realizar una operación de escritura mientras aún mantiene recursos para una operación de lectura. Por ejemplo, si SELECCIONA de una tabla y luego intenta ACTUALIZAR algo que ha seleccionado sin cerrar primero el Conjunto de resultados.


Yo tuve el mismo problema. Aparentemente, la función de reversión parece sobrescribir el archivo db con el diario, que es el mismo que el archivo db pero sin el cambio más reciente. He implementado esto en mi código a continuación y ha estado funcionando bien desde entonces, mientras que antes mi código simplemente se atasca en el bucle cuando la base de datos permanece bloqueada.

Espero que esto ayude

mi código python

############## #### Defs #### ############## def conn_exec( connection , cursor , cmd_str ): done = False try_count = 0.0 while not done: try: cursor.execute( cmd_str ) done = True except sqlite.IntegrityError: # Ignore this error because it means the item already exists in the database done = True except Exception, error: if try_count%60.0 == 0.0: # print error every minute print "/t" , "Error executing command" , cmd_str print "Message:" , error if try_count%120.0 == 0.0: # if waited for 2 miutes, roll back print "Forcing Unlock" connection.rollback() time.sleep(0.05) try_count += 0.05 def conn_comit( connection ): done = False try_count = 0.0 while not done: try: connection.commit() done = True except sqlite.IntegrityError: # Ignore this error because it means the item already exists in the database done = True except Exception, error: if try_count%60.0 == 0.0: # print error every minute print "/t" , "Error executing command" , cmd_str print "Message:" , error if try_count%120.0 == 0.0: # if waited for 2 miutes, roll back print "Forcing Unlock" connection.rollback() time.sleep(0.05) try_count += 0.05 ################## #### Run Code #### ################## connection = sqlite.connect( db_path ) cursor = connection.cursor() # Create tables if database does not exist conn_exec( connection , cursor , ''''''CREATE TABLE IF NOT EXISTS fix (path TEXT PRIMARY KEY);'''''') conn_exec( connection , cursor , ''''''CREATE TABLE IF NOT EXISTS tx (path TEXT PRIMARY KEY);'''''') conn_exec( connection , cursor , ''''''CREATE TABLE IF NOT EXISTS completed (fix DATE, tx DATE);'''''') conn_comit( connection )


puede intentar esto: .timeout 100 para establecer el tiempo de espera. No sé qué sucede en la línea de comandos pero en C # .Net cuando hago esto: "UPDATE table-name SET column-name = value;" Obtengo que la base de datos está bloqueada, pero este "UPDATE table-name SET column-name = value" va bien.

Parece que cuando agregas; sqlite buscará más comandos.


Adminer es una alternativa phpmyadmin pequeña (pero poderosa) que uso para monitorear la base de datos sqlite. Por alguna razón la base de datos se bloqueó. Así es como lo arreglé.

  1. Descargué el archivo sqlite a mi sistema (FTP)
  2. Se eliminó el archivo sqlite en línea
  3. Subido el archivo al proveedor de alojamiento

Funciona bien ahora.


Pooling=true " Pooling=true " a la cadena de conexión y funcionó.


El comando lsof en mi entorno de Linux me ayudó a darme cuenta de que un proceso estaba colgado manteniendo el archivo abierto.
Mató el proceso y el problema se resolvió.