MySQL'de --secure-file-priv ile nasıl başa çıkmalıyım?


358

MySQL öğreniyorum ve bir LOAD DATAcümle kullanmayı denedim . Aşağıdaki gibi kullandığımda:

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

Aşağıdaki hatayı aldım:

MySQL sunucusu --secure-file-priv seçeneğiyle çalışıyor, bu nedenle bu ifadeyi yürütemiyor

Bu hatayı nasıl çözebilirim?

Aynı hata mesajında ​​başka bir soru kontrol ettim , ancak yine de bir çözüm bulamıyorum.

MySQL 5.6 kullanıyorum


csv dosyanızın paylaşım yolu
Zafar Malik

1
Tabii ki, mysqldump --tabmysql dışında kendi veri almak için yeterince zor değildi gibi kullanmaya çalışırken bu hatayı alırsınız.
William Entriken

1
vhu'nun cevabına ek olarak aşağıda wolfsshield'ın cevabını arayın. Çalıştırmak için '/' konumuna geçmeniz gerekiyor (win10 kullanıyorum)
Rsc Rsc

4
LOCAL kullanın. LOAD DATA LOCAL INFILE ...
mpoletto

Yanıtlar:


474

Amaçlandığı gibi çalışıyor. MySQL sunucunuz temel olarak hangi dizinleri kullanarak dosya yükleyebileceğinizi sınırlayan --secure-file-priv seçeneğiyle başlatılmıştır LOAD DATA INFILE.

SHOW VARIABLES LIKE "secure_file_priv";Yapılandırılmış dizini görmek için kullanabilirsiniz .

İki seçeneğiniz var:

  1. Dosyanızı ile belirtilen dizine taşıyın secure-file-priv.
  2. Devre dışı bırak secure-file-priv. Bu başlangıçtan kaldırılmalıdır ve dinamik olarak değiştirilemez. Bunu yapmak için MySQL başlatma parametrelerinizi (platforma bağlı olarak) ve my.ini'nizi kontrol edin.

4
Varsayılan olarak my.ini, W2012 sunucusunda MySQL 5.6 çalıştırılırken "C: \ ProgramData \ MySQL \ MySQL Server 5.6" içinde bulunabilir. Ayrıca (örn --defaults dosyası = "C: \ ProgramData \ MySQL \ MySQL Server 5.6 \ my.ini) hizmeti başlatma parametrelerini kontrol etmek isteyebilirsiniz onlar da listeleyebilir olarak --secure-file-priv. Kendisini
vhu

2
@Mohitbhasi, my-default.ini "C: \ Program Files \ MySQL \ MySQL Server 5.6" klasöründe olmalıdır. Vhu'nun belirttiği konum "C: \ ProgramData \ MySQL \ MySQL Server 5.6" dır. Fark etmediyseniz.
NurShomik

68
Değer: NULL. FML.
William Entriken

11
"Select .. outfile" SHOW VARIABLES LIKE "secure_file_priv";
komutunu kullanırsanız

9
"parametreleri kontrol et" ve "kontrol my.ini" çok iyi bir cevap değil
Roland Seuhs

235

Aynı sorunu yaşadım. Sonunda komuttaki LOCALseçeneği kullanarak çözdüm

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

Daha fazla bilgiyi burada bulabilirsiniz http://dev.mysql.com/doc/refman/5.7/en/load-data.html

LOCAL belirtilirse, dosya istemci ana bilgisayarındaki istemci programı tarafından okunur ve sunucuya gönderilir. Dosya tam konumunu belirtmek için tam yol adı olarak verilebilir. Göreli bir yol adı olarak verilirse, ad, istemci programının başlatıldığı dizine göre yorumlanır.


2
Bu benim için çalıştı ve hiçbiri. Denedim: 1. benim txt dosyası yüklemek için C:\ProgramData\MySQL\MySQL Server 5.7\Uploadsdevre dışı bırakılması 2., secure_file_priviçinde my.inive MySQL 3. Bu seferki yeniden başlatmadan! Teşekkürler :)
Kamal Nayan

