MacOS系统上的MySQL Docker Container INFILE/INTO OUTFILE语句

Sle*_*667 27 java mysql docker docker-compose

我有一个Java程序和一个mysql Docker容器(图片:mysql:5.7.20).我的MacOs是High Sierra 10.13.4.

问题简而言之

在MacOS上使用Docker(10.13.4.).在docker容器里面(图片: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-compose volume部分: - "./data/datahub/import:/var/lib/mysql-files/datahub/import"
  • 然后MySQL将此.csv文件读入表中:
    • LOAD DATA INFILE '.csv-file' REPLACE INTO TABLE 'my-table';
  • 然后在该数据库上的一些东西发生
  • 之后,MySQL编写.csv输出文件
    • SELECTtbl .sku ,tbl .删除了,tbl .data_source_valuesINTO 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:
Run Code Online (Sandbox Code Playgroud)

来自该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)

datahub容器中的.csv文件显示以下内容,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
Run Code Online (Sandbox Code Playgroud)

我认为没有问题,这个文件属于root用户,因为这个文件大部分都可以被MySQL读取.当我mysql通过su mysqlDocker容器内部更改为用户时,我得到以下内容:

$ 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
Run Code Online (Sandbox Code Playgroud)

现在发生了一些奇怪的事情

  • 与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
Run Code Online (Sandbox Code Playgroud)

我做了一个stat deactivated_product_merged_bub.csvmysql用户,然后突然我可以cat在那个文件上做(因为你看到我chmod 777对那个文件来cat工作 - 但它没有用).

  • stat 作为根

输出:

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: -
Run Code Online (Sandbox Code Playgroud)
  • 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: -
Run Code Online (Sandbox Code Playgroud)

有谁知道,这里发生了什么或暗示我可以搜索更深入的东西?

我的猜测是,这是因为将Docker与MacO和已安装的卷一起使用.

web*_*ars 1

您可能正在尝试访问 docker for mac 默认共享路径之外的文件(来自 docker osx 文档)

默认情况下,您可以直接共享 /Users/、/Volumes/、/private/ 和 /tmp 中的文件。要添加或删除导出到 Docker 的目录树,请使用 Docker 首选项鲸鱼菜单中的文件共享选项卡 -> 首选项 -> 文件共享。(请参阅首选项。)

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

在本例中,docker for mac 使用的是在 Mac OS 上由 hyperkit 运行的 Linux 虚拟机。客户端在 macOSx 上运行,守护进程在 VM 中运行。这说明您必须在受限路径列表中共享文件。