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です。
これは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ディレクトリの読み取りと書き込みが可能になります。これがセキュリティに与える影響を既に検討していることを願っています。
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
既に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 $
MySQLはここで愚かになっています。/tmp/data/...の下にファイルを作成しようとします。したがって、次のことができます。
mkdir /tmp/data
mount --bind /data /tmp/data
次に、クエリを試してください。これは何時間も問題をデバッグした後、私にとってはうまくいきました。
あなたはこれを行うことができます :
mysql -u USERNAME --password=PASSWORD --database=DATABASE --execute='SELECT `FIELD`, `FIELD` FROM `TABLE` LIMIT 0, 10000 ' -X > file.xml
この問題は長い間私を悩ませてきました。この議論では、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の両方に対してこれを行う必要があります。
試すべきこと:
secure_file_priv
システム変数は設定されていますか?存在する場合、すべてのファイルをそのディレクトリに書き込む必要があります。同じ問題があり、次の手順でこの問題を修正しました。
ターミナルで次のコマンドを実行し、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ファイルに書き込みます...
私の場合、解決策は、ディレクトリパス内のすべてのディレクトリをmysql
(chmod a+rx
)で読み取り可能およびアクセス可能にすることでした。ディレクトリは、コマンドラインの相対パスで指定されたままです。
chmod a+rx /tmp
chmod a+rx /tmp/migration
etc.
私はちょうどこの同じ問題に出くわしました。私の問題は、ダンプしようとしたディレクトリがmysqldプロセスの書き込み権限を持っていなかったことです。最初のSQLダンプは書き出されますが、csv/txtファイルの書き込みは失敗します。 SQLダンプは現在のユーザーとして実行され、csv/txtへの変換はmysqldを実行しているユーザーとして実行されるように見えます。そのため、ディレクトリには両方のユーザーの書き込み権限が必要です。
UbuntuはSELinuxを使用していますか?有効で強制されているかどうかを確認します。 /var/log/audit/audit.logが役立つ場合があります(Ubuntuがこれを使用している場合は、RHEL/Fedoraの場所です)。
相対パスではなく、絶対パスを指定する必要があります。
書き込み先の/ dataディレクトリへのフルパスを指定します。
CentOs 6.7でも同じ問題が発生しました。私の場合、すべての権限が設定されていて、エラーが発生しました。問題は、SE Linuxが「強制」モードになっていたことです。
コマンドSudo setenforce 0
を使用して「許容」に切り替えました
その後、すべてがうまくいきました。