การเข้าถึงถูกปฏิเสธเนื่องจากโหลดข้อมูล infile ใน MySQL


108

ฉันใช้แบบสอบถาม MySQL ตลอดเวลาใน PHP แต่เมื่อฉันลอง

LOAD DATA INFILE

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

# 1045 - การเข้าถึงถูกปฏิเสธสำหรับผู้ใช้ 'user' @ 'localhost' (ใช้รหัสผ่าน: ใช่)

ไม่มีใครรู้ว่านี่หมายถึงอะไร?

คำตอบ:


201

ฉันเพิ่งพบปัญหานี้เช่นกัน ฉันต้องเพิ่มLOCALคำสั่ง SQL ของฉัน

ตัวอย่างเช่นสิ่งนี้ทำให้เกิดปัญหาการอนุญาต:

LOAD DATA INFILE '{$file}' INTO TABLE {$table}

เพิ่มLOCALลงในใบแจ้งยอดของคุณและปัญหาการอนุญาตจะหายไป ชอบมาก:

LOAD DATA LOCAL INFILE '{$file}' INTO TABLE {$table}

12
นี่เป็นสิ่งที่แตกต่าง อัปโหลดไฟล์ของคุณไปยังเซิร์ฟเวอร์ในไดเร็กทอรีชั่วคราว สิ่งนี้จำเป็นในบางครั้ง แต่ถ้า infile อยู่บนเซิร์ฟเวอร์ MySQL อยู่แล้วคุณก็แค่ทำงานซ้ำซ้อน
jeffcook2150

1
ใช่นี่เป็นเคล็ดลับสำหรับฉันฉันกำลังส่งต่อพอร์ตเซิร์ฟเวอร์ฐานข้อมูลผ่าน ssh และฉันคิดว่ามันกำลังมองหาไฟล์บนเซิร์ฟเวอร์ฐานข้อมูลระยะไกลที่ไม่มีส่วน LOCAL
mike

2
@jeremysawesome สำหรับฉันสิ่งนี้ทำให้เกิดข้อผิดพลาดต่อไปนี้: รหัสข้อผิดพลาด: 1148 ไม่อนุญาตคำสั่งที่ใช้กับ MySQL เวอร์ชันนี้ ฉันลองใช้คำตอบสำหรับปัญหานี้เช่นการแก้ไขไฟล์ mysql เป็น local-infile = 1 แต่ก็ล้มเหลวเช่นกัน
OrwellHindenberg

การอัปเดต mySQL เป็น 6.2.5 ช่วยแก้ปัญหานี้ให้ฉัน
OrwellHindenberg

4
คุณอาจต้องเรียก mysql ด้วย--local-infileตัวเลือก
shabbychef

32

ฉันมีปัญหานี้ ฉันค้นหารอบ ๆ และไม่พบคำตอบที่น่าพอใจ ฉันสรุปด้านล่างผลการค้นหาของฉัน

ข้อผิดพลาดการเข้าถึงถูกปฏิเสธอาจหมายความว่า:

  • 'user' @ 'localhost' ไม่มีสิทธิ์ FILE ( GRANT FILE on *.* to user@'localhost'); หรือ,
  • ไฟล์ที่คุณพยายามโหลดไม่มีอยู่บนเครื่องที่ใช้เซิร์ฟเวอร์ mysql (หากใช้ LOAD DATA INFILE) หรือ,
  • ไฟล์ที่คุณพยายามโหลดไม่มีอยู่ในเครื่องของคุณ (หากใช้ LOAD DATA LOCAL INFILE) หรือ,
  • ไฟล์ที่คุณพยายามโหลดนั้นไม่สามารถอ่านได้ทั่วโลก (คุณต้องการไฟล์และไดเร็กทอรีหลักทั้งหมดเพื่อให้อ่านได้ทั่วโลก: ไดเร็กทอรี chmod 755; และ chmod 744 file.dat)

