Câu hỏi Làm thế nào tôi có thể nhận được xung quanh MySQL Errcode 13 với SELECT INTO OUTFILE?


Tôi đang cố gắng để đổ các nội dung của một bảng vào một tập tin csv bằng cách sử dụng một câu lệnh MySQL SELECT INTO OUTFILE. Nếu tôi làm:

SELECT column1, column2
INTO OUTFILE 'outfile.csv'
FIELDS TERMINATED BY ','
FROM table_name;

outfile.csv sẽ được tạo trên máy chủ trong cùng thư mục mà các tệp của cơ sở dữ liệu này được lưu trữ.

Tuy nhiên, khi tôi thay đổi truy vấn của mình thành:

SELECT column1, column2
INTO OUTFILE '/data/outfile.csv'
FIELDS TERMINATED BY ','
FROM table_name;

Tôi có:

ERROR 1 (HY000): Can't create/write to file '/data/outfile.csv' (Errcode: 13)

Errcode 13 là một lỗi quyền hạn, nhưng tôi nhận được nó ngay cả khi tôi thay đổi quyền sở hữu / dữ liệu thành mysql: mysql và cấp cho nó quyền 777. MySQL đang chạy như người dùng "mysql".

Kỳ lạ tôi có thể tạo tập tin trong / tmp, chỉ cần không có trong bất kỳ thư mục khác tôi đã cố gắng, ngay cả với các quyền thiết lập như vậy mà người dùng mysql sẽ có thể ghi vào thư mục.

Đây là MySQL 5.0.75 chạy trên Ubuntu.


110
2018-05-06 18:00


gốc


Nhìn thấy như là 13 là một lỗi hệ thống, điều này có lẽ không phải là nó, nhưng có một thiết lập mySQL giới hạn INTO OUTFILE vào một thư mục: dev.mysql.com/doc/refman/5.0/en/… có thể đáng xem nhanh cho dù nó được đặt thành /tmp. - Pekka 웃
Biến đó trống trên cài đặt của tôi, mà theo tài liệu đó có nghĩa là các thư mục đầu ra của tôi không bị giới hạn. - Ryan Olson


Các câu trả lời:


Phiên bản cụ thể nào của Ubuntu là phiên bản Ubuntu Server này?

Các phiên bản Ubuntu Server gần đây (chẳng hạn như 10.04) được gửi kèm với AppArmor và cấu hình của MySQL có thể đang ở chế độ thực thi theo mặc định. Bạn có thể kiểm tra điều này bằng cách thực hiện sudo aa-status như vậy:

# sudo aa-status
5 profiles are loaded.
5 profiles are in enforce mode.
   /usr/lib/connman/scripts/dhclient-script
   /sbin/dhclient3
   /usr/sbin/tcpdump
   /usr/lib/NetworkManager/nm-dhcp-client.action
   /usr/sbin/mysqld
0 profiles are in complain mode.
1 processes have profiles defined.
1 processes are in enforce mode :
   /usr/sbin/mysqld (1089)
0 processes are in complain mode.

