[MySQL] 아키텍처

당당·2024년 5월 1일
0

MySQL

목록 보기
4/18

📔설명

MySQL 엔진 아키텍처, InnoDB 스토리지 엔진 아키텍처, MyISAM 스토리지 엔진 아키텍처, MySQL 로그 파일을 알아보자!


🍸MySQL 엔진 아키텍처

1. MySQL 전체 구조

MySQL 엔진 : 클라이언트로부터의 접속쿼리 요청을 처리하는 커넥션 핸들러SQL 파서전처리기, 쿼리 최적화 실행을 위한 옵티마이저가 중심
=> DBMS의 두뇌

스토리지 엔진 : 실제 데이터를 디스크 스토리지에 저장하거나 디스크 스토리지로부터 데이터를 읽어오는 부분 전담
=> 동시에 여러개 사용 가능

create table test(col1 int, col2 int) engine=innodb;

핸들러(Handler) 요청 : MySQL 엔진의 쿼리 실행기에서 데이터를 쓰거나 읽어야 할 때 각 스토리지 엔진에 쓰기 또는 읽기 요청
=> 핸들러 API를 통해 MySQL 엔진과 데이터를 주고 받음

--얼마나 핸들러 API를 통해 많은 데이터 작업이 있었는지
show global status like 'Handler%';


2. MySQL 스레딩 구조

MySQL 서버는 스레드 기반으로 작동하며, 포그라운드 스레드백그라운드 스레드로 구분

--실행 중인 스레드 목록
select thread_id, name, type, processlist_user, processlist_host
from performance_schema.threads
order by type, thread_id;

마지막 one_connection 스레드만이 실제 사용자의 요청을 처리하는 포그라운드 스레드다.

포그라운드 스레드(클라이언트 스레드)

  • 최소한 MySQL 서버에 접속된 클라이언트 수만큼 존재
  • 사용자가 요청하는 쿼리 문장 처리
  • 사용자가 커넥션 종료시 스레드는 다시 스레드 캐시(Thread Cache)로 돌아감
    => 스레드 캐시에 일정 개수 이상 대기 중 스레드가 있으면 스레드 캐시에 넣지 않고 스레드 종료
    => thread_cache_size로 설정
  • 데이터를 MySQL의 데이터 버퍼캐시로부터 가져옴
  • 버퍼나 캐시에 없는 경우 직접 디스크의 데이터나 인덱스 파일로부터 데이터를 읽어와 작업 처리
    => MyISAM : 디스크 쓰기 작업까지 포그라운드 스레드가 처리
    => InnoDB : 데이터 버퍼캐시까지만 포그라운드 스레드가 처리, 나머지 버퍼로부터 디스크까지 기록하는 작업은 백그라운드 스레드가 처리

백그라운드 스레드

  • 인서트 버퍼를 병합하는 스레드
  • 로그를 디스크로 기록하는 스레드
  • InnoDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드
  • 데이터를 버퍼로 읽어 오는 스레드
  • 잠금이나 데드락을 모니터링하는 스레드

3. 메모리 할당 및 사용 구조

글로벌 메모리 영역 : MySQL 서버가 시작되면서 운영체제로부터 할당

글로벌 메모리 영역

하나의 메모리 공간만 할당
=> 필요에 따라 2개 이상 메모리 공간 할당받더라도, 모든 스레드에 의해 공유

  • 테이블 캐시
  • InnoDB 버퍼 풀
  • InnoDB 어댑티브 해시 인덱스
  • InnoDB 리두 로그 버퍼

로컬 메모리 영역

MySQL 서버상에 존재하는 클라이언트 스레드가 쿼리를 처리하는 데 사용하는 메모리 영역

세션 : 클라이언트와 MySQL 서버와의 커넥션

클라이언트가 MySQL 서버에 접속하면, MySQL 서버는 클라이언트 커넥션으로부터 요청을 처리하기 위해 스레드를 하나씩 할당함
=> 클라이언트가 사용하는 메모리 공간이기 때문에 클라이언트 메모리 영역이라고도 함
=> 세션 메모리 영역이라고도 함

  • 커넥션 버퍼
  • 정렬(소트)버퍼
  • 조인 버퍼
  • 바이너리 로그 캐시
  • 네트워크 버퍼

4. 플러그인 스토리지 엔진 모델

-- 지원되는 스토리지 엔진 확인
show engines;

