Bagaimana saya menangani --secure-file-priv di MySQL?

358

Saya belajar MySQL dan mencoba menggunakan LOAD DATAklausa. Ketika saya menggunakannya seperti di bawah ini:

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

Saya mendapat kesalahan berikut:

Server MySQL berjalan dengan opsi --secure-file-priv sehingga tidak dapat menjalankan pernyataan ini

Bagaimana cara mengatasi kesalahan ini?

Saya telah memeriksa pertanyaan lain pada pesan kesalahan yang sama , tetapi masih tidak dapat menemukan solusi.

Saya menggunakan MySQL 5.6

Mohit Bhasi
sumber
bagikan path file csv Anda
Zafar Malik
1
Tentu saja, Anda mendapatkan kesalahan ini ketika mencoba menggunakan mysqldump --tab, seolah-olah itu tidak cukup sulit untuk mendapatkan data Anda sendiri dari mysql.
William Entriken
1
selain jawaban vhu, cari di bawah untuk jawaban wolfsshield. Anda perlu beralih ke '/' untuk membuatnya bekerja (saya menggunakan win10)
Rsc Rsc
4
gunakan LOKAL. LOAD DATA LOCAL INFILE ...
mpoletto

Jawaban:

474

Ini berfungsi sebagaimana dimaksud. Server MySQL Anda telah dimulai dengan opsi --secure-file-priv yang pada dasarnya membatasi direktori mana Anda dapat memuat file LOAD DATA INFILE.

Anda dapat menggunakan SHOW VARIABLES LIKE "secure_file_priv";untuk melihat direktori yang telah dikonfigurasi.

Anda memiliki dua opsi:

  1. Pindahkan file Anda ke direktori yang ditentukan oleh secure-file-priv.
  2. Nonaktifkan secure-file-priv. Ini harus dihapus dari startup dan tidak dapat dimodifikasi secara dinamis. Untuk melakukan ini, periksa parameter memulai MySQL Anda (tergantung pada platform) dan my.ini.
vhu
sumber
4
Secara default my.ini dapat ditemukan dari "C: \ ProgramData \ MySQL \ MySQL Server 5.6" saat menjalankan MySQL 5.6 di server W2012. Anda mungkin juga ingin memeriksa parameter startup layanan (mis. --Defaults-file = "C: \ ProgramData \ MySQL \ MySQL Server 5.6 \ my.ini) karena mereka mungkin juga mendaftar --secure-file-privsendiri.
vhu
2
@Mohitbhasi, my-default.ini harus berada di folder "C: \ Program Files \ MySQL \ MySQL Server 5.6". Lokasi yang dimaksud adalah "C: \ ProgramData \ MySQL \ MySQL Server 5.6". Untuk berjaga-jaga jika Anda belum menyadarinya.
NurShomik
67
Nilai: NULL. FML.
William Entriken
11
Perhatikan bahwa jika menggunakan "select .. into outfile" Anda harus menentukan path lengkap dan path lengkap harus sesuai dengan hasilSHOW VARIABLES LIKE "secure_file_priv";
TheSatinKnight
9
"periksa parameter" dan "periksa my.ini" bukan jawaban yang sangat bagus
Roland Seuhs
234

Saya memiliki masalah yang sama. Saya akhirnya dipecahkan menggunakan LOCALopsi dalam perintah

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

Anda dapat menemukan info lebih lanjut di sini http://dev.mysql.com/doc/refman/5.7/en/load-data.html

Jika LOCAL ditentukan, file dibaca oleh program klien pada host klien dan dikirim ke server. File dapat diberikan sebagai nama path lengkap untuk menentukan lokasi pastinya. Jika diberikan sebagai nama jalur relatif, nama tersebut ditafsirkan relatif terhadap direktori di mana program klien dimulai.

Staza
sumber
2
Ini bekerja untuk saya dan tidak lain. Saya mencoba: 1. untuk meng-upload file txt saya di C:\ProgramData\MySQL\MySQL Server 5.7\Uploads, 2. menonaktifkan secure_file_privdi my.inidan restart mysql 3. satu ini! Terima kasih :)
Kamal Nayan
10
Saya mendapat pesan kesalahan ini untuk MariaDB: "ERROR 1148 (42000): Perintah yang digunakan tidak diizinkan dengan versi MariaDB ini". Versi persisnya: "mysql Ver 15.1 Distrib 10.1.22-MariaDB, untuk Linux (x86_64) menggunakan readline 5.2"
jciloa
11
Saya mendapat "Perintah yang digunakan tidak diizinkan dengan versi MySQL ini" untuk mysql versi 5.7.19.
Alison S
2
@AlisonS Coba tambahkan --local-infilebendera saat berjalan mysql. stackoverflow.com/questions/10762239/...
Illya Moskvin
1
The used command is not allowed with this MySQL versiondari MySQL 8.0
bitfishxyz
118

