Як я можу обійти MySQL Errcode 13 з SELECT INTO OUTFILE?


114

Я намагаюся скинути вміст таблиці у файл 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.


3
Бачачи, що 13 є системною помилкою, це, мабуть, не це, але є параметр mySQL, що обмежує INTO OUTFILE каталогом: dev.mysql.com/doc/refman/5.0/en/…, можливо, варто швидко ознайомитись, чи це встановити /tmp.
Пекка

Ця змінна в моїй установці порожня, що відповідно до цього документа означає, що мої вихідні каталоги не повинні обмежуватися.
Райан Олсон

Відповіді:


189

Яка конкретна версія 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 блокує запис / доступ. Що ви можете зробити - це відредагувати, /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
Я ненавиджу це вказувати, але є причина, що App Armor не дозволяє цього. Тепер MySQL має можливість змінювати та читати що-небудь у папці / data. Тільки зараз не зламайте.
Райан Уорд

2
@Serdar, Набір правил AppArmor MySQL, розповсюджений у дистрибутиві, не дозволяє це за замовчуванням . Це має сенс, оскільки це є гарною базовою лінією правил для нової установки. Я вважаю, що ми повинні бути та ми маємо право змінювати набори правил, щоб відповідати нашим потребам після встановлення. Це був оригінальний намір запитувача дозволити MySQL писати в конкретні каталоги. Але якщо це не є явним вище, зверніть увагу на те, що людям, що спотикаються над цим рішенням: ПОПЕРЕДЖЕННЯ: зміна вище дозволить MySQL читати та записувати в каталог / data. Ми сподіваємось, що ви вже врахували наслідки для цього.
Він-Г

1
ВЕЛИКИЙ ВІДПОВІДЬ !!! Це вирішило мою проблему, я також намагався писати в будь-який інший каталог. Тепер я мушу дослідити, про що це все було! :) Дізнавшись про це, я рекомендую іншим читати про apparmor (а значить, команду aa-status): en.wikipedia.org/wiki/AppArmor
David L

