LOAD DATA INFILE错误代码:13

时间:2010-11-18 13:27:57

标签: mysql file-io

在我的远程MySQL中,当我尝试执行此查询时, 我收到MySQL错误代码:13。

查询 -

LOAD DATA INFILE 
'/httpdocs/.../.../testFile.csv'
INTO TABLE table_temp
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\\r \\n'
(sku, qty);

错误代码:13 Can't get stat of '/httpdocs/.../.../testFile.csv' (Errcode: 2)

一个。数据库userlogin具有所有授权权限。

CREATE USER 'userName'@'%' IDENTIFIED BY '************';

GRANT ALL PRIVILEGES ON * . * TO 'userName'@'%' IDENTIFIED BY '************' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;

GRANT ALL PRIVILEGES ON `userName\_%` . * TO 'userName'@'%';

湾我还将文件和文件夹权限设置为chmod 777(rwxrwxrwx)    使用FTP工具

19 个答案:

答案 0 :(得分:97)

我知道这篇文章很老,但搜索结果仍然存在。我无法在网上找到这个问题的解决方案,所以我最终自己搞清楚了。如果您正在使用Ubuntu,那么有一个名为“Apparmor”的程序阻止MySQL查看该文件。如果您希望MySQL能够从“tmp”目录中读取文件,那么您需要执行以下操作:

sudo vim /etc/apparmor.d/usr.sbin.mysqld