플러그인 형태의 스토리지 엔진은 쉽게 업그레이드 가능

-- 플러그인 내용 확인
show plugins;


5. 컴포넌트

플러그인 아키텍처의 단점을 보완하기 위해 컴포넌트 아키텍처 지원

  • 플러그인은 오직 MySQL 서버와 인터페이스 가능, 플러그인끼리 통신X
  • 플러그인은 MySQL 서버의 변수나 함수를 직접 호출하므로 안전X
  • 플러그인은 상호 의존 관계 설정X로 초기화 어려움

6. 쿼리 실행 구조

쿼리 파서

쿼리 파서 : 쿼리 문장토큰으로 분리해 트리 형태 구조로 만들어냄
=> 기본 문법 오류 발견

전처리기

전처리기 : 파서 트리를 기반으로 쿼리 문장에 구조적인 문제점 확인
=> 칼럼 이름, 내장 함수, 테이블 등 개체를 매핑해 객체 존재 여부객체 접근 권한 등 확인

옵티마이저

옵티마이저 : 사용자의 요청으로 들어온 쿼리 문장을 저렴한 비용으로 가장 빠르게 처리할지 결정

실행 엔진

실행 엔진 : 만들어진 계획대로 각 핸들러에게 요청해서 받은 결과를 또 다른 핸들러 요청입력으로 연결하는 역할

핸들러(스토리지 엔진)

핸들러 : MySQL 실행 엔진의 요청에 따라 데이터를 디스크저장하고, 디스크로부터 읽어 오는 역할


7. 스레드 풀

내부적으로 사용자의 요청을 처리하는 스레드 개수줄여서 동시 처리되는 요청이 많더라도 MySQL 서버의 CPU가 제한된 개수스레드 처리에만 집중할 수 있게 해서 서버 자원 소모 줄이는 목적


8. 트랜잭션 지원 메타데이터

데이터 딕셔너리/메타데이터 : 데이터베이스 서버에서 테이블구조 정보스토어드 프로그램 등의 정보

테이블의 구조 정보나 스토어드 프로그램의 코드 관련 정보를 모두 InnoDB 테이블에 저장하고, 시스템 테이블데이터 딕셔너리 정보를 모두 모아 mysql DB에 저장
=> 스키마 변경 작업 중간에 MySQL 서버가 비정상적으로 종료되어도 스키마 변경이 완전한 성공 또는 완전한 실패로 정리



🍹InnoDB 스토리지 엔진 아키텍처

1. 프라이머리 키에 의한 클러스터링

InnoDB의 모든 테이블은 기본적으로 프라이머리 키를 기준으로 클러스터링되어 저장
=> 프라이머리 키 값의 순서대로 디스크에 저장
=> 세컨더리 인덱스는 레코드의 주소 대신 프라이머리 키의 값논리적인 주소로 사용
=> 오라클의 IOT와 동일


2. 외래 키 지원

외래 키는 부모 테이블과 자식 테이블 모두 해당 칼럼인덱스 생성이 필요

--외래키 체크 일시적 해제
set foreign_key_checks =OFF;

3. MVCC(Multi Version Concurrency Control)

언두 로그를 이용

하나의 레코드에 대해 여러 개의 버전이 동시에 관리


4. 잠금 없는 일관된 읽기(Non-Locking Consistent Read)

MVCC를 이용해 잠금을 걸지 않고 읽기 작업 수행
=> 변경되기 전의 데이터를 읽기 위해 언두 로그 사용


5. 자동 데드락 감지

내부적으로 잠금이 교착 상태에 빠지지 않았는지 체크하기 위해 잠금 대기 목록을 그래프 형태로 관리

데드락 감지 스레드 : 주기적으로 잠금 대기 그래프를 검사해 교착 상태에 빠진 트랜잭션들을 찾아 강제 종료
=> 동시 처리 스레드가 많아지거나 트랜잭션이 가진 잠금 수가 많아지면 느려짐
=> innodb_dealock_detect를 off로 설정하고, innodb_lock_wait_timeout을 활성화해서 사용하면 성능이 더 좋아질 수 있음


6. 자동화된 장애 복구

innodb_force_recovery 시스템 변수를 설정해 MySQL 서버를 시작하면,
서버 시작시 innoDB 스토리지 엔진이 데이터 파일이나 로그 파일 손상 여부 검사 과정을 진행
=> 로그 파일 손상시 6으로 설정하고 기동
=> 데이터 파일 손상시 1로 설정하고 기동

