ไม่สามารถส่งออกข้อมูล MySQL ไปยังไฟล์


13

ฉันพยายามที่จะส่งออกข้อมูลจากตาราง MySQL ไปยังไฟล์ แต่ได้รับข้อผิดพลาดในการอนุญาต:

$ pwd
/home/dotancohen
$ mkdir in
$ chmod 777 in/
$ mysql -ugs -p
mysql> USE someDatabase;
mysql> SELECT * FROM data INTO OUTFILE '/home/dotancohen/in/data.csv';
ERROR 1045 (28000): Access denied for user 'gs'@'localhost' (using password: YES)
mysql>

หากไดเรกทอรีที่เป็นปัญหาถูก chmodded ไปที่ 777 แล้วทำไมผู้ใช้ MySQL ไม่สามารถเขียนไฟล์ได้? น่าสนใจพอฉันไม่สามารถเขียนถึง / tmp / อย่างใดอย่างหนึ่ง

แก้ไข: ดูเหมือนว่าผู้ใช้ DB มีสิทธิ์ MySQL ที่เหมาะสม:

mysql> show grants;
+----------------------------------------------------------------------------------+
| Grants for gs@localhost                                                          |
+----------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'gs'@'localhost' IDENTIFIED BY PASSWORD 'somePassword'     | 
| GRANT ALL PRIVILEGES ON `gs\_%`.* TO 'gs'@'localhost'                            | 
+----------------------------------------------------------------------------------+
2 rows in set (0.01 sec)

2
คุณต้องให้สิทธิ์การเข้าถึง MySQL บนแผนผังไดเรกทอรีทั้งหมด การให้สิทธิ์inจะไม่มีจุดหมายหาก MySQL ไม่สามารถเข้าถึงdotanchoenได้ กล่าวอีกนัยหนึ่งกล่องเงินฝากความปลอดภัยในตู้นิรภัยของธนาคารสามารถเปิดทิ้งไว้ได้กว้าง แต่ถ้าประตูตู้นิรภัยของธนาคารถูกล็อคคุณจะไม่ได้เข้าไปในกล่อง gsผู้ใช้ของคุณต้องมีFILEสิทธิ์mysql ในการเรียกใช้คิวรีนั้น

ปัญหาคือคุณอาจไม่ได้เลือก perms? สิทธิ์ Mysql ไม่ได้รับการควบคุมโดยสิทธิ์ของไดเรกทอรี คุณต้องใช้ mysql -u <ชื่อผู้ใช้> -p เพื่อเรียกใช้เป็นผู้ใช้ mysql เฉพาะ ในการให้สิทธิ์การเข้าถึงแก่ผู้ใช้กับฐานข้อมูลให้ดู MySql grant dev.mysql.com/doc/refman/5.1/en/grant.html

ขอขอบคุณผู้ใช้รายนี้มีSELECTสิทธิ์ ฉันมักจะเรียกดูฐานข้อมูลในฐานะผู้ใช้รายนี้
dotancohen

ขอบคุณมาร์คนั่นคือสิ่งที่ฉันกลัว ดังนั้นฉันไม่สามารถมีโฟลเดอร์ "กล่องจดหมาย" ที่ผู้ใช้รายอื่นสามารถเขียนได้โดยไม่ต้องให้พวกเขาอ่าน / เขียนไปยังโฮมไดเร็กตอรี่ของฉันด้วย?
dotancohen

2
ตรวจสอบให้แน่ใจว่าผู้ใช้มีFILEสิทธิ์ตามที่อธิบายเอกสาร MySQL
Mike Purcell

คำตอบ:


12

ตามเอกสาร MySQL บนSELECT ... เข้าสู่ภายนอก

ไฟล์ใด ๆ ที่สร้างโดย INTO OUTFILE หรือ INTO DUMPFILE สามารถเขียนได้โดยผู้ใช้ทั้งหมดบนโฮสต์เซิร์ฟเวอร์ เหตุผลก็คือเซิร์ฟเวอร์ MySQL ไม่สามารถสร้างไฟล์ที่เป็นของผู้อื่นที่ไม่ใช่ผู้ใช้ภายใต้บัญชีที่มันกำลังทำงานอยู่ (คุณไม่ควรรัน mysqld ในฐานะรูทด้วยเหตุผลนี้และเหตุผลอื่น ๆ ) ไฟล์ดังกล่าวจะต้องสามารถเขียนได้ทั่วโลกเพื่อให้คุณสามารถจัดการเนื้อหาของไฟล์ได้

คุณควรส่งออกSELECT INTO OUTFILEไปยัง / var / lib / mysql ดังนี้

SELECT * FROM data INTO OUTFILE 'data.csv';

แน่นอนคุณต้องทำให้แน่ใจว่าคุณได้รับอนุญาต FILE บน gs @ localhost

มีสองวิธีในการให้สิทธิ์นี้

วิธี # 1

GRANT FILE ON *.* TO 'gs'@'localhost';

วิธีที่ # 2

UPDATE mysql.user SET File_priv = 'Y' WHERE user='gs' AND host='localhost';
FLUSH PRIVILEGES;

