여러 조인 시 tmp 테이블에 대한 MySQL 키 파일이 잘못됨
저는 도움을 청하러 자주 오지는 않지만, 이 일로 인해 매우 답답하고 누군가 그것을 전에 경험해 봤으면 합니다.
여러 조인(join)을 사용하여 테이블에서 레코드를 가져오려고 할 때마다 다음 오류가 발생합니다.
#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it
따라서 이 쿼리는 다음 오류를 생성합니다.
SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1
하지만 이건 아니야:
SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1
그리고 이것도 마찬가지야
SELECT * FROM `core_username`
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1
원인은 무엇입니까?tmp 테이블 수리는 어떻게 해야 할지 모르겠지만 매번 새로운 tmp 테이블이기 때문에 문제가 될 것 같지는 않습니다.사용자 이름 테이블은 상당히 크지만(현재는 233,718 레코드) 그것과 관련이 있을 것 같지는 않습니다.
어떤 도움이라도 주시면 감사하겠습니다.
업데이트: 추가 테스트 후 결과를 주문하려고 할 때만 오류가 발생하는 것으로 보입니다.즉, 이 쿼리는 제가 기대하는 것을 제공합니다.
SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
LIMIT 1
단, 다음 항목을 추가합니다.
ORDER BY `core_username`.`name` ASC
에러가 트리거 됩니다.이 문제는 현재 사용하고 있는 특정 웹 서버에서만 발생합니다.데이터베이스를 다운로드하여 로컬호스트와 다른 서버에서 동일한 작업을 시도하면 정상적으로 실행됩니다.MySQL 버전은 5.0.77입니다.
이 사실을 알고 있기 때문에 이 블로그 투고에서 설명한 것처럼 tmp 테이블이 너무 크고 MySQL이 초크를 하고 있다는 것을 확신합니다.아직 해결책이 뭔지 모르겠어요.
임시 테이블에서 이 오류가 발생할 수 있습니다.
#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it
그 이유는/tmp
폴더의 공간이 부족합니다.일부 Linux 설치에서는/tmp
는 자체 파티션에 있으며 공간이 부족합니다.큰 MySQL 쿼리가 이 파티션을 채웁니다.
사용할 수 있습니다.df -h
유무를 확인하다\tmp
는 자체 파티션에 있으며 할당되는 공간의 양입니다.
자체 파티션에 있고 공간이 부족한 경우 다음 중 하나를 수행할 수 있습니다.
(a) /tmp를 수정하여 파티션의 공간이 넓어지도록 합니다(예를 들어 메인 파티션으로 재할당 또는 이동).
(b) 다른 파티션의 다른 임시 폴더를 사용하도록 MySql 구성을 변경합니다./var/tmp
MySQL tmpdir는 큰 테이블을 사용할 때 수백 MB를 소비할 수 있으므로 쿼리를 실행하는 동안 사용 가능한 공간(/tmp)을 확인하십시오.나한테는 이런 게 통했어
$ while true; do df -h /tmp; sleep .5; done
이것을 실행하다
REPAIR TABLE `core_username`,`core_site`,`core_person`;
또는 다음을 수행합니다.
select * from (
SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
LIMIT 1)
ORDER BY `name` ASC
ANALYZE TABLE을 실행하면 도움이 될 수 있습니다.
이 문제가 갑자기 큰 테이블(약 1억 행)에 나타나 MySQL은 /tmp를 사용하여 1GB가 넘는 임시 테이블을 쓰려고 했지만 /tmp가 약 6억으로 제한되었기 때문에 실패했습니다.
InnoDB 테이블의 통계는 다소 오래되었다는 것이 판명되었습니다.ANALYZE TABLE ...을 실행한 후 통계가 업데이트되고 문제가 해결되었습니다.보다 정확한 통계를 통해 MySQL은 쿼리를 올바르게 최적화할 수 있었고 더 이상 큰 tmp 파일이 필요하지 않았습니다.
이제 "mysqlcheck -Aa"를 정기적으로 실행하여 모든 테이블 통계를 최신 상태로 유지합니다.
50만 이상의 레코드가 있는 테이블에 대한 쿼리에서 이 문제가 발생했습니다.이 에러는, 을 가리키고 있는 것과 같은 타입의 에러를 나타내고 있었습니다./tmp 디렉토리에 있는 MYI 파일은 확인 시 거의 존재하지 않았습니다./etc/my.cnf 파일의 힙과 임시 파일 크기를 이미 늘렸습니다.
쿼리의 문제는 마지막에 ORDER 절이 실제로 포함되어 있다는 것입니다.이 절을 생략하면 쿼리는 오류 없이 동작합니다.LIMIT도 있었어요. 저는 최근에 나온 5개의 레코드를 보려고 했어요.ORDER 절을 포함하면 질식되어 오류가 발생합니다.
mysqld가 ORDER를 적용하기 위해 자이언트 테이블의 모든 레코드가 포함된 내부 임시 테이블을 만들고 있었습니다.
이 문제를 해결하려면 추가 WHERE 조건을 적용하여 큰 테이블의 레코드를 작은 세트로 제한해야 합니다.필터링을 할 날짜/시간 필드가 있어서 편리했습니다.
그게 도움이 됐으면 좋겠어요.
Unix의 경우 MySQL은 TMPDIR 환경변수 값을 임시 파일을 저장할 디렉토리의 경로 이름으로 사용합니다.TMPDIR이 설정되어 있지 않은 경우 MySQL은 시스템 기본값(보통 /tmp, /var/tmp 또는 /usr/tmp)을 사용합니다.
Windows, Netware 및 OS2에서는 MySQL은 TMPDIR, TEMP 및 TMP 환경변수 값을 순서대로 확인합니다.처음 설정된 것으로 판명된 경우 MySQL은 이를 사용하고 나머지 항목은 확인하지 않습니다.TMPDIR, TEMP 또는 TMP가 설정되어 있지 않은 경우 MySQL은 Windows 시스템 기본값(통상은 C:\windows\temp)을 사용합니다.
임시 파일 디렉토리를 포함하는 파일시스템이 너무 작을 경우 mysqld에 --tmpdir 옵션을 사용하여 공간이 충분한 파일시스템 내의 디렉토리를 지정할 수 있습니다.
MySQL 5.0에서는 --tmpdir 옵션을 라운드 로빈 방식으로 사용되는 여러 경로 목록으로 설정할 수 있습니다.경로는 UNIX에서는 콜론 문자(":")와 Windows, NetWare 및 OS/2에서는 세미콜론 문자(";")로 구분해야 합니다.
저도 같은 문제를 겪고 있어요.
해결 방법은 다음과 같습니다. 1. "select *"를 사용하지 마십시오.필요한 필드를 선택합니다. 2. 쿼리를 분할합니다.선택한 필드가 너무 많은 경우 이를 일부 쿼리로 분할할 수 있습니다.결과를 포함하는 변수를 변경하지 않으려면 나중에 결과를 "array_merge()"할 수 있습니다.
제 경우 쿼리를 5개의 쿼리로 분할하고 PHP를 사용하여 어레이를 Marge합니다.
문제는 mysql 서버에 있습니다.애플리케이션 개발자(저와 같은)에게 권한이 없는 것일 뿐입니다.
저도 비슷한 문제가 있었어요.제 경우 소유자/허가가 잘못되어 문제가 발생하였습니다.데이터 디렉토리의 소유자를 mysql 사용자로 변경하면 문제가 해결되었습니다.
mysql에는 공간이 없기 때문에 파일 tmp만 늘려주세요.쿼리에 대해서는...
mount -o remount,size=[NEW MAX SIZE HERE] tmpfs /tmp
링크 레퍼런스:
일반 오류: 126 테이블 '/tmp/#sql_254c_0'에 대한 키 파일이 잘못되었습니다.MYI'; 수복을 시도하다
[오류] /usr/sbin/mysqld:'/mysqltmp/#sql_ca1a_0' 테이블의 키 파일이 잘못되었습니다.MYI'; 수복을 시도하다
3개의 테이블 중 하나의 인덱스 키가 잘못되었을 수 있습니다. 3개의 테이블 모두에서 복구 명령을 실행해 보십시오.
EXPLINE 키워드를 사용하면 이 쿼리를 최적화하는 방법을 알 수 있습니다.기본적으로 필요한 것은 가능한 한 빨리 결과 세트를 작게 하는 것입니다.core_username에 마지막까지 모든 행의 결과 세트가 있는 경우 주문 시 다음과 같은 위험이 있습니다.이것.
core_username만으로 문제없이 오더할 수 있다면 min() 행을 서브쿼리로 얻을 수 있습니다.
언급URL : https://stackoverflow.com/questions/2090073/mysql-incorrect-key-file-for-tmp-table-when-making-multiple-joins
'it-source' 카테고리의 다른 글
테이블 'db_session'은 'DELETE'의 대상과 별도의 데이터 소스로 두 번 지정됩니다. (0) | 2022.10.30 |
---|---|
vue.js 2에서 Larabel의 baseurl을 사용하려면 어떻게 해야 하나요? (0) | 2022.10.30 |
PowerMockito 모의 단일 정적 메서드 및 반환 객체 (0) | 2022.10.30 |
Vuex: 디스패치에서는 약속을 반환하여 체인으로 묶을 수 있습니까? (0) | 2022.10.30 |
입력 유형="텍스트"에서 원하는 대로 변경 사항을 추적하는 가장 좋은 방법은 무엇입니까? (0) | 2022.10.30 |