Как я должен заняться --secure-file-priv в MySQL?


358

Я изучаю MySQL и попытался использовать LOAD DATAпредложение. Когда я использовал его, как показано ниже:

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

Я получил следующую ошибку:

Сервер MySQL работает с параметром --secure-file-priv, поэтому он не может выполнить этот оператор

Как мне справиться с этой ошибкой?

Я проверил другой вопрос в том же сообщении об ошибке , но все еще не могу найти решение.

Я использую MySQL 5.6


поделитесь путем к вашему файлу csv
Zafar Malik

1
Конечно, вы получаете эту ошибку при попытке использовать mysqldump --tab, как будто это не было достаточно сложно, чтобы получить ваши собственные данные из MySQL.
Уильям Энтрикен,

1
в дополнение к ответу vhu, ищите ответ wolfsshield ниже. вам нужно переключиться на '/', чтобы заставить его работать (я использую win10)
Rsc Rsc

4
используйте МЕСТНОЕ. LOAD DATA LOCAL INFILE ...
Мполетто

Ответы:


474

Это работает как задумано. Ваш сервер 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
По умолчанию my.ini можно найти в «C: \ ProgramData \ MySQL \ MySQL Server 5.6» при запуске MySQL 5.6 на сервере W2012. Вы также можете проверить параметры запуска службы (например, --defaults-file = "C: \ ProgramData \ MySQL \ MySQL Server 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». На всякий случай, если вы не заметили.
НурШомик

68
Значение: NULL. FML.
Уильям Энтрикен

11
Обратите внимание, что если вы используете «select .. into outfile», вы должны указать полный путь, а полный путь должен совпадать с результатамиSHOW VARIABLES LIKE "secure_file_priv";
TheSatinKnight

9
«проверить параметры» и «проверить my.ini» не очень хороший ответ
Роланд Сеухс

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. загрузить файл в текстовом C:\ProgramData\MySQL\MySQL Server 5.7\Uploads, 2. отключив secure_file_privв my.iniи перезагрузке MySQL 3. Это один! Спасибо :)
Камаль Наян

10
Я получил это сообщение об ошибке для MariaDB: «ОШИБКА 1148 (42000): используемая команда не разрешена с этой версией MariaDB». Точная версия: «mysql Ver 15.1 Distrib 10.1.22-MariaDB, для Linux (x86_64) с использованием readline 5.2»
jciloa

11
Я получил "Используемая команда не разрешена с этой версией MySQL" для версии 5.7.19 mysql.
Элисон С

2
@AlisonS Попробуйте добавить --local-infileфлаг при запуске mysql. stackoverflow.com/questions/10762239/…
Илья Москвин

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

118

В Ubuntu 14 и Mysql 5.5.53 этот параметр включен по умолчанию. Чтобы отключить его, вам нужно добавить его secure-file-priv = ""в файл my.cnf в группе настроек mysqld. например:-

[mysqld]
secure-file-priv = ""

1
Это сработало и для меня. Та же версия Ubuntu и MySQL
Родни

1
+1 работал для меня. Если вы используете Ubuntu, не забудьте перезапустить службу mysql: sudo service mysql restart
Emiliano Sangoi

1
Это то, что работает, если вам нужно указать местоположение, которое вы выбираете для каждого оператора, где это применимо. Это работает с MySQL 5.7 на Windows Server, как вы объяснили. Если вы просто закомментируете строку, как # secure-file-priv = ~тогда, она по-прежнему имеет ошибку, поскольку значение показывает, что NULLвыполнение этого пути решает проблему, когда вы хотите выбрать, в какие каталоги вы можете экспортировать данные на сервер и т. Д.
Bitcoin Murderous Maniac

1
У меня работал с MySQL 5.7 на Windows, в то время как другие решения не.
CGritton

Примечание: если вы делаете это в Docker, вы должны перезапустить Docker-контейнер.
user1717828

38

Я работаю над MySQL5.7.11 на Debian, команда, которая работала для меня, чтобы увидеть каталог:

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;хотя и дала ожидаемый результат.
Маджид Фуладпур

