Jak mam rozwiązać problem --secure-file-priv w MySQL?

357

Uczę się MySQL i próbowałem użyć LOAD DATAklauzuli. Kiedy użyłem go jak poniżej:

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

Wystąpił następujący błąd:

Serwer MySQL działa z opcją --secure-file-priv, więc nie może wykonać tej instrukcji

Jak rozwiązać ten błąd?

Sprawdziłem inne pytanie dotyczące tego samego komunikatu o błędzie , ale nadal nie mogę znaleźć rozwiązania.

Korzystam z MySQL 5.6

Mohit Bhasi
źródło
udostępnij ścieżkę pliku csv
Zafar Malik
1
Oczywiście ten błąd pojawia się przy próbie użycia mysqldump --tab, jakby nie było wystarczająco trudno wyciągnąć własne dane z mysql.
William Entriken,
1
oprócz odpowiedzi vhu wyszukaj poniżej odpowiedź wolfsshield. musisz przełączyć na '/', aby działało (używam win10)
Rsc Rsc
4
użyj LOKALNIE. LOAD DATA LOCAL INFILE ...
mpoletto,

Odpowiedzi:

473

Działa zgodnie z przeznaczeniem. Twój serwer MySQL został uruchomiony z opcją --secure-file-priv , która zasadniczo ogranicza, z których katalogów można ładować pliki LOAD DATA INFILE.

Możesz użyć, SHOW VARIABLES LIKE "secure_file_priv";aby zobaczyć katalog, który został skonfigurowany.

Masz dwie opcje:

  1. Przenieś plik do katalogu określonego przez secure-file-priv.
  2. Wyłącz secure-file-priv. Trzeba to usunąć ze startu i nie można go dynamicznie modyfikować. W tym celu sprawdź parametry startowe MySQL (w zależności od platformy) i my.ini.
vhu
źródło
4
Domyślnie my.ini można znaleźć w „C: \ ProgramData \ MySQL \ MySQL Server 5.6”, gdy uruchomisz MySQL 5.6 na serwerze W2012. Możesz także sprawdzić parametry uruchamiania usługi (np. --Defaults-file = "C: \ ProgramData \ MySQL \ MySQL Server 5.6 \ my.ini), ponieważ mogą one również --secure-file-privsame listę .
vhu
2
@Mohitbhasi, my-default.ini powinien znajdować się w folderze „C: \ Program Files \ MySQL \ MySQL Server 5.6”. Lokalizacja, do której odnosi się vhu, to „C: \ ProgramData \ MySQL \ MySQL Server 5.6”. Na wypadek, gdybyś tego nie zauważył.
NurShomik
67
Wartość: NULL. FML.
William Entriken,
11
Zauważ, że jeśli używasz „select .. do outfile”, musisz podać pełną ścieżkę, a pełna ścieżka musi pasować do wynikówSHOW VARIABLES LIKE "secure_file_priv";
TheSatinKnight
9
„sprawdź parametry” i „sprawdź mój.ini” nie jest zbyt dobrą odpowiedzią
Roland Seuhs
234

Miałem ten sam problem. W końcu rozwiązałem za pomocą LOCALopcji w poleceniu

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

Więcej informacji można znaleźć tutaj http://dev.mysql.com/doc/refman/5.7/en/load-data.html

Jeśli określono LOKALNY, plik jest odczytywany przez program kliencki na hoście klienta i wysyłany na serwer. Plik można podać jako pełną nazwę ścieżki, aby określić jego dokładną lokalizację. Jeśli podano jako względną nazwę ścieżki, jest ona interpretowana względem katalogu, w którym uruchomiono program kliencki.

Staza
źródło
2
To zadziałało dla mnie i dla nikogo innego. Próbowałem: 1. przesłać swój plik txt w C:\ProgramData\MySQL\MySQL Server 5.7\Uploads2. wyłączenie secure_file_privw my.inii ponowne uruchomienie bazy MySQL 3. To jeden! Dzięki :)
Kamal Nayan
10
Otrzymałem następujący komunikat o błędzie dla MariaDB: „BŁĄD 1148 (42000): Użyte polecenie jest niedozwolone w tej wersji MariaDB”. Dokładna wersja: „mysql Ver 15.1 Distrib 10.1.22-MariaDB, dla Linux (x86_64) przy użyciu readline 5.2”
jciloa
11
Dostałem „Użyte polecenie nie jest dozwolone w tej wersji MySQL” dla mysql w wersji 5.7.19.
Alison S
2
@AlisonS Spróbuj dodać --local-infileflagę podczas uruchamiania mysql. stackoverflow.com/questions/10762239/…
Illya Moskvin
1
The used command is not allowed with this MySQL versionz MySQL 8.0
bitfishxyz
117

