【问题标题】:How should I tackle --secure-file-priv in MySQL?我应该如何处理 MySQL 中的 --secure-file-priv?
【发布时间】:2020-05-05 07:43:09
【问题描述】:

我正在学习 MySQL 并尝试使用 LOAD DATA 子句。当我如下使用它时:

LOAD DATA INFILE "text.txt" INTO table mytable;

我收到以下错误:

MySQL 服务器使用 --secure-file-priv 选项运行,因此无法执行此语句

我该如何解决这个错误?

我检查了another question on the same error message,但仍然找不到解决方案。

我使用的是 MySQL 5.6

【问题讨论】:

  • 您的 csv 文件的共享路径
  • 当然,您在尝试使用mysqldump --tab 时会收到此错误,好像从mysql 中取出您自己的数据还不够困难。
  • 除了vhu的答案,在下面搜索wolfsshield的答案。你需要切换到'/'才能让它工作(我使用的是win10)
  • 使用本地。 LOAD DATA LOCAL INFILE ...
  • @mpoletto "错误代码:1148。此 MySQL 版本不允许使用的命令"

标签: mysql database


【解决方案1】:

它按预期工作。您的 MySQL 服务器已使用 --secure-file-priv 选项启动,该选项基本上限制了您可以使用 LOAD DATA INFILE 从哪些目录加载文件。

您可以使用SHOW VARIABLES LIKE "secure_file_priv"; 查看已配置的目录。

你有两个选择:

  1. 将文件移动到secure-file-priv指定的目录。
  2. 禁用secure-file-priv。这必须从启动中删除,并且不能动态修改。为此,请检查您的 MySQL 启动参数(取决于平台)和 my.ini。

【讨论】:

  • 在 W2012 服务器上运行 MySQL 5.6 时,默认情况下 my.ini 可以从“C:\ProgramData\MySQL\MySQL Server 5.6”中找到。您可能还需要检查服务启动参数(例如 --defaults-file="C:\ProgramData\MySQL\MySQL Server 5.6\my.ini),因为它们也可能列出 --secure-file-priv 本身。
  • @Mohitbhasi, my-default.ini 应该在“C:\Program Files\MySQL\MySQL Server 5.6”文件夹中。 vhu 所指的位置是“C:\ProgramData\MySQL\MySQL Server 5.6”。以防万一你没有注意到。
  • 值:NULL。 FML。
  • 注意,如果使用“select .. into outfile”必须指定完整路径,并且完整路径必须与SHOW VARIABLES LIKE "secure_file_priv";的结果匹配
  • “检查参数”和“检查my.ini”不是很好的答案
【解决方案2】:

我使用命令中的LOCAL 选项解决了这个问题:

LOAD DATA LOCAL INFILE "text.txt" INTO TABLE mytable;

您可以找到更多信息here

如果指定了 LOCAL,则文件由客户端程序读取 客户端主机并发送到服务器。该文件可以作为一个完整的 路径名以指定其确切位置。如果作为相对路径给出 名称,名称是相对于目录进行解释的 客户端程序已启动。

【讨论】:

  • 这对我和其他人都有效。我试过:1.在C:\ProgramData\MySQL\MySQL Server 5.7\Uploads中上传我的txt文件,2.在my.ini中禁用secure_file_priv并重新启动mysql 3.这个!谢谢:)
  • 我收到 MariaDB 的此错误消息:“错误 1148 (42000):此 MariaDB 版本不允许使用的命令”。确切版本:“mysql Ver 15.1 Distrib 10.1.22-MariaDB, for Linux (x86_64) using readline 5.2”
  • 对于 mysql 版本 5.7.19,我得到“此 MySQL 版本不允许使用的命令”。
  • @AlisonS 在运行mysql 时尝试添加--local-infile 标志。 stackoverflow.com/questions/10762239/…
  • The used command is not allowed with this MySQL version 来自 MySQL 8.0
【解决方案3】:

在 Ubuntu 14 和 Mysql 5.5.53 上,此设置似乎默认启用。要禁用它,您需要将 secure-file-priv = "" 添加到 mysqld 配置组下的 my.cnf 文件中。例如:-

[mysqld]
secure-file-priv = ""

【讨论】:

  • 这对我也有用。 Ubuntu和MySQL相同版本
  • +1 为我工作。如果你使用的是 Ubuntu,别忘了重启 mysql 服务:sudo service mysql restart
  • 如果您需要它指向您在适用的每个语句中选择的位置,这就是有效的方法。正如您所解释的,这适用于 Windows Server 上的 MySQL 5.7。如果您只是注释掉 # secure-file-priv = ~ 这样的行,那么它仍然有错误,因为值显示为 NULL,这样做可以解决问题,当您想选择可以导出到服务器上的目录等时。
  • 在 Windows 上使用 MySQL 5.7 为我工作,而其他解决方案没有。
  • 注意:如果在 Docker 中执行此操作,您必须重新启动 Docker 容器。
