java - create - MySQL Docker Container INFILE/INTO OUTFILE en el sistema MacOS
mysql dockerfile example (1)
Tengo un programa Java y un contenedor mysql Docker (imagen: mysql: 5.7.20). Mi MacOs es High Sierra 10.13.4.
El problema en definitiva
Usando Docker en MacOS (10.13.4.). Dentro de un contenedor docker (imagen: mysql: 5.7.20) principalmente las consultas (ejecutadas desde un programa java)
LOAD DATA INFILE ...
-
SELECT ... INTO OUTFILE ...
funcionan bien, pero a veces el programa java lanza las excepciones:
- SQLException: No se puede crear / escribir en el archivo ''...'' (Código de error: 2 - No existe tal archivo o directorio)
- SQLException: No se puede obtener la estadística de ''...'' Código de error: 2 - No existe tal archivo o directorio)
- SQLException: el servidor MySQL se ejecuta con la opción --secure-file-priv por lo que no puede ejecutar esta declaración
- SQLException: no se encontró el archivo ''...'' (Código de error: 2 - No existe tal archivo o directorio)
por cierto el archivo existe y los permisos deben estar bien (ver versión más larga)
La version mas larga
El proceso es el siguiente:
- se crea un archivo .csv
- este archivo .csv se copia en un directorio, que se monta para el contenedor de la ventana acoplable
- Docker-
- "./data/datahub/import:/var/lib/mysql-files/datahub/import"
:- "./data/datahub/import:/var/lib/mysql-files/datahub/import"
- Docker-
- luego MySQL lee este archivo .csv en una tabla:
-
LOAD DATA INFILE ''.csv-file'' REPLACE INTO TABLE ''my-table'';
-
- entonces algunas cosas en esa base de datos pasan
- después de eso MySQL escribe un archivo de salida .csv
-
SELECT
tbl.
sku,
tbl.
eliminado,
tbl.
data_source_valuesINTO OUTFILE ''output.csv'' FIELDS TERMINATED BY ''|'' ENCLOSED BY ''"'' ESCAPED BY ''"'' FROM (SELECT ...
INTO OUTFILE ''output.csv'' FIELDS TERMINATED BY ''|'' ENCLOSED BY ''"'' ESCAPED BY ''"'' FROM (SELECT ...
-
Este proyecto tiene algunas pruebas de integración de java para este proceso. Estas pruebas son en su mayoría verdes, pero a veces fallan con:
- SQLException: No se puede crear / escribir en el archivo ''...'' (Código de error: 2 - No existe tal archivo o directorio)
- SQLException: No se puede obtener la estadística de ''...'' Código de error: 2 - No existe tal archivo o directorio)
- SQLException: el servidor MySQL se ejecuta con la opción --secure-file-priv por lo que no puede ejecutar esta declaración
- SQLException: no se encontró el archivo ''...'' (Código de error: 2 - No existe tal archivo o directorio)
El archivo Dock-Compose se ve como:
version: ''3''
services:
datahub_db:
image: "mysql:5.7.20"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=${DATAHUB_DB_ROOT_PASSWORD}
- MYSQL_DATABASE=${DATAHUB_DB_DATABASE}
volumes:
- "datahub_db:/var/lib/mysql"
- "./data/datahub/import:/var/lib/mysql-files/datahub/import"
- "./data/akeneo/import:/var/lib/mysql-files/akeneo/import"
ports:
- "${DATAHUB_DB_PORT}:3306"
...
volumes:
datahub_db:
El registro de ese contenedor de base de datos de Docker muestra lo siguiente (pero a veces, esto sucedió cuando todas las pruebas también están en verde)
-
datahub_db_1 | 2018-06-01T10:04:33.937646Z 144 [Note] Aborted connection 144 to db: ''datahub_test'' user: ''root'' host: ''172.18.0.1'' (Got an error reading communication packets)
El archivo .csv dentro del contenedor datahub, muestra lo siguiente, para ls -lha
root@e02e2074fb6b:/var/lib/mysql-
files/datahub/import/test/products/kaw# ls -lha
total 4.0K
drwxr-xr-x 3 root root 96 Jun 1 09:36 .
drwxr-xr-x 3 root root 96 Jun 1 09:36 ..
-rw-r--r-- 1 root root 378 Jun 1 06:47 deactivated_product_merged_bub.csv
Creo que no hay problema, que este archivo pertenece a la raíz, porque MySQL puede leerlo principalmente. Cuando cambio al usuario mysql
través de su mysql
dentro del contenedor Docker, obtengo lo siguiente:
$ ls -al
total 4
drwxr-xr-x 3 mysql mysql 96 Jun 1 09:36 .
drwxr-xr-x 3 mysql mysql 96 Jun 1 09:36 ..
-rw-r--r-- 1 mysql mysql 378 Jun 1 06:47 deactivated_product_merged_bub.csv
Ahora algo extraño sucedió.
- con el usuario root, podría hacer un
cat deactivated_product_merged_bub.csv
- con el usuario mysql no pude obtener:
Salida:
$ cat deactivated_product_merge_bub.csv
cat: deactivated_product_merge_bub.csv: No such file or directory
Hice una stat deactivated_product_merged_bub.csv
como usuario de mysql y de repente pude hacer un cat
en ese archivo (como ve chmod 777
en ese archivo para que el cat
funcione, pero no funcionó).
-
stat
como root
Salida:
root@e02e2074fb6b:/var/lib/mysql-files/datahub/import/test/products/kaw# stat
deactivated_product_merged_bub.csv
File: ''deactivated_product_merged_bub.csv''
Size: 378 Blocks: 8 IO Block: 4194304 regular file
Device: 4fh/79d Inode: 4112125 Links: 1
Access: (0777/-rwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2018-06-01 09:23:38.000000000 +0000
Modify: 2018-06-01 06:47:44.000000000 +0000
Change: 2018-06-01 09:04:53.000000000 +0000
Birth: -
-
stat
como usuario mysql
Salida:
$ stat deactivated_product_merged_bub.csv
File: ''deactivated_product_merged_bub.csv''
Size: 378 Blocks: 8 IO Block: 4194304 regular file
Device: 4fh/79d Inode: 4112125 Links: 1
Access: (0777/-rwxrwxrwx) Uid: ( 999/ mysql) Gid: ( 999/ mysql)
Access: 2018-06-01 09:32:25.000000000 +0000
Modify: 2018-06-01 06:47:44.000000000 +0000
Change: 2018-06-01 09:04:53.000000000 +0000
Birth: -
Pregunta
¿Alguien sabe qué sucedió aquí o tiene una pista de lo que podría buscar para profundizar más?
Mi especulación es que se debe a que utiliza Docker con MacOs y el volumen montado.
Es posible que esté intentando acceder a un archivo que se encuentra fuera de las rutas compartidas predeterminadas de la ventana acoplable para mac (desde la documentación de la ventana acoplable osx)
De forma predeterminada, puede compartir archivos en / Usuarios /, / Volúmenes /, / privados / y / tmp directamente. Para agregar o eliminar árboles de directorios que se exportan a Docker, use la pestaña Uso compartido de archivos en el menú de preferencias de Docker ballena -> Preferencias -> Uso compartido de archivos. (Ver Preferencias).
En el caso, la ventana acoplable para mac está utilizando una máquina virtual Linux ejecutada por un hipervínculo en Mac OS. El cliente se ejecuta en macOSx y el demonio en la máquina virtual. Eso explica que tienes que compartir archivos en una lista restringida de rutas.