ฉันจะจัดการ --secure-file-priv ใน MySQL ได้อย่างไร


357

ฉันกำลังเรียนรู้ MySQL และลองใช้LOAD DATAประโยค เมื่อฉันใช้มันเป็นด้านล่าง:

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

ฉันได้รับข้อผิดพลาดต่อไปนี้:

เซิร์ฟเวอร์ MySQL กำลังทำงานด้วยตัวเลือก --secure-file-priv ดังนั้นจึงไม่สามารถดำเนินการตามคำสั่งนี้ได้

ฉันจะแก้ไขข้อผิดพลาดนี้ได้อย่างไร

ฉันได้ตรวจสอบคำถามอื่นในข้อความแสดงข้อผิดพลาดเดียวกันแต่ยังหาวิธีแก้ปัญหาไม่ได้

ฉันใช้ MySQL 5.6


แชร์พา ธ ของไฟล์ csv ของคุณ
Zafar Malik

1
แน่นอนคุณได้รับข้อผิดพลาดนี้เมื่อพยายามใช้mysqldump --tabราวกับว่ามันไม่ยากพอที่จะดึงข้อมูลของคุณเองออกจาก mysql
William Entriken

1
นอกจากคำตอบของ vhu แล้วค้นหาคำตอบของ wolfsshield ด้านล่าง คุณต้องเปลี่ยนเป็น '/' เพื่อให้มันทำงานได้ (ฉันใช้ win10)
Rsc Rsc

4
ใช้ LOCAL LOAD DATA LOCAL INFILE ...
mpoletto ถึง

คำตอบ:


473

มันทำงานได้ตามที่ตั้งใจไว้ MySQL เซิร์ฟเวอร์ของคุณได้รับการเริ่มต้นกับ--secure-ไฟล์ privตัวเลือกซึ่งโดยทั่วไปจะ จำกัด LOAD DATA INFILEจากการที่ไดเรกทอรีคุณสามารถโหลดไฟล์โดยใช้

คุณอาจใช้SHOW VARIABLES LIKE "secure_file_priv";เพื่อดูไดเรกทอรีที่ได้รับการกำหนดค่า

คุณมีสองทางเลือก:

  1. secure-file-privย้ายไฟล์ของคุณไปยังไดเรกทอรีที่ระบุโดย
  2. secure-file-privปิดการใช้งาน สิ่งนี้จะต้องถูกลบออกจากการเริ่มต้นและไม่สามารถแก้ไขได้แบบไดนามิก ในการทำเช่นนี้ให้ตรวจสอบพารามิเตอร์เริ่มต้น MySQL ของคุณ (ขึ้นอยู่กับแพลตฟอร์ม) และ my.ini

4
ตามค่าเริ่มต้น my.ini สามารถหาได้จาก "C: \ ProgramData \ MySQL \ MySQL Server 5.6" เมื่อใช้งาน MySQL 5.6 บนเซิร์ฟเวอร์ W2012 คุณอาจต้องการตรวจสอบพารามิเตอร์การเริ่มต้นบริการ (เช่น --defaults-file = "เซิร์ฟเวอร์ C: \ ProgramData \ MySQL \ MySQL \ MySQL \ MySQL. 5.6 \ my.ini) เนื่องจากพวกเขาอาจแสดงรายการ--secure-file-privเอง
vhu

2
@Mohitbhasi my-default.ini ควรอยู่ในโฟลเดอร์ "C: \ Program Files \ MySQL \ MySQL Server 5.6" ตำแหน่ง vhu ถูกอ้างถึงคือ "เซิร์ฟเวอร์ C: \ ProgramData \ MySQL \ MySQL 5.6" ในกรณีที่คุณไม่ได้สังเกต
NurShomik

67
ค่า: NULL บัดซบ
William Entriken

11
โปรดทราบว่าหากใช้ "select .. to outfile" คุณจะต้องระบุเส้นทางแบบเต็มและเส้นทางแบบเต็มต้องตรงกับผลลัพธ์ของSHOW VARIABLES LIKE "secure_file_priv";
TheSatinKnight

9
"ตรวจสอบพารามิเตอร์" และ "ตรวจสอบ my.ini" ไม่ใช่คำตอบที่ดีมาก
Roland Seuhs

234

ฉันมีปัญหาเดียวกัน ในที่สุดฉันก็แก้ไขโดยใช้LOCALตัวเลือกในคำสั่ง

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

คุณสามารถหาข้อมูลเพิ่มเติมได้ที่นี่http://dev.mysql.com/doc/refman/5.7/en/load-data.html

หากระบุ LOCAL ไฟล์จะถูกอ่านโดยโปรแกรมไคลเอ็นต์บนโฮสต์ไคลเอ็นต์และส่งไปยังเซิร์ฟเวอร์ ไฟล์สามารถกำหนดเป็นชื่อพา ธ เต็มเพื่อระบุตำแหน่งที่แน่นอน หากกำหนดเป็นชื่อพา ธ สัมพัทธ์ชื่อจะถูกแปลความสัมพันธ์กับไดเร็กทอรีที่โปรแกรมไคลเอ็นต์เริ่มทำงาน


2
สิ่งนี้ใช้ได้สำหรับฉันและไม่มีใครอื่น ฉันพยายาม 1. การอัปโหลดไฟล์ txt ของฉันในC:\ProgramData\MySQL\MySQL Server 5.7\Uploads2 ปิดการใช้งานsecure_file_privในmy.iniและรีสตาร์ท MySQL 3. หนึ่งนี้! ขอบคุณ :)
Kamal Nayan