【解决方案4】:

我正在 Debian 上开发 MySQL5.7.11,让我查看目录的命令是:

mysql> SELECT @@global.secure_file_priv;

【讨论】:

  • 使用SHOW VARIABLES LIKE "secure_file_priv"; 我得到ERROR 1146 (42S02): Table 'performance_schema.session_variables' doesn't exist 在其他情况下也会抛出,我最终将不得不处理。 SELECT @@global.secure_file_priv; 命令虽然产生了预期的结果。
  • 这对我有用——Ubuntu Mysql 5.7.21:将输出文件更改为目录 /var/lib/mysql-files/output.txt
  • 那你如何编辑它?我试图在 /etc/mysql/my.cnf 中编辑它,但它似乎没有效果 - 它保持为 NULL
【解决方案5】:

@vhu 我做了SHOW VARIABLES LIKE "secure_file_priv";,它返回了C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\,所以当我插入它时,它仍然没有工作。

当我直接转到my.ini 文件时,我发现路径的格式有点不同:

C:/ProgramData/MySQL/MySQL Server 8.0/Uploads

然后当我用它运行它时,它起作用了。唯一的区别是斜线的方向。

【讨论】:

  • 是的,是的,是的……为什么这个答案在下面。我挣扎了很长时间,然后得到了它。我回来添加这个作为答案,但它太远了,在我浪费时间之前我没有看到它。
  • 并非所有英雄都穿着斗篷。
  • 太棒了,这是 MySql 8.0 上的确切问题
  • 谢谢,结合thisthis 的答案对我来说效果很好
【解决方案6】:

以下是我在 Windows 7 中禁用 secure-file-priv 的方法(vhu's answer 中的选项 #2):

  1. 通过进入 services.msc 停止 MySQL 服务器服务。
  2. 转到C:\ProgramData\MySQL\MySQL Server 5.6ProgramData 在我的例子中是一个隐藏文件夹)。
  3. 在记事本中打开my.ini 文件。
  4. 搜索“secure-file-priv”。
  5. 通过在行首添加“#”来注释该行。对于 MySQL Server 5.7.16 及更高版本,注释将不起作用。您必须将其设置为像这样的空字符串 - secure-file-priv=""
  6. 保存文件。
  7. 进入 services.msc 启动 MySQL 服务器服务。

【讨论】:

  • 从 MySQL Server 5.7.16 开始,注释掉该行将不起作用,因为它将恢复为默认值,从而禁用导入和导出操作。如果要允许从任何目录进行这些操作,现在需要将其设置为空字符串。
  • Ramnath,请使用 5.7.x 版本的@dbc 详细信息编辑您的答案。谢谢。
  • 添加一个空字符串对我有用;请更改答案以添加一个空字符串,例如 secure-file-priv=""
  • 对于 Windows,请确保使用正斜杠
【解决方案7】:

如果文件是您机器的本地文件,请在您的命令中使用 LOCAL

LOAD DATA LOCAL INFILE "text.txt" INTO table mytable;

