Como devo enfrentar o --secure-file-priv no MySQL?

358

Estou aprendendo MySQL e tentei usar uma LOAD DATAcláusula. Quando eu usei como abaixo:

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

Eu recebi o seguinte erro:

O servidor MySQL está sendo executado com a opção --secure-file-priv, portanto não pode executar esta instrução

Como eu lido com esse erro?

Eu verifiquei outra pergunta na mesma mensagem de erro , mas ainda não consigo encontrar uma solução.

Estou usando o MySQL 5.6

Mohit Bhasi
fonte
caminho de compartilhamento de arquivo CSV
Zafar Malik
11
Obviamente, você recebe esse erro ao tentar usar mysqldump --tab, como se não fosse difícil o suficiente para obter seus próprios dados do mysql.
William Entriken
11
além da resposta de vhu, procure abaixo a resposta de wolfsshield. você precisa mudar para '/' para fazê-lo funcionar (eu estou usando o win10)
Rsc Rsc
4
use LOCAL. LOAD DATA LOCAL INFILE ...
mpoletto

Respostas:

474

Está funcionando como pretendido. Seu servidor MySQL foi iniciado com a opção --secure-file-priv, que basicamente limita de quais diretórios você pode carregar arquivos usando LOAD DATA INFILE.

Você pode usar SHOW VARIABLES LIKE "secure_file_priv";para ver o diretório que foi configurado.

Você tem duas opções:

  1. Mova seu arquivo para o diretório especificado por secure-file-priv.
  2. Desativar secure-file-priv. Isso deve ser removido da inicialização e não pode ser modificado dinamicamente. Para fazer isso, verifique seus parâmetros de inicialização do MySQL (dependendo da plataforma) e my.ini.
vhu
fonte
4
Por padrão, my.ini pode ser encontrado em "C: \ ProgramData \ MySQL \ MySQL Server 5.6" ao executar o MySQL 5.6 no servidor W2012. Você também pode verificar os parâmetros de inicialização do serviço (por exemplo, --defaults-file = "C: \ ProgramData \ MySQL \ MySQL Server 5.6 \ my.ini), pois eles também podem se listar --secure-file-priv.
vhu
2
@Mohitbhasi, my-default.ini deve estar na pasta "C: \ Arquivos de Programas \ MySQL \ MySQL Server 5.6". O local ao qual vhu estava se referindo é "C: \ ProgramData \ MySQL \ MySQL Server 5.6". Apenas no caso de você não ter notado.
NurShomik 16/01
67
Valor: NULL. FML.
William Entriken
11
Observe que se estiver usando "select .. into outfile", você deve especificar o caminho completo e o caminho completo deve corresponder aos resultados deSHOW VARIABLES LIKE "secure_file_priv";
TheSatinKnight
9
"cheque os parâmetros" e "cheque meu.ini" não é uma resposta muito boa
Roland Seuhs
234

Eu tive o mesmo problema. Finalmente resolvi usando a LOCALopção no comando

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

Você pode encontrar mais informações aqui http://dev.mysql.com/doc/refman/5.7/en/load-data.html

Se LOCAL for especificado, o arquivo será lido pelo programa do cliente no host do cliente e enviado ao servidor. O arquivo pode ser fornecido como um nome de caminho completo para especificar sua localização exata. Se dado como um nome de caminho relativo, o nome é interpretado em relação ao diretório em que o programa cliente foi iniciado.

Staza
fonte
2
Isso funcionou para mim e para ninguém. Eu tentei: 1. para carregar meu arquivo txt no C:\ProgramData\MySQL\MySQL Server 5.7\Uploads, 2. incapacitante secure_file_privno my.inie reiniciar mysql 3. Este! Obrigado :)
Kamal Nayan
10
Recebi esta mensagem de erro para o MariaDB: "ERRO 1148 (42000): O comando usado não é permitido com esta versão do MariaDB". A versão exata: "mysql Ver 15.1 Distrib 10.1.22-MariaDB, para Linux (x86_64) usando o readline 5.2"
jciloa
11
Eu recebi "O comando usado não é permitido com esta versão do MySQL" para o mysql versão 5.7.19.
Alison S
2
@AlisonS Tente adicionar a --local-infilebandeira ao executar mysql. stackoverflow.com/questions/10762239/…
Illya Moskvin
11
The used command is not allowed with this MySQL versiondo MySQL 8.0
bitfishxyz
118

No Ubuntu 14 e Mysql 5.5.53, essa configuração parece estar ativada por padrão. Para desativá-lo, você precisa adicionar secure-file-priv = ""ao seu arquivo my.cnf no grupo de configuração do mysqld. por exemplo:-

