SQL 서버의 적절한 IO 블록 크기는 64KB? 진실을 알려드립니다.

먼저 진실을 밝히고 넘어가겠습니다. SQL Server의 적절한 IO 블록 크기가 64KB라고 말하는 사람들이 있습니다. 안타깝게도 이는 사실이 아닙니다. 이러한 오해는 Microsoft가 모범 사례를 통해 데이터베이스 파티션/볼륨에 NTFS 할당 단위 크기인 64KB를 사용해야 한다고 명시한 사실에서 기인합니다. 물론 FILESTREAM/FILETABLE 스토어처럼 일부 예외가 존재하는 경우가 있습니다. 이 두 가지를 혼동하여 이러한 오해가 생겨났습니다. 여기서 한가지만 분명히 하고 […]


먼저 진실을 밝히고 넘어가겠습니다.

SQL Server의 적절한 IO 블록 크기가 64KB라고 말하는 사람들이 있습니다. 안타깝게도 이는 사실이 아닙니다. 이러한 오해는 Microsoft가 모범 사례를 통해 데이터베이스 파티션/볼륨에 NTFS 할당 단위 크기인 64KB를 사용해야 한다고 명시한 사실에서 기인합니다.

물론 FILESTREAM/FILETABLE 스토어처럼 일부 예외가 존재하는 경우가 있습니다. 이 두 가지를 혼동하여 이러한 오해가 생겨났습니다. 여기서 한가지만 분명히 하고 넘어가겠습니다. SQL Server IO 블록 크기와 NTFS 할당 단위는 별개입니다.

그렇다면 SQL Server IO 블록 크기는 무엇일까요? 궁금하실 텐데요, 진실은 단지 한가지 크기로만 존재하지 않는다는 것입니다. 즉 SQL Server IO 블록 크기는 수행되는 연산 및 이와 관련된 데이터 저장소에 따라 매우 다양합니다.

세부적인 내용을 살펴보기 전에 퓨어스토리지의  SQL Server 모범 사례를 확인해보십시오. NTFS 할당 단위에 대해 간단히 설명되어 있습니다.

 

트랜잭션 로그 쓰기

트랜잭션 로그 쓰기에 대한 기본적인 사실은 지연된 트랜잭션 내구성(delayed durability) 기능을 사용하지 않는 한 트랜잭션 로그 쓰기가 발생할 때마다 즉각적으로 저장 된다는 점입니다. 지연된 트랜잭션 내구성에 대해 잘 모르시는 경우 성능 최적화 도구로 사용 전에 이에 대한 정보를 충분히 확인 하시기를 권장합니다.

트랜잭션 로그 쓰기에 대한 또 한가지 진실은 쓰기가 섹터에 정렬된다는 것입니다. 이는 시스템의 섹터 크기에 따라 512 바이트일 수도 있고, 일부의 경우 4096 바이트(4Kn 드라이브, 일부 PCIe 카드)가 될 수도 있습니다. 퓨어스토리지의 플래시어레이(FlashArray)의 경우 섹터 크기는 512 바이트입니다.

트랜잭션 로그 IO를 위해 SQL이 섹터 크기의 쓰기만을 수행한다는 것을 의미할까요? 절대 그렇지 않습니다. 만일 그렇다면, 다양한 데이터를 처리하고 있는 스토리지 시스템에 수많은 데이터 이동을 발생시켜 매우 비효율적일 것입니다. SQL Server는 로그 버퍼(log buffer)라 불리는 구조를 가지고 있습니다.

이 구조는 로그 데이터를 하나로 묶어 로그 플러시(log flush)로 한번에 수행되도록 합니다. 로그 플러시의 최대 크기는 60KB입니다. 그러나 실제로는 60KB 범위 내에서 어떤 크기도 될 수 있습니다. 로그 플러시가 발생하는 경우에 대해 Microsoft에서 SQL Server Premier Field Engineer(PFE)로 근무하는 팀 채프만(Time Chapman)의 블로그를 보면, 이에 대해 자세히 설명하고 있습니다.

[블로그|트위터]. 팀 채프만의 블로그 내용은 다음과 같습니다.

