【问题标题】:Alternative to LOAD_FILE() function?LOAD_FILE() 函数的替代方案?
【发布时间】:2012-06-13 09:56:14
【问题描述】:

我已经搜索并找到了这篇文章 (http://stackoverflow.com/questions/1814297/cant-load-file-data-in-the-mysql-directory) 但它对我不起作用。

我是 Ubuntu 12.04,MySQL 版本是 5.5.22-0ubuntu1

我已经以 root 身份登录 MySQL,所以授权应该没问题:

mysql> show grants;
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION        |
+---------------------------------------------------------------------+

我正在尝试将文本文件中的一些数据插入 MySQL 数据库,而 LOAD_FILE 函数似乎无法正常工作

我创建了一个测试文件,权限为 777 并复制到安装的根目录(我尝试将所有者/组更改为 root:root 和 mysql:mysql 仍然不行):

mysql> select load_file('/test.txt');
+------------------------+
| load_file('/test.txt') |
+------------------------+
| NULL                   |
+------------------------+
1 row in set (0.00 sec)

但如果我试试这个:

mysql> select load_file('/etc/hosts');

它工作正常。如果我将测试文件复制到/etc,它仍然会失败。

以前有没有人见过这种情况,或者可以指出另一种加载到数据库中的方法?

【问题讨论】:

    标签: mysql


    【解决方案1】:

    要使用load_file,必须满足以下条件(来自documentation):

    1. 文件必须位于服务器主机上
    2. 您必须指定文件的完整路径名,并且您必须拥有FILE 权限。
    3. 该文件必须可供所有人读取,并且其大小必须小于 max_allowed_packet 字节。
    4. 如果secure_file_priv 系统变量设置为非空目录名,则要加载的文件必须位于该目录中。

    如果文件包含您要执行的 SQL 语句,则更简单的方法可能是将其通过管道输入:

    mysql -u foo -p dbname < filename.sql

    【讨论】:

    • secure_file_priv 为空。我在本地运行并使用完整路径,它是可读的。测试文件的大小更小 thabn /etc/hosts 所以以上所有内容都应该没问题。它不是 SQL 语句,所以它也不起作用。基本上,它是文本文件中发送的大量数字列表,并且作为测试步骤的一部分接收类似的数据。
    • 你确定这里的路径吗? select load_file('/test.txt'); 这不是完整路径,除非文件实际上位于 /test.txt
    • 文件被复制到那里。我也尝试过各种路径,例如/home/me/test.txt,但它不起作用。
    • 唯一剩下的就是检查权限了。
    【解决方案2】:

    我不是 MySQL 专家,但我观察到 MySQL 5.5 版与 UBUNTU OS 存在问题。

    即使遵循mysql docs LOAD_FILE() 中的文档也没有工作。 有一个名为 apparmour 的服务,阻止函数 LOAD_FILE() 执行,我尝试停止该服务但它仍然存在.....

    我知道这并不能解决你的问题,但至少它会帮助你找到问题所在......

    【讨论】:

      【解决方案3】:

      考虑一下这个单线(注意,我在 Ubuntu 上):

      printf "$(cat update_xml.sql)" "$(cat my.xml | sed s/"'"/"\\\'"/g)" | mysql -h myRemoteHost -u me -p***
      

      在 update_xml.sql 中有:

      UPDATE
         myTable
      SET
         myXmlColumn = '%s'
      WHERE
         ...
      

      【讨论】:

        【解决方案4】:

        添加此内容以供将来参考。可能对 OP 没有帮助。

        如前所述,AppArmor 是罪魁祸首。您需要将 load_file 所需的路径列入提供的配置文件,该配置文件可在此处找到:/etc/apparmor.d/usr.sbin.mysqld。 apparmor.d 文档可以在here 找到。这是推荐的方式,因为 AppArmor 有其存在的理由。

        替代方案:

        • 这是不推荐的方法。禁用 usr.sbin.mysqld 配置文件,这样您就不会公开所有服务。只需使用ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/usr.sbin.mysqld 将配置文件链接到/etc/apparmor.d/disable。使用/etc/init.d/apparmor restart 重新加载配置文件。对于开发机器来说,这可能是有意义的。
        • 如果您实际上不需要 AppArmor,这是非常不推荐的方法。可以使用/etc/init.d/apparmor teardown 卸载配置文件。使用update-rc.d -f apparmor remove 禁用初始化脚本。

        以上所有内容都需要root权限,但我跳过了所有命令前面重复的sudo

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-03-08
          • 1970-01-01
          • 1970-01-01
          • 2014-05-26
          • 2012-01-25
          • 2023-03-10
          • 2010-10-03
          • 1970-01-01
          相关资源
          最近更新 更多