Comment dois-je gérer --secure-file-priv dans MySQL?

358

J'apprends MySQL et j'ai essayé d'utiliser une LOAD DATAclause. Quand je l'ai utilisé comme ci-dessous:

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

J'ai eu l'erreur suivante:

Le serveur MySQL fonctionne avec l'option --secure-file-priv, il ne peut donc pas exécuter cette instruction

Comment puis-je résoudre cette erreur?

J'ai vérifié une autre question sur le même message d'erreur , mais je ne trouve toujours pas de solution.

J'utilise MySQL 5.6

Mohit Bhasi
la source
partager le chemin de votre fichier csv
Zafar Malik
1
Bien sûr, vous obtenez cette erreur lorsque vous essayez d'utiliser mysqldump --tab, comme si ce n'était pas assez difficile d'extraire vos propres données de mysql.
William Entriken
1
en plus de la réponse de vhu, recherchez ci-dessous la réponse de wolfsshield. vous devez basculer sur '/' pour le faire fonctionner (j'utilise win10)
Rsc Rsc
4
utilisez LOCAL. LOAD DATA LOCAL INFILE ...
mpoletto

Réponses:

474

Cela fonctionne comme prévu. Votre serveur MySQL a été démarré avec l' option --secure-file-priv qui limite essentiellement les répertoires à partir desquels vous pouvez charger des fichiers en utilisantLOAD DATA INFILE .

Vous pouvez utiliser SHOW VARIABLES LIKE "secure_file_priv";pour voir le répertoire qui a été configuré.

Vous avez deux options:

  1. Déplacez votre fichier vers le répertoire spécifié par secure-file-priv.
  2. Désactiver secure-file-priv. Cela doit être supprimé du démarrage et ne peut pas être modifié dynamiquement. Pour ce faire, vérifiez vos paramètres de démarrage MySQL (selon la plate-forme) et my.ini.
vhu
la source
4
Par défaut, my.ini se trouve dans "C: \ ProgramData \ MySQL \ MySQL Server 5.6" lors de l'exécution de MySQL 5.6 sur le serveur W2012. Vous pouvez également vérifier les paramètres de démarrage du service (par exemple, --defaults-file = "C: \ ProgramData \ MySQL \ MySQL Server 5.6 \ my.ini) car ils peuvent également s'afficher eux- --secure-file-privmêmes.
vhu
2
@Mohitbhasi, my-default.ini doit se trouver dans le dossier "C: \ Program Files \ MySQL \ MySQL Server 5.6". L'emplacement auquel vhu faisait référence est "C: \ ProgramData \ MySQL \ MySQL Server 5.6". Juste au cas où vous ne l'auriez pas remarqué.
NurShomik
67
Valeur: NULL. FML.
William Entriken
11
Notez que si vous utilisez "select .. into outfile", vous devez spécifier le chemin complet et le chemin complet doit correspondre aux résultats deSHOW VARIABLES LIKE "secure_file_priv";
TheSatinKnight
9
"vérifier les paramètres" et "vérifier mon.ini" n'est pas une très bonne réponse
Roland Seuhs
234

J'ai eu le même problème. J'ai finalement résolu en utilisant l' LOCALoption de la commande

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

Vous pouvez trouver plus d'informations ici http://dev.mysql.com/doc/refman/5.7/en/load-data.html

Si LOCAL est spécifié, le fichier est lu par le programme client sur l'hôte client et envoyé au serveur. Le fichier peut être donné sous la forme d'un nom de chemin complet pour spécifier son emplacement exact. S'il est donné en tant que nom de chemin relatif, le nom est interprété par rapport au répertoire dans lequel le programme client a été démarré.

Staza
la source
2
Cela a fonctionné pour moi et personne d'autre. J'ai essayé: 1. télécharger mon fichier txt C:\ProgramData\MySQL\MySQL Server 5.7\Uploads, 2. la désactivation secure_file_privdans my.iniet redémarrer mysql 3. Celui - ci! Merci :)
Kamal Nayan
10
J'ai reçu ce message d'erreur pour MariaDB: "ERREUR 1148 (42000): La commande utilisée n'est pas autorisée avec cette version de MariaDB". La version exacte: "mysql Ver 15.1 Distrib 10.1.22-MariaDB, pour Linux (x86_64) utilisant readline 5.2"
jciloa
11
J'ai obtenu "La commande utilisée n'est pas autorisée avec cette version de MySQL" pour la version 5.7.19 de mysql.
Alison S
2
@AlisonS Essayez d'ajouter le --local-infiledrapeau lors de l'exécution mysql. stackoverflow.com/questions/10762239/…
Illya Moskvin
1
The used command is not allowed with this MySQL versionde MySQL 8.0
bitfishxyz
118

