MySQL lsof가 너무 많은 임시 파일을 보는 이유

저자 : 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 연습을 시작하세요.

추천

출처blog.csdn.net/n88Lpo/article/details/108590890