Как я могу обойти MySQL Errcode 13 С SELECT в OUTFILE?

Я пытаюсь сбросить содержимое таблицы в 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 ответов


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

последние версии сервера Ubuntu (например, 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 блокирует записи / доступ. Что ты можешь сделать, так это edit /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. Мы надеемся, что вы уже рассмотрели последствия этого для безопасности.


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


Я знаю, вы сказали, что уже пытались установить разрешения на 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/.... Так что вы можете сделать следующее:

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

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


некоторые вещи, чтобы попробовать:

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

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

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

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


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

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

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

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

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


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

  • операционная система: ubuntu 12.04
  • лампа установлена
  • предположим, что ваш каталог для сохранения выходного файла: /var/www/csv/

выполните следующую команду на терминале и отредактируйте этот файл с помощью редактора gedit, чтобы добавить свой каталог в выходной файл.

судо команду gedit /и т. д./В AppArmor.д/УСР.сбин.mysqld

  • теперь файл будет открыт в Редакторе пожалуйста, добавьте свой каталог есть

    /var / www / csv/* rw,

  • аналогично, я добавил в свой файл, как следующее заданное изображение:

enter image description here

выполнить следующую команду для перезапуска служб :

sudo/etc / init.Д/в AppArmor перезапустить

для пример я выполняю следующий запрос в phpmyadmin query builder для вывода данных в csv-файле

SELECT colName1, colName2,colName3
INTO OUTFILE '/var/www/csv/OUTFILE.csv'
FIELDS TERMINATED BY ','
FROM tableName;

это успешно сделано и записать все строки с выбранными столбцами в выходные данные.CSV-файл...


вы должны предоставить абсолютный путь, а не относительный путь.

укажите полный путь к каталогу /data, в который вы пытаетесь написать.


использует ли Ubuntu SELinux? Проверьте, включен ли он и применяется ли. /var / log / аудит / аудит.журнал может быть helpul (если это то, где Ubuntu вставляет его-это местоположение RHEL/Fedora).


У меня была такая же проблема на CentOS 6.7 В моем случае все разрешения были установлены и все равно ошибка. Проблема заключалась в том, что SE Linux находился в режиме "принудительного исполнения".

я переключил его на "разрешительный", используя команду sudo setenforce 0

потом у меня все получилось.