10
ฉันได้รับข้อความแสดงข้อผิดพลาดนี้สำหรับ MariaDB: "ข้อผิดพลาด 1148 (42000): คำสั่งที่ใช้ไม่ได้รับอนุญาตกับรุ่น MariaDB นี้" รุ่นที่แน่นอน: "mysql Ver 15.1 Distrib 10.1.22-MariaDB, สำหรับ Linux (x86_64) โดยใช้ readline 5.2"
jciloa

11
ฉันได้รับ "คำสั่งที่ใช้ไม่ได้รับอนุญาตกับ MySQL เวอร์ชันนี้" สำหรับ mysql รุ่น 5.7.19
Alison S

2
@AlisonS ลองเพิ่มธงเมื่อทำงาน--local-infile stackoverflow.com/questions/10762239/…mysql
Illya Moskvin

1
The used command is not allowed with this MySQL versionจาก MySQL 8.0
bitfishxyz

117

ใน Ubuntu 14 และ Mysql 5.5.53 การตั้งค่านี้ดูเหมือนว่าจะเปิดใช้งานตามค่าเริ่มต้น ในการปิดการใช้งานคุณต้องเพิ่มsecure-file-priv = ""ไฟล์ my.cnf ของคุณภายใต้กลุ่ม mysqld config เช่น:-

[mysqld]
secure-file-priv = ""

1
สิ่งนี้ใช้ได้สำหรับฉันเช่นกัน รุ่นเดียวกันของ Ubuntu และ MySQL
Rodney

1
+1 ทำงานให้ฉัน หากคุณกำลังใช้งาน Ubuntu อย่าลืมเริ่มบริการ mysql ใหม่: บริการ sudo บริการ mysql เริ่มระบบใหม่
Emiliano Sangoi

1
นี่คือสิ่งที่ใช้งานได้หากคุณต้องการให้ชี้ไปยังตำแหน่งที่คุณเลือกต่อคำสั่งที่เกี่ยวข้อง ใช้งานได้กับ MySQL 5.7 บน Windows Server เช่นเดียวกับที่คุณอธิบาย หากคุณเพียงแค่แสดงความคิดเห็นในบรรทัดเช่น# secure-file-priv = ~นั้นมันก็ยังมีข้อผิดพลาดเนื่องจากค่าแสดงว่าNULLทำเช่นนี้วิธีนี้จะช่วยแก้ปัญหาเมื่อคุณต้องการเลือกไดเรกทอรีที่คุณสามารถส่งออกไปยังเซิร์ฟเวอร์ ฯลฯ
Bitcoin Murderous Maniac

1
ทำงานกับฉันด้วย MySQL 5.7 บน Windows ในขณะที่โซลูชันอื่นไม่ทำงาน
CGritton

หมายเหตุ: หากทำสิ่งนี้ใน Docker คุณจะต้องรีสตาร์ทคอนเทนเนอร์ Docker
user1717828