อัพเดท 2012-05-01 07:09 EDT

ในการให้สิทธิ์ FILE แก่คุณให้ทำดังนี้:

  • ขั้นตอนที่ 01) service mysql restart --skip-networking --skip-grant-tables
  • ขั้นตอนที่ 02) mysql <hit enter>
  • ขั้นตอนที่ 03) UPDATE mysql.user SET File_priv = 'Y' WHERE user='gs' AND host='localhost';
  • ขั้นตอนที่ 04) exit
  • ขั้นตอนที่ 05) service mysql restart

ขอบคุณ SHOW GRANTSฉันปรับปรุงคำถามที่มีการส่งออกของ ดูเหมือนว่าผู้ใช้ DB ควรมีสิทธิ์ที่เหมาะสม
dotancohen

ผู้ใช้ DB ไม่มีสิทธิ์ที่เหมาะสม สิทธิ์ FILE จะได้รับเฉพาะกับผู้ใช้ที่มีความGRANT ALL PRIVILEGES ON *.*เหมือนและRELOAD SHUTDOWNสิ่งนี้เป็นเช่นนั้นเพราะนั่นเป็นสิทธิ์ระดับผู้ดูแลระบบทั่วโลก GRANT ALLสิทธิพิเศษที่คุณมีคือสำหรับgsฐานข้อมูลเท่านั้น
RolandoMySQLDBA

1

การแจกแจงที่แตกต่างกันและระบบปฏิบัติการต่างก็ไม่ได้จัดการปลายทางทั้งหมดสำหรับ OUTFILEs เหมือนกัน

ตัวอย่างเช่นเมื่อรัน mysqld daemon บน Linux ซึ่งใช้ซ็อกเก็ตบางครั้ง OUTFILE จะถูกเขียนไปยัง/tmpไดเรกทอรี ไม่ใช่เรื่องใหญ่มันเป็นเพียงแค่การใช้วิธีการ OUTFILE มีข้อบกพร่องคือการจัดการกับสิทธิ์และการค้นหาที่ไฟล์ไป

เนื่องจากจุดประสงค์ของคำถามนี้ไม่ใช่ "วิธีใช้ OUTFILE" โดยเฉพาะ แต่คุณเพียงแค่ต้องการเก็บข้อมูล MySQL บางส่วนไว้ในไฟล์นี่เป็นอีกทางเลือกหนึ่งที่ไม่ต้องการให้คุณคลำไปรอบ ๆ ด้วยการอนุญาต FILE เป็นต้น .

$ (echo 'SELECT * FROM data' | mysql -ugs -p[password])> /home/dotancohen/in/data.csv

ผลลัพธ์ของสิ่งนี้คือคั่นด้วยแท็บโดยค่าเริ่มต้น สำหรับเครื่องหมายจุลภาคเพียงแค่ไพพ์ผ่านsedหรือบางสิ่งบางอย่างก่อนที่จะเขียนลงในไฟล์


1

ฉันใช้เวลาหลายชั่วโมงในการทำความเข้าใจคำแนะนำในหน้านี้และหน้าอื่น ๆ ของ StackOverflow

ไม่ว่าฉันจะเปลี่ยนสิทธิ์ใน MySql ได้อย่างไรฉันก็ไม่สามารถทำงานอะไรได้เลย

ฉันเปลี่ยนกลับเป็นสิทธิ์ที่ฉันเริ่มต้นด้วย

ในที่สุดสิ่งที่ทำงานให้ฉันได้ง่ายกว่าคำแนะนำของคนอื่น:

echo "select id, emailAddress FROM contacts" | mysql --user=myusername --password mydatabasename > /home/my_output_file.tsv


1
วิธีการของคุณดีสำหรับการใช้งานใน Bash CLI อย่างไรก็ตามคำถามใน OP ถามเกี่ยวกับวิธีการส่งออกข้อมูลไปยังไฟล์จากไคลเอนต์ MySQL CLI
dotancohen

0

เกี่ยวกับสองวิธีในการส่งออกข้อมูลไปยัง CSV (ควรเป็น TSV จริง ๆ ) ที่กล่าวถึงข้างต้นฉันพบว่าหากมีค่าว่างในรายการที่คุณกำลังส่งออกมีความเสี่ยงที่ข้อมูลอาจเกิดความยุ่งเหยิงเนื่องจากการจัดสรรที่ไม่ถูกต้อง ข้อมูลไปยังคอลัมน์ที่เกี่ยวข้อง

ด้วยความกังวลสำหรับความถูกต้องของข้อมูลสำหรับการกู้คืนฉันพบเว็บไซต์นี้:

https://www.eversql.com/exporting-mysql-schema-structure-to-xml-using-mysql-clients/

มันกล่าวถึง--xmlตัวเลือกในการmysqldumpอนุญาตให้ส่งออกข้อมูลไปยังรูปแบบ XML ซึ่งสามารถแยกวิเคราะห์โดยสคริปต์ที่กำหนดเองเป็นรูปแบบที่จำเป็นรวมถึง TSV

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