10
MariaDB için bu hata iletisini aldım: "HATA 1148 (42000): Kullanılan komut bu MariaDB sürümü ile izin verilmiyor". Tam sürüm: "mysql Ver 15.1 dağıtmak 10.1.22-MariaDB, Linux için (x86_64) readline 5.2 kullanarak"
jciloa

11
Mysql sürüm 5.7.19 için "Kullanılan komut bu MySQL sürümü ile izin verilmez" var.
Alison S

2
@AlisonS Çalışırken --local-infilebayrağı eklemeyi deneyin mysql. stackoverflow.com/questions/10762239/…
Illya Moskvin

1
The used command is not allowed with this MySQL version8.0
bitfishxyz

118

Ubuntu 14 ve Mysql 5.5.53'te bu ayar varsayılan olarak etkindir. Devre dışı bırakmak secure-file-priv = ""için mysqld yapılandırma grubu altındaki my.cnf dosyanıza eklemeniz gerekir . Örneğin:-

[mysqld]
secure-file-priv = ""

1
Bu benim için de işe yaradı. Aynı Ubuntu ve MySQL sürümü
Rodney

1
+1 Benim için çalıştı. Ubuntu kullanıyorsanız, mysql hizmetini yeniden başlatmayı unutmayın: sudo service mysql restart
Emiliano Sangoi

1
Geçerli olduğunda, ifade başına seçtiğiniz bir konumu göstermesi gerektiğinde bu çalışır. Bu, açıkladığınız gibi Windows Server'da MySQL 5.7 ile çalışır. Satır gibi yorum yaparsanız, bu şekilde yaptığı gibi # secure-file-priv = ~hala hatayı NULLgörürseniz, sunucuda hangi dizinleri dışa aktarabileceğinizi seçmek istediğinizde sorunu çözer.
Bitcoin Murderous Maniac

1
Benim için Windows üzerinde MySQL 5.7 ile çalıştı, ancak diğer çözümler işe yaramadı.
CGritton

Not: Bunu Docker'da yapıyorsanız, Docker kapsayıcısını yeniden başlatmanız gerekir.
user1717828

38

Debian üzerinde MySQL5.7.11 üzerinde çalışıyorum, dizini görmek için benim için çalışan komut:

mysql> SELECT @@global.secure_file_priv;

İle SHOW VARIABLES LIKE "secure_file_priv";alıyorum ERROR 1146 (42S02): Table 'performance_schema.session_variables' doesn't exist, diğer durumlarda atılır ve sonunda uğraşmak zorunda olan. SELECT @@global.secure_file_priv;Komut olsa beklenen neticeyi.
Majid Fouladpour

1
Bu benim için çalıştı - Ubuntu Mysql 5.7.21: çıktı dosyasını
/var/lib/mysql-files/output.txt

2
Nasıl düzenlersiniz? /Etc/mysql/my.cnf içinde düzenlemeye çalıştım ve hiçbir etkisi yok gibi görünüyor - NULL kalır
Slavik

25

Windows 7'de devre dışı bırakmak için benim için işe yarayan şeysecure-file-priv ( vhu'nun cevabından Seçenek # 2 ):

  1. MySQL sunucu hizmetini girerek durdurun services.msc.
  2. Git C:\ProgramData\MySQL\MySQL Server 5.6( ProgramDatabenim durumumda gizli bir klasördü).
  3. my.iniDosyayı Not Defteri'nde açın .
  4. 'Secure-file-priv' ifadesini arayın.
  5. Satırın başına '#' ekleyerek satırın yorumunu yapın. MySQL Server 5.7.16 ve üstü için yorum yapmak işe yaramaz. Bunun gibi boş bir dizeye ayarlamanız gerekir -secure-file-priv=""
  6. Dosya 'yı kaydet.
  7. MySQL sunucu hizmetini başlatarak başlatın services.msc.

