2010-10-19 22 views
7

Tengo un script que intenta cargar algunos datos en MySQL con LOAD DATA INFILE. Por alguna razón, funciona si el archivo está en el directorio /tmp, pero no si el archivo está en otro directorio con permisos idénticos. No puedo encontrar ninguna forma de obtener MySQL para importar datos desde fuera del directorio /tmp, o el directorio de la base de datos, pero no encuentro nada en el manual que explique por qué este sería el caso.¿Qué archivos y permisos de directorio se requieren para MySQL LOAD DATA INFILE?

La situación:

$ ls -l/
... 
drwxrwxrwt 21 root root 4096 2010-10-19 20:02 tmp 
drwxrwxrwt 2 root root 4096 2010-10-19 20:14 tmp2 

$ ls -l /tmp/data.csv 
-rwxr-xr-x 1 timm timm 415431 2010-10-19 20:02 /tmp/data.csv 

$ ls -l /tmp2/data.csv 
-rwxr-xr-x 1 timm timm 415431 2010-10-19 20:14 /tmp2/data.csv 

AFAICT estos son idénticos en los aspectos importantes. Sin embargo, si en la línea de comandos de MySQL que hago:

> LOAD DATA INFILE '/tmp2/data.csv' IGNORE INTO TABLE ports 
     FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY ' '; 
ERROR 29 (HY000): File '/tmp2/data.csv' not found (Errcode: 13) 

> LOAD DATA INFILE '/tmp/data.csv' IGNORE INTO TABLE ports 
     FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY ' '; 
Query OK, 1 row affected, 1 warning (0.04 sec) 
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0 

que deduzco de mensajes en los foros que ErrNo 13 indica un problema de permisos. Parece que /tmp es tratado especialmente por MySQL, pero ¿por qué? Lo más cercano que puedo encontrar es una línea en el manual que dice:

Por razones de seguridad, cuando se leen archivos de texto ubicados en el servidor, los archivos deben residir en el directorio de la base de datos o ser legibles por todos.

/tmp no está en el directorio de la base de datos, pero tal vez se trata como si lo fuera. Entonces, ¿cómo debo configurar las cosas para que puedan leer archivos fuera de /tmp?

+0

¿Qué sucede si 'exportas TMPDIR =/tmp2' antes de ejecutar' mysql'? –

+0

No sé cómo hacer que MySQL use variables de mi entorno, pero si cambio el valor de 'tmpdir' en my.cnf no afecta el comportamiento (tmp2 aún falla, aunque ahora es la temperatura directorio) –

+0

El directorio temporal me salvó el día usando LOAD DATA INFILE –

Respuesta

1

Errno 13 puede deberse a SELinux en caso de que esté utilizando una distribución de servidor Linux (por ejemplo, RedHat Enterprise Linux o CentOS). Compruebe 'audit.log' para ver si SELinux se queja de su ruta /tmp2. A continuación, puede agregar su ruta a través del semanage fcontext -a -t mysqld_db_t "/tmp2(/.*)?" y ejecutar restorecon -R /tmp2.

Sin embargo, la solución podría ser mucho más simple y yo habría respondido directamente bajo su pregunta (en lugar de proporcionar una respuesta), si supiera cómo ..

+0

Por lo que vale, estoy usando Ubuntu 10.04 Desktop edition, con MySQL instalado desde paquetes Ubuntu. –

+0

Bien, entonces SELinux no es el problema allí. ¿Has probado 'LOAD DATA LOCAL INFILE ...'? ¿Te da el mismo resultado? – Joachim

16
mysqlimport --local <database> <infile> 

O

LOAD DATA LOCAL INFILE... should fix the issue. 
+1

+1 sin local se resuelve en el contexto del proceso del servidor, por lo que puede cargar datos del cliente y del servidor – Unreason

2

He encontrado un problema similar (no se puede leer un archivo en /tmp) y al agregar LOCAL después de LOAD DATA INFILE solucionó el problema.

Este Launchpad bug report podría tener algunas explicaciones de por qué esto está sucediendo.

1

Errcode 13 significa que faltan permisos (a diferencia de Errcode 2, lo que significa que el archivo no existe). MySQL necesita el archivo para ser leído por cualquier persona. Los permisos de tus archivos están bien.

Una vez que tuvimos el mismo problema en un servidor CentOS y fue causado por AppArmor que prohíben la aplicación MySQL para acceder a los archivos que no están enumerados en una lista blanca en /etc/apparmor.d/usr. Sbin. mysqld. ¿Tal vez tienes algún tipo de traje de seguridad que causa un comportamiento similar?

Según lo mencionado por otros, el uso de LOAD DATA INFILE LOCAL puede ser una solución.

Cuestiones relacionadas