2010-05-06 262 views
108

我想使用MySQL SELECT INTO OUTFILE語句將表的內容轉儲到csv文件。如果我做的:如何使用SELECT INTO OUTFILE解決MySQL Errcode 13?

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

outfile.csv將此數據庫的文件存儲在同一目錄服務器上創建

然而,當我改變我的查詢:

​​

我得到:

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

ERRCODE 13是一個權限錯誤,但我得到它,即使我改變的所有權/數據到mysql:mysql並給它777權限。 MySQL以用戶「mysql」的身份運行。

奇怪的是,我可以在/ tmp中創建文件,而不是在我嘗試過的任何其他目錄中,即使設置了權限以便用戶mysql應該能夠寫入目錄。

這是在Ubuntu上運行的MySQL 5.0.75。

+3

看到13是一個系統錯誤,這可能不是它,但有一個mySQL設置限制INTO OUTFILE到一個目錄:http://dev.mysql.com/doc/refman/5.0/en/server -system-variables.html#sysvar_secure_file_priv也許值得快速查看它是否設置爲「/ tmp」。 – 2010-05-06 18:04:38

+0

我的安裝中該變量爲空,根據該文檔,這意味着我的輸出目錄不應受到限制。 – 2010-05-06 18:06:57

回答

180

Ubuntu的哪個特定版本是這個,並且是Ubuntu Server Edition?

默認情況下,AppArmor和MySQL的配置文件附帶的最新Ubuntu Server Edition(例如10.04)可能處於強制模式。你可以通過執行sudo aa-status像這樣檢查:

# 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. 

如果包括在mysqld的強制模式,那麼它是一個可能拒絕寫。當AppArmor阻止寫入/訪問時,條目也將寫入/var/log/messages。你可以做的是編輯/etc/apparmor.d/usr.sbin.mysqld並添加/data//data/*接近底部,像這樣:

... 
/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,** 
} 

然後讓AppArmor配置重新加載配置文件。

# sudo /etc/init.d/apparmor reload 

警告:上述更改將允許MySQL讀取和寫入到/ data目錄。我們希望你已經考慮過這個問題的安全性。

+0

這是Ubuntu 9.04,但AppArmor拒絕寫入。非常感謝,這爲我解決了這個問題。 – 2010-06-07 13:47:03

+0

高興地幫助:) – 2010-06-08 03:49:43

+0

omg-謝謝你!一直困在這方面太久了。 – therealsix 2010-08-09 03:45:29

1

您需要提供絕對路徑,而不是相對路徑。

提供您嘗試寫入的/ data目錄的完整路徑。

+0

這看起來像是我的絕對路徑。不是嗎? – 2010-05-06 19:08:11

+0

這是一條絕對路徑,是的。 – 2010-05-06 19:20:18

+2

以mysql用戶身份驗證您是否可以在mysql之外創建文件:'touch/data/outfile.csv' – 2010-05-06 19:51:05

13

我知道你說過你已經設置了權限設置爲777,但是因爲我有證據表明對我來說這是一個權限問題,我張貼了我正在運行的希望它可以提供幫助。這是我的經驗:

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 $ 
+0

我@服務器:/數據$ PWD /數據 我@服務器:/數據$ LS -al 共60 ... drwxrwxrwx 2 mysql的mysql的4096 2010-05-06 16:27 dumptest 我@服務器:/data $ mysqldump -u dbuser -p -T dumptest -B db_name --tables test 輸入密碼: mysqldump:收到錯誤:1:無法創建/寫入文件'/data/dumptest/test.txt'(錯誤代碼:13)執行'SELECT INTO OUTFILE'時 me @ server:/ data $ sudo chmod a + rwx dumptest/ me @ server:/ data $ mysqldump -u dbuser -p -T dumptest -B db_name --tables測試 輸入密碼: mysqldump:有錯誤:1 :(同樣的錯誤) – 2010-05-06 20:35:04

+0

Oy,好吧,沒有意識到評論不會格式化,但雙重檢查了幾種不同的方式。首先用mysql:mysql擁有的目標目錄,然後用用戶擁有的目標目錄運行dump命令,兩種方式仍然給我相同的權限錯誤。 – 2010-05-06 20:36:40

+0

爲了記錄,儘管已經改變了apparmor權限,但這仍然適用於我 – Alex 2012-11-02 19:17:58

4

有些事情嘗試:

  • secure_file_priv系統變量設置?如果是,則必須將所有文件寫入該目錄。
  • 確保該文件不存在 - MySQL將只創建新文件,不會覆蓋現有文件。
+1

