【问题标题】:Not able to change privileges with MySQL database无法使用 MySQL 数据库更改权限
【发布时间】:2015-12-24 13:09:19
【问题描述】:

我正在寻找备份 MySQL 数据库。当在命令行中输入以下命令时,它会起作用:

SELECT * INTO OUTFILE 'backup.txt' FROM table_name;

backup.txt 文件已创建。一切都很好。

当上述命令通过 php 文件中的 MySQL 查询提交时:

mysql_query("SELECT * INTO OUTFILE 'backup.txt' FROM table_name");

它不起作用。 backup.txt 文件未创建。

接下来,查看权限并使用命令行输入以下命令:

GRANT FILE ON *.* TO 'root'@'localhost';

此命令已被接受,但 MySQL 查询仍然不起作用。

完整的php文件如下图:

// connect to db host
//mysql_connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD)
$connection = mysql_connect("localhost", "mysql -u root", "")
    or die('Could not connect: ' . mysql_error($connection));

// select db
$db = mysql_select_db("test", $connection);

// change privileges
mysql_query("GRANT FILE ON *.* TO 'root'@'localhost'"); 

// create query
$query = "SELECT * INTO OUTFILE 'backup.txt' FROM table_name";

//perform query
mysql_query($query);

// close mysql connection  
mysql_close($connection); 

谁能解释这里发生了什么以及我如何让 MySQL 查询工作并创建输出文件 backup.txt

正在使用 Windows 机器上的 WampServer。

【问题讨论】:

  • grant file on just one database 的可能重复项
  • 问题顶部的 A 和 B 中使用的凭据是什么,涉及 1221 块之前的部分
  • 你没有向我们展示mysql_query前后的代码
  • 感谢您的帮助。问题已解决。我一直在使用“mysql -u root”作为用户名。在“select * into outfile ...”之前,我的所有数据库查询都可以正常工作。通过将用户名更改为“root”,它现在可以工作了。事实有时比小说更离奇。

标签: php mysql


【解决方案1】:

在我运行 mysql 命令行 (MCL) 的那一刻,我是一个 o/s 用户,在某种程度上拥有权限(我们称他们为 creds 以获取凭据)到所有 o/s 目录。假设在此代码尝试期间信用不会改变,无法想象他们会。重点是,我就是拥有这些信誉的用户。

没有路径,如您所做的那样,完整或相对路径,MCL 将写入 outfile 调用中架构的数据目录。因此,例如在我的系统上,那将是

C:\Users\All Users\MySQL\MySQL Server 5.6\data\so_gibberish

so_gibberish 是架构/数据库名称,我将使用use so_gibberish 命令或作为数据库提供,以在使用 开关 运行 mysql 命令行时使用。或者它将是一些等效的linux路径。

通过 MCL,我会进入一个数据库 (use),而不是一个没有 use 的 MCL 连接。这意味着我很可能在进入 db 沙盒之前不会发出 outfile 命令(我稍后会提出这一点,因为它与错误 1046 相关)。你的命令会在我的系统上转储 .txt 文件(上面的路径向上)。在我的测试中确实如此。

现在介绍 PHP。

如果您正在运行一个连接但不使用mysql_select_db 函数的PHP 脚本,那么

错误 1046:未选择数据库

只有在您运行如下代码检查错误时才会返回:

<?php
    //error_reporting(E_ALL); 
    //ini_set('display_errors', 1);
    ...
    ... (load credential variables used below)
    ...
    $link = mysql_connect($dbhost, $dbuser, $dbpass) or die("Unable to Connect to '$dbhost'");
    //mysql_select_db($dbname) or die("Could not open the db '$dbname'");
    echo "I made it here<br/>";
    $test_query = "SELECT * INTO OUTFILE 'file456.txt' FROM mytable";
    $result = mysql_query($test_query);
    echo mysql_errno($link) . ": " . mysql_error($link) . "<br>";
    mysql_close($link);

并不是说人们倾向于检查错误。我敢打赌你不在这个电话里。他们只是认为一切都很好。

请注意,尽管 error_reporting 对此没有影响。影响它的是您是否在mysql_query 之后检查错误。你可以像我一样rem out或clear rems并测试这个理论。因此,您可能会收到 1046 错误但不知道。

现在有什么 o/s 用户的情况,因此 php 到 mysql 进程伪装成的信誉。这是由原始设置驱动的。为什么这很重要?因为该用户/那些凭据很可能与您在 o/s 提示符下使用 MCL 执行此操作的第一部分时使用的凭据完全不同。

文件可能是通过 php 创建的,但由于您没有使用文件的完整路径进行路径,只是文件名,如果您要检查,它可能位于您系统上的某个地方而您不知道它对于错误并且没有到达。为了验证这个理论,在没有完整路径的mysql_user之后包含上面的错误检查,并进行目录扫描以找到它。

所以在我的测试中,我在 MCL 中写出 file123.txt,在 php 中我写出 file456.txt(或其他)。除非出现任何错误消息,否则我会扫描文件系统以查看它们出现的位置。

你不会是第一个认为 OUTFILE 失败的人,只是稍后,也许几个月后,在某个目录中找到残留文件并有一个灵光乍现的时刻:哦,是的,我记得那些文件,它们在这里做什么?

调用失败的原因可能是 PHP 的凭据问题,与用户或组世界或其他设置 chmod 问题有关。


通过 PHP,如果伪装的 o/s 用户具有凭据,则完全路径到 /full/path/here/out123.txt 等 outfile 可以有一个很好的解决方案。但是,在托管环境中,您不能简单地说 make it /tmp/out123.txt,因为那里的权限会失败。因此,没有广泛的笔触“插入此答案”可以解决它,而无需您进行一些体面的修补会话。

所以对于 PHP 的总结,我将研究以下内容:

  • 文件正在被写出,你只是不知道在哪里。
  • 文件失败,但你不知道,因为之后没有错误检查 mysql_query(比如一般的mysql错误,没有选择db, 任何)。
  • 由于 o/s 用户从 PHP 伪装成的 Creds 问题 mysql 并且是所需的 o/s 文件系统级别的凭据 文件 i/o。

至于错误 1221 错误,如 cmets 中所述并链接到它的那部分,您不能在单个数据库上 GRANT FILE。提供了该答案类型here

【讨论】:

  • 感谢您的全面回复德鲁。我需要一些时间来完成这一切并尝试各种事情,所以我会在完成后通知您。
  • 尝试了完整路径无济于事。添加错误检查代码并收到以下消息:未备份 1045:用户 'mysql -u root'@'localhost' 的访问被拒绝(使用密码:NO)。这听起来像是一个特权问题,但 GRANT FILE ON ... 没有帮助。
  • 这可以解释为什么stackoverflow.com/questions/6091427/…
  • 我只指 quickythyme 的评论
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 2017-02-01
  • 2013-06-19
  • 2010-12-10
  • 1970-01-01
相关资源
最近更新 更多