MySQL LOAD DATA INFILE需要哪些文件和目录权限?

7
我有一个脚本,尝试使用LOAD DATA INFILE将一些数据加载到MySQL中。出于某种原因,如果文件在/tmp目录中,则可以正常工作,但如果文件在另一个具有相同权限的目录中,则无法正常工作。我找不到任何方法使MySQL从/tmp目录外或数据库目录导入数据,但我在手册中找不到任何说明为什么会出现这种情况。
$ ls -l /
...
drwxrwxrwt  21 root root  4096 2010-10-19 20:02 tmp
drwxrwxrwt   2 root root  4096 2010-10-19 20:14 tmp2

$ ls -l /tmp/data.csv 
-rwxr-xr-x 1 timm timm 415431 2010-10-19 20:02 /tmp/data.csv

$ ls -l /tmp2/data.csv 
-rwxr-xr-x 1 timm timm 415431 2010-10-19 20:14 /tmp2/data.csv

据我所知,这些在重要方面是相同的。但是,如果在MySQL命令行中执行以下操作:
> LOAD DATA INFILE '/tmp2/data.csv' IGNORE INTO TABLE ports
      FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY ' ';
ERROR 29 (HY000): File '/tmp2/data.csv' not found (Errcode: 13)

> LOAD DATA INFILE '/tmp/data.csv' IGNORE INTO TABLE ports 
      FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY ' ';
Query OK, 1 row affected, 1 warning (0.04 sec)
Records: 1  Deleted: 0  Skipped: 0  Warnings: 0

我从论坛帖子中了解到,errno 13表示权限问题。MySQL似乎会特殊处理/tmp目录,但为什么呢?我能找到的最接近的答案是手册中的一行文字:
“出于安全原因,在读取位于服务器上的文本文件时,这些文件必须位于数据库目录中或可被所有人读取。”
/tmp不在数据库目录中,但也许它被视为在其中。那么我该如何设置才能使其读取/tmp以外的文件呢?

如果您在运行 mysql 前导出 TMPDIR=/tmp2,会发生什么? - Frédéric Hamidi
我不知道如何让MySQL使用来自我的环境的变量,但如果我在my.cnf中更改tmpdir的值,它不会影响行为(即使现在是临时目录,tmp2仍然失败)。 - Tim Martin
临时目录使用LOAD DATA INFILE功能拯救了我的一天。 - Joaquín L. Robles
4个回答

17
mysqlimport --local <database> <infile>

LOAD DATA LOCAL INFILE... should fix the issue.

1
+1 在没有本地解析的情况下,它是在服务器进程的上下文中解决的 - 因此您可以从客户端和服务器加载数据。 - Unreason

3

Errcode 13表示缺少权限(与Errcode 2相反,后者表示文件不存在)。MySQL需要文件可被任何人读取。您的文件权限很好。

我们曾在CentOS服务器上遇到过同样的问题,原因是AppArmor禁止MySQL应用程序访问未在/etc/ap­par­mor.d/usr.​sbin.​mysqld白名单中列出的文件。也许您有某种安全套件导致类似的行为?

正如其他人所提到的,使用LOAD DATA INFILE LOCAL可能是一种解决方法。


尝试做完全相同的事情,编辑AppArmor的mysql白名单文件解决了这个问题。谢谢。 - Rich S

2

我遇到了类似的问题(无法读取 /tmp 中的文件),在 LOAD DATA INFILE 后添加 LOCAL 解决了问题。

这个Launchpad bug报告可能会解释为什么会出现这种情况。


1

如果您使用的是Linux服务器发行版(例如RedHat Enterprise Linux或CentOS),则错误号13可能是由于SELinux引起的。检查'audit.log'以查看SELinux是否在抱怨您的/tmp2路径。然后,您可以通过semanage fcontext -a -t mysqld_db_t "/tmp2(/.*)?"添加您的路径,并运行restorecon -R /tmp2

但是,解决方案可能会简单得多,如果我知道如何直接回答您的问题(而不是提供答案),我会直接在您的问题下回复。


说句实话,我正在使用Ubuntu 10.04桌面版,MySQL是从Ubuntu软件包中安装的。 - Tim Martin
好的,所以 SELinux 不是问题。您尝试过使用 'LOAD DATA LOCAL INFILE...' 吗?它是否给出了相同的结果? - Joachim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接