본문 바로가기

Database

(11)
[REAL MYSQL 8.0] 옵티마이저 와 실행계획 (2) - 정렬 MySQL 의 정렬 처리 특징 MySQL 은 정렬을 위한 별도의 메모리 공간을 쿼리 수행시 할당 받는다. 이를 Sort Buffer 소트 버퍼 라고 하며 버퍼의 크기는 정렬 대상의 크기에 따라 최대 sort_buffer_size 변수 만큼 가변적으로 할당 받는다. 소트버퍼는 쿼리 수행 완료후, 바로 반납된다. 그렇다면 소트 버퍼보다 예상 레코드 수가 크다면 어떻게 처리될까? 소팅을 버퍼의 크기만큼 여러 조각으로 나누어, 매 처리 결과를 디스크에 임시저장을 한 후 병합한다. 이를 멀티 머지라고 한다. 디스크 I/O 가 계속 발생하는 것이므로, 성능에 영향이 있다. 하지만 이를 해결하기 위해 sort_buffer_size 를 늘리는 것은 옳지 않다고 한다. 소트 버퍼를 늘려도 속도에 대한 효과는 미미하고, ..
[REAL MYSQL 8.0] 옵티마이저 와 실행계획 (1) - 데이터 처리 옵티마이저는 최적의 실행계획을 수립하기 위한 DBMS 의 뇌라고 볼 수 있다. 실행계획을 이해하려면 옵티마이저에 대한 이해가 필수이다. 옵티마이저에 의한 쿼리 처리 과정 SQL 을 SQL Parser 에 의해 분리 하여 Parse Tree 를 생성 Parse Tree 를 보고 인덱스와 어떤 테이블을 읽을지 선정 (실행계획 수립) 불필요 조건 제거, 연산 단순화 조인의 경우 읽을 순서 선정 (드라이빙 테이블, 드리븐 테이블) 조건문과 인덱스의 통계정보를 활용하여 어떤 인덱스를 태울지 선정 가져온 레코드들을 임시 테이블에 넣고 가공할 필요가 있는지 판단 결정된 실행계획에 따라 실제로 엔진에 의해 쿼리 수행 옵티마이저의 종류 규칙 기반 최적화 - Oracle 에서 예전에 자주 사용하던 방식. 내장된 우선순위를..
Redis 를 이용한 분산 락 구현 분산락? 서비스가 점점 커지다보면 서버의 갯수가 늘고, 요즘에는 대부분이 클라우드환경에서 자동 수평확장 설정을 통하여 얼마든지 서버의 기동대수가 늘 수 있도록 확장에 용이한 구조로 설계를 합니다. 이런 환경에서 서비스를 운영하다보면 여러서버에서 특정한 요청 처리에 대하여 공통된 락이 필요한 경우가 있습니다. 이때 사용하는 락을 분산락이라고 합니다. 저의 경우에는 서버의 대수와는 별개로 이체, 송금 도메인에서 클라이언트 단의 오류로 인하여 동시성 처리가 되어 있지 않은 이체, 송금 서버에 동시에 여러번의 요청이 들어와 여러번의 이체가 되는 대형 장애가 발생한 적이 있었고 이를 해결하기 위해 Redis 를 활용하여 여러대의 서버에 낙관적락을 분산락으로 잡아 같은 요청이 중복으로 요청되는 상황에 대한 처리를 ..
[Real MySQL 8.0] 인덱스 랜덤 I/O 와 순차 I/O 인덱스를 설명하기 전, 랜덤 I/O 와 순차 I/O 에 대해 알아야한다. 고전적인 HDD 디스크는 디스크를 돌려 순차적으로 읽을 경우 한바퀴에 모든 데이터를 조회 할 수있다. 반면에, 읽어야 하는 데이터를 순차적으로 조회하지 않는다면 3개의 데이터를 조회하는데 3번 디스크를 돌려야한다. 이를 랜덤 I/O 라고 한다. 즉 일반적으로 순차 I/O 가 랜덤 I/O 보다 훨씬 성능이 좋다. 이는 디스크를 돌리지 않는 SDD 에서도 마찬가지이다. 인덱스 레인지 스캔은 일반적으로 랜덤 I/O 이며, 풀 스캔의 경우 순차 I/O 이다. 그래서 테이블의 데이터 대부분을 읽어야하는 경우, 풀 스캔 후 가공하는 편이 성능이 더 좋다. 인덱스 인덱스란 말 그대로 목차와 비슷한 역할을 한다. 인덱..
MySQL Gap Lock, Next key Lock (갭락, 넥스트 키락) 과 데드락 Real MySQL 8.0 을 보다가, Lock 과 Transaction isolation 에 대해 설명이 너무 부족한 것 같아 개인적으로 추가 정리를 해보고자 합니다. 그 중에서도 이번 포스팅은 MySQL 만의 특별한 락인 Gap Lock 을 다루어 보고자 합니다. Gap Lock(갭락) MySQL 은 레코드 기반의 잠금을 지원하여 주로 레코드 잠금(실제로는 레코드의 인덱스를 잠금)으로 동시성을 제어하는데, 갭 락은 실제 존재하는 레코드가 아닌, 레코드가 존재하지 않는 빈 공간에 대해서 거는 MySQL 만의 특별한 잠금이다. ID(PK) 3 4 10 예시로 위와 같은 데이터가 있다고 치면, (1~2) (5~9) (10~) 을 잠그는걸 갭 락이라고 한다. 또, 존재하는 레코드 인덱스에 대한 락 (3, 4..
[REAL MYSQL 8.0] InnoDB 스토리지 아키텍쳐 InnoDB 스토리지 엔진은 MySQL 스토리지 엔진중 거의 유일하게 레코드 기반의 잠금을 지원하여 높은 동시성 처리가 가능하여 많은 서비스 어플리케이션에서 가장 대중적으로 사용되고 있다. InnoDB 스토리지 엔진의 특징을 하나씩 살펴보자. InnoDB 스토리지의 특징 PK 에 의한 클러스터링 InnoDB 의 테이블들은 기본적으로 PK 클러스터 인덱스로 지정되어 저장된다. 즉 PK 순서대로 물리적으로 저장된다는 뜻이다. 그로인해 InnoDB 는 PK 기준 검색 및 레인지 스캔이 상당히 빠르다. 더보기 Clustered Index Clustered Index 는 테이블 당 하나만 지정할 수 있고, 지정한 컬럼을 대상으로 물리적으로 정렬되어 저장되는 인덱스이다. 물리적으로 정렬되어 있어, 빠른 검색속도를 ..
RDS Slow Query Log 세팅 및 쿼리 개선 최근에 팀원이 기간에 따른 급여 이체 대상자 수 통계가 달력에 나타나는 기능을 개발하였는데, 3개월 이상의 단위로 조회할때 속도가 매우 느리다는 이야기를 들었다. 통계성 데이터기 때문에 현재 데이터를 쿼리하기보다는 리포트용으로 별도로 데이터를 적재하는 배치를 구현하는게 좋지 않나? 라는 의견을 개발 초기 PR 단계에서 냈었는데, 우선 개발 당시에는 과거 데이터를 보는 용도가 아니라, 다가올 급여이체에 대한 정보를 보는 용도의 목적이 크다고 하여 개발되었었는데, 처음 속도가 느리다는 문의가 들어올때에는 내가 개발한 부분이 아니라서 음 데이터 양이 많아서 그런가? 라고 넘겼으나.. 30초 이상이 걸린다는 이야기를 듣고 부랴부랴 slow query log 를 찾아보았다. 그러나 왠걸, slow query lo..
Redis 자료구조와 활용 예시 Redis? 싱글스레드로 동작하는 오픈소스 인 메모리 key - value 데이터 저장소입니다. Why Redis? 주 메모리에 데이터를 상주시킴으로서 디스크에 액세스 할 필요 없이 빠른 I/O 를 제공합니다. 다양한 기능 및 다양한 자료구조를 제공함으로서, 다양한 방법으로 활용 할 수 있습니다. In-memory 데이터베이스지만, 디스크에 스냅샷을 저장함으로서 안정성을 확보합니다. Replication 을 지원함으로서 고 가용성을 확보할 수 있습니다. When Redis? 몇가지 사용사례를 살펴보고 아래에서 사용사례별 어떤 자료구조를 사용하면 좋은지 알아보겠습니다. Cashing: 디스크 기반의 RDBMS 나 NoSQL 앞에 배치해 특정 요청에 대한 디스크 액세스를 최소화 할 수 있습니다. Sessio..