16
MySQL Server 5.7.16'dan itibaren satırın yorumlanması çalışmaz, çünkü daha sonra içe aktarma ve dışa aktarma işlemlerini devre dışı bırakan varsayılana geri döner. Herhangi bir dizinden bu işlemlere izin vermek istiyorsanız, şimdi boş bir dizeye ayarlamanız gerekir.
dbc

1
Ramnath, lütfen 5.7.x sürümü için cevabınızı @dbc detayıyla düzenleyin. Teşekkürler.
Rafael Gomes Francisco

Boş bir dize eklemek benim için işe yarıyor; lütfen secure-file-priv = "" gibi boş bir dize eklemek için cevabı değiştirin
Rajesh Goel

Windows için eğik çizgi kullandığınızdan emin olun
Oliver Oliver

22

Dosya makineniz için yerelse , komutunuzda LOCAL kullanın

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

15

@vhu

Yaptım SHOW VARIABLES LIKE "secure_file_priv";ve geri döndüC:\ProgramData\MySQL\MySQL Server 8.0\Uploads\ bu yüzden fişi taktığımda hala işe yaramadı.

Doğrudan my.ini dosyasına gittiğimde yolun biraz farklı biçimlendirildiğini keşfettim: C:/ProgramData/MySQL/MySQL Server 8.0/Uploads

Sonra bununla koştuğumda işe yaradı. Tek fark eğik çizgilerin yönüdür.


Evet evet evet ... bu cevap neden aşağıda. uzun süre mücadele ettim ve sonra anladım. Ben cevap olarak eklemek için geri geldi ama o kadar aşağı zamanımı boşa önce görmedim.
Rsc Rsc

Her kahraman pelerin giymez.
JRK

9

Aynı sorunu 'secure-file-priv' ile yaşadım. .İni dosyasına yorum yapmak işe yaramadı ve 'secure-file-priv' tarafından belirtilen dizindeki hareketli dosya da çalışmadı.

Son olarak, dbc'nin önerdiği gibi, 'secure-file-priv' öğesini boş bir dizeye eşit yapmak çalıştı. Bu yüzden, yukarıdaki cevapları denedikten sonra birileri sıkışırsa, umarım bunu yapmak yardımcı olacaktır.


9

Benim için işe yarayan şey:

  1. Dosyanızı içinde belirtilen klasörün içine koyun secure-file-priv.

Bu türü bulmak için:

mysql> "secure_file_priv" gibi değişkenleri gösterir;


  1. Var mı kontrol edin local_infile = 1.

Bunu yazarak yapın:

mysql> "local_infile" gibi değişkenleri gösterir;

Alırsan:

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

Ardından bir yazmaya ayarlayın:

mysql> set global local_infile = 1;


  1. Dosyanızın tam yolunu belirtin. Benim durumumda:

mysql> veri yükleme "C: / ProgramData / MySQL / MySQL Server 8.0 / Yüklemeler / file.txt" tablo testine;


6

Bu konu bu gönderi sırasında 522 bin kez incelendi . Dürüst olmak gerekirse , MySQL ne zaman aşırı koruyucu mantıksız annemiz oldu ? Ne zaman alıcı güvenlik girişimi - gerçekten sadece bizi zincirlemek için hizmet!

Birçok arama ve birçok denemeden sonra her şey başarısız oldu.
Çözümüm:

  1. Eski kutudaki PhpMyAdmin içe aktarma yoluyla .csv dosyasını içe aktarın (cmd satırında büyükse)
  2. bir .sql dosyası oluşturma
  3. .sql dosyasını indir
  4. .sql dosyasını MySQL çalışma tezgahı üzerinden içe aktarın

4