Pada Ubuntu 14 dan Mysql 5.5.53 pengaturan ini tampaknya diaktifkan secara default. Untuk menonaktifkannya, Anda perlu menambahkan secure-file-priv = ""file my.cnf Anda di bawah grup konfigurasi mysqld. misalnya:-

[mysqld]
secure-file-priv = ""
Mustafa
sumber
1
Ini juga bekerja untuk saya. Versi Ubuntu dan MySQL yang sama
Rodney
1
+1 Berfungsi untuk saya. Jika Anda menggunakan Ubuntu, jangan lupa restart layanan mysql: sudo service mysql restart
Emiliano Sangoi
1
Inilah yang berfungsi jika Anda membutuhkannya untuk menunjuk ke lokasi yang Anda pilih per pernyataan yang berlaku. Ini berfungsi dengan MySQL 5.7 di Windows Server seperti yang Anda jelaskan. Jika Anda cukup berkomentar seperti # secure-file-priv = ~itu masih memiliki kesalahan karena nilainya menunjukkan bahwa NULLmelakukannya dengan cara ini menyelesaikan masalah ketika Anda ingin memilih direktori mana yang dapat Anda ekspor ke server, dll.
Bitcoin Murderous Maniac
1
Bekerja untuk saya dengan MySQL 5.7 di Windows, sedangkan solusi lain tidak.
CGritton
NB: jika melakukan ini di Docker Anda harus memulai kembali wadah Docker.
user1717828
38

Saya sedang mengerjakan MySQL5.7.11 di Debian, perintah yang berhasil bagi saya untuk melihat direktori adalah:

mysql> SELECT @@global.secure_file_priv;
Carlos Med
sumber
Dengan SHOW VARIABLES LIKE "secure_file_priv";saya mendapatkan ERROR 1146 (42S02): Table 'performance_schema.session_variables' doesn't existyang juga dilemparkan dalam keadaan lain dan saya akhirnya harus berurusan dengan. The SELECT @@global.secure_file_priv;perintah meskipun menghasilkan hasil yang diharapkan.
Majid Fouladpour
1
Ini berhasil bagi saya - Ubuntu Mysql 5.7.21: mengubah file output ke direktori
/var/lib/mysql-files/output.txt
2
Bagaimana Anda mengeditnya? Saya mencoba mengeditnya di /etc/mysql/my.cnf dan sepertinya tidak berpengaruh - tetap NULL
Slavik
25

