2021년 2월 10일 수요일

MySQL 8.0.16 미만에서 동작하는 TempTable storage engine에 대하여

MySQL 8.0.13에서 메모리 사용률이 60% 미만인 데, 대량의 임시테이블 사용 시 가상 메모리 사용률이 급격히 올라가는 경우가 있었다.
MySQL 공식문서를 찾아보았지만, 정보가 부실하여 소스코드를 해석하면서 알아보기로 하였다.

TempTable 이란?
TempTable 스토리지 엔진에 대한 설명은 아래의 글을 참고
https://jongguheo.blogspot.com/2020/11/temptable-storage-engine.html

버전에 따른 차이
동작의 차이는 아래와 같은 기준으로 나뉘어져 있다.
  1. MySQL 8.0.15 이하
  2. MySQL 8.0.16 이상
  3. MySQL 8.0.23 이상
MySQL 8.0.15 이하
해당 버전에서는 "temptable_use_mmap" 라고 하는 시스템 변수가 존재하지 않는다.
변수의 의미는 설정 해놓은 "temptable_max_ram"를 초과 했을 때 메모리 맵 파일 or 디스크 임시 테이블 사용여부를 결정한다.
(temptable_max_ram의 기본 값은 1G)

temptable_use_mmap가 존재하지 않으므로 temptable_max_ram 초과 시 메모리 맵 파일을 사용하게 된다. 이로 인해 임시 테이블을 사용하는 SQL이 많은 경우 가상메모리 사용률이 높아질 수 있다.

소스코드를 해석해보면..
// 설정해놓은 temptable_max_ram 보다 많은 메모리를 임시 테이블에서 사용하고 있을 경우 True
// 작은 경우 False
if (bytes_allocated_in_ram > temptable_max_ram) { 
    t = Mem_type::DISK;
  } else {
    const size_t new_bytes_allocated_in_ram =
        bytes_allocated_in_ram.fetch_add(bytes) + bytes;

    DBUG_ASSERT(new_bytes_allocated_in_ram - bytes <=
                std::numeric_limits<decltype(bytes)>::max() - bytes);

    // 현재 임시 테이블이 사용하고 있는 메모리와 처리하려고 하는 데이터량을 합산
// 합산 한 후에 temptable_max_ram와 비교
// temptable_max_ram 보다 작은 경우 True. 큰 경우 False if (new_bytes_allocated_in_ram <= temptable_max_ram) { t = Mem_type::RAM; } else { t = Mem_type::DISK; bytes_allocated_in_ram.fetch_sub(bytes); } } void *ptr;
  // 아래의 조건문을 MySQL 8.0.16에서 유심히 보도록 하자.
  if (t == Mem_type::RAM) {
    ptr = mem_fetch_from_ram(bytes);
    if (ptr == nullptr) {
      throw Result::OUT_OF_MEM;
    }
  } else {
    DBUG_ASSERT(t == Mem_type::DISK);
    ptr = mem_fetch_from_disk(bytes);
    if (ptr == nullptr) {
      throw Result::RECORD_FILE_FULL;
    }
  }
https://github.com/mysql/mysql-server/blob/mysql-8.0.15/storage/temptable/include/temptable/allocator.h#L636

MySQL 8.0.16 이상
temptable_use_mmap이 추가되어 메모리 맵 파일을 사용할 지, 디스크 임시 테이블을 사용할 지 컨트롤할 수 있게 되었다.
if (t == Mem_type::RAM) {
    ptr = mem_fetch_from_ram(bytes);
    if (ptr == nullptr) {
      throw Result::OUT_OF_MEM;
    }
  } else {
    DBUG_ASSERT(t == Mem_type::DISK);
    // temptable_use_mmap가 OFF로 설정되어 있는 경우 True
    // 즉, 디스크 임시 테이블을 사용하도록 한다.
    if (!temptable_use_mmap) {
      throw Result::RECORD_FILE_FULL;
    }
    ptr = mem_fetch_from_disk(bytes);
    if (ptr == nullptr) {
      throw Result::RECORD_FILE_FULL;
    }
  }
https://github.com/mysql/mysql-server/blob/mysql-8.0.16/storage/temptable/include/temptable/allocator.h#L655

MySQL 8.0.23 이상
해당 버전에서는 "temptable_max_mmap" 라고 하는 시스템 변수가 추가되었다.
변수의 의미는 temptable_use_mmap가 ON인 경우 메모리 맵 파일이 사용할 수 있는 맥시멈을 나타낸다.
해당 수치를 초과하는 경우는 디스크 임시 테이블을 사용하게 된다.
(temptable_max_mmap의 기본 값은 1G)

# Refer
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html
https://dev.mysql.com/doc/refman/8.0/en/internal-temporary-tables.html

결혼이민비자 신청방법(F-6-1 국민의 배우자)

 제가 일본인 여자친구와 결혼 후, 한국에 귀국하기 위해 신청한 결혼이민비자에 대하여 작성해보도록 하겠습니다. 필자는 일본에서 근무하고 있었으며, 한국에서의 소득은 없었습니다. 결혼이민비자를 신청한 날짜는 2021-04-21 이며, 사증이 발급된 날짜...