进入文件后,您将看到My​​SQL可以使用的一堆目录。将行/tmp/** rwk添加到文件中(我不确定它在哪里重要,但这里是我放置它的示例):

  /etc/mysql/*.pem r,

  /etc/mysql/conf.d/ r,

  /etc/mysql/conf.d/* r,

  /etc/mysql/*.cnf r,

  /usr/lib/mysql/plugin/ r,

  /usr/lib/mysql/plugin/*.so* mr,

  /usr/sbin/mysqld mr,

  /usr/share/mysql/** r,

  /var/log/mysql.log rw,

  /var/log/mysql.err rw,

  /var/lib/mysql/ r,

  /var/lib/mysql/** rwk,


  /tmp/** rwk,


  /var/log/mysql/ r,

  /var/log/mysql/* rw,

  /var/run/mysqld/mysqld.pid w,

  /var/run/mysqld/mysqld.sock w,

  /run/mysqld/mysqld.pid w,

  /run/mysqld/mysqld.sock w,

现在您需要做的就是重新加载Apparmor:

sudo /etc/init.d/apparmor reload

注意我使用了“vim”,但用你最喜欢的文本编辑器代替你知道如何使用它。

答案 1 :(得分:51)

在我的查询中添加关键字“LOCAL”对我有用:

LOAD DATA LOCAL INFILE 'file_name' INTO TABLE table_name

可以找到关键字的详细说明here

答案 2 :(得分:19)

这通常是一个文件访问权限问题,但我看到你已经在b点解决了这个问题,但为了以防万一,值得一试。另一个选择是使用LOAD DATA LOCAL INFILE,它可以解决许多文件访问权限问题。要使用此方法,您需要先在本地复制文件(最好在mysql文件夹中)。 •如果指定了LOCAL,则客户端主机上的客户端程序将读取该文件并将其发送到服务器。

  

目录权限不足

     

此示例中的错误已导致   因为你想要的文件   import不在目录中   用户可以读取MySql服务器   正在运行。注意所有   目录的父目录   这是需要可读的   MySql用户为此工作。保存   / tmp文件通常可以作为   这通常是可读的(和   所有用户都可写。错误代码   号码是13。   的 Source

编辑:

请记住,您不仅需要拥有文件夹的文件夹,还需要上层目录的权限。

MySql论坛上的this帖子示例。

如果您的文件包含在以下结构中: /tmp/imports/site1/data.file

你需要(我认为,755工作)r + x在这些目录上的'other':

的/ tmp

的/ tmp /进口

以及主要的两个:

的/ tmp /进口/ SITE1

/tmp/imports/site1/data.file

您需要文件和目录是世界可读的。 抱歉,如果你已经尝试过这种方法,但是可能值得回顾一下你的步骤,不要再费力去仔细检查。

答案 3 :(得分:14)

mysql配置文件中有一个属性在[mysqld]部分下 名字 - tmpdir

例如:

tmpdir = c:/temp (Windows) or tmpdir = /tmp (Linux)

LOAD DATA INFILE命令只能在此位置执行读写操作。

因此,如果您将文件放在指定位置,那么LOAD DATA INFILE可以轻松读取/写入任何文件。

另一个解决方案

我们也可以通过以下命令导入数据

load data local infile

在这种情况下,不需要将文件移动到tmpdir,您可以给出文件的绝对路径,但是要执行此命令,您需要更改一个标志值。标志是

--local-infile

您可以在访问mysql时通过命令提示符更改其值

mysql -u username -p --local-infile=1

干杯

答案 4 :(得分:5)

我使用Ubuntu 12.04,我必须创建表,然后执行以下操作之一:

使用local会出错(mysql 5.5):

> LOAD DATA LOCAL INFILE "file.csv" INTO table inverter FIELDS TERMINATED BY ',';
ERROR 1148 (42000): The used command is not allowed with this MySQL version

出于安全原因,默认情况下禁用LOAD DATA INFILE命令,在此处重新启用它并且它应该有效:https://stackoverflow.com/a/16286112/445131

您可以使用mysqlimport导入csv文件:

mysqlimport -u root -p --fields-terminated-by=',' --local dbname tablename.csv

请注意,csv文件在扩展名之前必须与表格具有相同的名称。

答案 5 :(得分:5)

错误13只是权限问题。 即使我有相同的问题,也无法将数据加载到mysql表,然后自己解决了这个问题。

  

以下是解决方案:

默认

  

- local-infile设置为值0

,为了使用 LOAD DATA LOCAL INFILE,必须启用它。

所以启动mySQL 就像这样:

  

mysql -u username -p --local-infile

这将使启动期间启用LOCAL INFILE,因此使用它不会有任何问题!

答案 6 :(得分:2)

如果您使用的是Fedora / RHEL / CentOO,您可以暂时禁用SELinux:

setenforce 0

加载您的数据,然后重新启用它:

setenforce 1

答案 7 :(得分:2)

解决这个问题我遇到了很多麻烦,有两件事要做:

  • local-infile =1段之后的两个位置使用[mysql]更新文件sudo gedit /etc/apparmor.d/usr.sbin.mysqld(这允许使用LOCAL INFILE sql命令)。

  • 通过/var/www/更新,因此apparmor允许您通过添加以下行来写入/name of your directory/ r,的特殊文件:

/name of your directory/* rw,

/var/www/toto/

您的目录名称可以是for customer in customers: if customer.ID not in (select ID from fullcustomer) insert customer into fullcustomer (这允许使用您的文件所在的目录)。

答案 8 :(得分:1)

  

用于Ubuntu用户

我在Ubuntu 15.10上运行mysql 5.6.28而我遇到了完全相同的问题,我在my.cnf中拥有了所有必要的标志 tmpdir = / tmp 本地的infile = 1 重新启动mysql,我仍然会得到 LOAD DATA INFILE错误代码:13

就像尼尔森提到的问题是" apparmor",有点赞助权限的mysql,然后我找到了解决方案感谢this quick&简单的教程。

基本上,假设您的tmp目标为/tmp

将新的tmpdir条目添加到/etc/apparmor.d/local/usr.sbin.mysqld

sudo nano /etc/apparmor.d/local/usr.sbin.mysqld

*添加此

/tmp/ r,
/mnt/foo/tmp/** rw,

重新加载AppArmor

sudo service apparmor reload

重启MySQL

sudo service mysql restart

我希望能帮助一些Ubuntu-ers

答案 9 :(得分:0)

  1. 在db_name上授予所有特权。*至'db_user'@'localhost';
  2. 。*上的GRANT FILE到'db_user'@'localhost'由'password'标识;
  3. 冲洗特权;
  4. SET GLOBAL local_infile = 1;
  5. MYSQL“ secure-file-priv”的配置中的变量必须为空 行!

答案 10 :(得分:0)

CentOS 7+最低安全解决方案:(也应与RedHat一起使用)

chcon -Rv --type=mysqld_db_t /YOUR/PATH/

说明:

知道您已应用在secure-file-priv=/YOUR/PATH/中使用my.cnf的良好做法,以便使用load data infile sql语句,您仍然看到以下内容:

ERROR 13 (HY000): Can't get stat of '/YOUR/PATH/FILE.EXT' (Errcode: 13 "Permission denied")

这是由SELinux Enforcing模式引起的,将模式更改为Permissive或禁用SELinux是不安全的。
简而言之,

chcon更改文件的SELinux安全上下文或 文件/目录的方式类似于“ chown”或“ chmod”的方式 用于更改文件的所有权或标准文件权限。

SELinux Enforcing模式阻止mysqld访问具有安全上下文类型default_t的目录,因此我们需要将路径的安全上下文类型更改为{{1} }。要查看当前的安全上下文类型,请使用以下命令:

mysqld_db_t

如果您要重置/撤消解决方案,请应用以下命令:

ls --directory --scontext /YOUR/PATH/

以下链接中引用了我共享的解决方案:

https://wiki.centos.org/HowTos/SELinux
https://mariadb.com/kb/en/selinux/
https://linux.die.net/man/8/mysqld_selinux

答案 11 :(得分:0)

我知道,这是一个旧线程,但是仍然有许多人面临LOAD DATA INFILE的问题!

有很多不错的答案,但对我来说,这些答案都不起作用:)

我正在使用mariadb / server docker容器运行MariaDB,它在Ubuntu上运行,但是apparmor没有任何问题

对我来说,问题很简单,我在/root/data.csv中有文件,当然mysql用户无法访问它!

另一方面,人们建议使用LOAD DATA LOCAL INFILE作为替代方案,尽管它可以工作,但是其性能不如标准的“ LOAD DATA INFILE”,因为当使用“ LOCAL”时,它假定文件正在加载来自远程终端,其处理方式也有所不同。

为获得最佳性能,请始终使用“ LOAD DATA INFILE”,除非您必须直接从远程服务器或便携式计算机/台式机加载文件。由于安全原因,这当然是禁用的,因此,根据操作系统,您必须通过服务器的配置文件“ /etc/my.cnf”或“ /etc/my.cnf.d/server.cnf”允许“ LOCAL_INFILE”。

最后,对我而言,容器将“ secure_file_priv”参数定义为“ / data”

b510bf09bc5c [testdb]> SHOW GLOBAL VARIABLES LIKE '%SECURE_FILE_%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| secure_file_priv | /data/ |
+------------------+--------+

这意味着,仅当从“ / data”文件夹中加载数据文件时,LOAD DATA INFILE才起作用!注意这一点,并使用正确的文件夹:)

希望这对某人有帮助。

干杯。

答案 12 :(得分:0)

在过去的几天里,我也一直在努力解决这个问题,我也转向堆栈溢出寻求答案。

但是,似乎没有人提到通过MySQL自己的导入数据向导工具将数据导入MySQL的最简单方法!

只需右键单击表格,表格就会出现在其中。

just right click on the table and it comes up there

以上答案均无助于我,因此,如果遇到问题,请使用此功能! :)

答案 13 :(得分:0)

  1. 检出此系统变量local_infile已打开
 SHOW VARIABLES LIKE 'local_infile';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| local_infile  | ON    |
+---------------+-------+

否则,请使用以下命令重新启动mysqld

sudo ./mysqld_safe --local-infile
  1. 将csv文件更改为/tmp文件夹,以便mysqls可以读取它。

  2. 导入到数据库

mysql> LOAD DATA INFILE '/tmp/a.csv'  INTO TABLE table_a  FIELDS TERMINATED BY ','  ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;
Query OK, 18 rows affected (0.17 sec)
Records: 18  Deleted: 0  Skipped: 0  Warnings: 0

答案 14 :(得分:0)

如果您在Mac上使用XAMPP,这对我有用:

将CSV / TXT文件移至/ Applications / XAMPP / xamppfiles / htdocs /,如下所示

LOAD DATA LOCAL INFILE '/Applications/XAMPP/xamppfiles/htdocs/file.csv' INTO TABLE `tablename` FIELDS TERMINATED BY ',' LINES TERMINATED BY ';'

答案 15 :(得分:0)

OLD:

LOAD DATA INFILE '/home/root12/Downloads/task1.csv' INTO TABLE test.task FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;

File '/home/root12/Downloads/task1.csv' not found (Errcode: 13 - Permission denied)

为我工作的新工作:

LOAD DATA LOCAL INFILE '/home/root12/Downloads/task1.csv' INTO TABLE test.task FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;

Query OK, 500 rows affected, 284 warnings (1.24 sec)
Query OK, 5000 rows affected, 2846 warnings (1.24 sec)

答案 16 :(得分:0)

如果您使用cPanel或phpmyadmin导入CSV using LOAD DATA,请务必启用Use LOCAL keyword。这在共享服务器环境中对我有用。

答案 17 :(得分:0)

load data infile '/root/source/in.txt' into table employee; ==>错误代码:13

load data infile '/tmp/in.txt' into table employee; ==>作品

CentOS版本6.6(最终版) - 5.5.32 MySQL社区服务器(GPL)

与Linux文件权限相关的内容

答案 18 :(得分:0)

I have experienced same problem and applied the solutions above.

First of all my test environment are as follows

  • Ubuntu 14.04.3 64bit
  • mysql Ver 14.14 Distrib 5.5.47, for debian-linux-gnu (x86_64) using readline 6.3 (installed by just 'sudo apt-get install ...' command)

My testing results are

i) AppArmor solution only work for /tmp cases.

ii) Following solution works without AppArmor solution. I would like to appreciate Avnish Mehta for his answer.

$ mysql -u root -p --in-file=1
...
mysql> LOAD DATA LOCAL INFILE '/home/hongsoog/study/mysql/member.dat'
    -> INTO TABLE member_table;

Important three points are

  • start mysql client with --in-file=1 option
  • use LOAD DATA LOCAL INFILE instead of LOAD DATA INFILE
  • check all path element have world read permission from the / to data file path. For example, following subpath should be world readable or mysql group readable if INFILE is targeting for '/home/hongsoog/study/mysql/memer.dat'

    • /home
    • /home/hongsoog
    • /home/hongsoog/study/mysql
    • /home/hongsoog/study/mysql/member.data

When you start mysql client WITHOUT "--in-file=1" option and use

LOAD DATA LOCAL INFILE ...
, you will get

ERROR 1148 (42000): The used command is not allowed with this MySQL version


In summary, "--in-file=1" option in mysql client command and "LOAD DATA LOCAL INFILE ..." should go hand in hand.

Hope to helpful to anyone.