저자 : Gao Peng (스크린 이름 여덟 이상), "32에서 MySQL 마스터의 원리에 대한 심층적 이해"시리즈 저자.
시리즈 링크 : https://www.jianshu.com/nb/43148932
버전 : 5.7.29
1. 제기 된 질문
정상적인 상황에서는 lsof 명령을 사용하여 현재 MySQL에서 사용하는 임시 파일의 사용을 확인합니다. 이는 이러한 임시 파일을 ls 명령으로 표시 할 수 없기 때문입니다. 5.7에서 생성 방법은 Liunx api mkstemp를 사용하여이 파일을 생성하는 것입니다. 프로세스에 따라 다르며 파일 디스크립터를 반환 한 후 api unlink를 사용하여 삭제합니다.
소스 코드는 주로 create_temp_file 함수에 포함 된이 섹션입니다.
org_file=mkstemp(to);
if (mode & O_TEMPORARY)
(void) my_delete(to, MYF(MY_WME));
5.7의 다음과 같은 일반적인 기능 중 일부는 다음과 같은 이러한 종류의 임시 파일을 사용합니다.
실행 계획 파일 정렬 파일 이름 : MY로 시작
lsof|grep delete
如:/tmp/MYdRH1GW (deleted)
큰 트랜잭션 이진 로그 캐시 파일 이름 : ML 시작
lsof|grep delete
如:/tmp/MLq9INFu (deleted)
온라인 DDL에는 일반적 으로 ib로 시작 하는 키 추가와 같은 정렬이 포함됩니다.
alter table testsort add key(id);
lsof|grep delete
如:
/tmp/ibCxlYQg (deleted)
/tmp/ib51nvZ1 (deleted)
设置 innodb_tmpdir可以将这类文件放到指定的目录
그러나 MySQLD 프로세스가 막 시작되었을 때 이런 종류의 파일을 확인하면 다음과 같은 많은 파일을 찾을 수 있습니다.
[root@mgr2 ~]# lsof|grep delete|grep mysql|wc -l
215
[root@mgr2 ~]#
이 파일의 크기는 기본적으로 0이고 모두 ib로 시작합니다. 한 친구가이 질문을 한 적이 있습니다. 자세한 설명은 다음과 같습니다.
2. MySQLD 초기화 후 임시 파일 유형
실제로 5.7에서는 이러한 파일이 create_temp_file 함수에 의해 생성되고 MySQLD가 시작될 때 분석을 위해 중단 점을 넣을 수 있습니다.
다음 파일은 ib로 시작하는 임시 파일입니다.
srv_monitor_file (srv0start.cc:2022) : show engine innodb status 명령을 출력 할 때 일반적으로 사용하는 파일입니다. 주요 기능은 srv_printf_innodb_monitor입니다. 스택 핀 :
srv_dict_tmpfile (srv0start.cc:2032) : 주로 외래 키 생성 정보의 출력과 관련이 있습니다.
srv_misc_tmpfile (srv0start.cc:2041) : 주로 외래 키 발생 오류 출력과 관련이 있습니다.
lock_latest_err_file (lock0lock.cc:465) : 주로 교착 상태 오류 출력과 관련이 있습니다.
dict_foreign_err_file (dict0dict.cc:1245) : 주로 오류 출력을 던지는 외래 키와 관련이 있습니다.
사실이 파일들은 너무 많이 차지하지 않는다는 것을 알 수 있습니다. 사실이 5 개의 파일은 초기화 후에 생성되었습니다.
셋째, lsof의 기본 출력이 훨씬 더 많은 이유
분명히 위의 ib로 시작하는 5 개의 파일 만 있습니다. 그래서 lsof (매개 변수없이)를하면 무엇을 볼 수 있습니까?
다음은 초기화 할 때 표시되는 번호입니다.
[root@mgr2 support-files]# lsof|grep delete|grep mysql|wc -l
215
[root@mgr2 support-files]# lsof|grep delete|grep mysql
mysqld 12916 mysql 10u REG 8,5 9765 17109405 /tmp/ibpuzts2 (deleted)
mysqld 12916 mysql 11u REG 8,5 0 23137683 /tmp/ibA4q9iX (deleted)
mysqld 12916 mysql 12u REG 8,5 0 23137684 /tmp/ibRdXEl4 (deleted)
mysqld 12916 mysql 13u REG 8,5 0 23137685 /tmp/ibe6hfHJ (deleted)
mysqld 12916 mysql 19u REG 8,5 0 23137686 /tmp/ibfb7rps (deleted)
mysqld 12916 12920 mysql 10u REG 8,5 9765 17109405 /tmp/ibpuzts2 (deleted)
mysqld 12916 12920 mysql 11u REG 8,5 0 23137683 /tmp/ibA4q9iX (deleted)
mysqld 12916 12920 mysql 12u REG 8,5 0 23137684 /tmp/ibRdXEl4 (deleted)
mysqld 12916 12920 mysql 13u REG 8,5 0 23137685 /tmp/ibe6hfHJ (deleted)
mysqld 12916 12920 mysql 19u REG 8,5 0 23137686 /tmp/ibfb7rps (deleted)
mysqld 12916 12944 mysql 10u REG 8,5 9765 17109405 /tmp/ibpuzts2 (deleted)
mysqld 12916 12944 mysql 11u REG 8,5 0 23137683 /tmp/ibA4q9iX (deleted)
mysqld 12916 12944 mysql 12u REG 8,5 0 23137684 /tmp/ibRdXEl4 (deleted)
mysqld 12916 12944 mysql 13u REG 8,5 0 23137685 /tmp/ibe6hfHJ (deleted)
mysqld 12916 12944 mysql 19u REG 8,5 0 23137686 /tmp/ibfb7rps (deleted)
mysqld 12916 12945 mysql 10u REG 8,5 9765 17109405 /tmp/ibpuzts2 (deleted)
mysqld 12916 12945 mysql 11u REG 8,5 0 23137683 /tmp/ibA4q9iX (deleted)
mysqld 12916 12945 mysql 12u REG 8,5 0 23137684 /tmp/ibRdXEl4 (deleted)
此处省略....
우리는 주로 다음 열에 중점을 둡니다.
PID : 프로세스의 프로세스 ID 번호입니다.
TID : 작업 (스레드) ID입니다.
FD : 파일의 파일 설명자 번호입니다.
SIZE / OFF : 파일의 크기 또는 바이트 단위의 파일 오프셋입니다.
NAME : 파일이있는 마운트 지점 및 파일 시스템의 이름입니다. 자세한 내용은 man을 참조하십시오.
출력에서 우리는
PID는 모두 12916입니다. 이것은 mysqld의 PID이지만 TID는 다릅니다. 물론 멀티 스레딩의 원인입니다.
FD와 NAME은 실제로 정기적으로 반복되며 실제로 5 개의 값만 있습니다. 이것은 위에서 언급 한 5 개의 임시 파일을 나타냅니다.
SIZE는 비교적 작습니다.
따라서 출력은 최대 215 줄이지 만 실제로 전체 MySQLD 프로세스는 파일 설명자 (FD)가 스레드간에 공유되기 때문에 앞에서 언급 한 5 개의 임시 파일 인 5 개의 파일 만 엽니 다. , 모든 스레드 lsof는 볼 때이 5 개의 임시 파일을 표시합니다 .MySQL에 세션이 많으면 스레드가 많으므로 lsof가 보는 임시 파일의 수는 스레드 데이터의 양 * 5입니다. 따라서 임시 파일의 공간 사용량을 확인할 때 과도한 출력에 놀라지 말고 MySQLD 프로세스의 임시 파일 만 출력하면됩니다. 출력은 다음과 같습니다.
[root@mgr2 proc]# lsof|grep delete|grep mysql |awk '{if ($3=="mysql") print}'
mysqld 12916 mysql 10u REG 8,5 9765 17109405 /tmp/ibpuzts2 (deleted)
mysqld 12916 mysql 11u REG 8,5 0 23137683 /tmp/ibA4q9iX (deleted)
mysqld 12916 mysql 12u REG 8,5 0 23137684 /tmp/ibRdXEl4 (deleted)
mysqld 12916 mysql 13u REG 8,5 0 23137685 /tmp/ibe6hfHJ (deleted)
mysqld 12916 mysql 19u REG 8,5 0 23137686 /tmp/ibfb7rps (deleted)
或者加上lsof加上参数只看进程的临时文件,而不去查看子线程的临时文件
[root@mgr2 ~]#lsof -p 12916|grep delete
mysqld 12916 mysql 10u REG 8,5 9765 17109405 /tmp/ibpuzts2 (deleted)
mysqld 12916 mysql 11u REG 8,5 0 23137683 /tmp/ibA4q9iX (deleted)
mysqld 12916 mysql 12u REG 8,5 0 23137684 /tmp/ibRdXEl4 (deleted)
mysqld 12916 mysql 13u REG 8,5 0 23137685 /tmp/ibe6hfHJ (deleted)
mysqld 12916 mysql 19u REG 8,5 0 23137686 /tmp/ibfb7rps (deleted)
MySQL8.0.21에서 이러한 임시 파일의 이름에 몇 가지 변경 사항이 있으며 다음과 같이 Linx에서 이러한 방식으로 직접 (O_TMPFILE 플래그) 생성 될 수 있습니다.
open(dirname_buf, O_RDWR | O_TMPFILE | O_CLOEXEC,
S_IRUSR | S_IWUSR)
我测试得到的名字如下:
[root@mgr4 ~]# lsof|grep a.out|grep delete
a.out 11703 root 3u REG 8,5 0 24237415 /tmp/#24237415 (deleted)
MySQLD启动后查看的临时文件名如下:
[root@mgr4 ~]# lsof -p 11488|grep delete
mysqld 11488 mysql 10u REG 8,5 0 24237413 /tmp/#24237413 (deleted)
mysqld 11488 mysql 11u REG 8,5 0 24237414 /tmp/#24237414 (deleted)
mysqld 11488 mysql 12u REG 8,5 0 24237416 /tmp/#24237416 (deleted)
mysqld 11488 mysql 19u REG 8,5 0 24237417 /tmp/#24237417 (deleted)
임시 파일 이름은 변경되었지만 기본 용도는 5.7과 유사합니다.
넷째, 쓰레드 간 파일 기술자 (FD) 공유
이 단락은 Linux 시스템 프로그래밍을 빌려서 다음과 같이 설명합니다.
다섯, 테스트
다음과 같이 테스트하기 위해 간단한 다중 스레드 코드를 작성할 수 있습니다 (잘못된 판단을 내리지 않고).
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
void* u_sleep(void* t)
{
char file_temp[]="ibXXXXXX";
int fd = mkstemp(file_temp);
unlink( file_temp);
int i = 0;
char* teststr="aasd";
printf("thead tmpfile: %s\n",file_temp);
for(i = 0;i<100000;i++)
{
write(fd,teststr,strlen(teststr));
}
sleep(100);
}
int main(void)
{
int ret = 0;
pthread_t tid[5];
int i = 0;
int fd = 0;
int tid_num = 0;
int tmp_file_num=5;
char file_temp[]="ibXXXXXX";
for(i=0;i<tmp_file_num;i++)
{
strcpy(file_temp,"ibXXXXXX");
mkstemp(file_temp);
printf("%s\n",file_temp);
unlink( file_temp);
}
for (i = 0;i<sizeof(tid)/sizeof(pthread_t);i++)
{
pthread_create(tid+tid_num,NULL,u_sleep,NULL);
tid_num++;
}
for(i = 0;i<sizeof(tid)/sizeof(pthread_t);i++)
{
ret = pthread_join( *(tid+i) , NULL );
}
}
이 코드는 실제로 mkstemp를 통해 5 개의 임시 파일을 설정하고 메인 프로세스에서 링크 해제를 시뮬레이션하고 ib (MySQL 임시 파일 시뮬레이션)로 시작하여 5 개의 스레드를 설정하고 각 스레드가 임시 파일을 생성합니다. , 무언가를 쓰면 스레드가 잠시 휴면 상태가되면 주 스레드가 스레드가 리소스를 회수 할 때까지 기다리므로 관찰 할 충분한 시간을 가질 수 있습니다.
이러한 방식으로 관찰은 파일 설명자 (FD)가 스레드간에 공유되는지 여부입니다. 관찰 할 수있는 출력은 60 (메인 제어 스레드 1 개, 자식 스레드 5 개, 기본 제어 스레드가 임시 파일 5 개, 스레드 공유 6 개)이 될 것으로 예상됩니다. 즉, 30 개이고 각 하위 스레드는 1 개의 임시 파일과 5 개의 임시 파일을 만들고 6 개의 스레드는 30 개를 다시 공유합니다. 다음 출력은 다음과 같습니다.
[root@mgr2 ~]# lsof|grep delete|grep a.out|wc -l
60
[root@mgr2 ~]# lsof|grep delete|grep a.out|awk '{if ($3=="root") print}'
a.out 13460 root 3u REG 8,5 0 43691141 /root/ibpotqYK (deleted)
a.out 13460 root 4u REG 8,5 0 43691142 /root/ibxlgopk (deleted)
a.out 13460 root 5u REG 8,5 0 43691144 /root/ibHOmmQT (deleted)
a.out 13460 root 6u REG 8,5 0 43691145 /root/ibvmykht (deleted)
a.out 13460 root 7u REG 8,5 0 43691146 /root/ib3TViI2 (deleted)
a.out 13460 root 8u REG 8,5 400000 43691147 /root/ibEn9hAb (deleted)
a.out 13460 root 9u REG 8,5 400000 43691148 /root/ibkexi9B (deleted)
a.out 13460 root 10u REG 8,5 400000 43691149 /root/ibJJZi1K (deleted)
a.out 13460 root 11u REG 8,5 400000 43691150 /root/ibRRxKtk (deleted)
a.out 13460 root 12u REG 8,5 400000 43691151 /root/ibWuKsWT (deleted)
[root@mgr2 ~]# lsof|grep delete|grep a.out|more
a.out 13460 root 3u REG 8,5 0 43691141 /root/ibpotqYK (deleted)
a.out 13460 root 4u REG 8,5 0 43691142 /root/ibxlgopk (deleted)
a.out 13460 root 5u REG 8,5 0 43691144 /root/ibHOmmQT (deleted)
a.out 13460 root 6u REG 8,5 0 43691145 /root/ibvmykht (deleted)
a.out 13460 root 7u REG 8,5 0 43691146 /root/ib3TViI2 (deleted)
a.out 13460 root 8u REG 8,5 400000 43691147 /root/ibEn9hAb (deleted)
a.out 13460 root 9u REG 8,5 400000 43691148 /root/ibkexi9B (deleted)
a.out 13460 root 10u REG 8,5 400000 43691149 /root/ibJJZi1K (deleted)
a.out 13460 root 11u REG 8,5 400000 43691150 /root/ibRRxKtk (deleted)
a.out 13460 root 12u REG 8,5 400000 43691151 /root/ibWuKsWT (deleted)
a.out 13460 13461 root 3u REG 8,5 0 43691141 /root/ibpotqYK (deleted)
a.out 13460 13461 root 4u REG 8,5 0 43691142 /root/ibxlgopk (deleted)
a.out 13460 13461 root 5u REG 8,5 0 43691144 /root/ibHOmmQT (deleted)
a.out 13460 13461 root 6u REG 8,5 0 43691145 /root/ibvmykht (deleted)
a.out 13460 13461 root 7u REG 8,5 0 43691146 /root/ib3TViI2 (deleted)
a.out 13460 13461 root 8u REG 8,5 400000 43691147 /root/ibEn9hAb (deleted)
a.out 13460 13461 root 9u REG 8,5 400000 43691148 /root/ibkexi9B (deleted)
a.out 13460 13461 root 10u REG 8,5 400000 43691149 /root/ibJJZi1K (deleted)
a.out 13460 13461 root 11u REG 8,5 400000 43691150 /root/ibRRxKtk (deleted)
a.out 13460 13461 root 12u REG 8,5 400000 43691151 /root/ibWuKsWT (deleted)
省略很多.....
그래서 우리의 진술이 증명되었습니다.
코드를 스캔하여 작성자 WeChat 추가
전체 텍스트가 끝났습니다.
MySQL 즐기기 :)
Ye 교사의 "MySQL Core Optimization"수업이 MySQL 8.0으로 업그레이드되었습니다. 코드를 스캔하여 MySQL 8.0 연습을 시작하세요.