sql - 如何使用SELECT INTO OUTFILE绕过MySQL Errcode 13?
我试图使用MySQL SELECT INTO OUTFILE语句将表的内容转储到csv文件。 如果我做:
SELECT column1, column2
INTO OUTFILE 'outfile.csv'
FIELDS TERMINATED BY ','
FROM table_name;
将在存储该数据库文件的同一目录中的服务器上创建outfile.csv。
但是,当我将查询更改为:
SELECT column1, column2
INTO OUTFILE '/data/outfile.csv'
FIELDS TERMINATED BY ','
FROM table_name;
我明白了:
ERROR 1 (HY000): Can't create/write to file '/data/outfile.csv' (Errcode: 13)
Errcode 13是一个权限错误,但即使我将/ data的所有权更改为mysql:mysql并赋予它777权限,我也能得到它。 MySQL以用户" mysql"的形式运行。
奇怪的是我可以在/ tmp中创建文件,而不是在我尝试的任何其他目录中,即使权限设置使用户mysql应该能够写入目录。
这是在Ubuntu上运行的MySQL 5.0.75。
13个解决方案
185 votes
Ubuntu的特定版本是什么,这是Ubuntu服务器版?
最近的Ubuntu Server Editions(例如10.04)附带AppArmor,MySQL的配置文件默认情况下可能处于强制模式。 您可以通过执行/var/log/messages来检查这一点,如下所示:
# sudo aa-status
5 profiles are loaded.
5 profiles are in enforce mode.
/usr/lib/connman/scripts/dhclient-script
/sbin/dhclient3
/usr/sbin/tcpdump
/usr/lib/NetworkManager/nm-dhcp-client.action
/usr/sbin/mysqld
0 profiles are in complain mode.
1 processes have profiles defined.
1 processes are in enforce mode :
/usr/sbin/mysqld (1089)
0 processes are in complain mode.
如果mysqld包含在强制模式中,那么它可能会拒绝写入。 当AppArmor阻止写入/访问时,条目也将写入/var/log/messages。 你可以做的是编辑/etc/apparmor.d/usr.sbin.mysqld并在底部附近添加/data/和/data/*,如下所示:
...
/usr/sbin/mysqld {
...
/var/log/mysql/ r,
/var/log/mysql/* rw,
/var/run/mysqld/mysqld.pid w,
/var/run/mysqld/mysqld.sock w,
**/data/ r,
/data/* rw,**
}
然后让AppArmor重新加载配置文件。
# sudo /etc/init.d/apparmor reload
警告:上面的更改将允许MySQL读取和写入/ data目录。 我们希望您已经考虑过此的安全隐患。
Vin-G answered 2019-06-27T07:30:34Z
17 votes
Ubuntu使用AppArmor,这是什么阻止您访问/ data /。 Fedora使用selinux,这会在RHEL / Fedora / CentOS机器上阻止这种情况。
要修改AppArmor以允许MySQL访问/ data /,请执行以下操作:
sudo /etc/init.d/apparmor restart
在目录列表中的任何位置添加此行:
sudo /etc/init.d/apparmor restart
然后做一个:
sudo /etc/init.d/apparmor restart
另一种选择是完全禁用AppArmor for mysql,这不是推荐的:
sudo /etc/init.d/apparmor restart
不要忘记重启apparmor:
sudo /etc/init.d/apparmor restart
rook answered 2019-06-27T07:31:53Z
14 votes
我知道你说过你已经尝试过设置777的权限了,但是因为我有证据表明这是一个权限问题我发布了我正在运行的内容,希望它可以提供帮助。 这是我的经历:
tmp $ pwd
/Users/username/tmp
tmp $ mkdir bkptest
tmp $ mysqldump -u root -T bkptest bkptest
mysqldump: Got error: 1: Can't create/write to file '/Users/username/tmp/bkptest/people.txt' (Errcode: 13) when executing 'SELECT INTO OUTFILE'
tmp $ chmod a+rwx bkptest/
tmp $ mysqldump -u root -T bkptest bkptest
tmp $ ls bkptest/
people.sql people.txt
tmp $
basilikode answered 2019-06-27T07:32:19Z
6 votes
MySQL在这里变得愚蠢。 它尝试在/ tmp / data / ....下创建文件。所以你可以做的是以下内容:
mkdir /tmp/data
mount --bind /data /tmp/data
然后尝试你的查询。 经过几个小时的调试后,这对我有用。
vimdude answered 2019-06-27T07:32:54Z
4 votes
有些事要尝试:
是secure_file_priv系统变量集? 如果是,则必须将所有文件写入该目录。
确保文件不存在--MySQL只会创建新文件,而不会覆盖现有文件。
mdma answered 2019-06-27T07:33:37Z
4 votes
这个问题困扰了我很长一段时间。 我注意到这个讨论没有指出RHEL / Fecora上的解决方案。 我正在使用RHEL而且我没有在Ubuntu上找到与AppArmer相对应的配置文件,但是我通过使目录PATH中的每个目录都可以被mysql读取和访问来解决了我的问题。 例如,如果创建目录/ tmp,则以下两个命令使SELECT INTO OUTFILE能够输出.sql和.sql文件
chown mysql:mysql /tmp
chmod a+rx /tmp
如果在主目录/ home / tom中创建目录,则必须对/ home和/ home / tom执行此操作。
fanchyna answered 2019-06-27T07:34:13Z
4 votes
你可以这样做 :
mysql -u USERNAME --password=PASSWORD --database=DATABASE --execute='SELECT `FIELD`, `FIELD` FROM `TABLE` LIMIT 0, 10000 ' -X > file.xml
Navrattan Yadav answered 2019-06-27T07:34:34Z
2 votes
就我而言,解决方案是使目录路径中的每个目录都可读并可由mysql(chmod a+rx)访问。 该目录仍由命令行中的相对路径指定。
chmod a+rx /tmp
chmod a+rx /tmp/migration
etc.
Alsciende answered 2019-06-27T07:35:02Z
2 votes
我刚遇到同样的问题。 我的问题是我试图转储的目录没有mysqld进程的写权限。 最初的sql转储会写出,但写入csv / txt文件会失败。 看起来sql dump作为当前用户运行,并且转换为csv / txt作为运行mysqld的用户运行。 因此该目录需要两个用户的写权限。
Matthew McMillan answered 2019-06-27T07:35:30Z
2 votes
我有同样的问题,我通过以下步骤解决了这个问题:
操作系统:ubuntu 12.04
灯安装
假设您保存输出文件的目录是:/ var / www / csv /
在终端上执行以下命令,并使用gedit编辑器编辑该文件,将目录添加到输出文件。
sudo gedit /etc/apparmor.d/usr.sbin.mysqld
现在文件将在编辑器中打开,请在那里添加您的目录
/ var / www / csv / * rw,
同样我已经添加到我的文件中,如下图所示:
执行下一个命令以重启服务:
sudo /etc/init.d/apparmor restart
例如,我执行以下查询到phpmyadmin查询构建器以输出csv文件中的数据
SELECT colName1, colName2,colName3
INTO OUTFILE '/var/www/csv/OUTFILE.csv'
FIELDS TERMINATED BY ','
FROM tableName;
它已成功完成并将包含所选列的所有行写入OUTPUT.csv文件...
Sunny S.M answered 2019-06-27T07:37:28Z
1 votes
您需要提供绝对路径,而不是相对路径。
提供您尝试写入的/ data目录的完整路径。
Ike Walker answered 2019-06-27T07:38:03Z
1 votes
Ubuntu使用SELinux吗? 检查它是否已启用并执行。 /var/log/audit/audit.log可能是帮助(如果Ubuntu坚持它的那个 - 那是RHEL / Fedora的位置)。
Charles answered 2019-06-27T07:38:31Z
0 votes
我在CentOs 6.7上遇到了同样的问题在我的情况下,所有权限都已设置,但仍然发生错误。 问题是SE Linux处于"强制执行"模式。
我把它改为" permissive" 使用命令sudo setenforce 0
然后一切都为我而努力。
Stefan Bicher answered 2019-06-27T07:39:14Z