Inilah yang bekerja untuk saya di Windows 7 untuk menonaktifkan secure-file-priv(Opsi # 2 dari jawaban vhu ):

  1. Hentikan layanan server MySQL dengan masuk ke services.msc.
  2. Pergi ke C:\ProgramData\MySQL\MySQL Server 5.6( ProgramDataadalah folder tersembunyi dalam kasus saya).
  3. Buka my.inifile di Notepad.
  4. Cari 'secure-file-priv'.
  5. Komentari baris keluar dengan menambahkan '#' di awal baris. Untuk MySQL Server 5.7.16 ke atas, komentar tidak akan berfungsi. Anda harus mengaturnya ke string kosong seperti ini -secure-file-priv=""
  6. Simpan file.
  7. Mulai layanan server MySQL dengan masuk ke services.msc.
Janaaaa
sumber
16
Pada MySQL Server 5.7.16, mengomentari baris tidak akan berfungsi, karena kemudian akan kembali ke default, yang menonaktifkan operasi impor dan ekspor. Anda sekarang perlu mengaturnya ke string kosong jika Anda ingin mengizinkan operasi ini dari direktori apa pun.
dbc
1
Ramnath, harap edit jawaban Anda dengan detail @dbc untuk versi 5.7.x. Terima kasih.
Rafael Gomes Francisco
Menambahkan string kosong berfungsi untuk saya; tolong ubah jawaban untuk menambahkan string kosong seperti secure-file-priv = ""
Rajesh Goel
Untuk Windows pastikan untuk menggunakan garis miring ke depan
Oliver Oliver
22

Jika file tersebut lokal untuk mesin Anda gunakan LOCAL dalam perintah Anda

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

@ vhu

Saya melakukan SHOW VARIABLES LIKE "secure_file_priv";dan itu kembali C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\sehingga ketika saya menghubungkannya, itu masih tidak berhasil.

Ketika saya pergi ke file my.ini secara langsung saya menemukan bahwa path diformat sedikit berbeda: C:/ProgramData/MySQL/MySQL Server 8.0/Uploads

Lalu ketika saya menjalankannya dengan itu, itu berhasil. Satu-satunya perbedaan adalah arah tebasan.

serigala
sumber
jawaban Anda berhasil untuk saya,
terima kasih
Ya ya ya ... mengapa jawaban ini sangat jauh di bawah. Saya berjuang untuk waktu yang lama dan kemudian mendapatkannya. Saya kembali untuk menambahkan ini sebagai jawaban tetapi sejauh ini saya tidak melihatnya sebelum membuang-buang waktu.
Rsc Rsc
Tidak semua pahlawan memakai jubah.
JRK
9

Saya memiliki masalah yang sama dengan 'secure-file-priv'. Mengomentari file .ini tidak berfungsi dan tidak juga memindahkan file dalam direktori yang ditentukan oleh 'secure-file-priv'.

Akhirnya, seperti yang disarankan dbc, membuat 'secure-file-priv' sama dengan string kosong berfungsi. Jadi kalau ada yang buntu setelah mencoba jawaban di atas, semoga melakukan ini akan membantu.

Rsc Rsc
sumber
9

Hal yang berhasil bagi saya:

  1. Masukkan file Anda ke dalam folder yang ditentukan secure-file-priv.

Untuk menemukan jenis itu:

mysql> tampilkan variabel seperti "secure_file_priv";


  1. Periksa apakah sudah local_infile = 1.

Lakukan pengetikan:

mysql> tampilkan variabel seperti "local_infile";

Jika Anda mendapatkan:

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

Kemudian atur menjadi satu ketikan:

mysql> set global local_infile = 1;


  1. Tentukan path lengkap untuk file Anda. Dalam hal ini:

mysql> memuat data infile "C: / ProgramData / MySQL / MySQL Server 8.0 / Uploads / file.txt" ke dalam tabel test;

Vinícius Souza
sumber
6

Utas ini telah dilihat sebanyak 522 kali pada saat posting ini. Jujur ketika MySQL menjadi ibu kami yang tidak masuk akal ? Upaya keamanan yang menghabiskan waktu - yang benar-benar hanya berfungsi untuk membelenggu kita!

Setelah banyak pencarian dan banyak upaya semuanya gagal.
Solusi saya:

  1. Impor file .csv melalui impor PhpMyAdmin pada kotak yang lebih lama (jika besar lakukan di cmd line)
  2. menghasilkan file .sql
  3. unduh file .sql
  4. impor file .sql melalui bangku kerja MySQL
Nelles
sumber
4

Saya membuat skrip impor NodeJS jika Anda menjalankan nodeJS dan data Anda dalam bentuk berikut (penawaran ganda + koma dan \ n baris baru)

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

Yang ini dikonfigurasi untuk berjalan di http: // localhost: 5000 / import .

Saya pergi baris demi baris dan membuat string kueri

"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 adalah file konfigurasi

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;

Penafian: Ini bukan solusi yang sempurna - Saya hanya mempostingnya untuk para dev yang berada di bawah timeline dan memiliki banyak data untuk diimpor dan menghadapi masalah konyol ini. Saya kehilangan banyak waktu dalam hal ini dan saya berharap untuk menyediakan dev lain pada waktu yang hilang.

Nelles
sumber
3

Saya punya banyak masalah dengan ini. Saya mengubah my.cnf dan segala macam hal gila yang coba ditunjukkan versi lain dari masalah ini.

Apa yang berhasil untuk saya:

Kesalahan yang saya dapatkan

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

Saya dapat memperbaikinya dengan membuka /usr/local/mysql/support-files/mysql.server dan mengubah baris berikut:

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

untuk

$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=$?
bukan libur
sumber
3

Jika Anda menjalankan pada Ubuntu, Anda mungkin juga perlu mengkonfigurasi Apparmor untuk memungkinkan MySQL untuk menulis ke folder Anda, misalnya inilah konfigurasi saya:

Tambahkan baris ini ke file /etc/apparmor.d/usr.sbin.mysqld:

/var/lib/mysql-files/* rw

Kemudian tambahkan 2 baris config ini ke bagian /etc/mysql/my.cnf:

[client]
loose-local-infile = 1

[mysqld]
secure-file-priv = ""

Inilah SQL saya:

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

Ini berhasil untuk saya. Semoga berhasil!

Kevin Hutchinson
sumber
Ya menempatkan path outfile dengan "/var/lib/mysql-files/filename.csv" bekerja untuk saya.
Anidhya Bhatnagar
3

Untuk versi mysql 8.0 Anda dapat melakukan ini:

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

Ini bekerja untuk saya di Mac High Sierra

Ruslan Krupenko
sumber
1

Saya punya masalah ini di windows 10. "--secure-file-priv di MySQL" Untuk menyelesaikan ini saya lakukan hal berikut.

  1. Di jendela pencarian (kiri bawah) saya mengetik "PowerShell".
  2. Klik kanan pada PowerShell dan jalankan sebagai admin.
  3. Menavigasi ke file nampan server. (C: \ Program Files \ MySQL \ MySQL Server 5.6 \ bin);
  4. Diketik ./mysqld
  5. Tekan "enter"

Server mulai seperti yang diharapkan.

Jason Allshorn
sumber
1

MySQL menggunakan variabel sistem ini untuk mengontrol di mana Anda dapat mengimpor file Anda

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

Jadi masalahnya adalah bagaimana mengubah variabel sistem seperti secure_file_priv.

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

sekarang Anda mungkin melihat seperti ini:

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

Di macOS Catalina, saya mengikuti langkah-langkah ini untuk mengatur secure_file_priv

1.Hentikan layanan MySQL

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

2. Mulai kembali penugasan MYSQL --secure_file_priv variabel sistem

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

Catatan: Menambahkan nilai kosong perbaiki masalah untuk saya, dan MYSQL akan mengekspor data ke direktori / usr / local / mysql / data / YOUR_DB_TABLE / EXPORT_FILE

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

Terima kasih

Sushil Adhikari
sumber
0

Tanpa mengubah file konfigurasi apa pun ..

  1. mencari nilai secure_file_privmenggunakan perintah diposting oleh @vhu: SHOW VARIABLES LIKE "secure_file_priv".
  2. tentukan path lengkap untuk kueri Anda seperti: select * from table into outfile 'secure_file_priv_PATH/OUTPUT-FILE' ... rest of your query

ini bekerja untuk saya di mysql-shell di ubuntu 18,04 LTS mysql 5.7.29

pengguna2804070
sumber