1(SRV_FORCE_IGNORE_CORRUPT)

테이블스페이스의 데이터인덱스 페이지에서 손상된 부분이 발견돼도 무시하고 서버 시작
=> 로그 파일에 Database page corruption on disk or a failed 출력시
=> mysqldumpselect into outfile ..을 사용해 데이터베이스 다시 구축

2(SRV_FORCE_NO_BACKGROUND)

백그라운드 스레드 가운데 메인 스레드 시작하지 않고 MySQL 서버 시작
=> InnoDB는 트랜잭션 롤백을 위해 언두 데이터를 관리하는데, 트랜잭션이 커밋되어 불필요한 언두 데이터는 메인 스레드에 의해 주기적으로 삭제(Undo purge)되는데, 해당 과정에서 장애 발생시

3(SRV_FORCE_NO_TRX_UNDO)

MySQL 서버는 다시 시작하면 언두 영역의 데이터를 먼저 읽어 데이터 파일에 적용한 후, 다음 리두 로그의 내용을 다시 덮어 써서 장애 시점의 데이터 상태를 만들어냄
=> 정상적인 MySQL 서버 시작시 최종적으로 커밋되지 않은 트랜잭션롤백 수행
=> 3으로 설정시, 커밋되지 않은 트랜잭션 작업을 롤백X, 즉 커밋되지 않고 종료된 트랜잭션은 계속 그 상태로 남아있게 하는 모드
=> mysqldump를 이용해 데이터를 백업하는 것이 좋음

4(SRV_FORCE_NO_IBUF_MERGE)

InnoDB는 Insert, Delete, Update데이터 변경인덱스 변경 작업을 상황에 따라 즉시 처리할 수 있고, 인서트 버퍼에 저장해두고 나중에 처리할 수도 있음
=> MySQL을 종료해도 병합되지 않을 수 있는데, 만약 MySQL이 재시작되면서 인서트 버퍼 손상 감지하면 MySQL 서버는 시작 못함
=> 인서트 버퍼내용무시하고 강제로 시작
=> 실제 데이터가 아니라 인덱스와 관련된 부분이므로 데이터베이스 다시 구축시 데이터 손실 없음

5(SRV_FORCE_NO_UNDO_LOG_SCAN)

MySQL 서버가 장애나 정상적으로 종료되는 시점에 진행 중인 트랜잭션이 있다면 MySQL은 그냥 커넥션을 강제로 끊어버리고 별도의 정리 작업 없이 종료
=> 재시작시 InnoDB엔진은 언두 레코드를 이용해 데이터 페이지를 복구하고, 리두 로그를 적용해 종료 시점이나 장애 발생 시점 재현
=> 마지막으로 커밋되지 않은 트랜잭션에서 변경한 작업 모두 롤백
=> 언두 로그 사용X시 MySQL 서버 실행 못함
=> 5로 시작시 언두 로그 무시하고 시작
=> 종료되던 시점에 커밋되지 않았던 작업모두 커밋된 것처럼 처리

6(SRV_FORCE_NO_LOG_REDO)

InnoDB 스토리지 엔진의 리두 로그 손상시 서버 시작 불가
=> 리두 로그 모두 무시한 채로 서버 시작
=> 커밋됐다 하더라도 리두 로그에만 기록되고 데이터 파일에 기록X인 데이터는 모두 무시
=> 즉 마지막 체크 포인트 시점의 데이터만 남음
=> 기존 리두 로그 모두 삭제하고 MySQL 서버 시작하는 것이 좋음


7. InnoDB 버퍼 풀

버퍼 풀 : 디스크의 데이터 파일이나 인덱스 정보메모리에 캐시해 두는 공간
=> 변경 작업을 모아서 처리하는 일괄 작업 역할도 같이 함
=> 버퍼 풀을 쪼개어 여러 개의 작은 버퍼 풀(버퍼 풀 인스턴스)로 나눔

버퍼 풀 구조

버퍼 풀이라는 거대한 메모리 공간을 페이지 크기로 쪼개어 데이터를 필요로 할 때 해당 데이터 페이지를 읽어서 각 조각에 저장
=> 페이지 크기 조각 관리를 위해 LRU 리스트, 플러시 리스트, 프리 리스트 관리