1: นี้ทำงานสำหรับฉัน: ไฟล์ที่คุณกำลังพยายามที่จะโหลดไม่สามารถอ่านได้ในโลก (คุณต้องไฟล์และไดเรกทอรีทั้งหมดแม่เพื่อจะเป็นโลกที่อ่านได้: chmod 755 ไดเรกทอรี; และ chmod 744 file.dat) ฉันไม่ได้เปลี่ยนสิทธิ์ในไดเรกทอรีทั้งหมดของฉัน
gavdotnet

1
ผู้ใช้ Tatiana ชี้ให้เห็นว่าคุณไม่สามารถให้สิทธิ์ FILE ต่อฐานข้อมูลเฉพาะสำหรับเซิร์ฟเวอร์ทั้งหมด คำสั่งให้สิทธิ์จะเป็น "GRANT FILE on . to user @ 'localhost' IDENTIFIED BY 'password');"
JAL

3
@JAL ฉันคิดว่าคุณหมายถึง "GRANT FILE ON *. * ให้กับผู้ใช้ ... " - อาจเป็นตัวอักษรดอกจันถูกถอดออก
Eugene M

ตามที่ @Eugene M กล่าวว่าสิ่งนี้ทำให้เกิดข้อผิดพลาดการใช้งาน DB GRANT และสิทธิ์ระดับโลกอย่างไม่ถูกต้อง
นักบัญชีم

20

ลองใช้คำสั่งนี้:

load data local infile 'home/data.txt' into table customer;

สิ่งนี้ควรใช้งานได้ มันใช้ได้ในกรณีของฉัน


3
ERROR 1148 (42000): The used command is not allowed with this MySQL version
Stewart

@Stewart โปรดลบ 'local' ออกจากคำสั่งด้านบน ดูเหมือนว่าเวอร์ชัน mysql ในภายหลังจะไม่รองรับแฟล็กนี้เมื่อตัวแปรโกลบอล 'local_infile' ถูกตั้งค่าเป็น 'ON' (ตามด้านล่าง) ดังนั้นคำสั่งจะเป็น; mysql> โหลด data infile 'home / data.txt' ลงในลูกค้าโต๊ะ; + --------------- + ------- + | Variable_name | มูลค่า | + --------------- + ------- + | local_infile | บน | + --------------- + ------- +
Kamran Hyder

@KamranHyder ดูเหมือนว่าคุณมีคำตอบที่ดีสำหรับฉัน ทำไมไม่เพิ่มเป็นคำตอบแบบเต็ม?
Stewart

10

ตรวจสอบให้แน่ใจว่าผู้ใช้ MySQL ของคุณได้รับสิทธิ์ FILE

หากคุณใช้เว็บโฮสติ้งที่ใช้ร่วมกันอาจมีโอกาสที่ผู้ให้บริการโฮสติ้งของคุณบล็อกนี้


บนเว็บโฮสติ้งที่ใช้ร่วมกัน: การใช้ "LOAD DATA LOCAL INFILE" จะมีประโยชน์หรือไม่
ปีเตอร์

3

สตริงจากลียงให้คำแนะนำที่ดีแก่ฉัน: ใน Windows เราต้องใช้สแลชไม่ใช่แบ็กสแลช รหัสนี้ใช้ได้กับฉัน:

    File tempFile = File.createTempFile(tableName, ".csv");
    FileUtils.copyInputStreamToFile(data, tempFile);

    JdbcTemplate template = new JdbcTemplate(dataSource);
    String path = tempFile.getAbsolutePath().replace('\\', '/');
    int rows = template.update(MessageFormat
            .format("LOAD DATA LOCAL INFILE ''{0}'' INTO TABLE {1} FIELDS TERMINATED BY '',''",
                    path, tableName));
    logger.info("imported {} rows into {}", rows, tableName);

    tempFile.delete();

2

ฉันพบปัญหาเดียวกันและแก้ไขได้โดยทำตามขั้นตอนเหล่านี้:

  • เปิดใช้งานตัวแปร load_infile
  • การอนุญาตไฟล์ที่ยิ่งใหญ่สำหรับผู้ใช้ mysql ที่กำหนดเองของฉัน
  • ปิดใช้งานตัวแปร secure_file_priv (ไฟล์ของฉันถูกอัพโหลดโดยเว็บเซิร์ฟเวอร์ไปยังโฟลเดอร์ / tmp ซึ่งแน่นอนว่าไม่ใช่ไดเร็กทอรีที่ปลอดภัยของ myslq / var / lib / mysql-file)

