MySQL 서버와 스레딩 구조

Photo by Raj Gandhi on Unsplash

MySQL 서버와 스레딩 구조

Real MySQL 8.0 스터디-1

💡
이 글은 Real MySQL 8.0공식 문서를 읽고 개인적으로 정리한 내용입니다.

1. MySQL 구조

MySQL 서버는 크게 MySQL 엔진스토리지 엔진으로 구분합니다.

1.1. MySQL 엔진

  • 커넥션 핸들러: Client 접속 및 쿼리 요청 처리

  • SQL 파서: SQL 쿼리를 토큰으로 분리 후 트리 변환

  • 전처리기: 토큰 트리를 문법으로 인식하고 문법 오류가 있는지 확인

  • 옵티마이저: 쿼리 실행문을 최적화

1.2. 스토리지 엔진

  • 실제 데이터를 디스크 스토리지에 저장하거나 디스크 스토리지로부터 데이터를 읽어오는 역할

  • MySQL 엔진 하나에 여러 개의 스토리지 엔진 사용 가능

1.3. 핸들러 API

MySQL 엔진스토리지 엔진이 데이터를 주고받기 위해 사용하는 API. 모든 쿼리에서 이 핸들러 API를 사용하여 데이터 작업을 처리하게 되는데, 이 때 상태 변수에 작업 처리 횟수를 기록합니다. SHOW STATUS 문으로 핸들러 API의 상태 변수를 확인할 수 있습니다.

  • Handler_external_lock: external_lock() 함수를 호출할 때마다 증가 (이 함수는 일반적으로 테이블 인스턴스에 대한 액세스의 시작과 끝에 호출됩니다.)

  • Handler_read_rnd_next: 데이터 파일의 다음 행을 읽기 위한 요청 수

  • Handler_write: 테이블에 행을 삽입하기 위한 요청 수

그럼 실제로 로깅이 되는지 확인해봅시다. 이전에 입력했던 명령문을 다시 입력하면 이 3개의 상태 변수가 변경됩니다.

  • Handler_external_lock: 2만큼 증가했습니다. 액세스 시작과 끝에 external_lock()가 호출됐다는 것을 알 수 있습니다.

  • Handler_read_rnd_next: 512만큼 증가했습니다. 명령문 한 번에 512행을 읽었네요.

  • Handler_write: 18만큼 증가한 걸로 보아 명령문 결과의 행만큼 증가했습니다.

핸들러 API를 직접 사용해볼 수도 있습니다. 공식 문서를 참고해주세요.

2. MySQL 스레딩 구조

MySQL 서버는 프로세스 기반이 아니라 스레드 기반으로 작동합니다.
크게 포그라운드(Foreground) 스레드와 백그라운드(Background) 스레드로 구분합니다. MySQL 서버에서 실행 중인 스레드 목록은 performance_schema.threads에서 확인 가능합니다.

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

  • 클라이언트가 요청하는 쿼리 문장을 처리

  • 데이터를 데이터 버퍼나 캐시로부터 가져오며, 버퍼나 캐시에 없는 경우 직접 디스크의 데이터나 인덱스 파일로부터 읽어와서 작업 처리

  • InnoDB 테이블은 버퍼나 캐시까지만 포그라운드 스레드가 처리(버퍼로부터 디스크까지 저장하는 작업은 백그라운드 스레드가 처리)

  • 커넥션 종료 시 스레드 캐시(Thread cache)로 되돌아가며, 스레드 캐시에 일정 개수 이상의 스레드가 있으면 스레드 캐시에 넣지 않고 스레드를 종료시켜 일정 개수의 스레드만 스레드 캐시에 존재

인상 깊은 것은 스레드 캐시라는 곳인데, 커넥션을 미리 만들어 놓고 스레드 캐시의 스레드를 클라이언트에 할당하는데, 커넥션 풀과 비슷합니다. Thread cache의 Thread를 사용하게 되면서 Thread를 만드는 부하를 감소시켜 성능에 장점이 생기게 됩니다. thread_cache_size 시스템 변수에서 스레드 캐시 크기를 확인 가능합니다.

2.2. 백그라운드 스레드

performance_schema.threads에서 TYPE이 BACKGROUND인 스레드들입니다. 백그라운드 스레드 개수는 MySQL 서버의 설정 내용에 따라 가변적일 수 있습니다. 여러 가지 작업들이 백그라운드로 처리되는데 너무 많아서 하나하나 다 알아볼 필요는 없을 것 같고, 그중에서 가장 중요한 것은 로그 스레드(Log thread)쓰기 스레드(Write thread)2개입니다.

  • 로그 스레드: 트랜잭션 로그를 기록하는 스레드

  • 쓰기 스레드: 버퍼의 데이터를 디스크로 내려쓰는 작업을 처리하는 스레드

2.3. 스레드 상태 변수 확인

  • Threads_cached: 포그라운드 스레드에서 언급했던 변수입니다. 현재 스레드 캐시에 있는 스레드 개수를 나타냅니다.

  • Threads_connected: 현재 연결된 스레드 개수

  • Threads_created: 접속을 위해 생성된 스레드 개수

  • Threads_running: Running 중인(Sleeping 상태가 아닌) 스레드 개수

스레드 상태들을 모니터링 시스템 변수를 적절히 조절하여 커넥션 튜닝을 할 수 있다는 생각이 드네요.


🎯정리

  • MySQL 엔진, 스토리지 엔진, 커넥션 핸들러가 무엇인지 간략히 알아보았습니다.

  • 프로세스 기반이 아닌 스레드 기반으로 작동하는 MySQL 서버의 스레드에 대해 알아보았습니다.


🔖참고