내부적으로 어떻게 작동는지 이해하기
출처 RealMysql 서적을 기반으로 이해한 내용 정리
1. Mysql스레딩구조
MySQL서버는 프로세스 기반이 아니라 '스레드'기반
(클라이언트 별로 커넥션을 주면서, 다수의 클라이언트가 연결되는 멀티스레드방식)
1) 포그라운드 스레드(클라이언트 스레드)
몇개? 최소한 서버에 접속된 클라이언트 수만큼 존재
무슨일? 사용자가 요청하는 쿼리문장을 처리하는 역할
어떤 요청이 있는데?
데이터를 MySQL의 데이터 버퍼에나 캐시로 부터 가지고 오는거,
버퍼나 캐시에 없으면 직접 디스크의 데이터나 인덱스 파일에서 읽어오는 작업
스토리지엔진에 따라 포그라운스레드가 하는일이 다름!
MyISAM : 읽기 작업을 주로 하기 때문에 '디스크' 쓰기 작업까지 함
InnoDB : 데이터 버퍼나 캐시영역까지만 스레드가 처리하고, 디스크까지 쓰는 작업은 백그라운드가 처리함
스레드의 생명주기는? 언제시작하고 언제 종료?
사용자가 DB커넥션을 시작하면 스레드가 시작되고,
DB커넥션을 종료하면 해당 커넥션은 스레드풀로 들어간다.
스레드풀?
대기하고 있는 스레드들을 모아둔 곳
그래서 스레드풀에 대기하고 있는 스레드가 많으면 스레드풀로 들어가는게 아니라 스레드를 종료시킴
-> 스레드캐시에는 일정개수의 스레드만 존재할 수 있도록 함
thread_cache_size : 스레드의 개수를 일정하게 유지하는 파라미터
*스레드개수 확인 명령어 : show variables like 'thread_cache_size';
2) 백그라운드 스레드
스토리지엔진에 따라 백그라운스레드가 하는일이 다름!
MyISAM : 대부분 수행하는 읽기작업은 포그라운드에서 해서 별로 해당사항이 없고,
InnoDB : 쓰기작업은 백그라운드에서 해서 여러가지 작업별로 처리
이노디비에서 어떤 작업들이 있는데?
1. 인서트버퍼를 병합하는 스레드
2. 로그를 디스크로 기록하는 스레드 (로그스레드)
3. InnDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드(쓰기스레드)
innodb_read_io_threads : 읽기 스레드의 개수 지정하는 파라미터
innodb_write_io_threads : 쓰기 스레드의 개수 지정하는 파라미터
(그런데, 이노디비 경우 데이터를 읽는 작업은 포그라운드스레드에서, 쓰기 작업을 백그라운드 스레드에서 이루어짐)
4. 데이터를 버퍼로 읽어들이는 스레드
5. 모니터링하는 스레드
6. 이런 스레드들을 총괄하는 메인스레드
이 작업들이 어떻게 수행되는데?
2. InnoDB 내부 구조
일단 크게 메모리영역, 디스크영역으로 볼 수 있음
메모리 영역을 논리적인 영역으로 보고, 디스크영역은 물리적인 영역으로 볼 수 있다.
1) 데이터 처리 매커니즘
일반적으로 데이터를 읽고 쓰는 메커니즘은 '메모리 영역'에서 처리가 우선
왜 메모리영역에서 처리하는데?
데이터베이스 시스템의 성능적인 목표(?)는 IO를 줄이는 것!
그러니까,
물리적 IO를 줄인다
= 디스크 영역에 접근하는 횟수를 줄인다.
= 물리적인 영역에서 블록을 읽고 쓰는 횟수를 줄인다. (논리적IO> 물리적IO)
= 캐시 히트율을 높인다
= 응답시간을 줄여준다
= 리소스가 많아도 빨리 처리함
= 비용을 줄인다
= 성능을 높인다
캐시히트(hit): 캐시를 사용할 수 있는 경우 (ex : 이전에 왔던 요청이랑 같은 요청일경우 빠르게 응답)
캐시미스(miss) : 캐시를 사용할 수 없는 경우 (ex : 처음 들어온 요청일 경우 디스크에서 찾아서 응답)
왜 물리적인 영역은 뭐가 문젠데?
디스크영역은 뒤에서 더 자세히 보겠지만 파일시스템 구조로 되어 있다.
그래서 디스크영역까지 가서 블록을 읽어 올려면 파일에서 데이터를 찾아서 읽어오는 랜덤엑세스 IO가 발생한다.
(아마 이걸 빨리 처리하려고 인덱스가 있는걸수도)
2) 구조1- 메모리영역
메모리영역은 쉽게 캐시 버퍼로 생각하면 될 것 같다.
-InnoDB Buffer Pool
데이터파일이나 인덱스 정보를 저장하는 캐시저장소역할(휘발성)
어떻게 동작하는가?
쿼리를 받음 = 데이터 블록을 읽음 = 버퍼풀에서 데이터를 찾음
= 요청받은 데이터블록이 버퍼풀에 있으면 -> 클라이언트한테 빨리 리턴함
= 하지만, 요청받은 적 없는 데이터블록을 받았으면(즉 버퍼풀에 없는 데이터블록이라면)
-> 디스크영역까지 접근해서 데이터를 읽고 클라이언트한테 리턴
-Data Page Buffer
Dirty Page (더티페이지)를 기록하는 곳
변경된 데이터이지만, 아직 디스크에 기록되지 않은 데이터들 보관하는 곳
이들이 모여 있는데 Data Page Buffer
왜 필요한가?
데이터처리 매커니즘의 목표는 디스크영역에 접근하는 IO를 최소화하는것!
이렇게 변경될 때마다 디스크에 접근하면 물리적IO가 증가함
그래서 디스크에 자주 접근하는게 아니라 변경된 데이터들을 모아놨다가(더티페이이지) 한번에 일괄처리를 한다.
주기적으로 어떤 조건이 되면 체크포인트 이벤트가 발생하는데,
이떄 write스레드가 더티페이지를 디스크영역에 접근해서 저장한다.
캐시저장소면 사라질수도 있는거아니냐? YES!
비정상적으로 종료되면 캐싱데이터가 다 소멸도는 휘발성 특징을 가지고 있다.
그래서 언두로그에 백업을 해놓는다.
-Undo log(언두로그)
데이터를 변경했지만, 변경되기 이전의 데이터를 보관하는곳
즉, 트랜잭션을 수행하기 이전의 데이터를 저장하는 곳
무슨 목적으로 사용하는데?
트랜잭션을 롤백하거나, '백업'하는 목적으로 사용된다.
그래서 현재의 트랜잭션을 과거로 되돌리는 용도로 사용
-Log Buffer(로그버퍼)
Redo log(리두로그)를 기록하는 곳
*데이터를 변경했을떄, 변경된 내용의 데이터를 보관하는 곳
즉, 변경된 내용들을 디스크에 기록하기 위한 '로그파일'들을 가짐
무슨 목적으로 사용하는데?
-미디어 Recovery : 디스크 자체가 깨지는 손상으로 발생하는 에러상황시 복구
-캐시 Recovery: 비정상적으로 작업이 종료될때 작업내용을 복구할때
-fast commit 목적 : 디스크영역에서 데이터를 찾아올때 랜덤엑세스 방식이 아니라 빠르게 가지고 올때
그래서 과거를 현재상태로 되돌리는 용도로 사용
-Insert Buffer(인서트버퍼)
인덱스를 업데이트해야할 데이터들을 모아둔 임시메모리공간
왜 사용하는데?
데이터를 변경할때 해당 테이블이 포함된 인덱스까지 업데이트하는 작업이 필요하다.
그런데 인덱스를 업데이트하는건 파일 디렉토리까지 가서 랜덤하게 디스크를 읽어야하기 때문에 IO증가!
그래서 디스크에 자주 접근하는게 아니라 업데이트 해야되는 인덱스들을 모아놨다가 한번에 일괄처리를 한다.
정리하면,
1. 클라이언트가 쿼리(select) 요청 (데이터 블록을 읽음) // 포그라운드 스레드가 처리함
2. 읽을 데이터 블록이 버퍼풀에 있는지 확인
2-1. 있으면, 메모리영역에서 바로 클라이언트한테 반환(버퍼풀거침)
2-2. 없으면, 디스크영역까지 가서 해당하는 데이터 블록을 읽어오는 작업 수행
3. 읽어온 내용을 메모리 영역에 한번 올려줌
4. 같은 데이터 블록을 요청하면 메모리영역에서 빠르게 반환 할 수 있음
1. 클라이언트가 쿼리(update) 요청 (변경할 데이터 블록 읽고, 변경작업) // 포그라운드 스레드가 처리함
2. 읽을 데이터 블록이 버퍼풀에 있는지 확인
2-1. 있으면, 메모리영역에서 데이터를 변경하고 바로 클라이언트한테 반환(버퍼풀거침)
2-2. 버퍼링작업수행 //백그라운드 스레드(log스레드/wirte스레드)
- log스레드가 변경된 기록(리두로그)를 로그버퍼에 기록
- 변경되었지만 아직 디스크영역에 저장하지 않은 더티페이지들이 쌓임
-> 디스크영역에 저장된 내용이랑 데이터가 다른 상태가 발생함!!
- 체크포인트 이벤트가 발생하면 write스레드가 일괄적으로 디스크영역에 접근해서 변경된 내용을 저장함
3. 같은 데이터 블록을 요청하면 메모리영역에서 빠르게 반환 할 수 있음
3) 구조2- 디스크영역
디스크영역은 파일디렉토리 구조를 가지고 있다고 보면 된다.
테이블별 별도의 파일을 가지고 있는게 아니라 하나의 테이블 스페이스를 가지고 있다.
-시스템 테이블스페이스(.frm파일)
테이블의 구조정보, 메타데이터(data dictionary)저장
-개별(File-per-Table) 테이블 스페이스(.idb파일)
테이블 당 데이터와 인덱스 정보 저장
'🌱 Computer Science > Database' 카테고리의 다른 글
[Mysql아키텍쳐3] InnoDB특징/MyISAM특징 (0) | 2020.01.22 |
---|---|
🚀 DB JOIN 정리(INNER/LEFT/RIGHT/OUTER) (8) | 2020.01.21 |
SQL 기본문법정리1(DDL/DML/DCL/TCL) (0) | 2020.01.20 |
[Mysql 아키텍쳐1] 커넥션풀/Mysql엔진/스토리지엔진 (0) | 2020.01.19 |
정형데이터 vs 비정형데이터 (RDBMS VS NOSQL) (0) | 2020.01.19 |
OLAP/OLTP/DW/ETL 용어정리 (0) | 2020.01.17 |