Nếu mysqld được bao gồm trong chế độ thực thi, thì đó có thể là từ chối viết. Các bài viết cũng sẽ được viết /var/log/messages khi AppArmor chặn ghi / truy cập. Những gì bạn có thể làm là chỉnh sửa /etc/apparmor.d/usr.sbin.mysqld và thêm /data/ và /data/* gần đáy như vậy:

...  
/usr/sbin/mysqld  {  
    ...  
    /var/log/mysql/ r,  
    /var/log/mysql/* rw,  
    /var/run/mysqld/mysqld.pid w,  
    /var/run/mysqld/mysqld.sock w,  
    **/data/ r,  
    /data/* rw,**  
}

Và sau đó làm cho AppArmor tải lại các cấu hình.

# sudo /etc/init.d/apparmor reload

CẢNH BÁO: thay đổi ở trên sẽ cho phép MySQL đọc và ghi vào thư mục / dữ liệu. Chúng tôi hy vọng bạn đã xem xét các tác động an ninh của điều này.


183
2018-06-07 02:23



Đây là Ubuntu 9.04, nhưng AppArmor đã từ chối việc viết. Cảm ơn rất nhiều, điều này đã giải quyết điều này cho tôi. - Ryan Olson
Tôi ghét chỉ ra điều này, nhưng có một lý do App Armor không cho phép điều này. MySQL hiện có khả năng sửa đổi và đọc bất cứ thứ gì trong thư mục / data. Chỉ cần không bị hack ngay bây giờ. - Cayetano Gonçalves
@ Serdar, Các ruleset MySQL AppArmor phân phối với distro không cho phép nó theo mặc định. Điều này có ý nghĩa vì nó là một cơ sở tốt của các quy tắc cho một cài đặt mới. Tôi tin rằng chúng ta nên và được phép sửa đổi các quy tắc để phù hợp với nhu cầu của chúng tôi sau khi cài đặt. Đó là ý định của người yêu cầu ban đầu để cho phép MySQL ghi vào các thư mục cụ thể. Nhưng nếu nó không phải là dễ dàng rõ ràng ở trên, một lưu ý để furhter người stumbling về giải pháp này: CẢNH BÁO: sự thay đổi ở trên sẽ cho phép MySQL để đọc và ghi vào thư mục / dữ liệu. Chúng tôi hy vọng bạn đã xem xét các tác động an ninh của điều này. - Vin-G
CÂU TRẢ LỜI CHÍNH XÁC!!! Nó giải quyết được vấn đề của tôi, tôi cũng đang cố viết vào bất kỳ thư mục nào khác. Bây giờ, tôi phải nghiên cứu tất cả những điều này là về! :) Tìm hiểu về điều này, tôi khuyên người khác nên đọc về apparmor (và do đó, lệnh aa-status): en.wikipedia.org/wiki/AppArmor - David L
Trong trường hợp của tôi, điều này đã giúp: /your/abs/folder/ r, /your/abs/folder/** rwk, } đừng quên bao gồm dấu phẩy ở cuối! - ACV


Ubuntu sử dụng AppArmor và đó là những gì ngăn cản bạn truy cập / dữ liệu /. Fedora sử dụng selinux và điều đó sẽ ngăn chặn điều này trên một máy RHEL / Fedora / CentOS.

Để sửa đổi AppArmor để cho phép MySQL truy cập / dữ liệu / thực hiện theo các bước sau:

sudo gedit /etc/apparmor.d/usr.sbin.mysqld

thêm dòng này vào bất kỳ đâu trong danh sách thư mục:

/data/ rw,

sau đó thực hiện:

sudo /etc/init.d/apparmor restart

Một tùy chọn khác là vô hiệu hóa AppArmor cho mysql, đây là KHÔNG ĐƯỢC KHUYẾN KHÍCH:

sudo mv /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/

Đừng quên khởi động lại apparmor:

sudo /etc/init.d/apparmor restart


17
2018-06-07 02:41



Để thực sự vô hiệu hóa apparmor cho mysql, tôi cần phải làm: cyberciti.biz/faq/ubuntu-linux-howto-disable-apparmor-commands - silver_mx


Tôi biết bạn đã nói rằng bạn đã thử thiết lập quyền cho 777, nhưng khi tôi có bằng chứng cho tôi đó là một vấn đề cho phép tôi đăng những gì tôi chính xác chạy hy vọng nó có thể giúp đỡ. Đây là kinh nghiệm của tôi:

tmp $ pwd
/Users/username/tmp
tmp $ mkdir bkptest
tmp $ mysqldump -u root -T bkptest bkptest
mysqldump: Got error: 1: Can't create/write to file '/Users/username/tmp/bkptest/people.txt' (Errcode: 13) when executing 'SELECT INTO OUTFILE'
tmp $ chmod a+rwx bkptest/
tmp $ mysqldump -u root -T bkptest bkptest
tmp $ ls bkptest/
people.sql  people.txt
tmp $ 

13
2018-05-06 20:16



tôi @ server: / data $ pwd / data me @ server: / dữ liệu $ ls -al tổng số 60 ... drwxrwxrwx 2 mysql mysql 4096 2010-05-06 16:27 dumptest me @ server: / data $ mysqldump -u dbuser -p -T dumptest -B db_name --tables test Nhập mật khẩu: mysqldump: Có lỗi: 1: Không thể tạo / ghi vào tập tin '/data/dumptest/test.txt' (Errcode: 13) khi thi hành 'SELECT INTO OUTFILE 'me @ server: / data $ sudo chmod a + rwx dumptest / me @ server: / dữ liệu $ mysqldump -u dbuser -p -T dumptest -B db_name --tables test Nhập mật khẩu: mysqldump: Có lỗi: 1: ( lỗi tương tự) - Ryan Olson
Oy, tốt, không nhận ra những lời bình luận sẽ không định dạng, nhưng hai lần kiểm tra một vài cách khác nhau. Đầu tiên với thư mục đích thuộc sở hữu của mysql: mysql, sau đó với thư mục đích thuộc sở hữu của người dùng tôi đã chạy lệnh dump như, cả hai cách vẫn cho tôi lỗi quyền tương tự. - Ryan Olson
Đối với các hồ sơ, điều này làm việc cho tôi mặc dù đã thay đổi quyền truy cập apparmor - Alex
Tôi đã cố gắng sửa đổi để apparmor, nó đã không làm việc. Thay đổi quyền 'chmod 777' đã làm việc cho tôi! - Sudarshan_SMD


MySQL đang trở nên ngu ngốc ở đây. Nó cố gắng để tạo các tập tin theo / tmp / data / .... Vì vậy, những gì bạn có thể làm là như sau:

mkdir /tmp/data
mount --bind /data /tmp/data

Sau đó thử truy vấn của bạn. Điều này làm việc cho tôi sau nhiều giờ gỡ lỗi vấn đề.


6
2018-06-18 22:00



Tôi thích câu trả lời này tốt nhất. Nó rất dễ dàng, nó hoạt động, và nó không đòi hỏi bạn phải thích ứng với người thích ứng. Cách khác để làm điều đó bằng cách sử dụng đường ống không hoạt động tốt cho các hàng xuất khẩu lớn vì tất cả các bộ đệm được thực hiện. - Chris Seline


Một số điều cần thử:

  • secure_file_priv biến hệ thống? Nếu có, tất cả các tệp phải được ghi vào thư mục đó.
  • đảm bảo rằng tệp không tồn tại - MySQL sẽ chỉ tạo các tệp mới, không ghi đè lên các tệp hiện có.

4
2018-06-04 05:04



Tôi cũng sẽ đi cho secure_file_priv. Nếu tệp đã tồn tại, thông báo lỗi là khác nhau (không phải là errcode 13). - Xavier Maillard
secure_file_priv hiện không được đặt, vì vậy tôi hiểu điều đó có nghĩa là tôi không nên bị giới hạn ở nơi tôi có thể ghi tệp. Tôi có hiểu lầm và tôi có cần phải đặt nó thành một cái gì đó như '/' một cách rõ ràng nếu tôi muốn có thể viết bất cứ nơi nào trên hệ thống tệp không? - Ryan Olson
Ngoài ra, tôi kiểm tra rằng tệp không tồn tại trước khi chạy truy vấn. - Ryan Olson
Cảm ơn vì bạn đã phản hồi. Dựa trên những phát hiện của bạn, tôi không nghĩ rằng một trong những đề xuất này gây ra vấn đề của bạn. - mdma


Vấn đề này đã làm phiền tôi trong một thời gian dài. Tôi nhận thấy rằng cuộc thảo luận này không chỉ ra giải pháp trên RHEL / Fecora. Tôi đang sử dụng RHEL và tôi không tìm thấy các tập tin cấu hình tương ứng với AppArmer trên Ubuntu, nhưng tôi đã giải quyết được vấn đề của mình bằng cách tạo thư mục MỌI trong thư mục PATH có thể đọc được và truy cập bởi mysql. Ví dụ, nếu bạn tạo một thư mục / tmp, hai lệnh sau đây làm cho SELECT INTO OUTFILE có thể xuất tệp .sql AND .sql

chown mysql:mysql /tmp
chmod a+rx /tmp

Nếu bạn tạo một thư mục trong thư mục chính của bạn / home / tom, bạn phải làm điều này cho cả hai / home và / home / tom.


4
2018-02-21 01:17



Sử dụng / tmp làm ví dụ không phải là một ý tưởng hay, và bạn thực sự không muốn thay đổi quyền sở hữu thư mục / tmp (trong hầu hết các trường hợp). - sastorsl
chown giải quyết cuộc sống của tôi - adrian4aes


Bạn có thể làm được việc này :

mysql -u USERNAME --password=PASSWORD --database=DATABASE --execute='SELECT `FIELD`, `FIELD` FROM `TABLE` LIMIT 0, 10000 ' -X > file.xml

4
2018-03-19 09:02





Trong trường hợp của tôi, giải pháp là làm cho mọi thư mục trong đường dẫn thư mục có thể đọc được và có thể truy cập bằng mysql (chmod a+rx). Thư mục vẫn được chỉ định bởi đường dẫn tương đối của nó trong dòng lệnh.

chmod a+rx /tmp
chmod a+rx /tmp/migration
etc.

2
2018-02-10 15:26





Tôi chỉ chạy vào cùng một vấn đề này. Vấn đề của tôi là thư mục mà tôi đã cố gắng để đổ vào không có quyền ghi cho quá trình mysqld. Vùng sql đầu tiên sẽ viết ra nhưng ghi tệp csv / txt sẽ thất bại. Hình như bãi sql chạy như người dùng hiện tại và chuyển đổi thành csv / txt được chạy khi người dùng đang chạy mysqld. Vì vậy, thư mục cần quyền ghi cho cả hai người dùng.


2
2018-02-01 17:24