프리 리스트 : InnoDB 버퍼 풀에서 실제 사용자 데이터로 채워지지 않은 비어 있는 페이지들의 목록
=> 새롭게 디스크의 데이터 페이지를 읽어와야 하는 경우 사용

Old 서브리스트 : LRU
New 서브리스트 : MRU

InnoDB 스토리지 엔진에서 데이터 찾는 과정

  • 필요한 레코드가 저장된 데이터 페이지버퍼 풀에 있는지 검사
    => InnoDB 어댑티브 해시 인덱스를 이용해 페이지 검색
    => 해당 테이블의 인덱스를 이용해 버퍼 풀에서 검색
    => 버퍼 풀에 이미 페이지가 있다면 해당 페이지의 포인터를 MRU 방향으로 승급
  • 디스크에서 필요한 데이터 페이지를 버퍼 풀에 적재하고, 적재된 페이지에 대한 포인터를 LRU 헤더부분에 추가
  • 버퍼 풀의 LRU 헤더 부분에 적재된 데이터 페이지가 실제로 읽히면 MRU 헤더 부분으로 이동
  • 버퍼 풀에 상주하는 데이터 페이지는 사용자 쿼리가 얼마나 최근에 접근했었는지에 따라 나이 부여
  • 필요한 데이터가 자주 접근됐다면 해당 페이지의 인덱스 키어댑티브 해시 인덱스에 추가

플러시 리스트 : 디스크로 동기화되지 않은 데이터를 가진 데이터 페이지(더티 페이지)의 변경 시점 기준의 페이지 목록 관리
=> 데이터 변경이 가해진 데이터 페이지는 리스트에 관리
=> 체크포인트를 발생시켜 리두 로그데이터 페이지 동기화

버퍼 풀과 리두 로그

버퍼 풀클린 페이지더티 페이지를 가진다.
=> 더티 페이지는 무한정 버퍼 풀에 머무를 수 있는 것이 아님
=> InnoDB 스토리지 엔진에서 리두 로그데이터 변경이 계속 발생하면 리두 로그 파일에 기록됐던 로그 엔트리는 어느 순간 다시 새로운 로그 엔트리로 덮어 쓰임

전체 리두 로그 파일에서 재사용 가능한 공간당장 재사용 불가능한 공간을 구분해서 관리
=> 활성 리두 로그 : 재사용 불가능한 공간 (화살표를 가진 엔트리들)

LSN(Log Sequence Number) : 리두 로그 파일의 공간은 계속 순환되어 재사용되지만 매번 기록될 때마다 로그 포지션은 증가한 값을 갖게 됨
=> InnoDB는 주기적으로 체크포인트를 발생시켜 리두 로그버퍼 풀더티 페이지디스크로 동기화 하는데, 가장 최근 체크포인트 지점LSN활성 리두 로그 공간 시작점
=> 체크포인트 에이지 : 가장 최근 체크포인트LSN마지막 리두 로그 엔트리LSN 차이

체크포인트 발생체크포인트 LSN보다 작은 리두 로그 엔트리와 관련된 더티 페이지는 모두 디스크에 동기화
=> 리두 로그 엔트리디스크로 동기화

버퍼 풀 플러시(Buffer Pool Flush)

더티 페이지 플러시 : 더티 페이지디스크동기화

InnoDB는 버퍼 풀에서 아직 디스크로 기록되지 않은 더티 페이지들을 악영향 없이 동기화하기 위해 2개의 플러시 기능백그라운드로 실행

플러시 리스트 플러시
: InnoDB가 주기적으로 플러시 함수를 호출해서 플러시 리스트에서 오래전에 변경된 데이터 페이지 순서대로 디스크에 동기화 작업 수행
=> 어댑티브 플러시 : 리두 로그의 증가 속도를 분석해서 적절한 수준으로 더티 페이지버퍼 풀에 유지될 수 있도록 디스크 쓰기 실행

LRU 리스트 플러시
: 사용 빈도가 낮은 데이터 페이지들을 제거해서 새로운 페이지들을 읽어올 공간을 만들어야 하는데, 이때 LRU 리스트 플러시 함수 사용
=> 스캔하면서 더티 페이지는 디스크에 동기화, 클린 페이지는 즉시 프리 리스트로 페이지를 옮김

버퍼 풀 상태 백업 및 복구