【讨论】:

    【解决方案8】:

    在发布此帖子时,该主题已被查看 570k 次。老实说,MySQL什么时候变成了我们过度保护的不讲道理的妈妈?多么耗时的安全尝试——这真的只会束缚我们!

    经过多次搜索和多次尝试,一切都失败了。 我的解决方案:

    对我有用的是:

    1. 在旧机器上通过 PhpMyAdmin 导入 .csv 文件(如果在 cmd 行大的话)
    2. 生成.sql 文件。
    3. 下载.sql文件。
    4. 通过 MySQL Workbench 导入 .sql 文件。

    【讨论】:

      【解决方案9】:

      对我有用的东西:

      1. 将您的文件放在secure-file-priv 中指定的文件夹中。

        要查找该类型:

        mysql> show variables like "secure_file_priv";  
        
      2. 检查你是否有local_infile = 1

        输入:

        mysql> show variables like "local_infile";
        

        如果你得到:

        +---------------+-------+
        | Variable_name | Value |
        +---------------+-------+
        | local_infile  | OFF   |
        +---------------+-------+
        

        然后将其设置为一种类型:

        mysql> set global local_infile = 1;
        
      3. 指定文件的完整路径。就我而言:

        mysql> load data infile "C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/file.txt" into table test;
        

      【讨论】:

        【解决方案10】:

        我对“secure-file-priv”也有同样的问题。 .ini 文件中的注释不起作用,在“secure-file-priv”指定的目录中移动文件也不起作用。

        最后,正如 dbc 建议的那样,使 'secure-file-priv' 等于一个空字符串是可行的。因此,如果有人在尝试上述答案后遇到困难,希望这样做会有所帮助。

        【讨论】:

          【解决方案11】:

          对于 mysql 8.0 版本,您可以这样做:

          mysql.server stop
          mysql.server start --secure-file-priv=''
          

          它在 Mac High Sierra 上对我有用。

          【讨论】:

          • 在 macOS 11.3 beta 中对我不起作用。 MySQL 5.7
          • 在 macOS 10.5.5 Catalina 中也不起作用;它将标志设置为空,但没有阻止错误。
          • 在 MaOS 10.15.7 Catalina / MySQL 8.0.22 Homebrew 中为我工作。
          【解决方案12】:

          如果您在 Ubuntu 上运行,您可能还需要配置 Apparmor 以允许 MySQL 写入您的文件夹,例如这是我的配置:

          将此行添加到文件 /etc/apparmor.d/usr.sbin.mysqld :

          /var/lib/mysql-files/* rw
          

          然后将这 2 行配置添加到 /etc/mysql/my.cnf 部分:

          [client]
          loose-local-infile = 1
          
          [mysqld]
          secure-file-priv = ""
          

          这是我的 SQL:

          select id from blahs into outfile '/var/lib/mysql-files/blahs';
          

          它对我有用。祝你好运!

          【讨论】:

          • 是的,将输出文件路径与“/var/lib/mysql-files/filename.csv”一起为我工作。
          【解决方案13】:

          如果您正在运行 nodeJS 并且您的数据采用以下形式(双引号 + 逗号和 \n 换行),我创建了一个 NodeJS 导入脚本

          INSERT INTO <your_table> VALUEs( **CSV LINE **)
          

          这个被配置为在http://localhost:5000/import上运行。

          我逐行创建查询字符串

          "city","city_ascii","lat","lng","country","iso2","iso3","id"
          "Tokyo","Tokyo","35.6850","139.7514","Japan","JP","JPN","1392685764",
          ...
          

          server.js

          const express = require('express'),
             cors = require('cors'),
             bodyParser = require('body-parser'),
             cookieParser = require('cookie-parser'),
             session = require('express-session'),
             app = express(),
             port = process.env.PORT || 5000,
             pj = require('./config/config.json'),
             path = require('path');
          
          app.use(bodyParser.json());
          app.use(cookieParser());
          app.use(cors());
          
          
          app.use(
             bodyParser.urlencoded({
                extended: false,
             })
          );
          
          var Import = require('./routes/ImportRoutes.js');
          
          app.use('/import', Import);
          if (process.env.NODE_ENV === 'production') {
             // set static folder
             app.use(express.static('client/build'));
          
             app.get('*', (req, res) => {
                res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
             });
          }
          
          app.listen(port, function () {
             console.log('Server is running on port: ' + port);
          });
          

          ImportRoutes.js

          const express = require('express'),
             cors = require('cors'),
             fs = require('fs-extra'),
             byline = require('byline'),
             db = require('../database/db'),
             importcsv = express.Router();
          
          importcsv.use(cors());
          
          importcsv.get('/csv', (req, res) => {
          
             function processFile() {
                return new Promise((resolve) => {
                   let first = true;
                   var sql, sqls;
                   var stream = byline(
                      fs.createReadStream('../PATH/TO/YOUR!!!csv', {
                         encoding: 'utf8',
                      })
                   );
          
                   stream
                      .on('data', function (line, err) {
                         if (line !== undefined) {
                            sql = 'INSERT INTO <your_table> VALUES (' + line.toString() + ');';
                            if (first) console.log(sql);
                            first = false;
                            db.sequelize.query(sql);
                         }
                      })
                      .on('finish', () => {
                         resolve(sqls);
                      });
                });
             }
          
             async function startStream() {
                console.log('started stream');
                const sqls = await processFile();
                res.end();
                console.log('ALL DONE');
             }
          
             startStream();
          });
          
          module.exports = importcsv;
          

          db.js 是配置文件

          const Sequelize = require('sequelize');
          const db = {};
          const sequelize = new Sequelize(
             config.global.db,
             config.global.user,
             config.global.password,
             {
                host: config.global.host,
                dialect: 'mysql',
                logging: console.log,
                freezeTableName: true,
          
                pool: {
                   max: 5,
                   min: 0,
                   acquire: 30000,
                   idle: 10000,
                },
             }
          );
          
          db.sequelize = sequelize;
          db.Sequelize = Sequelize;
          
          module.exports = db;
          
          

          免责声明:这不是一个完美的解决方案 - 我只为处于时间线下并且有大量数据要导入并且遇到这个荒谬问题的开发人员发布。我在这方面浪费了很多时间,我希望能节省其他开发人员同样浪费的时间。

          【讨论】:

            【解决方案14】:

            我遇到了各种各样的问题。我正在更改 my.cnf 以及这个问题的其他版本试图显示的各种疯狂的东西。

            什么对我有用:

            我遇到的错误

            The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

            我可以通过打开 /usr/local/mysql/support-files/mysql.server 并更改以下行来修复它:

            $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" -- $other_args >/dev/null &
              wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
            

            $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" --secure-file-priv="" $other_args >/dev/null &
              wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
            

            【讨论】:

              【解决方案15】:

              在 macOS Catalina,我按照以下步骤设置 secure_file_priv

              1.停止MySQL服务

               sudo /usr/local/mysql/support-files/mysql.server stop
              

              2.重启MYSQL分配--secure_file_priv系统变量

              sudo /usr/local/mysql/support-files/mysql.server start --secure-file-priv=YOUR_FILE_DIRECTORY
              

              注意:添加空值可以解决我的问题,MYSQL 会将数据导出到目录 /usr/local/mysql/data/YOUR_DB_TABLE/EXPORT_FILE

              sudo /usr/local/mysql/support-files/mysql.server start --secure-file-priv=
              

              谢谢

              【讨论】:

                【解决方案16】:

                这对我有用(在语句 LOAD DATE INFILE ... 中存在无法将 LOCAL 与我当前的 MySQL 版本一起使用的额外问题)

                sudo /usr/local/mysql/support-files/mysql.server start --secure-file-priv='' --local-infile
                

                以上适用于我机器上的给定路径;你可能需要调整你的路径。

                然后使用:

                mysql -u root -p
                

                重要的一点是,您应该在 MySQL 数据文件夹中有 CSV。在我的机器上它位于:/usr/local/mysql-8.0.18-macos10.14-x86_64/data

                如果需要,您可以更改文件夹权限以将 CSV 放入数据文件夹。

                设置:
                macOS Catalina 版本 10.15.5
                MySQL 版本 8.0.18

                【讨论】:

                  【解决方案17】:

                  MySQL 使用这个系统变量来控制你可以在哪里导入文件

                  mysql> SHOW VARIABLES LIKE "secure_file_priv";
                  +------------------+-------+
                  | Variable_name    | Value |
                  +------------------+-------+
                  | secure_file_priv | NULL  |
                  +------------------+-------+
                  

                  所以问题是如何更改secure_file_priv等系统变量。

                  1. 关机mysqld
                  2. sudo mysqld_safe --secure_file_priv=""

                  现在你可能会看到这样:

                  mysql> SHOW VARIABLES LIKE "secure_file_priv";
                  +------------------+-------+
                  | Variable_name    | Value |
                  +------------------+-------+
                  | secure_file_priv |       |
                  +------------------+-------+
                  

                  【讨论】:

                    【解决方案18】:

                    Linux 中您必须在

                    中编辑 my.cnf 文件
                    /etc/mysql/my.cnf
                    

                    并像这样更改26 line number 参数:

                    secure-file-priv= <your data path directory like /home/user/data>
                    

                    然后重新启动您的 MySQL 并重试。

                    泊坞窗 您必须使用 docker-compose 中的此命令将 my.cnf 文件与容器中的 my.cnf 文件一起挂载或手动添加:

                    volumes:
                      - ./persistent:/var/lib/mysql
                      - ./conf/my.cnf:/etc/mysql/my.cnf
                    

                    下一步更改主机中的 /conf/my.cnf 并像上面的方法一样配置 secure-file-priv param,此外,您必须将数据挂载到 mysql 容器中并设置该路径secure-file-priv param 并重新启动您的服务,最后,您可以加载您的数据了。

                    你可以用这个命令检查你的配置:

                    SHOW VARIABLES LIKE "secure_file_priv";
                    

                    【讨论】:

                      【解决方案19】:

                      我在 Windows 10 上遇到了这个问题。“--secure-file-priv in MySQL”为了解决这个问题,我做了以下操作。

                      1. 在 Windows 搜索(左下角)中,我输入了“powershell”。
                      2. 右键单击 powershell 并以管理员身份运行。
                      3. 导航到服务器 bin 文件。 (C:\Program Files\MySQL\MySQL Server 5.6\bin);
                      4. 键入 ./mysqld
                      5. 点击“回车”

                      服务器按预期启动。

                      【讨论】:

                        【解决方案20】:

                        无需更改任何配置文件..

                        1. 使用@vhu 发布的命令查找secure_file_priv 的值:SHOW VARIABLES LIKE "secure_file_priv"
                        2. 定义查询的完整路径,例如:select * from table into outfile 'secure_file_priv_PATH/OUTPUT-FILE' ... rest of your query

                        这对我在 ubuntu 18.04 LTS mysql 5.7.29 上的 mysql-shell 有效

                        【讨论】:

                          【解决方案21】:

                          我在命令中添加了LOCAL,但又产生了另一个问题:

                          Loading local data is disabled - this must be enabled on both the client and server sides
                          

                          为了解决这个问题,我只需按照here 中的三个步骤进行操作

                          【讨论】:

                            【解决方案22】:

                            这里是关于secure_file_priv的解释:

                            这里是LOAD DATA的解释:

                            在我的例子中,来自官方 Docker 镜像的 MySQL 正在使用中,所以我需要弄清楚如何设置secure_file_priv

                            • 为了更好地了解secure_file_priv 是什么,我在上面的链接中阅读了它;
                            • 阅读 MySQL 的 DockerHub 所说的话,https://hub.docker.com/_/mysql

                            要知道(docker)mysql 默认值:

                            $ docker run -it --rm mysql --verbose --help
                            Variables (--variable-name=value)
                            and boolean options {FALSE|TRUE}          Value (after reading options)
                            ----------------------------------------- -----------------------------
                            ...
                            local-infile                              FALSE
                            ...
                            secure-file-priv                          NULL
                            ...
                            

                            事实上,(在容器内)配置文件说:

                            root@a2b1e0c46541:/# cat /etc/mysql/my.cnf
                            #
                            # (...license...)
                            #
                            # The MySQL  Server configuration file.
                            #
                            # For explanations see
                            # http://dev.mysql.com/doc/mysql/en/server-system-variables.html
                            
                            [mysqld]
                            pid-file        = /var/run/mysqld/mysqld.pid
                            socket          = /var/run/mysqld/mysqld.sock
                            datadir         = /var/lib/mysql
                            secure-file-priv= NULL
                            
                            # Custom config should go here
                            !includedir /etc/mysql/conf.d/
                            

                            使用官方图片(如 README 中所述):

                            $ docker run --name mysql -e MYSQL_ROOT_PASSWORD=secret -d mysql \
                                     --secure_file_priv=/data
                            

                            如果您想允许LOCAL INFILE 加载,请同时定义选项local_infile=TRUE

                            现在你应该可以LOAD DATA INFILE '/data/data.csv' INTO TABLE some_table了。

                            注意:在同一任务中——一旦“INFILE”问题得到解决(上图)——我的 CSV 数据中的 empty 值存在问题,答案(和问题)非常有帮助:https://stackoverflow.com/a/5968530/687896

                            【讨论】:

                              【解决方案23】:

                              对于运行 MySQL 5.6.23 的 MacOS Mojave,我在 写入 文件时遇到了这个问题,但在 加载 文件时却没有。 (在以前版本的 Mac OS 中看不到)。由于这个问题的大多数答案都是针对其他系统的,我想我会发布解决这个问题的 my.cnf 文件(以及套接字问题),以防它对其他 Mac 用户有帮助。这是 /etc/my.cnf

                              [client]
                              default-character-set=utf8
                              
                              [mysqld]
                              character-set-server=utf8
                              secure-file-priv = ""
                              skip-external-locking
                              

                              (国际化与问题无关。)

                              没有其他要求。只需关闭 MySQL 服务器,然后在 Preferences(我们正在谈论 Mac)中再次打开即可。

                              【讨论】:

                                【解决方案24】:

                                我在这里遇到了同样的问题,ERRORCODE 2。是的,大多数答案都有意义,但是我尝试了最简单的方法:

                                我在文件路径中使用了双斜杠。

                                我的整个查询的示例路径>>试一试,如果它对你有用,请让大家知道。

                                加载数据本地 INFILE "E:\Irfan One Drive\OneDrive - Qtech\Documents\Suppliers\HB\Extended\HotelTransferZone.csv" 进入表temp_hb_transfer 以“|”结尾的字段 可选地由 '"' 括起来
                                以“\n”结尾的行

                                【讨论】:

                                  猜你喜欢
                                  • 2016-09-03
                                  • 2019-08-07
                                  • 1970-01-01
                                  • 2017-04-20
                                  相关资源
                                  最近更新 更多