메모리 최적화 테이블의 내구성
적용 대상: SQL Server
메모리 내 OLTP는 메모리 최적화 테이블에 대해 완전 내구성을 제공합니다. 메모리 최적화 테이블을 변경한 트랜잭션이 커밋되면 SQL Server는(디스크 기반 테이블의 경우처럼) 기본 스토리지를 사용할 수 있는 경우 변경 내용이 영구적이도록(데이터베이스가 다시 시작되도 유지됨) 보장합니다. 내구성의 두 가지 주요 구성 요소는 트랜잭션 로깅 및 디스크상 스토리지에 데이터 변경 내용 저장입니다.
내구성 있는 테이블의 크기 제한 사항에 대한 자세한 내용은 메모리 최적화 테이블의 메모리 요구 사항 예측을 참조하세요.
트랜잭션 로그
디스크 기반 테이블 또는 내구성 있는 메모리 최적화 테이블에 대한 모든 변경 내용은 하나 이상의 트랜잭션 로그 레코드에 캡처됩니다. 트랜잭션이 커밋되면 SQL Server는 트랜잭션이 커밋한 애플리케이션 또는 사용자 세션과 통신하기 전에 트랜잭션과 연결된 로그 레코드를 디스크에 씁니다. 이렇게 하면 트랜잭션에 의한 변경 사항이 내구성을 가집니다. 메모리 최적화 테이블의 트랜잭션 로그는 디스크 기반 테이블에서 사용하는 것과 동일한 로그 스트림과 완전히 통합됩니다. 이러한 통합에 따라 기존 트랜잭션 로그 백업, 복구 및 복원 작업이 추가 단계를 필요로 하지 않고 계속 수행될 수 있습니다. 그러나 메모리 내 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가 다시 시작되거나 데이터베이스가 다시 온라인 상태가 되면 데이터 및 델타 파일 쌍을 사용하여 메모리 최적화 데이터가 채워집니다. 델타 파일은 해당 데이터 파일에서 행을 읽을 때 삭제된 행에 대한 필터 역할을 합니다. 각 데이터 및 델타 파일 쌍은 독립적이므로 이러한 파일은 데이터를 메모리에 채우는 데 걸리는 시간을 줄이기 위해 병렬로 로드됩니다. 데이터가 메모리로 로드되면 메모리 내 OLTP 엔진은 메모리 최적화 데이터가 완전하도록 검사점 파일에 아직 포함되지 않은 활성 트랜잭션 로그 레코드를 적용합니다.
복원 작업 중
메모리 내 OLTP 검사점 파일이 데이터베이스 백업에서 만들어진 다음 하나 이상의 트랜잭션 로그 백업이 적용됩니다. 충돌 복구와 마찬가지로 메모리 내 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 1개에 맞을 수 있도록 2개 이상의 연속 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). 파일은 왼쪽부터 선택됩니다. CTP3는 결과 데이터 파일을 이상적인 크기의 100%를 초과하게 만들므로 선택되지 않습니다. |
CFP0 (80%), CFP1 (30%), CFP2 (10%), CFP3 (40%) | (CFP1, CFP2, CFP3). 파일은 왼쪽부터 선택됩니다. CFP0은 CFP1과 결합하면 결과 데이터 파일이 이상적인 크기의 100%보다 커지므로 CFP0을 건너뜁니다. |
사용 가능한 공간이 있는 CFP 중 일부는 병합할 수 없습니다. 예를 들어 인접한 두 CFP가 60% 채워진 경우 병합할 자격이 없으며 이러한 각 CFP에는 40%의 스토리지가 사용되지 않습니다. 최악의 경우 모든 CFP가 50% 채워진 경우 스토리지의 50%만 사용됩니다. CFP가 병합에 적합하지 않아 삭제된 행이 스토리지에 존재할 수 있지만 삭제된 행은 메모리 내 가비지 수집에 의해 메모리에서 이미 제거되었을 수 있습니다. 스토리지 및 메모리 관리는 가비지 수집과 별개입니다. 활성 CFP(모든 CFP가 업데이트되는 것은 아님)가 사용하는 스토리지는 메모리의 내구성 있는 테이블 크기보다 최대 2배 더 클 수 있습니다.
CFP의 수명 주기
CFP 할당을 취소하려면 여러 상태를 전환해야 합니다. 데이터베이스 검사점 및 로그 백업은 여러 단계를 통해 파일을 전환하고 더 이상 필요하지 않은 파일을 궁극적으로 정리하기 위해 수행되어야 합니다. 이러한 단계에 대한 자세한 설명은 sys.dm_db_xtp_checkpoint_files(Transact-SQL)를 참조하세요.
검사점 후에 강제 로그 백업을 수동으로 수행하여 가비지를 빠르게 수집할 수 있습니다. 프로덕션 시나리오에서 백업 전략의 일부로 수행되는 자동 검사점 및 로그 백업은 어떠한 수동 개입 없이도 이러한 단계를 통해 CFP를 원활하게 전환합니다. 가비지 수집 프로세스의 영향으로 메모리 최적화 테이블을 포함하는 데이터베이스에 메모리 내 크기에 비해 큰 스토리지가 존재할 수 있습니다. 검사점 및 로그 백업이 수행되지 않으면 검사점 파일의 디스크 사용 공간은 계속 증가합니다.