워밍업(Warminig Up) : 서비스 재부팅 시 디스크의 데이터가 버퍼 풀에 적재돼 있는 상태

-- 서버 셧다운 전 버퍼 풀 상태 백업
set global innodb_buffer_pool_dump_now=ON;

-- 재시작 후, 백업된 버퍼 풀의 상태 복구
set global innodb_buffer_pool_load_now=ON;
--버퍼 풀 복구하는 과정이 어느 정도 진행됐는지 상태 값 제공
show status like 'Innodb_buffer_pool_dump_status'\G
-- 버퍼 풀 복구 도중 서비스 시작시 버퍼 풀 복구 멈춤
set global innodb_buffer_pool_load_abort=ON;

버퍼 풀 적재 내용 확인

-- 테이블 인덱스별로 데이터 페이지가 얼마나 버퍼 풀에 적재 됐는지
select it.name table_name, ii.name index_name, ici.n_cahced_pages n_cached_pages
from information_schema.innodb_tables it
	inner join information_schema.innodb_indexes ii on ii.table_id=it.table_id
    inner join information_schema.innodb_cached_indexes ici on ici.index_id=ii.index_id
where it.name=concat('employees','/','employees');

8. Double Wirte Buffer

파셜 페이지(Partial-page) : 더티 페이지를 디스크 파일로 플러시할 때 일부만 기록되는 문제가 발생하면, 그 페이지 내용은 복구할 수 없을 수도 있는데, 페이지일부만 기록되는 현상
=> 하드웨어 오작동 또는 시스템 비정상 종료 등으로 발생


9. 언두 로그

언두 로그 : DML로 변경되기 이전 버전의 데이터

언두 로그 레코드 모니터링

-- 언두 레코드 건수 확인
show engine innodb status \G

언두 테이블스페이스 관리

언두 테이블스페이스 : 언두 로그가 저장되는 공간
=> 8.0.14 이상부터 항상 시스템 테이블스페이스 외부별도 로그 파일에 기록
=> 하나의 언두 테이블스페이스는 1개 이상 128개 이하롤백 세그먼트를 가짐
=> 롤백 세그먼트1개 이상언두 슬롯을 가짐

-- 테이블스페이스 생성
create undo tablespace undo_03 add datafile '파일경로';

--비활성화
alter undo tablespace undo_03 set inactive;

--삭제
drop undo tablespace undo_03;

Undo table truncate : 언두 테이블스페이스 공간을 필요한 만큼만 남기고 불필요하거나 과도하게 할당된 공간을 운영체제로 반납하는 것

  • 자동 모드 : 트랜잭션이 데이터 변경 시 언두 로그에 기록이 되는데, InnoDB 스토리지 엔진의 퍼지 스레드(Purge Thread)는 주기적으로 깨어나 언두 로그 공간에서 불필요해진 언두 로그를 삭제하는 작업 실행
    => 언두 퍼지
  • 수동 모드 : 언두 테이블스페이스비활성화해서 언두 테이블스페이스가 더이상 사용되지 않도록 설정하면 퍼지 스레드비활성 상태언두 테이블스페이스를 찾아서 불필요한 공간 잘라내고 운영체제로 해당 공간 반납
    => 언두 테이블스페이스가 최소 3개 이상은 돼야 작동

10. 체인지 버퍼

인덱스를 업데이트 하는 작업은 랜덤하게 디스크 읽는 작업이 필요
=> 변경해야 할 인덱스 페이지가 버퍼 풀에 있으면 바로 업데이트 수행
=> 디스크로부터 읽어와서 업데이트해야 한다면 즉시 실행하지 않고 임시 공간에 저장해 두고 바로 사용자에게 결과 반환

체인지 버퍼 : 위 경우 사용하는 임시 메모리 공간

사용자에게 결과를 전달하기 전에 반드시 중복 여부 체크해야 하는 유니크 인덱스체인지 버퍼 사용X

체인지 버퍼에 임시로 저장된 인덱스 레코드 조각은 이후 백그라운드 스레드에 의해 병합
=> 체인지 버퍼 머지 스레드

--체인지 버퍼 사용중인 메모리 공간 크기
select event_name, current_number_of_bytes_used
from performance_schema.memory_summary_global_by_event_name
where event_name='memory/innodb/ibuf0ibuf';


11. 리두 로그 및 로그 버퍼

리두 로그 : 영속성과 가장 밀접하게 관련