W Ubuntu 14 i Mysql 5.5.53 to ustawienie wydaje się być domyślnie włączone. Aby go wyłączyć, musisz dodać secure-file-priv = ""do pliku my.cnf w grupie konfiguracyjnej mysqld. na przykład:-

[mysqld]
secure-file-priv = ""
Mustafa
źródło
1
To również działało dla mnie. Ta sama wersja Ubuntu i MySQL
Rodney,
1
+1 Pracował dla mnie. Jeśli używasz Ubuntu, nie zapomnij restartu usługi mysql: mysql sudo service restart
Emiliano Sangoi
1
To działa, jeśli potrzebujesz, aby wskazać lokalizację wybraną według instrukcji, jeśli ma to zastosowanie. Działa to z MySQL 5.7 w systemie Windows Server, tak jak wyjaśniono. Jeśli po prostu skomentujesz wiersz w taki sposób, # secure-file-priv = ~to nadal występuje błąd, ponieważ wartość pokazuje, że NULLwykonanie tego w ten sposób rozwiązuje problem, gdy chcesz wybrać, do których katalogów możesz wyeksportować na serwer itp.
Bitcoin Murderous Maniac
1
Pracował dla mnie z MySQL 5.7 w systemie Windows, podczas gdy inne rozwiązania nie.
CGritton,
Uwaga: jeśli robisz to w Docker, musisz ponownie uruchomić kontener Docker.
user1717828,
38

Pracuję nad MySQL5.7.11 na Debianie, polecenie, które działało dla mnie, aby zobaczyć katalog to:

mysql> SELECT @@global.secure_file_priv;
Carlos Med
źródło
Z SHOW VARIABLES LIKE "secure_file_priv";dostaję, ERROR 1146 (42S02): Table 'performance_schema.session_variables' doesn't existktóry jest również rzucany w innych okolicznościach i będę musiał w końcu sobie poradzić. SELECT @@global.secure_file_priv;Komenda choć produkowane oczekiwanego rezultatu.
Majid Fouladpour
1
To zadziałało dla mnie - Ubuntu Mysql 5.7.21: zmieniłem plik wyjściowy na katalog /var/lib/mysql-files/output.txt
Shanemeister
2
Jak to wtedy edytować? Próbowałem edytować w /etc/mysql/my.cnf i wydaje się, że nie ma to żadnego efektu - pozostaje NULL
Slavik
24

Oto, co działało dla mnie w Windows 7, aby wyłączyć secure-file-priv(Opcja nr 2 z odpowiedzi vhu ):

  1. Zatrzymaj usługę serwera MySQL, wchodząc do services.msc.
  2. Idź do C:\ProgramData\MySQL\MySQL Server 5.6( ProgramDataw moim przypadku był to ukryty folder).
  3. Otwórz my.iniplik w Notatniku.
  4. Wyszukaj „secure-file-priv”.
  5. Skomentuj linię, dodając „#” na początku linii. W MySQL Server 5.7.16 i nowszych komentarze nie będą działać. Musisz ustawić pusty ciąg znaków taki jak ten -secure-file-priv=""
  6. Zapisz plik.
  7. Uruchom usługę serwera MySQL, wchodząc do services.msc.
