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-文件私法选项运行,因此它不能执行该语句”看看这里:stackoverflow.com/questions/32737478/...
偷偷摸摸的

Answers:


119

尝试执行以下SQL命令:

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

似乎您在连接数据库时遇到问题,而不是在写入您提到的文件夹时遇到问题。

另外,请确保您已授予FILEuser 'asdfsdf'@'localhost'

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

1
@Shackrock:查看更新的答案。确保您已授予FILE该用户。
巴勃罗·圣克鲁斯

48
这里有两个问题。1)GRANT ALL不执行GRANT FILE。2)GRANT FILE仅适用于*。*(即全局)。两者都是MySQL中的错误。
fijiaaron 2012年

4
仅供参考,在执行此操作之前请仔细考虑一下,您不是数据库管理员。我不高兴发现我更改了权限(“不!”!)。:-)
Ellen Spertus

1
似乎还存在写入文件系统中/ var / lib / mysql以外的位置的问题,这似乎与文档相反。即使目标文件夹由mysql:mysql拥有,并且每个人都具有rwx权限和/或使用sudo进行调用...(来自Ubuntu,来自此处)
quickthyme,2015年

2
你不需要使用FLUSH PRIVILEGESGRANT。仅当您使用SQL而不是使用SQL修改特权表时才需要GRANT
Barmar

56

老实说,我没有理会赠款,即使没有特权也可以使用:

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

5
这是因为您只是在进行常规的SELECT,而不是SELECT INTO OUTFILE(在这种情况下为.csv文件)。
2013年

5
对于较大的表,这样做是一种不好的方法,因为客户端会在将结果放入文件之前先缓冲整个结果集。
克里斯·塞琳

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剥夺了在PHPMyAdmin中以root用户身份修改用户权限的能力,因此您必须使用命令行来执行以下操作:

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

步骤2是允许该用户将文件转储到特定文件夹中。有几种方法可以做到这一点,但最终我将文件夹放入:

/home/user/tmp/db

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

这允许mysql用户写入文件。就像以前的海报所说的那样,您也可以使用MySQL temp文件夹,我不认为这真的很重要,但是除非您想让世界看到您的数据,否则您绝对不希望将其设为0777权限(可全局写入)。如果您要冲洗重复该过程,INTO OUTFILE则可能会出现问题,因为如果文件存在,将无法进行。如果您的文件是由其他用户拥有的,那么尝试unlink($file)将无法使用。如果您像我(偏执狂,大约0777),则可以使用以下命令设置目标目录:

chmod($dir,0777)

在执行SQL命令之前,然后

chmod($dir,0755)

之后立即unlink(file)删除文件。这使它们都在您的Web用户下运行,而无需调用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用户导出的,则按如下所示设置权限

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"

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.