Sur Ubuntu 14 et Mysql 5.5.53, ce paramètre semble être activé par défaut. Pour le désactiver, vous devez l'ajouter secure-file-priv = ""à votre fichier my.cnf sous le groupe de configuration mysqld. par exemple:-

[mysqld]
secure-file-priv = ""
Mustafa
la source
1
Cela a également fonctionné pour moi. Même version d'Ubuntu et MySQL
Rodney
1
+1 A fonctionné pour moi. Si vous utilisez Ubuntu, n'oubliez pas de redémarrer le service mysql: sudo service mysql restart
Emiliano Sangoi
1
C'est ce qui fonctionne si vous en avez besoin pour pointer vers un emplacement que vous sélectionnez par instruction, le cas échéant. Cela fonctionne avec MySQL 5.7 sur Windows Server, comme vous l'avez expliqué. Si vous commentez simplement la ligne comme # secure-file-priv = ~cela, alors elle a toujours l'erreur car la valeur indique que le NULLfait de cette façon résout le problème lorsque vous souhaitez choisir les répertoires vers lesquels vous pouvez exporter sur le serveur, etc.
Bitcoin Murderous Maniac
1
Fonctionné pour moi avec MySQL 5.7 sur Windows, contrairement aux autres solutions.
CGritton
NB: si vous faites cela dans Docker, vous devez redémarrer le conteneur Docker.
user1717828
38

Je travaille sur MySQL5.7.11 sur Debian, la commande qui a fonctionné pour moi pour voir le répertoire est:

mysql> SELECT @@global.secure_file_priv;
Carlos Med
la source
Avec SHOW VARIABLES LIKE "secure_file_priv";je reçois ERROR 1146 (42S02): Table 'performance_schema.session_variables' doesn't existce qui est également jeté dans d'autres circonstances et je devrai éventuellement y faire face. La SELECT @@global.secure_file_priv;commande a cependant produit le résultat attendu.
Majid Fouladpour
1
Cela a fonctionné pour moi - Ubuntu Mysql 5.7.21: a changé le fichier de sortie en répertoire /var/lib/mysql-files/output.txt
Shanemeister
2
Comment l'éditez-vous alors? J'ai essayé de le modifier dans /etc/mysql/my.cnf et cela semble n'avoir aucun effet - il reste NULL
Slavik
25

