SELECT INTO OUTFILEを使用してMySQL Errcode 13を回避するにはどうすればよいですか?


114

MySQL SELECT INTO OUTFILEステートメントを使用して、テーブルの内容をcsvファイルにダンプしようとしています。私が行った場合:

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

outfile.csvは、このデータベースのファイルが格納されているのと同じディレクトリのサーバーに作成されます。

ただし、クエリを次のように変更すると、

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

私は得ます:

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

Errcode 13は権限エラーですが、/ dataの所有権をmysql:mysqlに変更して777権限を付与しても取得されます。MySQLはユーザー「mysql」として実行されています。

不思議なことに、ユーザーmysqlがディレクトリに書き込むことができるように権限を設定しても、私が試した他のディレクトリではなく、/ tmpにファイルを作成できます。

これはUbuntuで実行されているMySQL 5.0.75です。


3
13はシステムエラーであると見ることは、これは、それはおそらくありませんが、MySQLはありディレクトリにINTO OUTFILEを制限する設定:dev.mysql.com/doc/refman/5.0/en/...は、それはだかどうかを簡単に見て、多分価値に設定し/tmpます。
ペッカ

私のインストールでは、その変数は空白です。これは、そのドキュメントによれば、出力ディレクトリを制限するべきではないことを意味します。
ライアンオルソン、

回答:


189

これはUbuntuの特定のバージョンで、これはこのUbuntu Server Editionですか?

最近のUbuntu Server Edition(10.04など)はAppArmorに同梱されており、MySQLのプロファイルはデフォルトで強制モードになっている可能性があります。これを確認するに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が実施モードに含まれている場合、それはおそらく書き込みを拒否するものです。/var/log/messagesAppArmorが書き込み/アクセスをブロックすると、エントリも書き込まれます。あなたができることは次のように編集/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ディレクトリの読み取りと書き込みを行うことができます。これによるセキュリティへの影響をすでにご検討いただいていると幸いです。


2
私はこれを指摘したくないのですが、App Armorがこれを許可しない理由があります。MySQLは、/ dataフォルダー内のすべてを変更および読み取る機能を備えています。ハッキングされないようにしてください。
ライアンワード

2
@Serdar、ディストリビューションで配布されるAppArmor MySQLルールセットは、デフォルトでは許可していません。これは、新規インストールのルールの適切なベースラインであるため、理にかなっています。インストール後のニーズに合わせてルールセットを変更する必要があると私は信じています。MySQLが特定のディレクトリに書き込むことができるようにすることは、元の要求者の意図でした。しかし、それが上記ですぐに明確にならない場合は、このソリューションに出くわす人々への注意:警告:上記の変更により、MySQLは/ dataディレクトリへの読み取りと書き込みが可能になります。これによるセキュリティへの影響をすでにご検討いただいていると幸いです。
Vin-G

1
素晴らしい答え!!! それは私の問題を解決しました、私はまた他のディレクトリに書き込もうとしていました。今、私はこれが何であるかについて研究しなければなりません!:)これについて学んだら、他の人にapparmor(したがって、aa-statusコマンド)について読むことをお勧めします:en.wikipedia.org/wiki/AppArmor
David L