SQL Server가 로그 버퍼를 디스크(트랜잭션 로그에 있는 인접 로그 블록)로 플러시 되도록 만드는 3가지 경우가 있습니다.

  1. 트랜잭션은 커밋 후 로그 버퍼에 트랜잭션 기록을 저장합니다. 이렇게 하면 해당 버퍼에 있는 모든 로그 레코드 (다시 말하면, 각 로그 버퍼에 대해 최대 60K의 트랜잭션 로그 레코드)가 로그 파일로 플러시 됩니다. 
  2.  로그 버퍼가 60K 한계에 도달하면 디스크로 플러시가 발생합니다. 
  3.  디스크로 쓰기를 해야 하는 데이터 페이지가 있으며, 그 페이지들과 관련된 로그 기록이 존재하는 경우 데이터 페이지를 데이터 파일에 쓰기 에 이 로그 기록들을 로그 파일에 기록해야 합니다. (이는 Write Ahead Logging(WAL) 프로토콜을 지원합니다. 

데이터 파일 IO

데이터 파일 IO는 트랜잭션 로그의 경우와 많이 다릅니다. 아시다시피, SQL Server는 두가지 주요 방법을 사용해 데이터베이스 파일로 쓰기를 합니다. 하나는 64KB~1MB(최대 256KB에서 증가) 사이의 IO를 발생시키는 체크포인트이고, 다른 하나는 레이지 라이터(lazy writer) 프로세스로 IO 특징 면에서 체크포인트와 유사합니다. 두 가지 방법 모두 액세스 패턴은 비슷해서 전체 페이지 (8KB 크기) 또는 전체 범위 (8개의 인접 페이지 그룹 즉, 64KB)를 액세스합니다. 읽기의 측면에서도 거의 비슷합니다. 단, 사용 중인 SQL Server 에디션에 따라 최대 512KB가 될 수도 있는 Read-Ahead는 예외입니다.

벌크 로드(Bulk load)처럼 대량 데이터가 데이터 파일로 전송(Push)되는 다른 방법들이 있으며, 이 또한 256KB인 멀티 페이지 쓰기 작업을 수행합니다.

지금까지 SQL Server IO블록 크기 설명을 통해 SQL Server IO특성을 살펴보았습니다.

그렇다면, 백업은 어떨까요? 또 복구는요? 그 부분도 살펴봐야겠죠!

 

백업 및 복구 연산

SQL Server 백업 및 복구의 경우, 엔진이 백업 매체에 따라 서로 다른 크기의 IO 블록을 선택합니다. 디스크나 파일 공유로 백업을 하는 경우, SQL은 1MB의 IO 블록 크기를 선택합니다.

 

여기서 끝나지 않습니다!

SQL Server는 다른 특수 구조를 위해 더 많은 유형의 IO 크기를 제공합니다. 전형적인 예로, 컬럼스토어(ColumnStore) 인덱스의 경우 최대 8MB 크기의 IO를 제공합니다. 또한 아래 예시에서 처럼, 더 많은 케이스를 고려해야 합니다. 파일 초기화, 인메모리 온라인 트랜잭션 처리(OLTP) 데이터 등 다양합니다. SQL Server는 방대한 제품이기 때문에 I/O 액세스 패턴이 다른 많은 주요 기능을 제공합니다.

이 주제에 대해 보다 자세히 알고 싶다면 밥 워드(Bob Ward)가 PASS Summit 2014에서 발표한 SQL Server I/O 프레젠테이션을 확인하십시오. 3시간 동안 머리가 아플 정도로 세부적인 내용을 다루지만, 그보다 더 기본적인 수준에서 설명할 수는 없습니다. 🙂

 

SQL Server I/O 블록 크기 참조 테이블

SQL Server IO Block Sizes

SQL Server I/O – 플래시어레이(FlashArray)

이제 SQL Server가 사용하는 다수의 IO 블록 크기에 대해 설명했으니, 플래시어레이(FlashArray) 스토리지 어레이 제품군의 성능 특징이 모두 32KB 크기의 IOPS로 명시되는 데 합리적인 이유가 있다는 사실을 상기시켜 드리며 마무리 하겠습니다. 위의 내용으로 짐작 하셨겠지만, 잘 알려진 4KB라는 수치는 실제로 데이터베이스와 크게 연관되지 않습니다.

SQL Server의 워크로드 구동을 위해 퓨어스토리지를 다른 공급업체와 비교하는 경우, 타 공급업체에게 서로 다른 IO 블록 크기에 따라 어떻게 달라지는지에 대한 정보를 요청하십시오. 여러분은 수천 명의 고객이SQL Server 데이터베이스를 퓨어스토리지 안전하게 운영하고 있는지 확신하실 수 있습니다.

 

다음 글을 기대해주십시오!

지금까지 읽어 주셔서 감사합니다. 다음 시간에는 데이터 중복제거 및 압축 기반 어레이의 적절한 테스트 방법을 이야기해 보겠습니다. 스포일러: DiskSpd를 실행하는 것 보다 훨씬 많은 것들이 필요합니다!

그럼 다음에 또 찾아 뵙겠습니다!