java - Оператор MySQL Docker INFILE/INTO OUTFILE в системе MacOS



docker-compose (1)

Возможно, вы пытаетесь получить доступ к файлу, который находится за пределами общих путей по умолчанию для Docker для Mac (из документации по Docker OSX)

По умолчанию вы можете обмениваться файлами в / Users /, / Volumes /, / private / и / tmp напрямую. Чтобы добавить или удалить деревья каталогов, экспортируемые в Docker, используйте вкладку «Общий доступ к файлам» в китовом меню параметров Docker -> «Настройки» -> «Общий доступ к файлам». (См. Настройки.)

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

В этом случае Docker для Mac использует виртуальную машину Linux, работающую под управлением HyperKit в Mac OS. Клиент работает на macOSx и демон в VM. Это объясняет, что вы должны делиться файлами в ограниченном списке путей.

У меня есть Java-программа и контейнер MySQL Docker (изображение: MySQL: 5.7.20). Мои MacOs - High Sierra 10.13.4.

Проблема вкратце

Использование Docker в MacOS (10.13.4.). Внутри Docker-контейнера (image: mysql: 5.7.20) в основном запросы (выполняемые из Java-программы)

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

работают нормально, но иногда Java-программа выдает исключения:

  • SQLException: не удается создать / записать в файл '…' (код ошибки: 2 - такой файл или каталог отсутствует)
  • SQLException: Невозможно получить статистику '…'. Код ошибки: 2 - Нет такого файла или каталога)
  • SQLException: сервер MySQL работает с параметром --secure-file-priv, поэтому он не может выполнить этот оператор
  • SQLException: файл '…' не найден (код ошибки: 2 - такого файла или каталога нет)

Кстати. файл существует и права должны быть в порядке (см. более длинную версию)

Длинная версия

Процесс следующий:

  • CSV-файл создается
  • этот файл .csv копируется в каталог, который монтируется для контейнера Docker
    • Раздел создания томов docker: - "./data/datahub/import:/var/lib/mysql-files/datahub/import"
  • затем MySQL читает этот файл .csv в таблицу:
    • LOAD DATA INFILE '.csv-file' REPLACE INTO TABLE 'my-table';
  • то происходит кое-что в этой базе данных
  • после этого MySQL записывает выходной файл .csv
    • SELECT ТАБЛ . sku , tbl . удалено , табл . data_source_values INTO 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 ...

Этот проект имеет несколько тестов интеграции Java для этого процесса. Эти тесты в основном зеленые, но иногда они терпят неудачу с:

  • SQLException: не удается создать / записать в файл '…' (код ошибки: 2 - такой файл или каталог отсутствует)
  • SQLException: Невозможно получить статистику '…'. Код ошибки: 2 - Нет такого файла или каталога)
  • SQLException: сервер MySQL работает с параметром --secure-file-priv, поэтому он не может выполнить этот оператор
  • SQLException: файл '…' не найден (код ошибки: 2 - такого файла или каталога нет)

Файл docker-compose выглядит так:

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:

Журнал из этого контейнера базы данных Docker показывает следующее (но иногда это происходило, когда все тесты тоже были зелеными)

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

Файл .csv внутри контейнера datahub показывает следующее: fo ls -lha

[email protected]:/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

Я думаю, что нет проблем с тем, что этот файл принадлежит root, потому что в основном этот файл может быть прочитан MySQL. Когда я переключаюсь на пользователя mysql через su mysql внутри контейнера Docker, я получаю следующее:

$ 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

Теперь произошло нечто странное.

  • с пользователем root, я мог бы сделать cat deactivated_product_merged_bub.csv
  • с пользователем MySQL я не мог я получил:

Выход:

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

Я сделал stat deactivated_product_merged_bub.csv как пользователь mysql, и внезапно я смог создать cat для этого файла (как вы видите, я chmod 777 для этого файла, чтобы заставить cat работать - но он не работал).

  • stat как корень

Выход:

[email protected]:/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 как пользователь mysql

Выход:

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

Вопрос

Кто-нибудь знает, что здесь произошло, или есть подсказка для того, что я могу искать, чтобы копать глубже?

Я предполагаю, что это связано с использованием Docker с MacO и подключенным томом.





docker-compose