적용 대상:SQL Server
메모리 내 OLTP는 메모리 최적화 테이블에 대해 완전 내구성을 제공합니다. 메모리 최적화 테이블을 변경한 트랜잭션이 커밋되면 SQL Server(디스크 기반 테이블의 경우처럼)는 기본 스토리지를 사용할 수 있는 경우 변경 내용이 영구(데이터베이스 다시 시작 시 유지됨)되도록 보장합니다. 내구성의 두 가지 주요 구성 요소는 트랜잭션 로깅 및 디스크상 스토리지에 데이터 변경 내용 저장입니다.
지속성 테이블의 크기 제한에 대한 자세한 내용은 Memory-Optimized 테이블에 대한 예상 메모리 요구 사항을 참조하세요.
트랜잭션 로그
디스크 기반 테이블 또는 내구성 있는 메모리 최적화 테이블에 대한 모든 변경 내용은 하나 이상의 트랜잭션 로그 레코드에 캡처됩니다. 트랜잭션이 커밋되면 SQL Server는 트랜잭션이 커밋한 애플리케이션 또는 사용자 세션과 통신하기 전에 트랜잭션과 연결된 로그 레코드를 디스크에 씁니다. 이렇게 하면 트랜잭션에 의한 변경 사항이 내구성을 가집니다. 메모리 최적화 테이블의 트랜잭션 로그는 디스크 기반 테이블에서 사용하는 것과 동일한 로그 스트림과 완전히 통합됩니다. 이 통합을 사용하면 추가 단계 없이 기존 트랜잭션 로그 백업, 복구 및 복원 작업이 계속 작동할 수 있습니다. 그러나 In-Memory OLTP는 워크로드의 트랜잭션 처리량을 크게 증가시킬 수 있으므로 로그 IO는 성능 병목 상태가 될 수 있습니다. 이 증가한 처리량을 견디기 위해 로그 IO 하위 시스템에서 증가한 로드를 처리할 수 있습니다.
데이터 및 델타 파일
메모리 최적화 테이블의 데이터는 메모리 내 힙 데이터 구조에 자유 형식 데이터 행으로 저장되며 메모리에 있는 하나 이상의 인덱스를 통해 연결됩니다. 디스크 기반 테이블에 사용되는 것과 같은 데이터 행에 대한 페이지 구조는 없습니다. 장기 지속성 및 트랜잭션 로그 잘림을 허용하기 위해 메모리 최적화 테이블에 대한 작업은 데이터 및 델타 파일 집합에 유지됩니다. 이러한 파일은 비동기 백그라운드 프로세스를 사용하여 트랜잭션 로그를 기반으로 생성됩니다. 데이터 및 델타 파일은 하나 이상의 컨테이너에 위치합니다(FILESTREAM 데이터에 사용되는 것과 동일한 메커니즘 사용). 이러한 컨테이너는 메모리 최적화 파일 그룹의 일부입니다.
데이터는 이 파일에 기록될 때 회전 미디어의 디스크 대기 시간을 최소화하는 엄격한 순차적 방식으로 기록됩니다. 서로 다른 디스크에 여러 컨테이너를 사용하여 I/O 작업을 분산시킬 수 있습니다. 서로 다른 디스크의 여러 컨테이너에 있는 데이터 및 델타 파일은 디스크의 데이터 및 델타 파일에서 메모리로 데이터를 읽을 때 데이터베이스 복원/복구 성능을 향상합니다.
사용자 트랜잭션은 데이터 및 델타 파일에 직접 액세스하지 않습니다. 모든 데이터 읽기 및 쓰기는 메모리 내 데이터 구조를 사용합니다.
데이터 파일
데이터 파일에는 INSERT 또는 UPDATE 작업의 일부로 여러 트랜잭션에 의해 삽입된 하나 이상의 메모리 최적화 테이블의 행이 포함되어 있습니다. 예를 들어, 메모리 최적화 테이블 T1에서 한 행을 가져오고 메모리 최적화 테이블 T2에서 다음 행을 가져올 수 있습니다. 행은 트랜잭션 로그의 트랜잭션 순서대로 데이터 파일에 추가되어 데이터 액세스가 순차적으로 이루어집니다. 이렇게 하면 임의 I/O와 비교할 때 상당히 나은 I/O 처리량이 가능합니다.
데이터 파일이 가득 차면 새 트랜잭션에 의해 삽입된 행은 다른 데이터 파일에 저장됩니다. 시간이 지남에 따라 지속성 메모리 최적화 테이블의 행은 더 많은 데이터 파일 중 하나에 저장되고 행이 포함된 각 데이터 파일은 연결되지 않았지만 연속된 트랜잭션 범위를 형성합니다. 예를 들어, 트랜잭션 커밋 타임스탬프 범위가 (100, 200)인 데이터 파일에는 커밋 타임스탬프가 100보다 크고 200보다 작거나 같은 트랜잭션에 의해 삽입된 모든 행이 포함됩니다. 커밋 타임스탬프는 커밋할 준비가 되면 트랜잭션에 할당된 일체적으로 증가하는 수입니다. 각 트랜잭션에는 고유한 커밋 타임스탬프가 있습니다.
행이 삭제되거나 업데이트되면 데이터 파일에서 행이 제거되거나 변경되지 않지만 삭제된 행은 다른 형식의 파일인 델타 파일에서 추적됩니다. 업데이트 작업은 각 행에 대한 삭제 및 삽입 작업의 튜플로 처리됩니다. 이렇게 하면 데이터 파일에서 임의의 IO가 제거됩니다.
크기: 각 데이터 파일의 크기는 16GB보다 메모리가 더 큰 컴퓨터의 경우 약 128MB, 16GB보다 메모리가 더 작거나 같은 컴퓨터의 경우 약 16MB입니다. SQL Server 2016(13.x)에서 SQL Server는 스토리지 하위 시스템이 충분히 빠르다고 판단되는 경우 큰 검사점 모드를 사용할 수 있습니다. 큰 검사점 모드에서 데이터 파일의 크기는 1GB로 설정됩니다. 이렇게 하면 처리량이 높은 워크로드에 대한 스토리지 하위 시스템의 효율성을 높일 수 있습니다.
델타 파일
각 데이터 파일은 트랜잭션 범위가 동일하고 해당 트랜잭션 범위에서 트랜잭션에 의해 삽입된 삭제된 행을 추적하는 델타 파일과 쌍을 이룹니다. 이 데이터 및 델타 파일은 CFP(체크포인트 파일 페어)라고 하며, 할당, 해제, 그리고 병합 작업의 단위로 사용됩니다. 예를 들어 트랜잭션 범위(100, 200)에 해당하는 델타 파일은 트랜잭션에 의해 삽입된 삭제된 행(100, 200)을 저장합니다. 데이터 파일과 마찬가지로 델타 파일도 순차적으로 액세스됩니다.
행이 삭제되면 행은 데이터 파일에서 제거되지 않지만 행에 대한 참조는 이 데이터 행이 삽입된 트랜잭션 범위와 연결된 델타 파일에 추가됩니다. 삭제할 행이 데이터 파일에 이미 있으므로 델타 파일에는 참조 정보 {inserting_tx_id, row_id, deleting_tx_id}만 저장되고 원래 삭제 또는 업데이트 작업의 트랜잭션 로그 순서를 따릅니다.
크기: 각 델타 파일의 크기는 16GB보다 메모리가 더 큰 컴퓨터의 경우 약 16MB, 16GB보다 메모리가 더 작거나 같은 컴퓨터의 경우 약 1MB입니다. SQL Server 2016(13.x)부터 SQL Server는 스토리지 하위 시스템이 충분히 빠르다고 판단되는 경우 큰 검사점 모드를 사용할 수 있습니다. 큰 검사점 모드에서 델타 파일의 크기는 128GB로 설정됩니다.
데이터 및 델타 파일 채우기
데이터 및 델타 파일은 메모리 최적화 테이블의 커밋된 트랜잭션에 의해 생성된 트랜잭션 로그 레코드를 기반으로 채워지고 삽입 및 삭제된 행에 대한 정보를 적절한 데이터 및 델타 파일에 추가합니다. 검사점이 완료되면 데이터/인덱스 페이지가 임의의 I/O로 플러시되는 디스크 기반 테이블과 달리, 메모리 최적화 테이블의 지속성은 지속적인 백그라운드 작업입니다. 트랜잭션을 삭제하거나 이전 트랜잭션에 의해 삽입된 모든 행을 업데이트하기 때문에 여러 개의 델타 파일이 액세스됩니다. 삭제 정보는 항상 델타 파일의 끝에 추가됩니다. 예를 들어 커밋 타임스탬프가 600인 트랜잭션은 새 행 하나를 삽입하고 다음 이미지와 같이 커밋 타임스탬프가 150, 250 및 450인 트랜잭션에 의해 삽입된 행을 삭제합니다. 4개의 파일 I/O 작업(삭제된 행의 경우 3개, 새로 삽입된 행의 경우 1개)은 모두 해당 델타 및 데이터 파일에 추가 전용 작업입니다.
데이터 및 델타 파일 액세스
데이터 및 델타 파일 쌍은 다음 이벤트가 발생할 때 액세스됩니다.
오프라인 검사점 작업자
이 스레드는 메모리 최적화 데이터 행을 해당 데이터 및 델타 파일 쌍에 삽입하고 삭제합니다. SQL Server 2014(12.x)에는 오프라인 검사점 작업자가 하나 있습니다. SQL Server 2016(13.x) 이상 버전에는 여러 검사점 작업자가 있습니다.
병합 작업
이 작업은 하나 이상의 데이터 및 델타 파일 쌍을 병합하고 새 데이터 및 델타 파일 쌍을 만듭니다.
크래시 복구 중
SQL Server가 다시 시작되거나 데이터베이스가 다시 온라인 상태가 되면 데이터 및 델타 파일 쌍을 사용하여 메모리 최적화 데이터가 채워집니다. 델타 파일은 해당 데이터 파일에서 행을 읽을 때 삭제된 행에 대한 필터 역할을 합니다. 각 데이터 및 델타 파일 쌍은 독립적이므로 이러한 파일은 데이터를 메모리에 채우는 데 걸리는 시간을 줄이기 위해 병렬로 로드됩니다. 데이터가 메모리에 로드되면 In-Memory OLTP 엔진은 메모리 최적화 데이터가 완료되도록 검사점 파일에서 아직 다루지 않는 활성 트랜잭션 로그 레코드를 적용합니다.
복원 작업 중
메모리 내 OLTP 검사점 파일이 데이터베이스 백업에서 만들어진 다음 하나 이상의 트랜잭션 로그 백업이 적용됩니다. 크래시 복구와 마찬가지로 In-Memory OLTP 엔진은 복구 시간에 미치는 영향을 최소화하기 위해 데이터를 메모리에 병렬로 로드합니다.
데이터 및 델타 파일 병합
메모리 최적화 테이블의 데이터는 하나 이상의 데이터 및 델타 파일 쌍(검사점 파일 쌍 또는 CFP라고도 함)에 저장됩니다. 데이터 파일에는 삽입된 행이 저장되고 델타 파일은 삭제된 행을 참조합니다. OLTP 작업을 실행하는 동안 DML 작업에서는 행을 업데이트, 삽입 및 삭제하고, 새 행을 유지하기 위한 새 CFP가 만들어지고, 삭제된 행에 대한 참조가 델타 파일에 추가됩니다.
시간이 지남에 따라 DML 작업을 통해 데이터 및 델타 파일 수가 증가하여 디스크 공간 사용량이 증가하고 복구 시간이 증가합니다.
이러한 비효율성을 방지하기 위해 이 문서의 뒷부분에 설명된 병합 정책에 따라 이전의 닫힌 데이터 및 델타 파일이 병합되므로 스토리지 배열은 파일 수가 감소된 동일한 데이터 집합을 나타내도록 압축됩니다.
병합 작업은 내부적으로 정의된 병합 정책을 기반으로 데이터 및 델타 파일 쌍(병합 원본이라고 함)인 하나 이상의 인접한 닫힌 검사점 파일 쌍(CFP)을 입력으로 사용하고 병합 대상이라고 하는 하나의 결과 CFP를 생성합니다. 원본 CFP의 각 델타 파일에 있는 항목은 해당 데이터 파일의 행을 필터링하여 필요하지 않은 데이터 행을 제거하는 데 사용됩니다. 원본 CFP의 나머지 행은 하나의 대상 CFP로 통합됩니다. 병합이 완료되면 결과 병합 대상 CFP가 원본 CFP(병합 원본)를 대체합니다. 병합 원본 CFP는 스토리지에서 제거되기 전에 전환 단계를 진행합니다.
다음 예제에서 메모리 최적화 테이블 파일 그룹에는 이전 트랜잭션의 데이터가 포함된 타임스탬프 500에 4개의 데이터 및 델타 파일 쌍이 있습니다. 예를 들어 첫 번째 데이터 파일의 행은 100 초과 200 이하인 타임스탬프가 있는 트랜잭션에 해당하며, (100, 200]으로도 표시할 수 있습니다. 두 번째 및 세 번째 데이터 파일은 삭제된 것으로 표시된 행이 채워진 비율이 50% 미만으로 표시됩니다. 병합 작업은 이러한 두 CFP를 결합하여 두 CFP의 합산 범위인 200 초과 400 이하인 타임스탬프가 있는 트랜잭션이 포함된 새 CFP를 만듭니다. (500, 600] 범위의 또 다른 CFP와 (200, 400] 범위의 트랜잭션에 대한 비어있지 않은 델타 파일을 살펴보면 병합 작업은 원본 CFP에서 더 많은 행을 삭제하는 등의 트랜잭션 작업과 동시에 수행할 수 있음을 보여 줍니다.
백그라운드 스레드는 병합 정책을 사용하여 모든 닫힌 CFP를 평가한 다음 적격인 CFP에 대해 하나 이상의 병합 요청을 시작합니다. 이러한 병합 요청은 오프라인 검사점 스레드에서 처리됩니다. 병합 정책 평가는 주기적으로 수행되며 검사점을 닫을 때에도 수행됩니다.
SQL Server 병합 정책
SQL Server는 다음의 병합 정책을 구현합니다.
삭제된 행을 고려한 후 두 개 이상의 연속 CFP를 통합할 수 있는 경우 결과 행이 대상 크기의 CFP 하나에 맞을 수 있도록 병합이 예약됩니다. 데이터 및 델타 파일의 대상 크기는 앞에서 설명한 대로 원래 크기 조정에 해당합니다.
데이터 파일이 대상 크기의 2배를 초과하고 행이 절반 넘게 삭제된 경우 단일 CFP가 자체적으로 병합될 수 있습니다. 예를 들어, 단일 트랜잭션이나 여러 동시 트랜잭션이 많은 양의 데이터를 삽입하거나 업데이트하여 데이터 파일이 대상 크기를 초과할 수 있습니다. 이는 트랜잭션이 여러 CFP에 걸쳐서 실행될 수 없기 때문에 데이터 파일의 크기가 목표 크기를 초과하게 되는 경우입니다.
다음은 병합 정책에서 병합할 CFP를 보여 주는 몇 가지 예입니다.
| 인접한 CFP 원본 파일(전체%) | 병합 선택 |
|---|---|
| CFP0(30%), CFP1(50%), CFP2(50%), CFP3(90%) | (CFP0, CFP1) CFP2는 결과 데이터 파일이 이상적인 크기의 100%를 초과하므로 선택되지 않습니다. |
| CFP0(30%), CFP1(20%), CFP2(50%), CFP3(10%) | (CFP0, CFP1, CFP2). 파일은 왼쪽부터 선택됩니다. CFP3은 결과 데이터 파일이 이상적인 크기의 100%를 초과하므로 선택되지 않습니다. |
| CFP0 (80%), CFP1 (30%), CFP2 (10%), CFP3 (40%) | (CFP1, CFP2, CFP3). 파일은 왼쪽부터 선택됩니다. CFP0은 CFP1과 결합된 경우 결과 데이터 파일이 이상적인 크기의 100%보다 크므로 건너뜁집니다. |
사용 가능한 공간이 있는 CFP 중 일부는 병합할 수 없습니다. 예를 들어, 인접한 두 CFP가 60% 가득 차면 병합할 자격이 없으며, 이러한 CFP들은 각각 40%의 스토리지가 사용되지 않는 상태입니다. 최악의 경우, 모든 CFP가 50% 가득 차서 스토리지 사용률이 단지 50%에 그칩니다. CFP가 병합 요건을 충족하지 않기 때문에 삭제된 행이 스토리지에 남아 있을 수 있지만, 이와 동시에 메모리 내 가비지 수집 프로세스에 의해 메모리에서 이미 제거되었을 수 있습니다. 스토리지 및 메모리 관리는 가비지 수집과 별개입니다. 활성 CFP에서 사용하는 스토리지(모든 CFP가 업데이트되는 것은 아님)는 메모리의 지속성 테이블 크기보다 최대 2배 더 클 수 있습니다.
CFP의 수명 주기
CFP 할당을 취소하려면 여러 상태를 전환해야 합니다. 데이터베이스 검사점 및 로그 백업은 여러 단계를 통해 파일을 전환하고 더 이상 필요하지 않은 파일을 궁극적으로 정리하기 위해 수행되어야 합니다. 이러한 단계에 대한 설명은 sys.dm_db_xtp_checkpoint_files 참조하세요.
검사점 후에 강제 로그 백업을 수동으로 수행하여 가비지를 빠르게 수집할 수 있습니다. 프로덕션 시나리오에서 백업 전략의 일부로 수행된 자동 검사점 및 로그 백업은 수동 개입 없이 이러한 단계를 통해 CFP를 원활하게 전환합니다. 가비지 수집 프로세스의 효과는 메모리 최적화 테이블이 있는 데이터베이스의 스토리지 크기가 메모리 크기에 비해 클 수 있다는 것입니다. 검사점 및 로그 백업이 발생하지 않으면 검사점 파일의 디스크 공간은 계속 증가합니다.