Janaaaa
źródło
16
Począwszy od MySQL Server 5.7.16, komentowanie linii nie będzie działać, ponieważ wtedy powróci do wartości domyślnej, co wyłącza operacje importu i eksportu. Musisz teraz ustawić pusty ciąg, jeśli chcesz zezwolić na te operacje z dowolnego katalogu.
dbc
1
Ramnath, edytuj swoją odpowiedź ze szczegółami @dbc dla wersji 5.7.x. Dzięki.
Rafael Gomes Francisco
Dodanie pustego ciągu działa dla mnie; zmień odpowiedź, aby dodać pusty ciąg, taki jak secure-file-priv = ""
Rajesh Goel
W systemie Windows użyj ukośników
Oliver Oliver
22

Jeśli plik jest lokalny dla twojego komputera, użyj LOCAL w swoim poleceniu

LOAD DATA LOCAL INFILE "text.txt" INTO table mytable;
garyrgilbert
źródło
14

@vhu

Zrobiłem SHOW VARIABLES LIKE "secure_file_priv";i to wróciło, C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\więc kiedy to podłączyłem, nadal nie działało.

Kiedy poszedłem bezpośrednio do pliku my.ini, odkryłem, że ścieżka jest sformatowana nieco inaczej: C:/ProgramData/MySQL/MySQL Server 8.0/Uploads

Potem, kiedy to uruchomiłem, zadziałało. Jedyną różnicą jest kierunek cięć.

wolfsshield
źródło
Twoja odpowiedź zadziałała dla mnie, bardzo
dziękuję
Tak tak tak ... dlaczego ta odpowiedź jest tak daleko poniżej. walczyłem przez długi czas, a potem go dostałem. wróciłem, by dodać to jako odpowiedź, ale jest tak daleko, że nie widziałem tego przed zmarnowaniem czasu.
Rsc Rsc
Nie wszyscy bohaterowie noszą peleryny.
JRK
8

Miałem ten sam problem z programem „secure-file-priv”. Komentowanie w pliku .ini nie działało, podobnie jak przenoszenie pliku do katalogu określonego przez „secure-file-priv”.

Wreszcie, zgodnie z sugestią dbc, działało „bezpieczne-plik-prywatny” równy pustemu ciągowi znaków. Więc jeśli ktoś utknie po wypróbowaniu powyższych odpowiedzi, mam nadzieję, że zrobienie tego pomoże.

Rsc Rsc
źródło
8

Rzecz, która zadziałała dla mnie:

  1. Umieść plik w folderze określonym w secure-file-priv.

Aby znaleźć ten typ:

mysql> pokaż zmienne takie jak „secure_file_priv”;


  1. Sprawdź, czy masz local_infile = 1.

Zrób to wpisując:

mysql> pokaż zmienne takie jak „local_infile”;

Jeśli dostaniesz:

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

Następnie ustaw jedną literę:

mysql> set global local_infile = 1;


  1. Podaj pełną ścieżkę do pliku. W moim przypadku:

mysql> ładuj infiltrację danych „C: / ProgramData / MySQL / MySQL Server 8.0 / Uploads / file.txt” do testu tabeli;

Vinícius Souza
źródło
6

Ten wątek był oglądany 522k razy w czasie tego postu. Szczerze mówiąc, kiedy MySQL stała się naszą nadmiernie opiekuńczą nieracjonalną mamą ? Cóż za czasochłonna próba bezpieczeństwa - która tak naprawdę służy jedynie do kajdan!

Po wielu poszukiwaniach i wielu próbach wszystko się nie udało.
Moje rozwiązanie:

  1. Zaimportuj plik .csv za pomocą importu PhpMyAdmin na starszym pudełku (jeśli duże zrobić w linii cmd)
  2. wygeneruj plik .sql
  3. pobierz plik .sql
  4. zaimportuj plik .sql za pośrednictwem stołu roboczego MySQL
Nelles
źródło
3

Miałem z tym różnego rodzaju problemy. Zmieniłem mój.cnf i wszelkiego rodzaju szalone rzeczy, które inne wersje tego problemu próbowały pokazać.

Co dla mnie zadziałało:

Wystąpił błąd

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