สำหรับจุดที่ 3 นี้คุณสามารถอ้างถึง: https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_secure_file_priv

BR,

ค.ศ.


2

สิ่งนี้เกิดขึ้นกับฉันเช่นกันและแม้ว่าจะทำตามขั้นตอนทั้งหมดที่ Yamir อธิบายไว้ในโพสต์ของเขาแล้วฉันก็ไม่สามารถทำให้มันใช้งานได้

ไฟล์อยู่ใน /tmp/test.csv ที่มีสิทธิ์ 777 ผู้ใช้ MySQL มีสิทธิ์ไฟล์ตัวเลือก LOCAL ไม่ได้รับอนุญาตจากเวอร์ชัน MySQL ของฉันดังนั้นฉันจึงติดขัด

ในที่สุดฉันก็สามารถแก้ปัญหาได้โดยเรียกใช้:

sudo chown mysql:mysql /tmp/test.csv

2

ฉันพบว่าง่ายถ้าคุณใช้บรรทัดคำสั่ง

เข้าสู่ระบบด้วยmysql -u[username] -p[password] --local-infile

แล้ว SET GLOBAL local_infile = 1;

เลือกฐานข้อมูลของคุณโดย use [db_name]

และในที่สุดก็ LOAD DATA LOCAL INFILE 'C:\\Users\\shant\\Downloads\\data-1573708892247.csv' INTO TABLE visitors_final_test FIELDS TERMINATED BY ','LINES TERMINATED BY '\r \n' IGNORE 1 LINES;


การเพิ่ม --local-inline ช่วยฉันได้ อย่างไรก็ตามตัวแปรโกลบอล local_infile ถูกตั้งค่าเป็นเปิดแล้วในกรณีของฉัน ฉันคิดว่าผู้ใช้ควรพิจารณาก่อนว่าค่าใดที่พวกเขาเขียนในตัวแปรนี้ก่อนที่จะแก้ไข
Eugene Maysyuk

สำหรับผู้ใช้ RDS => การเพิ่ม --local-infile ช่วยฉันใน RDS แต่SET GLOBAL local_infile = 1;ดูเหมือนจะไม่ทำงานใน RDS แต่อย่างไรก็ตามหากไม่มี--local-infileเคล็ดลับนั้นก็เกิดขึ้น
จริง

0

ฉันค้นพบว่าการโหลดตาราง MySQL นั้นรวดเร็วและไม่เจ็บปวด (ฉันใช้สคริปต์ตัวจัดการโมเดล python / Django):

1) สร้างตารางด้วยคอลัมน์ทั้งหมด VARCHAR (n) NULL เช่น:

mysql> CREATE TABLE cw_well2( api VARCHAR(10) NULL,api_county VARCHAR(3) NULL);


 2) ลบส่วนหัว (บรรทัดแรก) จาก csv จากนั้นโหลด (หากคุณลืม LOCAL คุณจะได้รับ "# 1045 - การเข้าถึงถูกปฏิเสธสำหรับผู้ใช้ 'user' @ 'localhost' (โดยใช้รหัสผ่าน: ใช่)”):

mysql> LOAD DATA LOCAL INFILE "/home/magula6/cogswatch2/well2.csv" INTO TABLE cw_well2 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'     -> ; Query OK, 119426 rows affected, 19962 warnings  (3.41 sec)


 3) แก้ไขคอลัมน์:

mysql> ALTER TABLE cw_well2 CHANGE spud_date spud_date DATE;

mysql> ALTER TABLE cw_well2 CHANGE latitude latitude FLOAT;

โวล่า!


-5

อาจหมายความว่ารหัสผ่านที่คุณระบุ'user'@'localhost'ไม่ถูกต้อง


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