MYSQL у файлі “доступ заборонено” - але мій користувач має “ВСІ” доступ .. і папка CHMOD 777


76

Будь-які ідеї?

SELECT * INTO OUTFILE '/home/myacnt/docs/mysqlCSVtest.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '*'
LINES TERMINATED BY '\n'
FROM tbl_property 
WHERE managerGroupID = {$managerGroupID}

Помилка:

Access denied for user 'asdfsdf'@'localhost' (using password: YES)

3
"ВСІ ПРИВІЛЕГІЇ" не включає всі привілеї. Що стосується цієї справи, він не включає FILEпривілеї, необхідні для SELECT INTO OUTFILEвиписок. У мене було кілька проблем з цією невідповідністю англійської мови та MySQL: dba.stackexchange.com/a/96894/53784
WAF

Якщо потім ви зіткнетеся з "Сервер MySQL працює з опцією --secure-file-priv, тому він не може виконати цей оператор", подивіться тут: stackoverflow.com/questions/32737478/…
підлий

Відповіді:


119

Спробуйте виконати цю команду SQL:

> grant all privileges 
  on YOUR_DATABASE.* 
  to 'asdfsdf'@'localhost' 
  identified by 'your_password';
> flush privileges; 

Здається, у вас виникають проблеми з підключенням до бази даних, а не записом у папку, яку ви згадуєте.

Також переконайтеся, що надали FILEкористувачеві 'asdfsdf'@'localhost'.

> GRANT FILE ON *.* TO 'asdfsdf'@'localhost';

1
@Shackrock: перевірте оновлену відповідь. Переконайтеся, що надали FILEкористувачеві.
Пабло Санта Круз,

49
Тут є два питання. 1) GRANT ALL не робить GRANT FILE. 2) GRANT FILE працює лише з *. * (Тобто глобально). Обидва вони є помилками в MySQL.
fijiaaron

4
FYI, добре подумайте, перш ніж робити це, ви не адміністратор баз даних. Моїй не було приємно виявити, що я змінив привілеї ("Ніоооооо!"). :-)
Еллен Спертус

1
Схоже, у нього також виникають проблеми із записом у місця розташування у файловій системі, крім / var / lib / mysql, що, здається, суперечить документації. Навіть коли цільова папка належить mysql: mysql і всі мають дозволи rwx та / або викликаються за допомогою sudo ... (надходить з Ubuntu тут)
quickthyme

2
Вам не потрібно використовувати FLUSH PRIVILEGESпісля GRANT. Це потрібно лише в тому випадку, якщо ви замінюєте таблицю привілеїв на SQL замість використання GRANT.
Бармар,

57

Чесно кажучи, я не намагався розібратися з грантами, і це працювало навіть без привілеїв:

echo "select * from employee" | mysql --host=HOST --port=PORT --user=UserName --password=Password DATABASE.SCHEMA > output.txt

5
Це тому, що ви просто виконуєте звичайний SELECT, а не SELECT INTO OUTFILE (у цьому випадку файл .csv).
aqn

5
Це поганий спосіб зробити це для більших таблиць, тому що клієнт буферизує весь набір результатів, перш ніж щось видавати у файл.
Chris Seline

6
MySQL розділить файл за допомогою вкладки за допомогою цього методу, що є ідеальним. Спробувавши десяток дозволів на файли, налаштування MySQL та різні гранти, які охоплювали 5 або 6 різних сторінок довідки, це спрацювало. Збережіть собі головний біль і використовуйте це.
Пол Кенджора,

Не забудьте перейти до відповідної кодової сторінки перед використанням цього методу, наприклад, "chcp 1252" або "chcp 65001", якщо в експортованих даних є спеціальні символи.
trapper_hag

Інша проблема з цим - уникнення NULL. Використання INFILE з результату цієї команди призведе до імпорту рядкового літералу "NULL", а не до фактичного NULL, який уникається за допомогою \ N.
bluefear

22

Як каже @fijaaron,

  1. GRANT ALL не означає GRANT FILE
  2. GRANT FILE працює лише з *.*

То роби

GRANT FILE ON *.* TO user;

4

Оскільки cP / WHM забрав можливість змінювати привілеї користувача як root у PHPMyAdmin, вам потрібно використовувати командний рядок для:

mysql>  GRANT FILE ON *.* TO 'user'@'localhost';

Крок 2 - дозволити цьому користувачеві скидати файл у певну папку. Є кілька способів зробити це, але в підсумку я вклав папку:

/home/user/tmp/db

і

chown mysql:mysql /home/user/tmp/db

Це дозволяє користувачеві mysql писати файл. Як сказано в попередніх плакатах, ви також можете використовувати тимчасову папку MySQL, я не думаю, що це насправді важливо, але ви точно не хочете робити це дозволом 0777 (можна записати у світ), якщо ви не хочете, щоб світ бачив ваші дані. Існує потенційна проблема, якщо ви хочете змити, повторіть процес, оскільки INTO OUTFILEвін не буде працювати, якщо файл існує. Якщо ваші файли належать іншому користувачеві, тоді спроба unlink($file)не працюватиме. Якщо ви схожі на мене (параноїк близько 0777), ви можете встановити цільовий каталог за допомогою:

chmod($dir,0777)

безпосередньо перед виконанням команди SQL, тоді

chmod($dir,0755)

відразу після, а потім unlink(file)- видалення файлу. Це продовжує працювати під вашим веб-користувачем і не потрібно викликати користувача mysql.


2

Я спробував усі рішення, але все ще недостатньо. Після ще кількох копань я врешті-решт виявив, що мені також довелося встановити прапор 'file_priv' і перезапустити mysql.

Відновити :

Надайте привілеї:

> GRANT ALL PRIVILEGES
  ON my_database.* 
  to 'my_user'@'localhost';

> GRANT FILE ON *.* TO my_user;

> FLUSH PRIVILEGES; 

Встановіть прапор:

> UPDATE mysql.user SET File_priv = 'Y' WHERE user='my_user' AND host='localhost';

Нарешті перезапустіть сервер mysql:

$ sudo service mysql restart

Після цього я міг писати в secure_file_privкаталог. Для мене це було / var / lib / mysql-files /, але ви можете перевірити це за допомогою наступної команди:

> SHOW VARIABLES LIKE "secure_file_priv";

1

Для майбутніх читачів один простий спосіб полягає в наступному, якщо вони хочуть експортувати оптом за допомогою bash,

akshay@ideapad:/tmp$ mysql -u someuser -p test -e "select * from offices"
Enter password: 
+------------+---------------+------------------+--------------------------+--------------+------------+-----------+------------+-----------+
| officeCode | city          | phone            | addressLine1             | addressLine2 | state      | country   | postalCode | territory |
+------------+---------------+------------------+--------------------------+--------------+------------+-----------+------------+-----------+
| 1          | San Francisco | +1 650 219 4782  | 100 Market Street        | Suite 300    | CA         | USA       | 94080      | NA        |
| 2          | Boston        | +1 215 837 0825  | 1550 Court Place         | Suite 102    | MA         | USA       | 02107      | NA        |
| 3          | NYC           | +1 212 555 3000  | 523 East 53rd Street     | apt. 5A      | NY         | USA       | 10022      | NA        |
| 4          | Paris         | +33 14 723 4404  | 43 Rue Jouffroy D'abbans | NULL         | NULL       | France    | 75017      | EMEA      |
| 5          | Tokyo         | +81 33 224 5000  | 4-1 Kioicho              | NULL         | Chiyoda-Ku | Japan     | 102-8578   | Japan     |
| 6          | Sydney        | +61 2 9264 2451  | 5-11 Wentworth Avenue    | Floor #2     | NULL       | Australia | NSW 2010   | APAC      |
| 7          | London        | +44 20 7877 2041 | 25 Old Broad Street      | Level 7      | NULL       | UK        | EC2N 1HN   | EMEA      |
+------------+---------------+------------------+--------------------------+--------------+------------+-----------+------------+-----------+

Якщо ви експортуєте не адміністратором, то встановіть дозвіл, як показано нижче

root@ideapad:/tmp# mysql -u root -p
MariaDB[(none)]> UPDATE mysql.user SET File_priv = 'Y' WHERE user='someuser' AND host='localhost';

Перезапустіть або перезавантажте mysqld

akshay@ideapad:/tmp$ sudo su
root@ideapad:/tmp#  systemctl restart mariadb

Зразок фрагмента коду

akshay@ideapad:/tmp$ cat test.sh 
#!/usr/bin/env bash

user="someuser"
password="password"
database="test"

mysql -u"$user" -p"$password" "$database" <<EOF
SELECT * 
INTO OUTFILE '/tmp/csvs/offices.csv' 
FIELDS TERMINATED BY '|' 
ENCLOSED BY '"' 
LINES TERMINATED BY '\n'
FROM offices;
EOF

Виконати

akshay@ideapad:/tmp$ mkdir -p /tmp/csvs
akshay@ideapad:/tmp$ chmod +x test.sh
akshay@ideapad:/tmp$ ./test.sh 
akshay@ideapad:/tmp$ cat /tmp/csvs/offices.csv 
"1"|"San Francisco"|"+1 650 219 4782"|"100 Market Street"|"Suite 300"|"CA"|"USA"|"94080"|"NA"
"2"|"Boston"|"+1 215 837 0825"|"1550 Court Place"|"Suite 102"|"MA"|"USA"|"02107"|"NA"
"3"|"NYC"|"+1 212 555 3000"|"523 East 53rd Street"|"apt. 5A"|"NY"|"USA"|"10022"|"NA"
"4"|"Paris"|"+33 14 723 4404"|"43 Rue Jouffroy D'abbans"|\N|\N|"France"|"75017"|"EMEA"
"5"|"Tokyo"|"+81 33 224 5000"|"4-1 Kioicho"|\N|"Chiyoda-Ku"|"Japan"|"102-8578"|"Japan"
"6"|"Sydney"|"+61 2 9264 2451"|"5-11 Wentworth Avenue"|"Floor #2"|\N|"Australia"|"NSW 2010"|"APAC"
"7"|"London"|"+44 20 7877 2041"|"25 Old Broad Street"|"Level 7"|\N|"UK"|"EC2N 1HN"|"EMEA"

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