No se pueden generar datos MySQL en el archivo

13

Estoy tratando de enviar los datos de una tabla MySQL a un archivo pero obtengo errores de permiso:

$ pwd
/home/dotancohen
$ mkdir in
$ chmod 777 in/
$ mysql -ugs -p
mysql> USE someDatabase;
mysql> SELECT * FROM data INTO OUTFILE '/home/dotancohen/in/data.csv';
ERROR 1045 (28000): Access denied for user 'gs'@'localhost' (using password: YES)
mysql>

Si el directorio en cuestión está modificado para 777, ¿por qué el usuario de MySQL no puede escribir el archivo? Curiosamente, tampoco puedo escribir en / tmp /.

EDITAR: Parece que el usuario de la base de datos tiene los permisos adecuados de MySQL:

mysql> show grants;
+----------------------------------------------------------------------------------+
| Grants for gs@localhost                                                          |
+----------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'gs'@'localhost' IDENTIFIED BY PASSWORD 'somePassword'     | 
| GRANT ALL PRIVILEGES ON `gs\_%`.* TO 'gs'@'localhost'                            | 
+----------------------------------------------------------------------------------+
2 rows in set (0.01 sec)
dotancohen
fuente
2
Debe otorgar derechos de acceso a MySQL en todo el árbol de directorios. La concesión de derechos no intiene sentido si MySQL no puede acceder dotanchoen. En otras palabras, la caja de depósito de seguridad en la bóveda del banco se puede dejar abierta de par en par, pero si la puerta de la bóveda del banco está cerrada, no entrará en la caja. Su gsusuario también debe tener el FILEprivilegio mysql para ejecutar realmente esa consulta.
El problema es que es posible que no tenga permisos seleccionados. Los permisos de Mysql no están controlados por los permisos de directorio. Debe usar mysql -u <nombre de usuario> -p para ejecutarse como un usuario específico de mysql. Para dar acceso de usuario a una base de datos, eche un vistazo a MySql grant. dev.mysql.com/doc/refman/5.1/en/grant.html
Gracias, este usuario tiene SELECTpermisos. A menudo busco en la base de datos como este usuario.
dotancohen
Gracias, Marc, de eso tenía miedo. ¿Entonces no puedo tener una carpeta de "bandeja de entrada" en la que otros usuarios puedan escribir, sin dejar que también lean / escriban en mi directorio personal?
dotancohen
2
Asegúrese de que el usuario tenga FILEprivilegios tal como lo describen los documentos de MySQL .
Mike Purcell

Respuestas:

12

De acuerdo con la documentación de MySQL en SELECT ... INTO OUTFILE

Todos los usuarios del host del servidor pueden escribir cualquier archivo creado por INTO OUTFILE o INTO DUMPFILE. La razón de esto es que el servidor MySQL no puede crear un archivo que sea propiedad de otra persona que no sea el usuario bajo cuya cuenta se está ejecutando. (Nunca debe ejecutar mysqld como root por esta y otras razones). Por lo tanto, el archivo debe poder escribirse en todo el mundo para que pueda manipular su contenido.

Debería enviar SELECT INTO OUTFILEa / var / lib / mysql de la siguiente manera

SELECT * FROM data INTO OUTFILE 'data.csv';

Por supuesto, debe asegurarse de tener permiso de ARCHIVO en gs @ localhost.

Hay dos formas de obtener este permiso

MÉTODO 1

GRANT FILE ON *.* TO 'gs'@'localhost';

MÉTODO # 2

UPDATE mysql.user SET File_priv = 'Y' WHERE user='gs' AND host='localhost';
FLUSH PRIVILEGES;

ACTUALIZACIÓN 2012-05-01 07:09 EDT

Para darse el privilegio de ARCHIVO, haga lo siguiente:

  • PASO 01) service mysql restart --skip-networking --skip-grant-tables
  • PASO 02) mysql <hit enter>
  • PASO 03) UPDATE mysql.user SET File_priv = 'Y' WHERE user='gs' AND host='localhost';
  • PASO 04) exit
  • PASO 05) service mysql restart
RolandoMySQLDBA
fuente
Gracias. Actualicé la pregunta con la salida de SHOW GRANTS. Parece que el usuario de la base de datos debería tener los permisos adecuados.
dotancohen
El usuario de la base de datos no tiene los permisos adecuados. El privilegio ARCHIVO solo se otorga a un usuario con GRANT ALL PRIVILEGES ON *.*, al igual que RELOADy SHUTDOWN. Esto es así porque esos son privilegios administrativos globales. El GRANT ALLprivilegio que tiene es solo para la gsbase de datos.
RolandoMySQLDBA
1

Las diferentes distribuciones y sistemas operativos no manejan todos los destinos de OUTFILE de la misma manera.

Por ejemplo, cuando se ejecuta un demonio mysqld en Linux, que usa un socket, el archivo OUTFILE a veces se escribe en el /tmpdirectorio. No es un gran problema, solo usar el enfoque OUTFILE tiene deficiencias, es decir, tratar con los permisos y encontrar a dónde fue el archivo.

Dado que el objetivo de esta pregunta no es específicamente "Cómo usar un OUTFILE", sino que solo está buscando capturar algunos datos de MySQL en un archivo, aquí hay una alternativa que no requiere que juegue con permisos de ARCHIVO, etc. .

$ (echo 'SELECT * FROM data' | mysql -ugs -p[password])> /home/dotancohen/in/data.csv

El resultado de esto está delimitado por tabulaciones de forma predeterminada. Para las comas, simplemente canalícelo sedo algo antes de escribirlo en el archivo.

AaronDanielson
fuente
1

Pasé horas tratando de entender las sugerencias en esta página y en muchas otras páginas de StackOverflow.

No importa cómo cambié los permisos en MySql, no pude hacer que nada funcionara.

Volví a los permisos con los que comencé.

Finalmente, lo que funcionó para mí fue más simple que las sugerencias de otros:

echo "select id, emailAddress FROM contacts" | mysql --user=myusername --password mydatabasename > /home/my_output_file.tsv

Ryan
fuente
1
Su método es bueno para usar cuando está en Bash CLI. Sin embargo, la pregunta en el OP pregunta sobre cómo enviar datos a un archivo desde la CLI del cliente MySQL.
dotancohen
0

Con respecto a los dos métodos para enviar datos a CSV (debería ser TSV) mencionados anteriormente, he encontrado que si hay valores vacíos en las entradas que está exportando, existe el riesgo de que los datos se puedan desordenar debido a una asignación incorrecta de los datos a las columnas correspondientes.

Con preocupación por la integridad de los datos para la recuperación, encontré este sitio web:

https://www.eversql.com/exporting-mysql-schema-structure-to-xml-using-mysql-clients/

Mencionó que la --xmlopción en mysqldumppermite exportar los datos en formato XML que luego podría analizarse mediante un script personalizado a cualquier formato necesario, incluido TSV.

Nguyen H Chan
fuente