[mysqld]
secure-file-priv = ""
Mustafa
fonte
11
Isso funcionou para mim também. Mesma versão do Ubuntu e MySQL
Rodney
11
+1 Trabalhou para mim. Se você estiver usando o Ubuntu, não se esqueça serviço mysql restart: sudo mysql serviço restart
Emiliano Sangoi
11
É isso que funciona se você precisar apontar para um local selecionado por instrução, quando aplicável. Isso funciona com o MySQL 5.7 no Windows Server, exatamente como você explicou. Se você simplesmente comentar a linha como # secure-file-priv = ~ela, ainda assim terá o erro, pois o valor é mostrado NULLdessa maneira resolve o problema quando você escolhe quais diretórios você pode exportar para o servidor etc.
Bitcoin Murderous Maniac
11
Trabalhou para mim com o MySQL 5.7 no Windows, enquanto as outras soluções não.
precisa
Nota: se estiver fazendo isso no Docker, reinicie o contêiner do Docker.
user1717828
38

Estou trabalhando no MySQL5.7.11 no Debian, o comando que funcionou para mim ver o diretório é:

mysql> SELECT @@global.secure_file_priv;
Carlos Med
fonte
Com SHOW VARIABLES LIKE "secure_file_priv";eu recebo o ERROR 1146 (42S02): Table 'performance_schema.session_variables' doesn't existque também é jogado em outras circunstâncias e, eventualmente, terei que lidar. O SELECT @@global.secure_file_priv;comando, porém, produziu o resultado esperado.
Majid Fouladpour
11
Isso funcionou para mim - Ubuntu Mysql 5.7.21: mudou o arquivo de saída para o diretório /var/lib/mysql-files/output.txt
Shanemeister
2
Como você o edita então? Eu tentei editá-lo no /etc/mysql/my.cnf e parece não ter nenhum efeito - ele permanece NULL
Slavik
25

