我正在学习 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
mysqldump --tab
时会收到此错误,好像从 mysql 中获取您自己的数据还不够难。
LOAD DATA LOCAL INFILE ...
它按预期工作。您的 MySQL 服务器已使用 --secure-file-priv 选项启动,该选项限制您可以使用 LOAD DATA INFILE
从哪些目录加载文件。
使用 SHOW VARIABLES LIKE "secure_file_priv";
查看已配置的目录。
你有两个选择:
将您的文件移动到由secure-file-priv 指定的目录。禁用安全文件私有。这必须从启动中删除,并且不能动态修改。为此,请检查您的 MySQL 启动参数(取决于平台)和 my.ini。
我使用命令中的 LOCAL
选项解决了它:
LOAD DATA LOCAL INFILE "text.txt" INTO TABLE mytable;
您可以找到更多信息here。
如果指定了 LOCAL,则该文件由客户端主机上的客户端程序读取并发送到服务器。该文件可以作为完整路径名给出以指定其确切位置。如果作为相对路径名给出,则该名称被解释为相对于启动客户端程序的目录。
C:\ProgramData\MySQL\MySQL Server 5.7\Uploads
中上传我的txt文件,2.在my.ini
中禁用secure_file_priv
并重新启动mysql 3.这个!谢谢 :)
The used command is not allowed with this MySQL version
从 MySQL 8.0
在 Ubuntu 14 和 Mysql 5.5.53 上,此设置似乎默认启用。要禁用它,您需要将 secure-file-priv = ""
添加到 mysqld 配置组下的 my.cnf 文件中。例如:-
[mysqld]
secure-file-priv = ""
# secure-file-priv = ~
之类的行,那么它仍然会出现错误,因为值显示为 NULL
这样做可以解决问题,当您想选择可以导出到服务器上的目录等时。
@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
然后当我用它运行它时,它起作用了。唯一的区别是斜线的方向。
我正在 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;
命令虽然产生了预期的结果。
以下是我在 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 服务器服务。
如果文件是您机器的本地文件,请在您的命令中使用 LOCAL
LOAD DATA LOCAL INFILE "text.txt" INTO table mytable;
在本文发布时,该主题已被查看 570k 次。老实说,MySQL什么时候变成了我们过度保护的不讲道理的妈妈?多么耗时的安全尝试——这真的只会束缚我们!
经过多次搜索和多次尝试,一切都失败了。我的解决方案:
对我有用的是:
通过旧框上的 PhpMyAdmin 导入导入 .csv 文件(如果在 cmd 行执行大)生成一个 .sql 文件。下载 .sql 文件。通过 MySQL Workbench 导入 .sql 文件。
对我有用的东西:
将您的文件放在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;
我对“secure-file-priv”有同样的问题。 .ini 文件中的注释不起作用,在“secure-file-priv”指定的目录中移动文件也不起作用。
最后,正如 dbc 建议的那样,使 'secure-file-priv' 等于一个空字符串是可行的。因此,如果有人在尝试上述答案后遇到困难,希望这样做会有所帮助。
对于 mysql 8.0 版本,您可以这样做:
mysql.server stop
mysql.server start --secure-file-priv=''
它在 Mac High Sierra 上对我有用。
如果您在 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';
它对我有用。祝你好运!
如果您正在运行 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;
免责声明:这不是一个完美的解决方案——我只为处于时间线下并且有大量数据要导入并且遇到这个荒谬问题的开发人员发布。我在这方面浪费了很多时间,我希望能节省另一个开发人员同样浪费的时间。
我遇到了各种各样的问题。我正在更改 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=$?
在 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=
谢谢
这对我有用(在语句 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
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 | |
+------------------+-------+
在 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";
我在 Windows 10 上遇到了这个问题。“--secure-file-priv in MySQL”为了解决这个问题,我做了以下事情。
在 Windows 搜索(左下角)中,我输入了“powershell”。右键单击powershell并以管理员身份运行。导航到服务器 bin 文件。 (C:\Program Files\MySQL\MySQL Server 5.6\bin);输入 ./mysqld 点击“回车”
服务器按预期启动。
无需更改任何配置文件..
使用@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
我将 LOCAL
添加到命令中,但它产生了另一个问题:
Loading local data is disabled - this must be enabled on both the client and server sides
为了解决这个问题,我只需遵循 here 中的三个步骤
以下是关于 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。
对于运行 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)中再次打开即可。
我在这里遇到了同样的问题,ERRORCODE 2。是的,大多数答案都有意义,但是我尝试了最简单的方法:
我在文件的路径中使用了双斜杠。
我的整个查询的示例路径>>尝试一下,如果它对你有用,请让大家知道。
将数据本地 INFILE "E:\Irfan One Drive\OneDrive - Qtech\Documents\Suppliers\HB\Extended\HotelTransferZone.csv" 加载到表 temp_hb_transfer
以“|”终止的字段中可选地由 '"' 封闭
由 '\n' 终止的行
--secure-file-priv
本身。SHOW VARIABLES LIKE "secure_file_priv";
的结果匹配