38

ฉันกำลังทำงานกับ MySQL5.7.11 บน Debian คำสั่งที่ใช้งานได้สำหรับฉันที่จะดูไดเรกทอรีคือ:

mysql> SELECT @@global.secure_file_priv;

เมื่อSHOW VARIABLES LIKE "secure_file_priv";ฉันได้รับERROR 1146 (42S02): Table 'performance_schema.session_variables' doesn't existซึ่งจะถูกโยนในสถานการณ์อื่น ๆ และฉันจะต้องจัดการกับในที่สุด SELECT @@global.secure_file_priv;คำสั่ง แต่ผลิตผลที่คาดหวัง
Majid Fouladpour

1
สิ่งนี้ใช้ได้กับฉัน - Ubuntu Mysql 5.7.21: เปลี่ยนไฟล์เอาต์พุตเป็นไดเร็กทอรี
/var/lib/mysql-files/output.txt

2
คุณจะแก้ไขได้อย่างไร? ฉันพยายามที่จะแก้ไขใน /etc/mysql/my.cnf และดูเหมือนว่าจะไม่มีผลกระทบ - มันยังคงเป็นโมฆะ
Slavik

24

นี่คือสิ่งที่ทำงานสำหรับฉันใน Windows 7 เพื่อปิดการใช้งานsecure-file-priv(ตัวเลือก # 2 จากคำตอบของ vhu ):

  1. หยุดบริการเซิร์ฟเวอร์ MySQL services.mscโดยจะเข้าสู่
  2. ไปที่C:\ProgramData\MySQL\MySQL Server 5.6( ProgramDataเป็นโฟลเดอร์ที่ซ่อนอยู่ในกรณีของฉัน)
  3. เปิดmy.iniไฟล์ใน Notepad
  4. ค้นหา 'secure-file-priv'
  5. ใส่ความคิดเห็นลงในบรรทัดโดยเพิ่ม '#' ที่จุดเริ่มต้นของบรรทัด สำหรับ MySQL Server 5.7.16 และสูงกว่าการแสดงความคิดเห็นจะไม่ทำงาน คุณต้องตั้งค่าให้เป็นสตริงที่ว่างเปล่าเช่นนี้ -secure-file-priv=""
  6. บันทึกไฟล์
  7. เริ่มบริการเซิร์ฟเวอร์ MySQL services.mscโดยจะเข้าสู่

16
ในฐานะของ MySQL Server 5.7.16 การแสดงความคิดเห็นในบรรทัดจะไม่ทำงานเพราะจะเปลี่ยนกลับเป็นค่าเริ่มต้นซึ่งจะปิดใช้งานการดำเนินการนำเข้าและส่งออก ตอนนี้คุณต้องตั้งค่าเป็นสตริงว่างถ้าคุณต้องการอนุญาตการดำเนินการเหล่านี้จากไดเรกทอรีใด ๆ
dbc

1
Ramnath โปรดแก้ไขคำตอบของคุณด้วยรายละเอียด @dbc สำหรับรุ่น 5.7.x ขอบคุณ
Rafael Gomes Francisco

การเพิ่มสตริงว่างทำงานสำหรับฉัน; โปรดเปลี่ยนคำตอบเพื่อเพิ่มสตริงว่างเช่น secure-file-priv = ""
Rajesh Goel

สำหรับ Windows โปรดใช้เครื่องหมายทับ
Oliver Oliver

22

หากไฟล์นั้นอยู่ในเครื่องของคุณให้ใช้LOCALในคำสั่งของคุณ

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

14

@vhu

ฉันทำSHOW VARIABLES LIKE "secure_file_priv";และมันกลับมาC:\ProgramData\MySQL\MySQL Server 8.0\Uploads\ดังนั้นเมื่อฉันเสียบที่มันยังคงไม่ทำงาน

เมื่อฉันไปที่ไฟล์ my.ini โดยตรงฉันค้นพบว่าพา ธ มีการจัดรูปแบบแตกต่างกันเล็กน้อย: C:/ProgramData/MySQL/MySQL Server 8.0/Uploads

จากนั้นเมื่อฉันวิ่งไปกับมันมันก็ใช้ได้ ความแตกต่างเพียงอย่างเดียวคือทิศทางของเครื่องหมายทับ


คำตอบของคุณทำงานสำหรับฉัน thnaks มาก
benaou mouad

ใช่ใช่ใช่ ... ทำไมคำตอบนี้จึงอยู่ต่ำกว่านี้ ฉันพยายามมานานแล้วก็รับมัน ฉันกลับมาเพิ่มนี่เป็นคำตอบ แต่มันไกลจนฉันไม่เห็นมันก่อนที่ฉันจะเสียเวลา
Rsc Rsc

ไม่ใช่ฮีโร่ทุกคนที่สวมเสื้อคลุม
JRK

8

ฉันมีปัญหาเดียวกันกับ 'secure-file-priv' ความคิดเห็นในไฟล์. ini ไม่ทำงานและไม่ได้ย้ายไฟล์ในไดเรกทอรีที่ระบุโดย 'secure-file-priv'

สุดท้ายตามที่ dbc แนะนำให้ทำให้ 'secure-file-priv' เท่ากับสตริงว่างที่ใช้งานได้ ดังนั้นหากใครติดค้างหลังจากพยายามตอบคำถามข้างต้นหวังว่าการทำเช่นนี้จะช่วยได้


8

สิ่งที่เหมาะกับฉัน:

  1. secure-file-privใส่ในไฟล์ของคุณของโฟลเดอร์ที่ระบุไว้ใน

หากต้องการค้นหาประเภทนั้น:

mysql> แสดงตัวแปรเช่น "secure_file_priv";


  1. local_infile = 1ตรวจสอบว่าคุณมี

ทำการพิมพ์นั้น:

mysql> แสดงตัวแปรเช่น "local_infile";

ถ้าคุณได้รับ:

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

จากนั้นตั้งค่าเป็นหนึ่งการพิมพ์:

mysql> ตั้งค่า local_infile ทั่วโลก = 1;


  1. ระบุพา ธ เต็มสำหรับไฟล์ของคุณ ในกรณีของฉัน:

mysql> data infile โหลด "C: / ProgramData / MySQL / MySQL Server 8.0 / อัพโหลด / file.txt" ในการทดสอบตาราง;


6

กระทู้นี้มีการดู522kครั้งในเวลาโพสต์นี้ สุจริตเมื่อไหร่ที่ MySQL กลายเป็นแม่ของเราที่ไม่มีเหตุผลป้องกัน ? ความพยายามในการรักษาความปลอดภัยใช้เวลานานมาก - ซึ่งทำหน้าที่เพื่อมอบกุญแจสู่เราเท่านั้น!

หลังจากการค้นหาหลายครั้งและหลายครั้งก็พยายามทุกอย่างล้มเหลว
ทางออกของฉัน:

  1. นำเข้าไฟล์. csv ผ่าน PhpMyAdmin นำเข้าบนกล่องรุ่นเก่า (ถ้ามีขนาดใหญ่ให้ทำที่บรรทัด cmd)
  2. สร้างไฟล์. sql
  3. ดาวน์โหลดไฟล์. sql
  4. นำเข้าไฟล์. sql ผ่านทางโต๊ะทำงาน MySQL

3

ฉันมีปัญหาทุกอย่างเกี่ยวกับเรื่องนี้ ฉันกำลังเปลี่ยน my.cnf และสิ่งที่บ้าทุกประเภทที่ปัญหานี้รุ่นอื่นพยายามแสดง

อะไรที่ทำให้ฉัน:

ข้อผิดพลาดที่ฉันได้รับ

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

ฉันสามารถแก้ไขได้โดยเปิด /usr/local/mysql/support-files/mysql.server และเปลี่ยนบรรทัดต่อไปนี้:

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

3

หากคุณใช้งาน Ubuntu คุณอาจต้องกำหนดค่า Apparmor เพื่ออนุญาตให้ MySQL เขียนไปยังโฟลเดอร์ของคุณเช่นนี่คือการกำหนดค่าของฉัน:

เพิ่มบรรทัดนี้ไปยังไฟล์ /etc/apparmor.d/usr.sbin.mysqld:

/var/lib/mysql-files/* rw

จากนั้นเพิ่มบรรทัดการกำหนดค่า 2 รายการเหล่านี้ในส่วน /etc/mysql/my.cnf:

[client]
loose-local-infile = 1

[mysqld]
secure-file-priv = ""

นี่คือ SQL ของฉัน:

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

มันใช้งานได้สำหรับฉัน โชคดี!


ใช่กำลังวางเส้นทาง outfile ด้วย "/var/lib/mysql-files/filename.csv" ทำงานให้ฉัน
Anidhya Bhatnagar

3

สำหรับรุ่น mysql 8.0 คุณสามารถทำได้:

  1. mysql.server หยุด
  2. mysql.server เริ่มต้น --secure-file-priv = ''

มันใช้งานได้สำหรับฉันใน Mac High Sierra


3

ฉันสร้างสคริปต์นำเข้า NodeJS หากคุณกำลังใช้งาน nodeJS และข้อมูลของคุณอยู่ในรูปแบบต่อไปนี้ (เครื่องหมายคำพูดคู่ + คอมม่าและ \ n บรรทัดใหม่)

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

หนึ่งนี้มีการกำหนดค่าให้ทำงานในhttp: // localhost: 5000 / นำเข้า

ฉันไปทีละบรรทัดและสร้างสตริงแบบสอบถาม

"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 เป็นไฟล์กำหนดค่า

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;

ข้อจำกัดความรับผิดชอบ: นี่ไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์แบบ - ฉันโพสต์เพียงเพื่อ devs ที่อยู่ภายใต้เส้นเวลาและมีข้อมูลจำนวนมากที่จะนำเข้าและกำลังพบกับปัญหาที่ไร้สาระนี้ ฉันเสียเวลาไปกับสิ่งนี้มากและฉันหวังว่าจะเหลืออีก dev คนเดียวในเวลาที่หายไป


1

ฉันมีปัญหานี้ใน windows 10 "--secure-file-priv ใน MySQL" เพื่อแก้ปัญหานี้ฉันทำสิ่งต่อไปนี้

  1. ในการค้นหา windows (ล่างซ้าย) ฉันพิมพ์ "powershell"
  2. คลิกขวาที่ powershell และวิ่งเป็นผู้ดูแลระบบ
  3. นำทางไปยังไฟล์ bin ของเซิร์ฟเวอร์ (C: \ Program เซิร์ฟเวอร์ Files \ MySQL \ MySQL 5.6 \ bin);
  4. พิมพ์. / mysqld
  5. กดปุ่ม "Enter"

เซิร์ฟเวอร์เริ่มต้นตามที่คาดไว้


1

MySQL ใช้ตัวแปรระบบนี้เพื่อควบคุมตำแหน่งที่คุณสามารถนำเข้าไฟล์ของคุณ

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

secure_file_privดังนั้นปัญหาที่เกิดขึ้นเป็นวิธีการเปลี่ยนตัวแปรของระบบเช่น

  1. ปิดตัวลง mysqld
  2. sudo mysqld_safe --secure_file_priv=""

ตอนนี้คุณอาจเห็นเช่นนี้:

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

0

ที่ macOS Catalina ฉันทำตามขั้นตอนนี้เพื่อตั้งค่า secure_file_priv

1. หยุดบริการ MySQL

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

2. รีสตาร์ท MYSQL ที่กำหนด --secure_file_priv ตัวแปรระบบ

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

หมายเหตุ: การเพิ่มค่าว่างแก้ไขปัญหาให้ฉันแล้ว MYSQL จะส่งออกข้อมูลไปยังไดเรกทอรี / usr / local / mysql / data / YOUR_DB_TABLE / EXPORT_FILE

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

ขอบคุณ


0

โดยไม่ต้องเปลี่ยนไฟล์คอนฟิกูเรชันใด ๆ ..

  1. ค้นหาค่าของการsecure_file_privใช้คำสั่งที่โพสต์โดย @vhu:SHOW VARIABLES LIKE "secure_file_priv"@vhu:
  2. กำหนดเส้นทางแบบเต็มสำหรับแบบสอบถามของคุณเช่น: select * from table into outfile 'secure_file_priv_PATH/OUTPUT-FILE' ... rest of your query

สิ่งนี้ใช้ได้กับฉันใน mysql-shell บน Ubuntu 18.04 LTS mysql 5.7.29

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.