28 votes

MySQL Conteneur Docker INFILE/ INTO OUTFILE déclaration sur le Système MacOS

Je dispose d'un programme Java et mysql est un conteneur Docker (image: mysql:5.7.20). Mon MacOs est High Sierra 10.13.4.

Le problème en bref

À l'aide de Docker sur MacOS (10.13.4.). À l'intérieur d'un conteneur docker (image: mysql:5.7.20), principalement les requêtes (exécuté à partir d'un programme java)

  • LOAD DATA INFILE ...
  • SELECT ... INTO OUTFILE ...

fonctionnent très bien, mais parfois, le programme java jette les exceptions:

  • SQLException: can't create/write to file ‘...' (Errcode: 2 - Aucun fichier ou répertoire)
  • SQLException: ne Peut pas obtenir stat de ‘...' Errcode: 2 - Aucun fichier ou répertoire)
  • SQLException: Le serveur MySQL est en cours d'exécution avec l'option --sécurisé de fichiers priv option de sorte qu'il ne peut pas exécuter cette instruction
  • SQLException: Fichier ‘...' not found (Errcode: 2 - Aucun fichier ou répertoire)

btw. le fichier existe et les autorisations doivent être fine (voir la version longue)

La version longue

Le processus est le suivant:

  • un .fichier csv est créé
  • c' .csv fichier est copié dans un répertoire, qui est monté pour le conteneur docker
    • docker-composer des volumes de l'article: - "./data/datahub/import:/var/lib/mysql-files/datahub/import"
  • puis MySQL lit ce .fichier csv dans une table:
    • LOAD DATA INFILE '.csv-file' REPLACE INTO TABLE 'my-table';
  • puis quelques trucs sur la base de données qui se passe
  • après que MySQL écrit une .csv fichier de sortie
    • SELECTtbl.sku,tbl.supprimé,tbl.data_source_valuesINTO OUTFILE 'output.csv' FIELDS TERMINATED BY '|' ENCLOSED BY '"' ESCAPED BY '"' FROM (SELECT ...

Ce projet a certaines java intégration-tests pour ce processus. Ces tests sont le plus souvent verts, mais parfois ils échouent avec:

  • SQLException: can't create/write to file ‘...' (Errcode: 2 - Aucun fichier ou répertoire)
  • SQLException: ne Peut pas obtenir stat de ‘...' Errcode: 2 - Aucun fichier ou répertoire)
  • SQLException: Le serveur MySQL est en cours d'exécution avec l'option --sécurisé de fichiers priv option de sorte qu'il ne peut pas exécuter cette instruction
  • SQLException: Fichier ‘...' not found (Errcode: 2 - Aucun fichier ou répertoire)

Le docker-composition de fichier ressemble à ceci:

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:

Le Journal à partir de ce menu fixe conteneur de base de données est le suivant (mais parfois, ce qui s'est passé lorsque tous les tests sont vertes, trop)

  • 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)

L' .fichier csv à l'intérieur de la datahub conteneur, le suivant, fo 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

Je pense qu'il n'y a pas de problème, que ce fichier appartient à la racine, car pour la plupart ce fichier peut être lu par MySQL. Lorsque je change d'utilisateur mysql par su mysql à l'intérieur du conteneur Docker, je reçois le texte suivant:

$ 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

Maintenant, certaines choses étranges qui s'est passé.

  • avec l'utilisateur root, j'ai pu faire une cat deactivated_product_merged_bub.csv
  • avec utilisateur mysql je ne pouvais pas j'ai eu:

Sortie:

$ cat deactivated_product_merge_bub.csv
cat: deactivated_product_merge_bub.csv: No such file or directory

J'ai fait un stat deactivated_product_merged_bub.csv comme utilisateur MySQL et tout à coup j'ai pu faire une cat sur ce fichier (comme vous le voyez j' chmod 777 de ce fichier pour obtenir le cat de travail - mais il ne fonctionne pas).

  • stat en tant que root

Sortie:

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 comme utilisateur mysql

Sortie:

$ 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: -

Question

Personne ne sait ce qui s'est passé ici, ou qui a un indice de ce que je pouvais de recherche à creuser plus profond?

À mon avis, c'est que c'est parce que l'utilisation de Docker avec MacOs et le volume monté.

2voto

DavidChilders Points 11

Il me semble que vous êtes probablement en cours d'exécution dans deux problèmes distincts se posent ici, à la fois liées à la configuration du serveur MySQL.

Le serveur MySQL est en cours d'exécution avec l'option --sécurisé de fichiers priv option de sorte qu'il ne peut pas exécuter cette instruction.

Cette option nécessite tout de chargement de fichiers ou d'un fichier d'exportation pour être placé dans l'emplacement de stockage spécifié dans le système de fichiers. Vous pouvez trouver l'emplacement à l'aide de la commande suivante à partir de la ligne de commande de MySQL client ou à partir de MySQL Workbench:

mysql> show variables like 'secure-file-priv';

Le résultat de ce devrait identifier l'emplacement où les fichiers peuvent être chargés et écrit à. Aucun autre emplacement devrait être autorisée lorsque sécurisé de fichiers priv est activé.

(Vous avez une erreur de lecture de la communication de paquets)

Cela est souvent causé par des données en cours de chargement ou exporté, ce qui dépasse le MySQL variable max-admis-paquet.

Vous pouvez même trouver la valeur max-admis-paquet à l'aide de la commande suivante à partir de la ligne de commande de MySQL client ou à partir de MySQL Workbench:

mysql> show variables like 'max-allowed-packet';

Cette question a été traitée et bien répondu à cette question: https://dba.stackexchange.com/questions/19135/mysql-error-reading-communication-packets

En résumé: Dans /etc/my.cnf ou my.ini sous la section [mysqld]:

[mysqld]
max_allowed_packet=268435456

Dans le fonctionnement de MySQL exemple:

SET GLOBAL max_allowed_packet = 268435456;

(Pas de redémarrer le service est requis.)

En aparté, le compte MySQL que vous utilisez doit avoir reçu le 'dossier' autorisation afin de charger ou d'exportation. Depuis que vous utilisez le root de MySQL (administrative) de compte cela ne devrait pas être un facteur, mais j'ai pensé que je pourrais l'inclure pour quelqu'un qui vient dans ce.

J'espère que cette aide.

1voto

webofmars Points 342

Il pourrait être possible que vous essayez d'accéder à un fichier qui est en dehors de la valeur par défaut des chemins de docker pour mac (à partir du menu fixe osx documentation)

Par défaut, vous pouvez partager des fichiers dans /Utilisateurs/ /Volumes/, /private/, et /tmp directement. Pour ajouter ou supprimer le répertoire des arbres qui sont exportés vers Menu fixe, utilisez l'onglet partage de Fichiers dans le Panneau de préférences de la baleine menu -> Préférences -> partage de Fichiers. (Voir Les Préférences.)

https://docs.docker.com/docker-for-mac/osxfs/#namespaces

Dans le cas, docker pour mac est à l'aide d'une machine virtuelle linux exécuter par hyperkit sur Mac OS. Le client d'exécuter sur macOSx et le démon dans la machine virtuelle. Qui expliquent que vous avez à partager des fichiers dans une liste restreinte de chemins.

0voto

Neda Peyrone Points 32

Je pense que vous avez un problème avec la permission de partager des dossiers entre les conteneurs docker et d'accueil. Vous devez mapper les containers, les utilisateurs avec de l'hôte utilisateurs par la mise en UIDE .fichier env.

UID=501 # run echo $UID to get current user id
version: '3'
  services:
    datahub_db:
      image: "mysql:5.7.20"
      user: $UID
      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:

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X