Byłem w stanie to naprawić, otwierając /usr/local/mysql/support-files/mysql.server i zmieniając następujący wiersz:

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

do

$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=$?
nie
źródło
3

Jeśli korzystasz z Ubuntu, być może będziesz musiał skonfigurować Apparmor, aby umożliwić MySQL zapisywanie w twoim folderze, np. Oto moja konfiguracja:

Dodaj tę linię do pliku /etc/apparmor.d/usr.sbin.mysqld:

/var/lib/mysql-files/* rw

Następnie dodaj te 2 wiersze konfiguracji do sekcji /etc/mysql/my.cnf:

[client]
loose-local-infile = 1

[mysqld]
secure-file-priv = ""

Oto mój SQL:

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

To zadziałało dla mnie. Powodzenia!

Kevin Hutchinson
źródło
Tak, umieszczenie ścieżki wyjściowej za pomocą „/var/lib/mysql-files/filename.csv” działało dla mnie.
Anidhya Bhatnagar
3

W przypadku wersji mysql 8.0 możesz to zrobić:

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

To działało dla mnie na Mac High Sierra

Ruslan Krupenko
źródło
3

Utworzyłem skrypt importu NodeJS, jeśli korzystasz z nodeJS, a dane są w następującej formie (podwójny cudzysłów + przecinek i \ n nowa linia)

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

Ten jest skonfigurowany do działania na http: // localhost: 5000 / import .

Idę linia po linii i tworzy ciąg zapytania

"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 to plik konfiguracyjny

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;

Oświadczenie: To nie jest idealne rozwiązanie - publikuję je tylko dla programistów, którzy są na osi czasu i mają wiele danych do zaimportowania i napotykają ten absurdalny problem. Straciłem na tym dużo czasu i mam nadzieję zaoszczędzić innemu twórcy tyle samo straconego czasu.

Nelles
źródło
1

Miałem ten problem w systemie Windows 10. „--secure-file-priv w MySQL” Aby rozwiązać ten problem, wykonałem następujące czynności.

  1. W wyszukiwaniu okien (lewy dolny róg) wpisałem „powershell”.
  2. Kliknij prawym przyciskiem myszy na PowerShell i uruchomiony jako administrator.
  3. Przejdź do pliku bin serwera. (C: \ Program Files \ MySQL \ MySQL Server 5.6 \ bin);
  4. Wpisany ./mysqld
  5. Wciśnij Enter"

Serwer uruchomił się zgodnie z oczekiwaniami.

Jason Allshorn
źródło
1

MySQL używa tej zmiennej systemowej, aby kontrolować, gdzie można importować pliki

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

Problem polega na tym, jak zmienić zmienne systemowe, takie jak secure_file_priv.

  1. zamknąć mysqld
  2. sudo mysqld_safe --secure_file_priv=""

teraz możesz zobaczyć tak:

mysql> SHOW VARIABLES LIKE "secure_file_priv";
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_file_priv |       |
+------------------+-------+
bitfishxyz
źródło
0

W macOS Catalina wykonałem te kroki, aby ustawić secure_file_priv

1. Zatrzymaj usługę MySQL

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

2. Zrestartuj MYSQL przypisując zmienne systemowe --secure_file_priv

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

Uwaga: Dodanie pustej wartości rozwiązuje problem dla mnie, a MYSQL wyeksportuje dane do katalogu / usr / local / mysql / data / YOUR_DB_TABLE / EXPORT_FILE

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

Dzięki

Sushil Adhikari
źródło
0

Bez zmiany plików konfiguracyjnych ..

  1. spojrzenie na wartości secure_file_privza pomocą polecenia wysłane przez @vhu: SHOW VARIABLES LIKE "secure_file_priv".
  2. zdefiniuj pełną ścieżkę do zapytania, na przykład: select * from table into outfile 'secure_file_priv_PATH/OUTPUT-FILE' ... rest of your query

działało to dla mnie w mysql-shell na Ubuntu 18.04 LTS mysql 5.7.29

użytkownik2804070
źródło