Mysql

디스크 I/O 병목

sangyunpark99 2025. 4. 22. 11:32

DB가 느린 이유

컴퓨터의 성능은 매년 빠르게 발전하고 있지만, 여전히 운영하는 시스템에서 가장 느린 부분은 디스크입니다.

특히, DB의 성능 병목은 대부분의 디스크 I/O에서 발생합니다.

결국, DB 성능 튜닝의 핵심은 디스크 I/O를 얼마나 줄일 수 있느냐에 달려 있다고 해도 과언이 아닙니다.

 

디스크 I/O가 병목인 이유

CPU나 메모리는 전자 회로 기판의 장치이기 때문에, 나노초(ns) 단위로 연산과 접근이 가능합니다.

하지만, 디스크는 여전히 기계적인 동작이 필요한 장치입니다. 특히 전통적인 하드디스크는 데이터를 읽기 위해 디스크 회전과 헤드 이동이라는 물리적 동작이 필요합니다.

 

이 물리적 구조 때문에, 데이터베이스 서버에서 디스크는 항상 병목 구간이 될 수밖에 없습니다.

아무리 CPU가 빠르고 메모리가 넉넉해도, 결국 데이터를 가져오는 속도가 느리면 전체 성능이 따라가질 못합니다.

 

SSD의 등장

디스크의 기계적 병목을 해결하기 위해 등장한 것이 전자식 저장 장치인 SSD(Solid State Drive)입니다.

SSD는 물리적 회전 없이 데이터를 전자적으로 읽고 쓰기 때문에, HDD에 비해 랜덤 I/O 성능이 수십 배 이상 빠릅니다.

대부분의 데이터베이스 서버는 이제 SSD 기반으로 구성되며, 디스크 병목을 줄이기 위한 하드웨어 선택이 성능에 직접적인 영향을 줍니다.

 

그러나, SSD는 모든 상황에서 완벽하지는 않습니다.

순차 I/O처럼 대량의 데이터를 연속적으로 읽는 작업에서는 HDD도 어느 정도 성능을 발휘할 수 있으며, 경우의 따라서는 SSD와 큰 차이가 나지 않기도 합니다.

 

또한 SSD는 가격 대비 저장 용량이 상대적으로 낮고, 쓰기 수명에 제한이 있다는 점도 고려해야 합니다.

따라서 SSD를 도입한다고 해서 무조건 모든 I/O 병목이 사라지는 것은 아닙니다.

 

랜덤 I/O & 순차 I/O

데이터베이스에서 디스크 I/O가 발생할 때, 그 방식은 크게 순차 I/O와 랜덤 I/O로 나눌 수 있습니다.

 

순차 I/O는 디스크 상에 데이터가 연속적으로 저장되어 있어, 디스크 헤드가 한 방향으로 쭉 이동하면서 데이터를 읽는 방식입니다.

이 경우 헤드 이동이 최소화되므로, 데이터를 빠르게 대량으로 읽을 수 있습니다.

 

랜덤 I/O는 읽어야 할 데이터가 디스크 곳곳에 흩어져 있을 때 발생합니다. 디스크 헤드는 매번 위치를 이동하며 데이터를 찾아야 하며, 이로 인해 반복적인 기계적인 지연이 발생하게 됩니다.

 

참고, SSD는 이러한 헤드 이동이 없기 때문에 랜덤 I/O에서도 좋은 성능을 냅니다.

 

 

랜덤 I/O가 느린 구체적인 이유

랜덤 I/O는 단순히 위치를 이동해서 느리다라는 개념을 넘어서, 읽기-쓰기 위치를 계속 바꾸기 때문에, 디스크 헤더가 매번 움직여야 한다는 점에서 비효율적입니다.

 

예를 들어, 3개의 페이지(3 x 16KB)를 디스크에 기록하려고 할 때, 순차 I/O는 디스크 헤더가 한 번만 움직이면 되지만, 랜덤 I/O는 헤더가 매번 새 위치로 이동하면서 3배의 시스템 콜과 디스크 탐색 비용이 발생합니다.

 

디스크에 데이터를 쓰고 읽는 데 걸리는 시간은 디스크 헤더를 움직여서 읽고 쓸 위치로 옮기는 단계에서 결정됩니다.

즉, 디스크의 성능은 디스크 헤더의 위치 이동 없이 얼마나 많은 데이터를 한 번에 기록하느냐에 의해 결정된다고 볼 수 있습니다.

 

I/O 병목을 DB가 해결하는 방법

대부분의 DBMS는 이 I/O 병목을 줄이기 위해서 버퍼링과 캐싱 계층을 활용합니다.

MySql에서는 InnoDB 로그 버퍼, 바이너리 로그 버퍼 등이 대표적인 캐시 계층입니다.

해당 버퍼들은 랜덤 I/O가 발생하지 않도록 작은 쓰기들을 묶어서 한 번에 순차적으로 기록하도록 설계되어 있습니다.

 

이러한 구조 덕분에 실제로는 물리 디스크에 접근하기 전에 메모리 내에서 처리 가능한 작업들을 최대한 캐싱하고 정렬해서 처리하는 구조를 띱니다.

 

참고, 인덱스 레인지 스캔(Index Range Scan)은 조회 대상 레코드들이 디스크 상에서 비연속적인 위치에 저장되어 있는 경우가 많기 때문에, 디스크가 여러 위치를 이동하며 데이터를 읽게 되므로 랜덤 I/O를 유발합니다.

반면, 풀 테이블 스캔(Full Table Scan)은 테이블 전체를 연속된 블록 단위로 순차적으로 읽기 때문에, 순차 I/O로 처리됩니다.
따라서 테이블의 대부분을 읽는 쿼리에서는 오히려 인덱스를 일부러 사용하지 않고 풀 테이블 스캔을 유도하는 것이 더 나은 성능을 보일 수 있습니다. 이는 랜덤 I/O보다 순차 I/O가 훨씬 더 빠르게 대량의 데이터를 읽어올 수 있기 때문입니다.

 

마무리

결국 데이터베이스 성능을 높이기 위한 핵심은 단순히 빠른 하드웨어를 도입하는 것이 아니라 디스크 I/O라는 병목 지점을 정확히 이해하고, 이를 줄이기 위한 소프트웨어적인 전략을 함께 설계하는 것에 있습니다.

 

 

참고 자료

  • Real MySQL 8.0(1권)