我也會去secure_file_priv。 如果文件已經存在,則錯誤消息不同(不是errcode 13)。 – 2010-06-04 05:18:19

+0

secure_file_priv目前沒有設置,所以據我的理解,這意味着我不應限制在哪裏可以寫入文件。如果我想能夠在文件系統的任何位置寫入,我是否會誤解這一點,是否需要明確地將其設置爲類似'/'的內容? – 2010-06-04 13:37:43

+0

另外,我在運行查詢之前檢查文件不存在。 – 2010-06-04 13:37:59

1

Ubuntu使用SELinux嗎?檢查它是否已啓用並執行。 /var/log/audit/audit.log可能是有幫助的(如果這是Ubuntu堅持的話 - 那就是RHEL/Fedora的位置)。

17

Ubuntu使用AppArmor,這是什麼阻止你訪問/ data /。 Fedora使用selinux,這可以防止在RHEL/Fedora/CentOS機器上出現這種情況。

要修改的AppArmor允許MySQL的訪問/數據/做如下:

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

任意位置添加此行的目錄列表:

/data/ rw,

然後做一個:

sudo /etc/init.d/apparmor restart

另一種選擇是禁用的AppArmor爲MySQL總之,這是不推薦

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

不要忘了重新啓動的AppArmor:

sudo /etc/init.d/apparmor restart

+0

要真正禁用mysql的apparmor我需要做的: https://www.cyberciti.biz/faq/ubuntu-linux-howto-disable-apparmor-commands/ – 2017-06-27 09:36:22

2

在我的情況下,解決方案是通過mysqlchmod a+rx)使目錄路徑中的每個目錄都可讀和可訪問。該目錄仍由命令行中的相對路徑指定。

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

這個問題一直困擾着我很長一段時間。我注意到這個討論沒有在RHEL/Fecora上指出解決方案。我正在使用RHEL,而且在Ubuntu上找不到與AppArmer相對應的配置文件,但是通過使目錄PATH中的EVERY目錄可讀並且可以通過mysql訪問,我解決了我的問題。例如,如果您創建一個目錄/ tmp中,以下兩個命令使SELECT INTO OUTFILE能夠輸出.SQL和.sql文件

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

如果你創建在你的家目錄/ home /湯姆目錄,你必須爲/ home和/ home/tom做到這一點。

+3

使用/ tmp作爲例子不是一件好事想法,並且你真的不想改變/ tmp目錄的所有權(在大多數情況下)。 – sastorsl 2015-04-13 10:59:19

+0

chown解決了我的生活 – adrian4aes 2018-02-14 15:09:10

6

MySQL在這裏變得很愚蠢。它嘗試在/ tmp/data/....下創建文件。因此,您可以執行的操作如下:

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

然後嘗試查詢。經過幾個小時的調試問題後,這對我有用。

+0

我最喜歡這個答案。這很容易,它的工作原理,它並不需要你與apparmor。使用管道的另一種方式不適用於大型導出,因爲所有緩衝都已完成。 – 2014-11-04 15:19:35

2

我剛碰到這個相同的問題。我的問題是我試圖轉儲到的目錄沒有mysqld進程的寫權限。最初的sql轉儲會寫出來,但寫入csv/txt文件將失敗。看起來,sql dump作爲當前用戶運行,並且轉換爲csv/txt作爲運行mysqld的用戶運行。所以這個目錄需要兩個用戶的寫權限。

4

你可以這樣做:

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

我有同樣的問題,我通過以下步驟修復了這個問題:

  • 操作系統:Ubuntu的12.04
  • 燈安裝
  • 假設你目錄保存輸出文件爲:/ var/www/csv/

Execute following command on terminal and edit this file using gedit editor to add your directory to output file.

須藤gedit中/etc/apparmor.d/usr.sbin.mysqld

  • 現在文件將在編輯器中打開,請添加有目錄

    在/ var/WWW/CSV/* RW,

  • 同樣我在文件中添加,如下面給出的圖片:

enter image description here

Execute next command to restart services :

須藤/etc/init.d/apparmor重啓

For example I execute following query into phpmyadmin query builder to output data in csv file

SELECT colName1, colName2,colName3 
INTO OUTFILE '/var/www/csv/OUTFILE.csv' 
FIELDS TERMINATED BY ',' 
FROM tableName; 

它做成功,並與選定的列到OUTPUT.csv寫入文件中的所有行...

0

我在CentOs上有同樣的問題6.7 在我的情況下,所有的權限都被設置了,但仍然出現了錯誤。問題是SE Linux處於「執行」模式。

我切換到「許可」使用下面的命令sudo setenforce 0

然後一切工作對我來說。

相關問題