Voici ce qui a fonctionné pour moi dans Windows 7 pour désactiver secure-file-priv(Option # 2 de la réponse de vhu ):

  1. Arrêtez le service serveur MySQL en entrant services.msc.
  2. Allez dans C:\ProgramData\MySQL\MySQL Server 5.6( ProgramDataétait un dossier caché dans mon cas).
  3. Ouvrez le my.inifichier dans le bloc-notes.
  4. Recherchez «secure-file-priv».
  5. Mettez la ligne en commentaire en ajoutant «#» au début de la ligne. Pour MySQL Server 5.7.16 et supérieur, les commentaires ne fonctionneront pas. Vous devez le définir sur une chaîne vide comme celle-ci -secure-file-priv=""
  6. Enregistrez le fichier.
  7. Démarrez le service serveur MySQL en allant dans services.msc.
Janaaaa
la source
16
À partir de MySQL Server 5.7.16, la mise en commentaire de la ligne ne fonctionnera pas, car elle reviendra alors à la valeur par défaut, ce qui désactive les opérations d'importation et d'exportation. Vous devez maintenant le définir sur une chaîne vide si vous souhaitez autoriser ces opérations à partir de n'importe quel répertoire.
dbc
1
Ramnath, veuillez modifier votre réponse avec @dbc detail pour la version 5.7.x. Merci.
Rafael Gomes Francisco
L'ajout d'une chaîne vide fonctionne pour moi; veuillez modifier la réponse pour ajouter une chaîne vide comme secure-file-priv = ""
Rajesh Goel
Pour Windows, assurez-vous d'utiliser des barres obliques
Oliver Oliver
22

Si le fichier est local sur votre ordinateur, utilisez LOCAL dans votre commande

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

@vhu

Je l'ai fait SHOW VARIABLES LIKE "secure_file_priv";et il est revenuC:\ProgramData\MySQL\MySQL Server 8.0\Uploads\ donc quand je l'ai branché, ça n'a toujours pas fonctionné.

Lorsque je suis allé directement dans le fichier my.ini, j'ai découvert que le chemin était formaté un peu différemment: C:/ProgramData/MySQL/MySQL Server 8.0/Uploads

Puis quand je l'ai couru avec ça, ça a marché. La seule différence étant la direction des barres obliques.

Wolfsshield
la source
votre réponse a fonctionné pour moi, thnaks beaucoup
benaou mouad
Oui oui oui ... pourquoi cette réponse est-elle si loin ci-dessous. j'ai lutté pendant longtemps et je l'ai eu. Je suis revenu pour ajouter ceci comme réponse mais c'est tellement bas que je ne l'ai pas vu avant de perdre mon temps.
Rsc Rsc
Les héros ne portent pas tous des capes.
JRK
9

J'ai eu le même problème avec 'secure-file-priv'. Les commentaires dans le fichier .ini n'ont pas fonctionné et le déplacement du fichier dans le répertoire spécifié par 'secure-file-priv' n'a pas fonctionné non plus.

Enfin, comme suggéré par dbc, faire en sorte que 'secure-file-priv' soit égal à une chaîne vide fonctionne. Donc, si quelqu'un est coincé après avoir essayé les réponses ci-dessus, j'espère que cela vous aidera.

Rsc Rsc
la source
9

La chose qui a fonctionné pour moi:

  1. Placez votre fichier dans le dossier spécifié dans secure-file-priv.

Pour trouver ce type:

mysql> afficher des variables comme "secure_file_priv";


  1. Vérifiez si vous en avez local_infile = 1.

Faites cette saisie:

mysql> afficher des variables comme "local_infile";

Si vous obtenez:

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

Ensuite, définissez-le sur une saisie:

mysql> set global local_infile = 1;


  1. Spécifiez le chemin complet de votre fichier. Dans mon cas:

mysql> charger le fichier de données "C: / ProgramData / MySQL / MySQL Server 8.0 / Uploads / file.txt" dans le test de table;

Vinícius Souza
la source
6

Ce fil a été vu 522k fois au moment de cet article. Honnêtement, quand MySQL est-elle devenue notre maman déraisonnable et trop protectrice ? Quelle longue tentative de sécurité - qui ne fait que nous enchaîner!

Après de nombreuses recherches et de nombreuses tentatives, tout a échoué.
Ma solution:

  1. Importez le fichier .csv via l'importation PhpMyAdmin sur une boîte plus ancienne (si la taille est importante sur la ligne cmd)
  2. générer un fichier .sql
  3. télécharger le fichier .sql
  4. importer un fichier .sql via le banc de travail MySQL
Nelles
la source
4

J'ai créé un script d'importation NodeJS si vous exécutez nodeJS et que vos données sont sous la forme suivante (guillemet double + virgule et \ n nouvelle ligne)

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

Celui-ci est configuré pour s'exécuter sur http: // localhost: 5000 / import .

Je vais ligne par ligne et crée une chaîne de requête

"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 est le fichier de configuration

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;

Avertissement: Ce n'est pas une solution parfaite - je ne le publie que pour les développeurs qui ont un calendrier et ont beaucoup de données à importer et qui rencontrent ce problème ridicule. J'ai perdu beaucoup de temps à ce sujet et j'espère épargner à un autre développeur le même temps perdu.

Nelles
la source
3

J'ai eu toutes sortes de problèmes avec ça. Je modifiais my.cnf et toutes sortes de choses folles que d'autres versions de ce problème essayaient de montrer.

Ce qui a fonctionné pour moi:

L'erreur que j'obtenais

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

J'ai pu le réparer en ouvrant /usr/local/mysql/support-files/mysql.server et en changeant la ligne suivante:

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

Si vous utilisez Ubuntu, vous devrez peut-être également configurer Apparmor pour autoriser MySQL à écrire dans votre dossier, par exemple voici ma configuration:

Ajoutez cette ligne au fichier /etc/apparmor.d/usr.sbin.mysqld:

/var/lib/mysql-files/* rw

Ajoutez ensuite ces 2 lignes de configuration aux sections /etc/mysql/my.cnf:

[client]
loose-local-infile = 1

[mysqld]
secure-file-priv = ""

Voici mon SQL:

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

Ça a marché pour moi. Bonne chance!

Kevin Hutchinson
la source
Oui, mettre le chemin du fichier de sortie avec "/var/lib/mysql-files/filename.csv" a fonctionné pour moi.
Anidhya Bhatnagar
3

Pour la version mysql 8.0, vous pouvez faire ceci:

  1. arrêt mysql.server
  2. mysql.server start --secure-file-priv = ''

Cela a fonctionné pour moi sur Mac High Sierra

Ruslan Krupenko
la source
1

J'ai eu ce problème sur Windows 10. "--secure-file-priv dans MySQL" Pour résoudre ce problème, j'ai fait ce qui suit.

  1. Dans la recherche Windows (en bas à gauche), j'ai tapé "powershell".
  2. Clic droit sur PowerShell et a couru en tant qu'administrateur.
  3. Accédé au fichier bin du serveur. (C: \ Program Files \ MySQL \ MySQL Server 5.6 \ bin);
  4. Tapé ./mysqld
  5. Appuyez sur "Entrée"

Le serveur a démarré comme prévu.

Jason Allshorn
la source
1

MySQL utilise cette variable système pour contrôler où vous pouvez importer vos fichiers

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

Le problème est donc de savoir comment modifier les variables système telles que secure_file_priv.

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

maintenant vous pouvez voir comme ceci:

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

Chez macOS Catalina, j'ai suivi ces étapes pour définir secure_file_priv

1.Arrêtez le service MySQL

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

2.Redémarrez MYSQL en affectant les variables système --secure_file_priv

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

Remarque: l'ajout d'une valeur vide résout le problème pour moi et MYSQL exportera les données vers le répertoire / usr / local / mysql / data / YOUR_DB_TABLE / EXPORT_FILE

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

Merci

Sushil Adhikari
la source
0

Sans modifier aucun des fichiers de configuration ..

  1. recherchez la valeur de l' secure_file_privaide de la commande affichée par @vhu: SHOW VARIABLES LIKE "secure_file_priv".
  2. définir le chemin complet de votre requête tel que: select * from table into outfile 'secure_file_priv_PATH/OUTPUT-FILE' ... rest of your query

cela a fonctionné pour mon dans mysql-shell sur ubuntu 18.04 LTS mysql 5.7.29

user2804070
la source