我应该如何解决——安全文件priv在MySQL?

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

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

我得到了以下错误:

MySQL服务器正在使用——secure-file-priv选项运行,所以它不能执行这条语句

如何解决这个错误?

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

我使用的是MySQL 5.6

830445 次浏览

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

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

你有两个选择:

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

我正在Debian上的MySQL5.7.11上工作,为我工作的命令是:

mysql> SELECT @@global.secure_file_priv;

下面是我在Windows 7中禁用secure-file-priv(选项#2来自vhu的回答)的方法:

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

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

最后,正如dbc建议的那样,使'secure-file-priv'等于一个空字符串就可以工作了。所以如果有人在尝试了上面的答案后被困住了,希望这样做会有所帮助。

在Ubuntu 14和Mysql 5.5.53上,这个设置默认是启用的。要禁用它,你需要在mysqld配置组下的my.cnf文件中添加secure-file-priv = ""。如:-

[mysqld]
secure-file-priv = ""

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

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

你可以找到更多信息在这里

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

我在这方面遇到了各种各样的问题。我在修改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来修复它。服务器,更改如下行:

$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=$?

我在windows 10上遇到了这个问题。为了解决这个问题,我做了以下工作。

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

服务器按预期启动。

如果文件是本地的,在你的命令中使用当地的

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

对我有用的是:

  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;
    

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

@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

当我用它运行时,它工作了。唯一不同的是斜线的方向。

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

将这一行添加到文件/etc/ apparor .d/usr.sbin中。mysqld:

/var/lib/mysql-files/* rw

然后在/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';

这对我很管用。好运!

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

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

这招在Mac High Sierra很管用。

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

谢谢

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

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

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

在这篇文章发表时,这个帖子已经被浏览了570k次。说实话,MySQL什么时候变成了我们过度保护的无理妈妈了?这是多么耗费时间的安全尝试——这实际上只会束缚我们!

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

对我有用的是:

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

我创建了一个NodeJS导入脚本,如果你正在运行NodeJS,你的数据是以下形式(双引号+逗号和\n新行)

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;


免责声明:这不是一个完美的解决方案-我只是发布它的开发者谁是在一个时间轴下,有大量的数据导入,并遇到这个荒谬的问题。我在这方面损失了很多时间,我希望其他开发人员也能节省同样的时间。

这为我工作(有额外的问题,不能使用本地与我当前的MySQL版本在语句LOAD DATE INFILE…)

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,可以更改文件夹权限。

< br > < p >设置: macOS Catalina版本10.15.5
MySQL版本8.0.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参数,此外,你必须在mysql容器中挂载你的数据,并为secure-file-priv参数设置路径,重新启动你的服务,最后,你可以加载你的数据。

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

SHOW VARIABLES LIKE "secure_file_priv";

对于运行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服务器,然后在首选项中再次打开(我们说的是Mac)。

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

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

为了解决这个问题,我在在这里中简单地执行了三个步骤

下面是关于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数据中的值有问题,答案(和问题)是非常有用的:https://stackoverflow.com/a/5968530/687896

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

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

我的示例路径和整个查询>>试一试,让每个人都知道它对你是否有效。

LOAD DATA LOCAL INFILE "E:\Irfan OneDrive \OneDrive - Qtech\Documents\Suppliers\HB\Extended\HotelTransferZone.csv" 放入表__abc0 以'|'结尾的字段 可选包含'"'
以'\n'