1
Это сработало для меня - Ubuntu Mysql 5.7.21: изменил выходной файл на каталог /var/lib/mysql-files/output.txt
Shanemeister

2
Как вы редактируете это тогда? Я попытался отредактировать его в /etc/mysql/my.cnf, и это, похоже, не имеет никакого эффекта - оно остается NULL
Славик

25

Вот что у меня работало в Windows 7, чтобы отключить secure-file-priv(Вариант № 2 из ответа Вху ):

  1. Остановите службу сервера MySQL, зайдя в services.msc.
  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. Запустите службу сервера MySQL, зайдя в services.msc.

16
Начиная с MySQL Server 5.7.16, комментирование строки не будет работать, потому что тогда оно вернется к значению по умолчанию, которое отключит операции импорта и экспорта. Теперь вам нужно установить пустую строку, если вы хотите разрешить эти операции из любого каталога.
декабря

1
Рамнатх, пожалуйста, отредактируйте свой ответ с подробным описанием @dbc для версии 5.7.x. Спасибо.
Рафаэль Гомес Франциско

Добавление пустой строки работает для меня; пожалуйста, измените ответ, добавив пустую строку вроде secure-file-priv = ""
Раджеш Гоэль

Для Windows обязательно используйте прямые косые черты
Оливер Оливер

22

Если файл является локальным для вашей машины, используйте ЛОКАЛЬНЫЙ в вашей команде

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

15

@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

9

У меня была такая же проблема с «secure-file-priv». Комментирование в INI-файле не сработало, равно как и перемещение файла в каталог, указанный в «secure-file-priv».

Наконец, как предположил dbc, сработав 'secure-file-priv' равным пустой строке, сработало. Так что, если кто-то застрянет после попытки ответа выше, надеюсь, что это поможет.


9

То, что сработало для меня:

  1. Поместите ваш файл в папку, указанную в secure-file-priv.

Чтобы найти этот тип:

mysql> показывать переменные вроде "secure_file_priv";


  1. Проверьте, есть ли у вас local_infile = 1.

Сделайте это, набрав:

mysql> показывать переменные типа "local_infile";

Если вы получаете:

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

Затем установите его на один набор:

mysql> set global local_infile = 1;


  1. Укажите полный путь к вашему файлу. В моем случае:

mysql> загрузить данные файла "C: / ProgramData / MySQL / MySQL Server 8.0 / Uploads / file.txt" в тест таблицы;


6

Эта тема была просмотрена 522k раз на момент публикации. Честно говоря, когда MySQL стала нашей чрезмерно защитной неразумной мамой ? Какая трудоемкая попытка безопасности - которая действительно только сковывает нас!

После многих поисков и многих попыток все не удалось.
Мое решение:

  1. Импортируйте файл .csv с помощью импорта PhpMyAdmin в старое окно (если большой размер в строке cmd)
  2. создать файл .sql
  3. скачать .sql файл
  4. импортировать файл .sql через рабочий стол MySQL

4

Я создал скрипт импорта 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;

Отказ от ответственности: это не идеальное решение - я публикую его только для разработчиков, которые работают в сжатые сроки и имеют много данных для импорта и сталкиваются с этой нелепой проблемой. Я потерял много времени на это, и я надеюсь сэкономить еще одного разработчика, потерявшего то же время.


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';

Это сработало для меня. Удачи!


Да, у меня получилось поставить путь к файлу outfile с помощью /var/lib/mysql-files/filename.csv.
Анидхья Бхатнагар

3

Для версии MySQL 8.0 вы можете сделать это:

  1. MySQL остановка сервера
  2. mysql.server start --secure-file-priv = ''

У меня это работало на Mac High Sierra


1

У меня была эта проблема на Windows 10. "--secure-file-priv в MySQL" Чтобы решить эту проблему, я сделал следующее.

  1. В окне поиска (внизу слева) я набрал "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

у меня это работает в mysql-shell на ubuntu 18.04 LTS mysql 5.7.29

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.