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"사용자로 실행 중입니다.

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

이것은 Ubuntu에서 실행되는 MySQL 5.0.75입니다.


3
시스템 오류가 13으로되어보고, 이것은 아마 아니지만, 디렉토리에 INTO OUTFILE을 제한 MySQL의 설정이 있습니다 : dev.mysql.com/doc/refman/5.0/en/... 이 있는지 여부 어쩌면 가치가 얼핏 로 설정합니다 /tmp.
Pekka

이 변수는 설치시 비어 있습니다. 해당 문서에 따르면 출력 디렉토리가 제한되지 않아야 함을 의미합니다.
Ryan Olson

답변:


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 폴더의 모든 내용을 수정하고 읽을 수 있습니다. 지금 해킹 당하지 마세요.
Ryan Ward 2011

2
@Serdar, 배포판과 함께 배포 된 AppArmor MySQL 규칙 세트 는 기본적으로 허용하지 않습니다 . 이것은 새로운 설치를위한 좋은 규칙의 기준이기 때문에 의미가 있습니다. 나는 우리가 설치 후 우리의 필요에 맞게 규칙 세트를 수정해야한다고 믿고 있습니다. MySQL이 특정 디렉토리에 쓸 수 있도록 허용하는 것이 원래 asker의 의도였습니다. 그러나 위에서 쉽게 명시 적이 지 않은 경우이 솔루션에 대해 더 이상 고민하는 사람들에게 참고할 사항이 있습니다. 경고 : 위의 변경으로 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

1
/ tmp에 쓰기 위해 작동합니다. 대신 창을 사용하십시오. 리눅스는 짜증
빅터 Ionescu에게

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/

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

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 비밀번호 입력 : mysqldump : Got error : 1 : Ca n't create / write to file '/data/dumptest/test.txt'(Errcode : 13) when running '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 비밀번호 입력 : mysqldump : 오류 발생 : 1 : ( 같은 오류)
Ryan Olson

글쎄요, 댓글이 형식화되지 않는다는 사실은 몰랐지만 몇 가지 다른 방법을 다시 확인했습니다. 먼저 mysql : mysql이 소유 한 대상 디렉토리를 사용하고 사용자가 소유 한 대상 디렉토리를 사용하여 dump 명령을 실행했지만 두 가지 방법 모두 동일한 권한 오류가 발생합니다.
Ryan Olson

기록을 위해, 이것은 의류 권한을 변경 했음에도 불구하고 저에게 효과적이었습니다
Alex

의류를 수정하려고했지만 효과가 없었습니다. 권한 변경 'chmod 777'이 저에게 효과적이었습니다!
Sudarshan_SMD

7

MySQL은 여기서 어리석어지고 있습니다. / tmp / data / .... 아래에 파일을 생성하려고 시도하므로 다음과 같이 할 수 있습니다.

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

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


이 답변이 가장 마음에 듭니다. 쉽고, 작동하며, 의상을 입을 필요가 없습니다. 파이프를 사용하여 수행하는 다른 방법은 수행되는 모든 버퍼링으로 인해 대규모 내보내기에 적합하지 않습니다.
Chris Seline 2014

6

이 문제는 오랫동안 나를 괴롭 혔습니다. 이 토론이 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 모두에 대해이를 수행해야합니다.


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로 제어 할 수 있습니까?
Hamman Samuel

4

시도 할 몇 가지 :

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

1
또한 secure_file_priv로 이동합니다. 파일이 이미있는 경우 오류 메시지가 다릅니다 (errcode 13 아님).
Xavier Maillard

secure_file_priv는 현재 설정되어 있지 않으므로 파일을 작성할 수있는 위치에 제한을 두어서는 안된다는 것을 이해합니다. 내가 그것을 오해하고 있으며 파일 시스템의 아무 곳에 나 쓸 수 있도록하려면 '/'와 같이 명시 적으로 설정해야합니까?
Ryan Olson

또한 쿼리를 실행하기 전에 파일이 존재하지 않는지 확인하고 있습니다.
Ryan Olson

피드백 감사드립니다. 귀하의 결과에 따르면 이러한 제안 중 어느 것도 귀하의 문제를 유발하지 않는다고 생각합니다.
mdma 2010-06-04

3

동일한 문제가 있으며 다음 단계에 따라이 문제를 해결했습니다.

  • 운영 체제 : 우분투 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

필자의 경우 해결책은 디렉토리 경로의 모든 디렉토리를 mysql( chmod a+rx) 로 읽고 액세스 할 수 있도록 만드는 것이 었습니다 . 디렉토리는 여전히 명령 줄에서 상대 경로로 지정되었습니다.

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

2

나는이 같은 문제에 부딪쳤다. 내 문제는 덤프하려는 디렉토리에 mysqld 프로세스에 대한 쓰기 권한이 없다는 것입니다. 초기 SQL 덤프는 기록되지만 csv / txt 파일의 기록은 실패합니다. SQL 덤프가 현재 사용자로 실행되고 csv / txt 로의 변환이 mysqld를 실행하는 사용자로 실행되는 것처럼 보입니다. 따라서 디렉토리에는 두 사용자 모두에 대한 쓰기 권한이 필요합니다.


1

상대 경로가 아닌 절대 경로를 제공해야합니다.

쓰려는 / data 디렉토리의 전체 경로를 제공하십시오.


그것은 나에게 절대적인 길처럼 보입니다. 그렇지 않습니까?
Pekka

2
mysql 사용자로 이것을 시도하여 mysql 외부에서 파일을 생성 할 수 있는지 확인하십시오.touch /data/outfile.csv
Ike Walker

1
먼저 mysql 사용자의 셸이 / bin / false로 설정 되었기 때문에 할 수 없어서 mysql로 ​​로그인 할 수 없었습니다. 이것이 문제의 원인이 아닌지 확인하기 위해 mysql의 셸을 / bin / bash로 설정하고 해당 사용자에게 su'd를 설정하고 / data의 파일을 터치했습니다. mysql이 소유 한 파일이 성공적으로 생성되었습니다.
Ryan Olson

3
"disable"쉘 중 하나를 사용하는 경우에도 계정에 su 할 수 있습니다. su --shell=/bin/sh nameofaccount
Marc B

고마워, 몰랐어.
Ryan Olson

1

Ubuntu는 SELinux를 사용합니까? 활성화되어 있고 적용되는지 확인하십시오. /var/log/audit/audit.log는 도움이 될 수 있습니다 (우분투가 고정하는 경우-RHEL / Fedora 위치).


0

CentOs 6.7에서 동일한 문제가 발생했습니다. 제 경우에는 모든 권한이 설정되었지만 여전히 오류가 발생했습니다. 문제는 SE Linux가 "강제"모드에 있다는 것입니다.

명령을 사용하여 "허용"으로 전환했습니다. sudo setenforce 0

그런 다음 모든 것이 잘되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.