ChatGPT解决这个技术问题 Extra ChatGPT

我应该如何解决 MySQL 中的 --secure-file-priv 问题?

我正在学习 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 版本不允许使用的命令”

R
Rob Bednark

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

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

你有两个选择:

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


默认情况下,在 W2012 服务器上运行 MySQL 5.6 时,可以从“C:\ProgramData\MySQL\MySQL Server 5.6”中找到 my.ini。您可能还想检查服务启动参数(例如 --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”。以防万一你没有注意到。
值:空。 FML。
请注意,如果使用“select .. into outfile”,则必须指定完整路径,并且完整路径必须与 SHOW VARIABLES LIKE "secure_file_priv"; 的结果匹配
“检查参数”和“检查 my.ini”不是一个很好的答案
g
galoget

我使用命令中的 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 的错误消息:“ERROR 1148 (42000): The used command is not allowed with this MariaDB version”。确切版本:“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
M
Mustafa

在 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 容器。
g
galoget

@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的答案,这对我很有效
d
dwlz

我正在 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
J
Janaaaa

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

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


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

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

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

M
Michael Nelles

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

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

对我有用的是:

通过旧框上的 PhpMyAdmin 导入导入 .csv 文件(如果在 cmd 行执行大)生成一个 .sql 文件。下载 .sql 文件。通过 MySQL Workbench 导入 .sql 文件。


g
galoget

对我有用的东西:

将您的文件放在secure-file-priv 中指定的文件夹中。要找到该类型:mysql> 显示变量,如“secure_file_priv”;检查你是否有 local_infile = 1。输入:mysql> show variables like "local_infile";如果你得到:+----------------+-------+ |变量名 |价值 | +---------------+--------+ |本地文件 |关闭 | +---------------+-------+ 然后将其设置为一种类型:mysql> set global local_infile = 1;指定文件的完整路径。在我的例子中:mysql> load data infile "C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/file.txt" into table test;


R
Rsc Rsc

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

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


g
galoget

对于 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 中为我工作。
K
Kevin Hutchinson

如果您在 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”一起为我工作。
M
Michael Nelles

如果您正在运行 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",
...

服务器.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;

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


n
notthehoff

我遇到了各种各样的问题。我正在更改 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=$?

S
Sushil Adhikari

在 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=

谢谢


S
Swan Toma

这对我有用(在语句 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


b
bytefish

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

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

所以问题是如何更改系统变量,例如 secure_file_priv

关闭 mysqld sudo mysqld_safe --secure_file_priv=""

现在你可能会看到这样的:

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

h
hassanzadeh.sd

在 Linux 中,您必须编辑 my.cnf 文件

/etc/mysql/my.cnf

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

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

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

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

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

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

您可以使用以下命令检查您的配置:

SHOW VARIABLES LIKE "secure_file_priv";

J
Jason Allshorn

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

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

服务器按预期启动。


u
user2804070

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

使用@vhu 发布的命令查找secure_file_priv 的值:SHOW VARIABLES LIKE "secure_file_priv"。定义查询的完整路径,例如: select * from table into outfile 'secure_file_priv_PATH/OUTPUT-FILE' ... 查询的其余部分

这适用于我在 ubuntu 18.04 LTS mysql 5.7.29 上的 mysql-shell


s
saleh sereshki

我将 LOCAL 添加到命令中,但它产生了另一个问题:

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

为了解决这个问题,我只需遵循 here 中的三个步骤


B
Brandt

以下是关于 secure_file_priv 的解释:

https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_secure_file_priv

以下是 LOAD DATA 的解释:

https://dev.mysql.com/doc/refman/8.0/en/load-data.html

在我的例子中,来自官方 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


D
David

对于运行 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)中再次打开即可。


I
Irfan

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

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

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

将数据本地 INFILE "E:\Irfan One Drive\OneDrive - Qtech\Documents\Suppliers\HB\Extended\HotelTransferZone.csv" 加载到表 temp_hb_transfer 以“|”终止的字段中可选地由 '"' 封闭
由 '\n' 终止的行