Как обойти MySQL Errcode 13 с помощью SELECT INTO OUTFILE? - PullRequest
113 голосов
/ 06 мая 2010

Я пытаюсь вывести содержимое таблицы в файл csv с помощью инструкции MySQL SELECT INTO OUTFILE. Если я сделаю:

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 писать в каталог.

Это MySQL 5.0.75, работающий в Ubuntu.

Ответы [ 13 ]

185 голосов
/ 07 июня 2010

Какая конкретная версия Ubuntu это и является ли это Ubuntu Server Edition?

Последние версии Ubuntu Server Edition (например, 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 включен в принудительном режиме, то он, вероятно, запрещает запись. Записи также будут записываться в /var/log/messages, когда AppArmor блокирует записи / доступы. То, что вы можете сделать, это отредактировать /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. Мы надеемся, что вы уже рассмотрели последствия этого для безопасности.

17 голосов
/ 07 июня 2010

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 для mysql, это НЕ РЕКОМЕНДУЕТСЯ :

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

Не забудьте перезапустить apparmor:

sudo /etc/init.d/apparmor restart

14 голосов
/ 07 мая 2010

Я знаю, что вы сказали, что пытались уже установить разрешения для 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 $ 
6 голосов
/ 19 июня 2012

MySQL здесь тупит. Он пытается создать файлы в / tmp / data / .... Итак, вы можете сделать следующее:

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

Тогда попробуйте свой запрос. Это сработало для меня после нескольких часов отладки проблемы.

5 голосов
/ 19 марта 2014

Вы можете сделать это:

mysql -u USERNAME --password=PASSWORD --database=DATABASE --execute='SELECT `FIELD`, `FIELD` FROM `TABLE` LIMIT 0, 10000 ' -X > file.xml
4 голосов
/ 21 февраля 2012

Эта проблема беспокоила меня долгое время. Я заметил, что это обсуждение не указывает на решение по RHEL / Fecora. Я использую RHEL, и я не нахожу файлы конфигурации, соответствующие AppArmer в Ubuntu, но я решил свою проблему, сделав КАЖДЫЙ каталог в каталоге PATH читаемым и доступным для mysql. Например, если вы создаете каталог / tmp, следующие две команды позволяют SELECT INTO OUTFILE выводить файл .sql AND .sql

chown mysql:mysql /tmp
chmod a+rx /tmp

Если вы создаете каталог в вашем домашнем каталоге / home / tom, вы должны сделать это как для / home, так и / home / tom.

4 голосов
/ 04 июня 2010

Некоторые вещи попробовать:

  • установлена ​​ли системная переменная secure_file_priv? Если это так, все файлы должны быть записаны в этот каталог.
  • убедитесь, что файл не существует - MySQL будет создавать только новые файлы, а не перезаписывать существующие.
3 голосов
/ 16 сентября 2015

У меня та же проблема, и я исправил эту проблему, выполнив следующие действия:

  • Операционная система: 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 ...

2 голосов
/ 01 февраля 2013

Я только что столкнулся с этой же проблемой. Моя проблема заключалась в том, что каталог, в который я пытался создать дамп, не имел разрешения на запись для процесса mysqld. Начальный дамп sql будет записан, но запись файла csv / txt не удастся. Похоже, дамп sql запускается как текущий пользователь, а преобразование в csv / txt выполняется как пользователь, запускающий mysqld. Таким образом, каталог должен иметь права на запись для обоих пользователей.

2 голосов
/ 10 февраля 2012

В моем случае решение состояло в том, чтобы сделать каждый каталог в пути к каталогу читаемым и доступным для mysql (chmod a+rx). Каталог по-прежнему указывается его относительным путем в командной строке.

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