Aqui está o que funcionou para mim no Windows 7 para desativar secure-file-priv(Opção # 2 da resposta do vhu ):

  1. Pare o serviço do servidor MySQL entrando em services.msc.
  2. Vá para C:\ProgramData\MySQL\MySQL Server 5.6( ProgramDataera uma pasta oculta no meu caso).
  3. Abra o my.iniarquivo no bloco de notas.
  4. Procure por 'secure-file-priv'.
  5. Comente a linha adicionando '#' no início da linha. Para o MySQL Server 5.7.16 e superior, os comentários não funcionarão. Você precisa configurá-lo para uma string vazia como esta -secure-file-priv=""
  6. Salve o arquivo.
  7. Inicie o serviço do servidor MySQL entrando em services.msc.
Janaaaa
fonte
16
A partir do MySQL Server 5.7.16, comentar a linha não funcionará, pois, então, voltará ao padrão, o que desabilita as operações de importação e exportação. Agora você precisa defini-lo como uma sequência vazia se desejar permitir essas operações a partir de qualquer diretório.
DBC
11
Ramnath, edite sua resposta com @dbc detail para a versão 5.7.x. Obrigado.
Rafael Gomes Francisco
Adicionar uma string vazia funciona para mim; altere a resposta para adicionar uma string vazia como secure-file-priv = ""
Rajesh Goel
Para Windows, certifique-se de usar barras invertidas
Oliver Oliver
22

Se o arquivo for local em sua máquina, use LOCAL em seu comando

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

@vhu

Eu fiz o SHOW VARIABLES LIKE "secure_file_priv";e ele retornou, C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\então quando o conectei, ele ainda não funcionava.

Quando fui diretamente para o arquivo my.ini, descobri que o caminho está formatado um pouco diferente: C:/ProgramData/MySQL/MySQL Server 8.0/Uploads

Então, quando eu corri com isso, funcionou. A única diferença é a direção das barras.

wolfsshield
fonte
sua resposta funcionou para mim, thnaks muito
benaou mouad
Sim, sim, sim ... por que essa resposta está tão abaixo? Eu lutei por muito tempo e depois consegui. Voltei para adicionar isso como resposta, mas é tão baixo que não o vi antes de perder meu tempo.
Rsc Rsc
Nem todos os heróis usam capas.
JRK
9

Eu tive o mesmo problema com 'secure-file-priv'. Comentar no arquivo .ini não funcionou e nem mover o arquivo no diretório especificado por 'secure-file-priv'.

Finalmente, como o dbc sugeriu, fazer 'secure-file-priv' igual a uma string vazia funcionou. Portanto, se alguém ficar preso depois de tentar as respostas acima, espero que isso ajude.

Rsc Rsc
fonte
9

O que funcionou para mim:

  1. Coloque seu arquivo dentro da pasta especificada em secure-file-priv.

Para encontrar esse tipo:

mysql> mostra variáveis ​​como "secure_file_priv";


  1. Verifique se você tem local_infile = 1.

Faça isso digitando:

mysql> mostra variáveis ​​como "local_infile";

Se você pegar:

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

Em seguida, defina-o como uma digitação:

mysql> define global local_infile = 1;


  1. Especifique o caminho completo para o seu arquivo. No meu caso:

mysql> carrega o infile "C: / ProgramData / MySQL / MySQL Server 8.0 / Uploads / file.txt" no teste de tabela;

Vinícius Souza
fonte
6

Este tópico foi visto 522k vezes no momento desta postagem. Honestamente, quando o MySQL se tornou nossa mãe desprotegida e irracional ? Que tentativa demorada de segurança - que realmente serve apenas para nos prender!

Depois de muitas pesquisas e muitas tentativas, tudo falhou.
Minha solução:

  1. Importe o arquivo .csv via importação do PhpMyAdmin na caixa antiga (se for grande na linha cmd)
  2. gerar um arquivo .sql
  3. baixar o arquivo .sql
  4. importar arquivo .sql via banco de trabalho MySQL
Nelles
fonte
4

Criei um script de importação do NodeJS se você estiver executando o nodeJS e seus dados estiverem no seguinte formato (aspas duplas + vírgula e \ n nova linha)

INSERT INTO <your_table> VALUEs( **CSV LINE **)

Este está configurado para ser executado em http: // localhost: 5000 / import .

Vou linha por linha e cria uma string de consulta

"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 é o arquivo de configuração

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;

Isenção de responsabilidade: Esta não é uma solução perfeita - só a estou postando para desenvolvedores que estão dentro de uma linha do tempo e têm muitos dados para importar e estão enfrentando esse problema ridículo. Perdi muito tempo com isso e espero poupar outro desenvolvedor do mesmo tempo perdido.

Nelles
fonte
3

Eu tive todos os tipos de problemas com isso. Eu estava mudando o my.cnf e todos os tipos de coisas loucas que outras versões desse problema tentaram mostrar.

O que funcionou para mim:

O erro que eu estava recebendo

The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

Consegui corrigi-lo abrindo /usr/local/mysql/support-files/mysql.server e alterando a seguinte linha:

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

para

$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=$?
notthehoff
fonte
3

Se você estiver executando no Ubuntu, também poderá ser necessário configurar o Apparmor para permitir que o MySQL grave em sua pasta, por exemplo, aqui está a minha configuração:

Adicione esta linha ao arquivo /etc/apparmor.d/usr.sbin.mysqld:

/var/lib/mysql-files/* rw

Em seguida, adicione estas 2 linhas de configuração nas seções /etc/mysql/my.cnf:

[client]
loose-local-infile = 1

[mysqld]
secure-file-priv = ""

Aqui está o meu SQL:

select id from blahs into outfile '/var/lib/mysql-files/blahs';

Funcionou para mim. Boa sorte!

Kevin Hutchinson
fonte
Sim, colocar o caminho do arquivo externo com "/var/lib/mysql-files/filename.csv" funcionou para mim.
Anidhya Bhatnagar 31/03
3

Para a versão mysql 8.0, você pode fazer o seguinte:

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

Funcionou para mim no Mac High Sierra

Ruslan Krupenko
fonte
1

Eu tive esse problema no windows 10. "--secure-file-priv no MySQL" Para resolver isso, fiz o seguinte.

  1. Na pesquisa do Windows (canto inferior esquerdo), digitei "powershell".
  2. Botão direito do mouse no PowerShell e executado como administrador.
  3. Navegado para o arquivo bin do servidor. (C: \ Arquivos de programas \ MySQL \ MySQL Server 5.6 \ bin);
  4. Digitado ./mysqld
  5. Clique em "Enter"

O servidor foi iniciado conforme o esperado.

Jason Allshorn
fonte
1

O MySQL usa essa variável de sistema para controlar onde você pode importar seus arquivos

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

Então o problema é como alterar variáveis ​​do sistema como secure_file_priv.

  1. desligar mysqld
  2. sudo mysqld_safe --secure_file_priv=""

agora você pode ver assim:

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

No macOS Catalina, segui estas etapas para definir secure_file_priv

1.Pare o serviço MySQL

 sudo /usr/local/mysql/support-files/mysql.server stop

2.Reinicie a atribuição do MYSQL às variáveis ​​de sistema --secure_file_priv

sudo /usr/local/mysql/support-files/mysql.server start --secure-file-priv=YOUR_FILE_DIRECTORY

Nota: Adicionar valor vazio corrige o problema para mim, e o MYSQL exportará dados para o diretório / usr / local / mysql / data / YOUR_DB_TABLE / EXPORT_FILE

sudo /usr/local/mysql/support-files/mysql.server start --secure-file-priv=

obrigado

Sushil Adhikari
fonte
0

Sem alterar nenhum dos arquivos de configuração.

  1. olhar para o valor secure_file_privusando o comando postado por @vhu: SHOW VARIABLES LIKE "secure_file_priv".
  2. defina o caminho completo para sua consulta, como: select * from table into outfile 'secure_file_priv_PATH/OUTPUT-FILE' ... rest of your query

isso funcionou para o meu no mysql-shell no ubuntu 18.04 LTS mysql 5.7.29

user2804070
fonte