我应该如何处理MySQL中的--secure-file-priv?


357

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

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

我收到以下错误:

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

我该如何解决这个错误?

我已经检查了关于同一错误消息的另一个问题,但仍然找不到解决方案。

我正在使用MySQL 5.6


CSV文件的共享路径
Zafar Malik 2015年

1
当然,在尝试使用时会出现此错误mysqldump --tab,好像很难从mysql中获取自己的数据一样。
William Entriken

1
除了vhu的答案外,请在下面搜索wolfsshield的答案。您需要切换到“ /”以使其正常工作(我正在使用win10)
Rsc Rsc

4
使用本地。 LOAD DATA LOCAL INFILE ...
mpoletto

Answers:


473

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

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

您有两种选择:

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

4
默认情况下,在W2012服务器上运行MySQL 5.6时,可以从“ C:\ ProgramData \ MySQL \ MySQL Server 5.6”中找到my.ini。您可能还需要检查服务的启动参数(例如--defaults文件=“C:\ ProgramData \ MySQL的\ MySQL服务器5.6 \ my.ini文件),因为它们也可能列出--secure-file-priv。本身
VHU指令

2
@ Mohitbhasi,my-default.ini应该位于“ C:\ Program Files \ MySQL \ MySQL Server 5.6”文件夹中。vhu所指的位置是“ C:\ ProgramData \ MySQL \ MySQL Server 5.6”。以防万一您没有注意到。
NurShomik

67
值:NULL。FML。
William Entriken

11
请注意,如果使用“选择..到outfile”,则必须指定完整路径,并且完整路径必须与SHOW VARIABLES LIKE "secure_file_priv";
–Satinatinnight

9
“检查参数”和“检查my.ini”不是一个很好的答案
Roland Seuhs 18-3-21

234

我遇到过同样的问题。我终于LOCAL在命令中使用选项解决了

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

您可以在这里找到更多信息http://dev.mysql.com/doc/refman/5.7/en/load-data.html

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


2
这对我和其他人都起作用。我想:1.上传我的txt文件中C:\ProgramData\MySQL\MySQL Server 5.7\Uploads,2禁用secure_file_privmy.ini并重新启动mysql的3。这一个!谢谢:)
Kamal Nayan

10
我收到了针对MariaDB的错误消息:“错误1148(42000):此MariaDB版本不允许使用的命令”。确切的版本:“ mysql ver 15.1 Distrib 10.1.22-MariaDB,用于Linux(x86_64),使用readline 5.2”
jciloa

11
对于5.7.19版的MySQL,我收到了“此MySQL版本不允许使用的命令”的信息。
艾莉森·S

2
@AlisonS尝试--local-infile在运行时添加标志mysqlstackoverflow.com/questions/10762239/...
Illya Moskvin

1
The used command is not allowed with this MySQL version从MySQL 8.0
bitfishxyz

117

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

[mysqld]
secure-file-priv = ""

1
这也为我工作。相同版本的Ubuntu和MySQL
Rodney

1
+1为我工作。如果您使用的是Ubuntu,请不要忘记重启mysql服务:sudo service mysql restart
Emiliano Sangoi

1
如果需要它指向您在适用的情况下根据每个语句选择的位置,则此方法有效。正如您所解释的,它可以在Windows Server上与MySQL 5.7一起使用。如果你只是注释掉欲行# secure-file-priv = ~那么它仍然有错误,因为值显示为NULL做这件事的时候,你要来接你可以导出到服务器等上目录这种方式解决了该问题
Bitcoin的杀气疯狂

1
在Windows上使用MySQL 5.7为我工作,而其他解决方案则没有。
CGritton,

注意:如果在Docker中执行此操作,则必须重新启动Docker容器。
user1717828

38

我正在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;命令虽然产生了预期的结果。
Majid Fouladpour

1
这对我有用-Ubuntu Mysql 5.7.21:将输出文件更改为目录/var/lib/mysql-files/output.txt
Shanemeister

2
那你怎么编辑呢?我试图在/etc/mysql/my.cnf中对其进行编辑,但似乎没有效果-保持为NULL
Slavik

24

这是在Windows 7中禁用secure-file-priv(对vhu的回答中的选项#2 )对我有效的方法

  1. 通过进入来停止MySQL服务器服务services.msc
  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. 通过进入启动MySQL服务器服务services.msc

16
从MySQL Server 5.7.16开始,注释掉该行将不起作用,因为它将恢复为默认设置,即禁用导入和导出操作。现在,如果要允许从任何目录进行这些操作,则需要将其设置为空字符串。
dbc

1
Ramnath,请使用5.7.x版本的@dbc详细信息编辑答案。谢谢。
拉斐尔·戈麦斯Francisco

添加一个空字符串对我有用;请更改答案以添加一个空字符串,例如secure-file-priv =“”
Rajesh Goel,

对于Windows,请确保使用正斜杠
Oliver Oliver

22

如果该文件在计算机本地,请在命令中使用LOCAL

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

14

@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

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


您的回答对我有用,非常感动
benaou mouad

是是是...为什么下面的答案如此之远。我挣扎了很长时间,然后才明白了。我回来添加这个作为答案,但是它是如此之遥,以至于我在浪费时间之前没有看到它。
Rsc Rsc

不是所有的英雄穿着斗篷。
JRK

8

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

最后,如dbc所建议的那样,使“ secure-file-priv”等于一个空字符串是可行的。因此,如果任何人在尝试完上述答案后都陷入困境,希望这样做会有所帮助。


8

对我有用的东西:

  1. 将文件放入中指定的文件夹中secure-file-priv

要找到该类型:

mysql>显示类似“ secure_file_priv”的变量;


  1. 检查你是否有local_infile = 1

输入以下内容:

mysql>显示类似“ local_infile”的变量;

如果你得到:

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

然后将其设置为一种输入:

mysql>设置全局local_infile = 1;


  1. 指定文件的完整路径。就我而言:

mysql>将文件“ C:/ ProgramData / MySQL / MySQL Server 8.0 / Uploads / file.txt”中的数据加载到表测试中;


6

撰写本文时,该线程已被查看522k次。老实说MySQL是什么时候成为我们过度保护的不合理妈妈?多么费时间的安全尝试-确实只会束缚我们!

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

  1. 通过PhpMyAdmin导入.csv文件,在较旧的框上导入(如果在cmd行较大)
  2. 生成一个.sql文件
  3. 下载.sql文件
  4. 通过MySQL工作台导入.sql文件

3

我对此有各种各样的问题。我正在更改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=$?

3

如果您在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”对我有用。
Anidhya Bhatnagar


3

如果您正在运行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;

免责声明: 这不是一个完美的解决方案-我只是将其发布给那些在时间表之下并且有大量数据要导入并且遇到此荒谬问题的开发人员。我为此花了很多时间,我希望能再度节省其他开发者的时间。


1

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

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

服务器已按预期启动。


1

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 |       |
+------------------+-------+

0

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

谢谢


0

无需更改任何配置文件。

  1. 寻找secure_file_priv使用@vhu:发布的命令的值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上的mysql-shell中的LTS mysql 5.7.29

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.