2010-07-23 36 views
93

Tengo una base de datos SQLite que estoy usando para un sitio web. El problema es que cuando intento INSERT INTO, me conseguir un PDOExceptionSQLite: base de datos de solo lectura

SQLSTATE[HY000]: General error: 8 attempt to write a readonly database 

I SSH'd en el servidor y permisos comprobados, y la base de datos tiene los permisos

-rw-rw-r-- 

No estoy familiarizado con los permisos en Unix, pero estoy bastante seguro de que esto significa

  • No es un directorio
  • propietario ha de lectura/escritura Permisos (que soy yo, de acuerdo con ls -l)
  • Grupo tiene permisos de lectura/escritura
  • todos los demás permisos sólo ha leído

También busqué por todas partes yo sabía que el uso del programa sqlite3, y no encontraron nada relevante.

Debido a que no sabía con qué permisos DOP está tratando de abrir la base de datos, lo hice

chmod o+w supplies.db 

Ahora, consigo otro PDOException:

SQLSTATE[HY000]: General error: 14 unable to open database file 

Pero sólo se produce cuando intente ejecutar una consulta INSERTdespués de la base de datos está abierta.

¿Alguna idea de lo que está pasando?

+0

básicamente el httpd (Apache> PHP> DOP) no es usted, por lo que no es propietario del archivo, por lo que no tiene permisos de escritura ... interesante ... – SparK

+0

'sudo chgrp www-data test.db' con la adición de permisos trabajados para mí – Zippp

Respuesta

250

El problema, como resulta, es que el driver PDO SQLite requiere que si se va a realizar una operación de escritura (INSERT, UPDATE, DELETE, DROP, etc), a continuación, la carpeta la base de datos reside en debe tener permisos de escritura, así como el archivo de base de datos real.

Encontré esta información en un comment at the very bottom of the PDO SQLite driver manual page.

+6

Además, SELinux (si está instalado) no debe aplicarse. Me llevó un día y medio darme cuenta de eso. –

+0

¡También se aplica a ruby-sqlite, muchas gracias! – Dorian

+0

@Dorian Gracias, no me di cuenta de que esto no era solo un problema de PHP/PDO, así que actualicé la pregunta original para ayudar a otros a encontrarla mejor. –

9

Esto puede suceder cuando el propietario del archivo SQLite en sí es no igual que el usuario que ejecuta el script. Se pueden producir errores similares si no se puede escribir toda la ruta del directorio (es decir, cada directorio en el camino).

¿A quién pertenece el archivo SQLite? ¿Tú?

¿Quién es el script que se ejecuta como? Apache o nadie?

+1

Poseo el archivo SQLite, pero no sé cómo se ejecuta el script. ¿Cómo puedo averiguarlo? (Tenga en cuenta, esto es en un host compartido y tengo permisos limitados) –

+0

Ah, eso hace las cosas más divertidas. Si está en hosting compartido, hay muchas posibilidades de que el script se ejecute como "nadie" o "apache". Haga que su secuencia de comandos cree un archivo ('file_put_contents ('./ foo.txt', 'Hello, world');'), que le mostrará con quién se está ejecutando. Lo más probable es que necesite que el script cree la base de datos SQLite. Esto puede ser un ejercicio entretenido si ya tiene datos en su archivo actual ... – Charles

+0

Buena idea, pero no-go. Cualquiera que sea PHP que se esté ejecutando ya que no tiene privilegios de escritura, entonces no puede crear el archivo. ¿Hay alguna forma PHP que pueda recuperar el usuario con el que se está ejecutando actualmente? –

2

Para mí, el problema era SELinux enforcement en lugar de los permisos. El error de "lectura única base de datos" se fue una vez que la aplicación discapacitados, siguiendo la sugerencia hecha por Steve V. en un comentario en the accepted answer.

echo 0 >/selinux/enforce 

Tras ejecutar este comando, todo funcionó como se esperaba (CentOS 6.3).

El problema específico que me encontré fue durante la configuración de Graphite. Comprobé tres veces que el usuario de apache poseía y podía escribir tanto en graphite.db como en mi directorio padre. Pero hasta que "fija" SELinux, todo lo que conseguí fue un seguimiento de la pila para el efecto de: DatabaseError: intento de escribir una base de datos de sólo lectura

+6

SELinux es una medida de seguridad, por lo que no debería desactivarse sin una buena razón. Sería mejor averiguar por qué SELinux está bloqueando en primer lugar y configurarlo correctamente en lugar de deshabilitarlo. –

1

Tengo el mismo error de IIS en Windows 7. Para corregir este error i Tuve que agregar permisos de control total a la cuenta IUSR para el archivo de base de datos sqlite. No necesita cambiar los permisos si usa sqlite en webmatrix en lugar de IIS.

-1

Tengo esto en mi navegador cuando cambié el uso de http://localhost a http://my.local.ip.address y luego cambió de nuevo a localhost - era necesario quedarse con la dirección IP una vez que había cambiado para que una vez

2

Esto puede ser causado por SELinux. Si no desea deshabilitar completamente SELinux, debe establecer el directorio db fcontext a httpd_sys_rw_content_t.

semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/railsapp/db(/.*)?" 
restorecon -v /var/www/railsapp/db 
0

Recibí este error cuando intenté escribir en una base de datos en un sistema Android.

Aparentemente, sqlite3 no solo necesita permisos de escritura para el archivo de base de datos y el directorio contenedor (como ya dijo @ austin-hyde en su respuesta) sino también la variable de entorno TMPDIR para apuntar a un directorio (posiblemente escribible).

En mi sistema Android lo fijo a TMPDIR="/data/local/tmp" y ahora mi script ejecuta como se esperaba :)

Cuestiones relacionadas