1
У моєму випадку це допомогло: /your/abs/folder/ r, /your/abs/folder/** rwk, }не забудьте включити кому в кінці!
ACV

1
працює для запису в / tmp. Використовуйте вікна замість цього. Linux смокче
Віктор Іонеску

17

Ubuntu використовує AppArmor, і саме це заважає вам отримувати доступ / дані /. Fedora використовує selinux, і це запобігає цьому на машині RHEL / Fedora / CentOS.

Щоб змінити AppArmor, щоб дозволити MySQL отримати доступ / дані /, виконайте наступне:

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


Щоб фактично відключити apparmor для mysql, мені потрібно було зробити: cyberciti.biz/faq/ubuntu-linux-howto-disable-apparmor-commands
silver_mx

14

Я знаю, ви сказали, що ви вже намагалися встановити дозволи 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 $ 

я @ сервер: / дані $ pwd / дані мені @ сервер: / дані $ ls -усього 60 ... drwxrwxrwx 2 mysql mysql 4096 2010-05-06 16:27 dumptest мені @ сервер: / дані $ mysqldump -u dbuser -p -T dumptest -B db_name --tables test Введіть пароль: mysqldump: Помилка: 1: Неможливо створити / записати у файл '/data/dumptest/test.txt' (Помилка: 13) під час виконання 'SELECT INTO OUTFILE 'me @ server: / data $ sudo chmod a + rwx dumptest / me @ server: / data $ mysqldump -u dbuser -p -T dumptest -B db_name --tables test Введіть пароль: mysqldump: Отримана помилка: 1: ( та сама помилка)
Райан Олсон

Ой, ну, не усвідомлював, що коментарі не форматуються, але двічі перевірили декілька способів. Спочатку з цільовим каталогом, який належить mysql: mysql, потім з цільовим каталогом, що належить користувачеві, я запустив команду dump, оскільки обидва способи все ще дають мені однакові помилки дозволів.
Райан Олсон

Для запису, це працювало для мене, незважаючи на те, що змінив дозволи на прихильність
Алекс

Я спробував внести модифікацію в apparmor, вона не спрацювала. Зміна дозволу 'chmod 777' працювала для мене!
Sudarshan_SMD

7

MySQL тут стає дурним. Він намагається створити файли під / tmp / data / .... Отже, що ви можете зробити, це наступне:

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

Потім спробуйте свій запит. Це спрацювало для мене через години налагодження проблеми.


Мені найбільше подобається ця відповідь. Це легко, це працює, і це не вимагає, щоб ви хотіли з apparmor. Інший спосіб зробити це за допомогою труб не працює добре для великого експорту через все буферизацію, що робиться.
Кріс Селін

6

Ця проблема мене давно хвилює. Я помітив, що ця дискусія не вказує на рішення щодо 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.


3
Використовувати / tmp як приклад - це не дуже гарна ідея, і ви дійсно не хочете змінювати право власності на каталог / tmp (у більшості випадків).
sastorsl

Зміна права власності на / tmp - це погано, але створення темп-папки всередині / tmp і chown mysql:mysqlвирішило мою проблему
Samuel Prevost


4

Деякі речі, які слід спробувати:

  • чи встановлена secure_file_privзмінна система? Якщо це так, всі файли повинні бути записані в цей каталог.
  • переконайтесь, що файл не існує - MySQL створить лише нові файли, а не замінить існуючі.

1
Я б також пішов на secure_file_priv. Якщо файл вже існує, повідомлення про помилку інше (не помилка 13).
Xavier Maillard

В даний час secure_file_priv не встановлено, тому, наскільки я розумію, це означає, що я не повинен обмежуватися тим, де я можу писати файли. Чи я не розумію цього і чи потрібно явно встановити це на щось на зразок "/", якщо я хочу мати можливість записувати в будь-якому місці файлової системи?
Райан Олсон

Також я перевіряю, що файл не існує перед запуском запиту.
Райан Олсон

Дякуємо за відгук. Виходячи з ваших висновків, я не думаю, що жодна з цих пропозицій не викликає ваших проблем.
mdma

3

У мене така ж проблема, і я вирішив цю проблему, виконавши наступні кроки:

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

Виконайте наступну команду на терміналі та відредагуйте цей файл за допомогою редактора gedit, щоб додати каталог у вихідний файл.

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

  • тепер файл буде відкрито в редакторі, будь ласка, додайте туди свій каталог

    / var / www / csv / * rw,

  • так само я додав у свій файл, як показано наступне зображення:

введіть тут опис зображення

Виконайте наступну команду для перезавантаження служб:

sudo /etc/init.d/apparmor перезапуск

Наприклад, я виконую наступний запит у phpmyadmin builder query для виведення даних у файл CSV

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

Це успішно зроблено і записати всі рядки з вибраними стовпцями у файл OUTPUT.csv ...


2

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

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

2

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


1

Вам потрібно надати абсолютний шлях, а не відносний шлях.

Надайте повний шлях до каталогу / data, до якого ви намагаєтесь записати.


Це схоже на абсолютний шлях для мене. Чи не так?
Печка

2
Спробуйте це як користувач mysql, щоб переконатися, що ви можете створити файл поза mysql:touch /data/outfile.csv
Ike Walker

1
По-перше, я не міг цього зробити, оскільки оболонку користувача mysql було встановлено на / bin / false, тому я не зміг увійти як mysql. Щоб переконатися, що це не сприяло проблемі, я встановив оболонку mysql в / bin / bash, su'd цьому користувачеві і торкнувся файлу в / data. Файл був створений успішно, належить mysql.
Райан Олсон

3
Ви можете подати заявку на обліковий запис, навіть якщо він використовує одну з оболонок "відключити": su --shell=/bin/sh nameofaccount
Марк Б

Спасибі, я цього не знав.
Райан Олсон

1

Чи використовує Ubuntu SELinux? Перевірте, чи він увімкнено та діє. /var/log/audit/audit.log може бути helpul (якщо саме Ubuntu впише це - це місце RHEL / Fedora).


0

У мене була така ж проблема з CentOs 6.7 У моєму випадку всі дозволи були встановлені, і все-таки сталася помилка. Проблема полягала в тому, що SE Linux знаходився в режимі "примусового виконання".

Я переключив його на "вседозволене" за допомогою команди sudo setenforce 0

Тоді для мене все склалося.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.