首页 文章

如何使用SELECT INTO OUTFILE绕过MySQL Errcode 13?

提问于
浏览
112

我试图使用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 回答

  • 6

    Ubuntu的特定版本是什么,这是Ubuntu服务器版?

    最近的Ubuntu Server Editions(例如10.04)附带AppArmor,MySQL的配置文件默认情况下可能处于强制模式 . 您可以通过执行 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重新加载配置文件 .

    # sudo /etc/init.d/apparmor reload
    

    警告:上面的更改将允许MySQL读取和写入/ data目录 . 我们希望您已经考虑过此的安全隐患 .

  • 2

    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

    另一种选择是完全禁用AppArmor for mysql,这是 NOT RECOMMENDED

    sudo mv /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/

    别忘了重启apparmor:

    sudo /etc/init.d/apparmor restart

  • 0

    我知道你说过你已经尝试过设置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 $
    
  • 4

    MySQL在这里变得愚蠢 . 它尝试在/ tmp / data / ....下创建文件 . 所以你可以做的是以下内容:

    mkdir /tmp/data
    mount --bind /data /tmp/data
    

    然后尝试你的查询 . 经过几个小时的调试后,这对我有用 .

  • 184

    有些事要尝试:

    • secure_file_priv 系统变量集?如果是,则必须将所有文件写入该目录 .

    • 确保文件不存在--MySQL只会创建新文件,而不会覆盖现有文件 .

  • 1

    这个问题困扰了我很长一段时间 . 我注意到这个讨论没有指出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执行此操作 .

  • 17

    你可以这样做 :

    mysql -u USERNAME --password=PASSWORD --database=DATABASE --execute='SELECT `FIELD`, `FIELD` FROM `TABLE` LIMIT 0, 10000 ' -X > file.xml
    
  • 2

    就我而言,解决方案是使目录路径中的每个目录都可以被 mysqlchmod a+rx )读取和访问 . 该目录仍由命令行中的相对路径指定 .

    chmod a+rx /tmp
    chmod a+rx /tmp/migration
    etc.
    
  • 13

    我刚遇到同样的问题 . 我的问题是我试图转储的目录没有mysqld进程的写权限 . 初始sql转储将写出,但csv / txt文件的写入将失败 . 看起来sql dump作为当前用户运行,并且转换为csv / txt作为运行mysqld的用户运行 . 因此该目录需要两个用户的写权限 .

  • 1

    我有同样的问题,我通过以下步骤解决了这个问题:

    • 操作系统:ubuntu 12.04
      安装了

    • 假设您保存输出文件的目录是:/ var / www / csv /

    在终端上执行以下命令,并使用gedit编辑器编辑此文件,将目录添加到输出文件 .

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

    • 现在文件将在编辑器中打开,请在那里添加您的目录

    / var / www / csv / * rw,

    • 同样我已经添加到我的文件中,如下图所示:

    enter image description here

    执行下一个命令以重启服务:

    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文件...

  • 4

    您需要提供绝对路径,而不是相对路径 .

    提供您尝试写入的/ data目录的完整路径 .

  • 2

    Ubuntu使用SELinux吗?检查它是否已启用并强制执行 . /var/log/audit/audit.log可能是helpul(如果那是Ubuntu坚持的地方 - 那就是RHEL / Fedora的位置) .

  • 4

    我在CentOs 6.7上遇到了同样的问题在我的情况下,所有权限都已设置,但仍然出现错误 . 问题是SE Linux处于“强制执行”模式 .

    我使用命令 sudo setenforce 0 将其切换为"permissive"

    然后一切都为我而努力 .

相关问题