1
私の場合、これは役に立ちました: /your/abs/folder/ r, /your/abs/folder/** rwk, }最後にカンマを含めることを忘れないでください!
ACV 2016年

1
/ tmpに書き込むように動作します。代わりにウィンドウを使用してください。Linuxはひどい
ビクターイオネスク2018年

17

UbuntuはAppArmorを使用しており、それが/ data /へのアクセスを妨げています。Fedoraはselinuxを使用しており、RHEL / Fedora / CentOSマシンでこれを防ぐことができます。

MySQLが/ data /にアクセスできるようにAppArmorを変更するには、次のようにします。

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

ディレクトリのリストのどこかにこの行を追加します:

/data/ rw,

次に:

sudo /etc/init.d/apparmor restart

別のオプションは、mysqlのAppArmorを完全に無効にすることです。これは推奨されません

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

apparmorを再起動することを忘れないでください:

sudo /etc/init.d/apparmor restart


実際にmysqlのapparmorを無効にするために必要なこと: cyberciti.biz/faq/ubuntu-linux-howto-disable-apparmor-commands
silver_mx

14

すでにアクセス許可を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 $ 

me @ server:/ data $ pwd / data me @ server:/ data $ ls -al total 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 Enter password:mysqldump:Got error:1:Ca n't to create / write to file '/data/dumptest/test.txt'(Errcode:13)when 'SELECT INTO OUTFILE 'me @ server:/ data $ sudo chmod a + rwx dumptest / me @ server:/ data $ mysqldump -u dbuser -p -T dumptest -B db_name --tables test Enter password:mysqldump:Got error:1:(同じエラー)
Ryan Olson、

オイ、まあ、コメントがフォーマットされないことに気づかなかったが、いくつかの異なる方法をダブルチェックした。最初にmysql:mysqlが所有するターゲットディレクトリで、次にdumpコマンドを実行していたユーザーが所有するターゲットディレクトリで、両方の方法で同じアクセス許可エラーが発生します。
ライアンオルソン、

ちなみに、これはapparmorのアクセス許可を変更したにもかかわらず、私にとってはうまくいきました
Alex

apparmorを変更しようとしましたが、うまくいきませんでした。許可の変更 'chmod 777'がうまくいきました!
Sudarshan_SMD 2015年

7

MySQLはここでバカになっています。/ tmp / data / ....の下にファイルを作成しようとします。したがって、次のことができます。

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

次に、クエリを試してください。これは何時間も問題をデバッグした後で私にとってはうまくいきました。


私はこの答えが一番好きです。それは簡単で、機能し、apparmorを使用する必要がありません。パイプを使用して行うもう1つの方法は、すべてのバッファリングが行われるため、大規模なエクスポートではうまく機能しません。
Chris Seline 2014年

6

この問題は長い間私を悩ませてきました。この議論はRHEL / Fecoraのソリューションを指摘していないことに気づきました。私はRHELを使用していますが、UbuntuのAppArmerに対応する構成ファイルが見つかりませんが、PATHのすべてのディレクトリをmysqlで読み取りおよびアクセス可能にすることで問題を解決しました。たとえば、ディレクトリ/ tmpを作成する場合、次の2つのコマンドにより、SELECT INTO OUTFILEは.sqlおよび.sqlファイルを出力できます。

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

ホームディレクトリ/ home / tomにディレクトリを作成する場合は、/ homeと/ home / tomの両方に対してこれを行う必要があります。


3
/ tmpを例として使用するのは良い考えではありません。また、(ほとんどの場合)/ tmpディレクトリの所有権を実際に変更したくない場合もあります。
sastorsl 2015

/ tmpの所有権を変更することは悪いことですが、/ tmp内に一時フォルダを作成しchown mysql:mysqlて問題を解決しました
Samuel Prevost

6

あなたはこれを行うことができます :

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

ありがとう!CSVとして出力を制御することは可能ですか?
ハマンサミュエル

4

試すこと:

  • それは secure_file_privシステム変数セットは?その場合、すべてのファイルをそのディレクトリに書き込む必要があります。
  • ファイルが存在しないことを確認してください-MySQLは新しいファイルを作成するだけで、既存のファイルを上書きしません。

1
secure_file_privも使用します。ファイルがすでに存在する場合、エラーメッセージは異なります(errcode 13ではありません)。
Xavier Maillard

secure_file_privは現在設定されていないので、理解できるように、ファイルを書き込むことができる場所を制限する必要はありません。私はそれを誤解していますか?ファイルシステムのどこにでも書き込みたい場合は、明示的に「/」などに設定する必要がありますか?
Ryan Olson

また、クエリを実行する前に、ファイルが存在しないことを確認しています。
Ryan Olson

フィードバックをお寄せいただきありがとうございます。あなたの調査結果に基づいて、これらの提案のどちらもあなたの問題を引き起こしているとは思いません。
mdma

3

同じ問題があり、次の手順でこの問題を修正しました:

  • オペレーティングシステム:ubuntu 12.04
  • 取り付けられたランプ
  • 出力ファイルを保存するディレクトリが/ var / www / csv /であるとします。

端末で次のコマンドを実行し、geditエディターを使用してこのファイルを編集し、出力ファイルにディレクトリを追加します。

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

  • 今ファイルはエディタで開かれるでしょうそこにあなたのディレクトリを追加してください

    / var / www / csv / * rw、

  • 同様に私は次の与えられた画像のように自分のファイルに追加しました:

ここに画像の説明を入力してください

次のコマンドを実行してサービスを再起動します。

sudo /etc/init.d/apparmor restart

たとえば、phpmyadminクエリビルダーに次のクエリを実行して、csvファイルにデータを出力します

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

それは正常に完了し、選択された列を持つすべての行をOUTPUT.csvファイルに書き込みます...


2

私の場合、解決策は、ディレクトリパス内のすべてのディレクトリをmysqlchmod a+rx)によって読み取りおよびアクセス可能にすることでした。ディレクトリはコマンドラインの相対パスで指定されたままです。

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

2

私はこの同じ問題に遭遇しました。私の問題は、ダンプしようとしたディレクトリにmysqldプロセスへの書き込み権限がないことでした。最初のSQLダンプは書き出されますが、csv / txtファイルの書き込みは失敗します。SQLダンプは現在のユーザーとして実行され、csv / txtへの変換はmysqldを実行しているユーザーとして実行されるように見えます。したがって、ディレクトリには両方のユーザーの書き込み権限が必要です。


1

相対パスではなく、絶対パスを指定する必要があります。

書き込み先の/ dataディレクトリへの完全パスを指定します。


それは私への絶対的な道のように見えます。違いますか?
ペッカ

2
あなたは、MySQLのファイル外を作成できることを確認するために、mysqlのユーザーとしてこれを試してください:touch /data/outfile.csv
アイクウォーカー

1
最初に、mysqlユーザーのシェルが/ bin / falseに設定されていたため、mysqlとしてログインできませんでした。それが問題の原因となっていないことを確認するために、mysqlのシェルを/ bin / bashに設定し、そのユーザーにsuを実行して、/ data内のファイルを変更しました。mysqlが所有するファイルが正常に作成されました。
ライアンオルソン、

3
:それは「無効」シェルのいずれかを使用していた場合でも、アカウントに次のことができSU su --shell=/bin/sh nameofaccount
マルク・B

ありがとう、私はそれを知らなかった。
ライアンオルソン、

1

UbuntuはSELinuxを使用していますか?それが有効になっていて強制されているかどうかを確認してください。/var/log/audit/audit.logが役立つ場合があります(Ubuntuがそれを固定している場合は、RHEL / Fedoraの場所です)。


0

CentOs 6.7でも同じ問題が発生しました。私の場合、すべての権限が設定されているにもかかわらず、エラーが発生しました。問題は、SE Linuxが「強制」モードになっていることでした。

コマンドを使用して「許可」に切り替えました sudo setenforce 0

その後、すべてがうまくいきました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.