Какие права доступа к файлам и каталогам требуются для MySQL LOAD DATA INFILE?

У меня есть сценарий, который пытается загрузить некоторые данные в MySQL с помощью LOAD DATA INFILE. По какой-то причине он работает, если файл находится в каталоге /tmp, но не работает, если файл находится в другом каталоге с такими же разрешениями. Я не могу найти способ заставить MySQL импортировать данные из-за пределов каталога /tmp или каталога базы данных, но я не могу найти в руководстве ничего, объясняющего, почему это так.

Ситуация:

$ ls -l /
...
drwxrwxrwt  21 root root  4096 2010-10-19 20:02 tmp
drwxrwxrwt   2 root root  4096 2010-10-19 20:14 tmp2

$ ls -l /tmp/data.csv 
-rwxr-xr-x 1 timm timm 415431 2010-10-19 20:02 /tmp/data.csv

$ ls -l /tmp2/data.csv 
-rwxr-xr-x 1 timm timm 415431 2010-10-19 20:14 /tmp2/data.csv

AFAICT они идентичны в важных отношениях. Однако, если в командной строке MySQL я делаю:

> LOAD DATA INFILE '/tmp2/data.csv' IGNORE INTO TABLE ports
      FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY ' ';
ERROR 29 (HY000): File '/tmp2/data.csv' not found (Errcode: 13)

> LOAD DATA INFILE '/tmp/data.csv' IGNORE INTO TABLE ports 
      FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY ' ';
Query OK, 1 row affected, 1 warning (0.04 sec)
Records: 1  Deleted: 0  Skipped: 0  Warnings: 0

Из сообщений на форуме я понял, что ошибка 13 указывает на проблему с разрешением. Кажется, что /tmp лечится MySQL специально, но почему? Самое близкое, что я могу найти, - это строчка в руководстве, в которой говорится:

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

/tmp нет в каталоге базы данных, но, возможно, он будет обработан так, как будто он есть. Итак, как мне настроить все, чтобы он мог читать файлы за пределами /tmp?


person Tim Martin    schedule 19.10.2010    source источник
comment
Что произойдет, если вы export TMPDIR=/tmp2 перед запуском mysql?   -  person Frédéric Hamidi    schedule 19.10.2010
comment
Я не знаю, как заставить MySQL использовать переменные из моей среды, но если я изменю значение tmpdir в my.cnf, это не повлияет на поведение (tmp2 по-прежнему не работает, хотя теперь это временный каталог)   -  person Tim Martin    schedule 20.10.2010
comment
Временный каталог спас мне день с помощью LOAD DATA INFILE   -  person Joaquín L. Robles    schedule 26.08.2014


Ответы (4)


Код ошибки 13 означает отсутствие разрешений (в отличие от кода ошибки 2, который означает, что файл не существует). MySQL требует, чтобы файл был доступен для чтения всем. Разрешения ваших файлов в порядке.

Однажды у нас была такая же проблема на сервере CentOS, и она была вызвана AppArmor, который запрещал приложению MySQL доступ к файлам, не указанным в белом списке в /etc/apparmor.d/usr. Sbin. Mysqld. Может быть, у вас есть какой-то защитный костюм, который вызывает подобное поведение?

Как уже упоминалось другими, использование LOAD DATA INFILE LOCAL может быть обходным решением.

person Jan    schedule 01.02.2013

Я столкнулся с аналогичной проблемой (невозможно прочитать файл в /tmp) и добавил LOCAL после того, как LOAD DATA INFILE устранил проблему.

В этом отчете об ошибке Launchpad могут быть некоторые пояснения: почему это происходит.

person David Locke    schedule 06.01.2011

Ошибка 13 может быть связана с SELinux, если вы используете дистрибутив сервера Linux (например, RedHat Enterprise Linux или CentOS). Проверьте 'audit.log', чтобы узнать, не жалуется ли SELinux на ваш /tmp2 путь. Затем вы можете добавить свой путь через semanage fcontext -a -t mysqld_db_t "/tmp2(/.*)?" и запустить restorecon -R /tmp2.

Однако решение могло бы быть намного проще, и я бы ответил прямо на ваш вопрос (вместо того, чтобы дать ответ), если бы я только знал, как ..

person Joachim    schedule 19.10.2010
comment
Как бы то ни было, я использую настольную версию Ubuntu 10.04 с MySQL, установленным из пакетов Ubuntu. - person Tim Martin; 20.10.2010
comment
Итак, проблема не в SELinux. Вы пробовали «ЗАГРУЗИТЬ ДАННЫЕ ЛОКАЛЬНЫЙ ИНФАЙЛ ...»? Дает ли это такой же результат? - person Joachim; 20.10.2010

person    schedule
comment
+1 без локального разрешается в контексте серверного процесса, поэтому вы можете загружать данные с клиента и с сервера. - person Unreason; 01.12.2010