[mysql] 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”사용자로 실행 중입니다.

이상하게도 내가 시도한 다른 디렉토리가 아닌 / tmp에 파일을 만들 수 있습니다. 사용자 mysql이 디렉토리에 쓸 수있는 권한이 설정되어 있어도 가능합니다.

이것은 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가 강제 모드에 포함되어 있다면 아마도 쓰기를 거부하는 것입니다. /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 디렉토리를 읽고 쓸 수 있습니다. 이것의 보안 영향을 이미 고려 하셨기를 바랍니다.


답변

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/

의류를 다시 시작하는 것을 잊지 마십시오.

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

그런 다음 쿼리를 시도하십시오. 이것은 문제를 디버깅 한 후 나를 위해 일했습니다.


답변

이 문제는 오랫동안 나를 괴롭 혔습니다. 이 토론이 RHEL / Fecora의 솔루션을 지적하지 않는다는 것을 알았습니다. RHEL을 사용하고 있으며 Ubuntu에서 AppArmer에 해당하는 구성 파일을 찾지 못했지만 PATH 디렉토리의 모든 디렉토리를 mysql에서 읽고 액세스 할 수 있도록하여 문제를 해결했습니다. 예를 들어 / tmp 디렉토리를 생성하는 경우 다음 두 명령은 SELECT INTO OUTFILE이 .sql 및 .sql 파일을 출력 할 수 있도록합니다.

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

홈 디렉토리 / home / tom에 디렉토리를 작성하는 경우 / home 및 / home / tom 모두에 대해이를 수행해야합니다.


답변

다음과 같이 할 수 있습니다.

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


답변

시도 할 몇 가지 :

  • 이다 secure_file_priv 시스템 변수 세트는? 그렇다면 모든 파일을 해당 디렉토리에 기록해야합니다.
  • 파일이 존재하지 않는지 확인하십시오. MySQL은 기존 파일을 덮어 쓰지 않고 새 파일 만 생성합니다.