NodeJS çalıştırıyorsanız ve verileriniz aşağıdaki formda ise (çift tırnak + virgül ve \ n yeni satır) bir NodeJS alma komut dosyası oluşturdum

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

Bu, http: // localhost: 5000 / import üzerinde çalışacak şekilde yapılandırılmıştır .

Satır satır gider ve sorgu dizesi oluşturur

"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 yapılandırma dosyasıdır

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;

Yasal Uyarı: Bu mükemmel bir çözüm değil - Ben sadece bir zaman çizelgesi altında ve almak için çok veri var ve bu saçma sorunla karşılaşan devs için gönderiyorum. Bu konuda çok zaman kaybettim ve aynı kayıp zamanı başka bir geliştiriciye yedeklemeyi umuyorum.


3

Bununla ilgili her türlü problemim vardı. Bu sorunun diğer sürümlerinin göstermeye çalıştığı my.cnf ve her türlü çılgın şeyi değiştiriyordum.

Benim için ne işe yaradı:

Aldığım hata

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

/Usr/local/mysql/support-files/mysql.server dosyasını açıp aşağıdaki satırı değiştirerek düzeltmeyi başardım:

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

için

$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 üzerinde çalışıyorsanız, Apparmor'u MySQL'in klasörünüze yazmasına izin verecek şekilde yapılandırmanız da gerekebilir, örneğin, benim yapılandırmam:

Bu satırı /etc/apparmor.d/usr.sbin.mysqld dosyasına ekleyin:

/var/lib/mysql-files/* rw

Ardından bu 2 yapılandırma satırını /etc/mysql/my.cnf bölümlerine ekleyin:

[client]
loose-local-infile = 1

[mysqld]
secure-file-priv = ""

İşte benim SQL:

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

Benim için çalıştı. İyi şanslar!


Evet, "/var/lib/mysql-files/filename.csv" ile dış yol koymak benim için çalıştı.
Anidhya Bhatnagar

3

MySQL 8.0 sürümü için şunları yapabilirsiniz:

  1. mysql.server durağı
  2. mysql.server start --secure-file-priv = ''

Mac High Sierra'da benim için çalıştı


1

Windows 10'da bu sorunu vardı. "- MySQL güvenli dosya-priv" Bunu çözmek için aşağıdakileri yaptım.

  1. Windows aramasında (sol altta) "powershell" yazdım.
  2. Powershell'e sağ tıklayın ve yönetici olarak koştu.
  3. Sunucu kutusu dosyasına gidin. (C: \ Program Dosyaları \ MySQL \ MySQL Server 5.6 \ bin);
  4. Yazılan ./mysqld
  5. "Enter" tuşuna basın

Sunucu beklendiği gibi başlatıldı.


1

MySQL, dosyaları nereye aktarabileceğinizi kontrol etmek için bu sistem değişkenini kullanır

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

Yani sorun, sistem değişkenlerinin nasıl değiştirileceği secure_file_priv.

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

şimdi şöyle görebilirsiniz:

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

0

MacOS Catalina'da, aşağıdaki adımları izledim secure_file_priv

1. MySQL hizmetini durdurma

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

2. --secure_file_priv sistem değişkenlerini atayarak MYSQL'i yeniden başlatın

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

Not: Boş değer eklemek sorunu benim için çözer ve MYSQL verileri / usr / local / mysql / data / YOUR_DB_TABLE / EXPORT_FILE dizinine dışa aktarır

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

Teşekkürler


0

Konfigürasyon dosyalarını değiştirmeden ..

  1. secure_file_priv@vhu tarafından gönderilen komutu kullanmanın değerini arayın:SHOW VARIABLES LIKE "secure_file_priv" .
  2. sorgunuz için tam yolu tanımlayın, örneğin: select * from table into outfile 'secure_file_priv_PATH/OUTPUT-FILE' ... rest of your query

Bu benim için çalıştı mysql-kabuk ubuntu 18.04 LTS mysql 5.7.29

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.