리두 로그 아카이빙

리두 로그 아카이빙 : 데이터 변경이 많아서 리두 로그덮어쓰인다고 하더라도 백업 실패하지 않게 해줌

--리두 로그 아카이빙 시작
do innodb_redo_log_archive_start('디렉터리레이블', '서브디렉터리이름');

--종료
do innodb_redo_log_archive_stop();

리두 로그 활성화 및 비활성화

MySQL 서버에서 트랜잭션이 커밋돼도 데이터 파일은 즉시 디스크로 동기화X, 반면 리두 로그항상 디스크로 기록

-- 리두 로그 비활성화
alter instance disable innodb redo_log;
--상태 변수 확인해 리두 로그 활성화/비활성화 확인
show global status like 'Innodb_redo_log_enabled';


12. 어댑티브 해시 인덱스

어댑티브 해시 인덱스(Adaptive Hash Index) : 사용자가 수동으로 생성하는 인덱스가 아니라 InnoDB 스토리지 엔진에서 사용자가 자주 요청하는 데이터에 대해 자동으로 생성하는 인덱스
=> 인덱스 키 값데이터 페이지 주소의 쌍으로 관리
=> 인덱스 키 값 : B-Tree 인덱스 고유 번호인덱스 실제 키 값 조합
=> 데이터 페이지 주소 : 버퍼 풀에 로딩된 페이지의 주소



🍺MyISAM 스토리지 엔진 아키텍처

1. 키 캐시

키 캐시/키 버퍼 : InnoDB의 버퍼 풀과 비슷한 역할
=> 인덱스만 대상
=> 인덱스의 디스크 쓰기 작업에 대해서만 부분적으로 버퍼링

Key_reads : 인덱스를 디스크에서 읽어 들인 횟수
Key_read_requests : 키 캐시로부터 인덱스 읽은 횟수

키 캐시 히트율 = 100-(Key_reads/Key_read_requests*100)
show global status like 'Key%';

--키 캐시 2GB 생성
kbuf_board.key_buffer_size=2GB

-- 게시판의 인덱스를 캐시
cache index db1.board, db2.board in kbuf_board;

2. 운영체제의 캐시 및 버퍼

MyISAM 스토리지 엔진은 디스크 I/O에 관한 캐시버퍼링 기능을 가지고 있지 않으므로 운영체제캐시 기능을 이용해야 함


3. 데이터 파일과 프라이머리 키(인덱스) 구조

InnoDB 스토리지 엔진 : 프라이머리 키에 의해 클러스터링되어 저장

MyISAM 테이블 : 프라이머리 키에 대한 클러스터링 없이 데이터 파일힙 공간처럼 활용
=> 프라이머리 키 값과 무관하게 INSERT되는 순서대로 데이터 파일에 저장
=> 프라이머리 키와 세컨더리 인덱스는 모두 데이터 파일에 저장된 레코드ROWID 값을 포인터로 가짐



🍻MySQL 로그 파일

1. 에러 로그 파일

MySQL이 실행되는 도중 발생하는 에러경고 메시지가 출력되는 로그 파일

  • MySQL이 시작하는 과정과 관련된 정보성 및 에러 메시지
  • 마지막으로 종료될 때 비정상적으로 종료된 경우 나타나는 InnoDB의 트랜잭션 복구 메시지
  • 쿼리 처리 도중에 발생하는 문제에 대한 에러 메시지
  • 비정상적으로 종료된 커넥션 메시지
  • InnoDB의 모니터링 또는 상태 조회 명령의 결과 메시지
  • MySQL의 종료 메시지

2. 제너럴 쿼리 로그 파일

제너럴 쿼리 로그 : 슬로우 쿼리 로그와는 조금 다르게 실행되기 전에 MySQL이 쿼리 요청을 받으면 바로 기록하기 때문에 실행 중 에러 발생해도 일단 로그 파일에 기록


3. 슬로우 쿼리 로그

슬로우 쿼리 로그 파일 : long_query_time 시스템 변수에 설정한 시간 이상의 시간이 소요된 쿼리가 모두 기록
=> 실제 소요된 시간을 기준으로 슬로우 쿼리 로그에 기록할지 여부를 판단하므로 반드시 쿼리가 정상적으로 실행 완료돼야 슬로우 쿼리 로그에 기록 가능

profile
MSSQL DBA 신입

0개의 댓글