我怎样才能绕过MySQL的Errcode 13与SELECT INTO OUTFILE?
我正在尝试使用MySQL SELECT INTO OUTFILE语句将表的内容转储到csv文件。 如果我做:
SELECT column1, column2 INTO OUTFILE 'outfile.csv' FIELDS TERMINATED BY ',' FROM table_name;
outfile.csv将在服务器上的这个数据库的文件存储在同一个目录下被创build。
但是,当我将我的查询更改为:
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中创build文件,而不是在我试过的任何其他目录下,即使设置了权限,以使用户mysql应该能够写入目录。
这是在Ubuntu上运行的MySQL 5.0.75。
Ubuntu的哪个特定版本是这个,并且是这个Ubuntu服务器版本?
最近的Ubuntu服务器版本(如10.04)与AppArmor一起提供,MySQL的configuration文件默认情况下可能处于强制模式。 你可以通过像这样执行sudo aa-status
来检查:
# 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重新加载configuration文件。
# sudo /etc/init.d/apparmor reload
警告:上面的更改将允许MySQL读取和写入/ data目录。 我们希望你已经考虑过这个安全问题。
Ubuntu使用AppArmor,这是什么阻止你访问/ data /。 Fedora使用selinux,这将阻止在RHEL / Fedora / CentOS机器上。
修改AppArmor以允许MySQL访问/ data /执行以下操作:
sudo gedit /etc/apparmor.d/usr.sbin.mysqld
在目录列表中的任何位置添加此行:
/data/ rw,
然后做一个:
sudo /etc/init.d/apparmor restart
另一个选项是完全禁用MySQL的AppArmor,这是不build议的 :
sudo mv /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
不要忘记重新启动apparmor:
sudo /etc/init.d/apparmor restart
我知道你说过,你已经设置了权限设置为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 $
MySQL在这里变得很愚蠢。 它试图在/ tmp / data /下创build文件。所以你可以做的是以下几点:
mkdir /tmp/data mount --bind /data /tmp/data
然后尝试您的查询。 经过几个小时的debugging问题后,这工作对我来说。
你可以这样做 :
mysql -u USERNAME --password=PASSWORD --database=DATABASE --execute='SELECT `FIELD`, `FIELD` FROM `TABLE` LIMIT 0, 10000 ' -X > file.xml
有些事情要尝试:
- 是
secure_file_priv
系统variables集? 如果是,则必须将所有文件写入该目录。 - 确保文件不存在 – MySQL将只创build新文件,不会覆盖现有的文件。
这个问题一直困扰着我很久。 我注意到这个讨论并没有指出RHEL / Fecora上的解决scheme。 我正在使用RHEL,而且在Ubuntu上找不到与AppArmer相对应的configuration文件,但是通过使目录PATH中的EVERY目录可读并且可以通过mysql访问,我解决了我的问题。 例如,如果您创build一个目录/ tmp,则以下两个命令使SELECT INTO OUTFILE能够输出.sql和.sql文件
chown mysql:mysql /tmp chmod a+rx /tmp
如果您在主目录/ home / tom中创build目录,则必须对/ home和/ home / tom执行此操作。
在我的情况下,解决scheme是使目录path中的每个目录都可读并且可以通过mysql
访问( chmod a+rx
)。 该目录仍由命令行中的相对path指定。
chmod a+rx /tmp chmod a+rx /tmp/migration etc.
我遇到了同样的问题。 我的问题是我试图转储到的目录没有mysqld进程的写权限。 最初的sql转储会写出来,但写入csv / txt文件将失败。 看起来,sql dump作为当前用户运行,并且转换为csv / txt作为运行mysqld的用户运行。 所以这个目录需要两个用户的写权限。
我有同样的问题,我通过以下步骤解决了这个问题:
- 操作系统:Ubuntu 12.04
- 灯安装
- 假设你的目录保存输出文件是:/ var / www / csv /
在terminal上执行以下命令并使用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文件…
您需要提供绝对path,而不是相对path。
提供您要写入的/ data目录的完整path。
Ubuntu使用SELinux吗? 检查是否已启用并执行。 /var/log/audit/audit.log可能是有帮助的(如果这是Ubuntu的支持,那就是RHEL / Fedora的位置)。
我在CentOs 6.7上遇到了同样的问题。在我的情况下,所有的权限都被设置了,但仍然出现了错误。 问题是SE Linux处于“执行”模式。
我使用命令sudo setenforce 0
将其切换为“宽容”
然后,一切都为我工作。