web-dev-qa-db-ja.com

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

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です。

114
Ryan Olson

これは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が実施モードに含まれている場合、おそらく書き込みを拒否しているものです。 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ディレクトリの読み取りと書き込みが可能になります。これがセキュリティに与える影響を既に検討していることを願っています。

187
Vin-G

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を完全に無効にすることです。これはNOT RECOMMENDEDです。

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

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

Sudo /etc/init.d/apparmor restart

17
rook

既に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 $ 
14
basilikode

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

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

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

7
vimdude

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

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

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

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

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

5
fanchyna

試すべきこと:

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

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

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

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

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

  • これでファイルがエディターで開かれますので、そこにディレクトリを追加してください

    / var/www/csv/* rw、

  • 同様に、次の画像のようにファイルに追加しました:

enter image description here

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

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ファイルに書き込みます...

3
Sunny S.M

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

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

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

2

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

1
Charles

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

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

1
Ike Walker

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

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

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

0
Stefan Bicher