SQL Server와 SQL Linux에서 인스턴스 파일 초기화 차이점
· Version : SQL Server, SQL Server Linux
SQL Server는 로그 파일 또는 데이터 파일이 증가하거나 새로 작성될때, 인스턴트 파일 초기화 작업을 진행한다. 이번 포스트에서는 인스턴스 파일이 초기화 될때, 기본 파일 시스템 구현과 Windows 와 Linux 간의 동작 차이를 알아본다.
· Database File Initialization : https://docs.microsoft.com/en-us/sql/relational-databases/databases/database-instant-file-initialization?view=sql-server-2017
SQL Server는 데이터 및 로그 파일을 만들거나 확장(증가)할때 아래 API를 호출 한다.
· CreateFile : 파일 작성 또는 열기
· SetEndOfFile : 파일 크기를 설정하고 I/O 장치에서 공간을 확보
· SetFileValidData : 유효한 데이터 크기 설정
파일이 로그 파일(LDF)인 경우 SQL Server는 알려진 패턴값을 할당된 공간에 쓴다. 데이터 파일 (MDF, NDF)인 경우 SQL Server는 인스턴스 파일 초기화 및 추적 플래그 1805 설정을 확인하여 할당된 공간에 패턴값을 쓸지 여부를 결정한다.
TF 1805 : 데이터 파일에 대한 인스턴스 파일 초기화를 비활성화 한다. 참고 : 스탬핑은 일반적으로 최적의 성능과 Windows 및 Linux 파일 시스템 페이지 및 블록크기 정렬과 정렬을 위해 4MB 청크로 수행 |
[Windows]
Windows 파일 시스템(NTFS, RTFS)에는 파일을 즉시 초기화 하기 위한 두 개의 멤버키가 있다.
· EOF : 파일 끝 위치
· VDL : 유효한 데이터 길이 위치
Empty File
파일이 처음 작성될 때 EOF와 VDL은 모두 파일의 시작을 가리킨다.
· EOF = 0
· VLD = 0
SetEndOfFile
SetEndOfFile은 파일을 확장하여 I/O 장치에서 공간을 확보하고 EOF 값을 조정한다. VLD 값은 변경되지 않은 상태로 유지된다.
· EOF = 10G
· VLD = 0
SetFileValidData
SetFileValidData는 VDL을 이동하는데 사용된다. VDL이 기록된 것으로 간주되는 경우(쓰기가 수행되지 않은 경우에도) VDL 오프셋 이전의 모든 데이터와 VDL 이전의 공간 읽기는 I/O 장치에서 오래된 데이터를 반환할 수 있다. VDL 이후의 데이터는 유효하지 않은 것으로 간주되며 읽기 요청에 대해 0이 리턴된다.
· EOF = 10GB
· VDL = 1GB
참고 : 보안 고려사항과 관련된 내용은 위의Database File Initialization 문서를 참고한다.
Write beyond the current VDL (WriteFile*)
VDL 오프셋 이상으로 쓰기가 발생하면 Windows는VDL을 이동하여 쓰기를 수용하고 이전 VDL과 쓰기 요청 시작 사이의 오프셋에 0을 쓴다.
· EOF = 10GB
· 이전 VDL =1 GB
· VDL = 5GB
Instant File Initialization (New File)
VDL 증분 변경 대신 SQL Server는 SetEndOfFile의 빠른 할당 기능을 사용하고 동일한 오프셋으로 SetFileValidData를 호출한다. VDL이전의 모든 데이터는 Windows 파일 시스템에 의해 쓰여진(유효한) 것으로 간주된다. 인스턴트 파일 초기화가 활성화 된 경우 Windows는 0을 쓰지 않으며 SQL Server가 데이터 파일의 패턴을 스탬프 처리 하지 않는다. 내부 SQL Server 데이터베이스 할당 구조는 SQL Server 데이터 파일 할당 및 유효한 데이터 읽기 활동을 추적한다.
Instant File Initialization (Grow)
인스턴스 파일 초기화를 사용하여 파일을 확장하면 새 오프셋으로 SetEndOfFile 및 SetFileValidData가 수행된다. Windows 는 새 오프셋과 이전 오프셋 사이의 데이터를 유요한 것으로 취급한다.
[Linux]
Fallocate(http://man7.org/linux/man-pages/man2/fallocate.2.html) 시스템 호출(ABI)을 사용한 Linux 지원 파일 할당 Windows API호출은 아래와 같이 Linux ABI 호출에 매핑 된다.
· CreateFile : Linux를 사용
· SetEndOfFile : Linux fallocate 사용
· SetFileValidData : Linux의 Noop
Windows와 Linux 파일 시스템의 주요 차이점은 유효한 데이터 길이( VDL)이 아닌 범위를 추적한다. Linux에서 각 범위에는 I/O 장치에 쓰여 졌는지 여부를 나타내는 플래그가 포함된다.
Empty File
파일이 처음 작성될 때 EOF= 0이고 포함 범위는 기록되지 않도록 (N)으로 설정된다. 쓰지 않은 범위의 읽기는 Linux에서 항상 0을 반환한다. Linux는I/O 장치를 사용하지 않지만 단순히 쓰지 않는 범위로 추적된 공간에 대해 리턴 버퍼를 0으로 채운다.
힌트 : 익스텐트 크기 및 조정에 대해서는 Linux 파일 시스템 설명서를 확인한다. 기본 크기는 일반적으로 최적의 성능을 위해 SQL Server 페이지는8K 및 64K 범위 경계에 잘 맞는 메모리 페이지 크기 경계(주로4K)와 정렬된다.
SetEndOfFile
파일 크기 증가는 대체 호출로 발생한다. Linux는 I/O 장치에서 공간을 확보하고 EOF와 추적 범위 메타 데이터를 설정하여 기록되지 않음을 나타낸다. Fallocate는 SetEndOfFile이 Windows 파일 시스템의 공간을 확보하는 것처럼 공간을 확보하여 대용량 파일을 빠르게 생성할 수 있다. 차이점은 SetFileValidData이다. Linux는 실제 쓰기 없이 범위 추적을 ‘쓰기’로 설정하는 기능을 제공하지 않는다.
성능 고려 사항 : 대상 파일 시스템에 대해 fallocate가 지원되지 않으면 SQL Server는 ftruncate를 사용한다. 이름과 달리 ftruncate ABI는 파일을 늘리는데 사용될 수 있지만 씬 프로비저닝된 조장이다.(공간은 메타데이터만 업데이트 되지 않는다.) ftruncate가 필요한 경우 실제 공간을 확보하고 제공하기 위해 SQLPAL이 파일에 0을 쓴다. SQLPAL 프로세스에 대한 오류가 없고 읽기 동작이 없다.
Write
첫 번째 쓰기가 수행되면 범위에 대한 메타 데이터도 업데이트 된다. 쓰기 및 쓰기 되지 않은 데이터를 추적하기 위해 익스텐트를 분할하거나Linux 커널에 의해 확장된 쓰기는 디스크의 공간에 0을 쓰므로 전체 익스텐트가 쓰기 된것으로 표시될 수 있다.
참고 : 대부분의 Linux 파일 시스템에서는 두 번의 쓰기 요청이 발생하지만 쓰기 크기 및 오프셋 정렬에 따라 더 커질수 있다. (데이터 파일 요청1개와 메타데이터 변경 요청 1개)
Windows 에서 SetFileValidData는 단일 메타 데이터 작업이다. VDL이 설정되면 쓰기(순차 또는 임의)는 VDL == EOF로 추가 메타 데이터 업데이트가 필요하지 않다. Linux에서 쓰기에는 데이터 쓰기 및 메타 데이터 쓰기가 필요한 익스텐트 업데이트가 필요하다. Linux 또는 Windows에서 가능한 한 빨리 파일을 쓰고 확장할 수 있다. 그러나 Linux에서 처음 쓰기를 수행하면 메타 데이터가 유지관리 된다.
· 데이터베이스에서 쓰기 속도가 중요한 경우 익스텐트 파일 초기화를 사용하고 첫 번째 쓰기에 추가 오버헤드가 발생하도록 한다.
참고 : 대부분의 쓰기 작업은Checkpoint 또는 Lazy Write와 같은 백그라운드 프로세스로 수행되므로 SQL Server에서 오버헤드를 숨기는 경우가 많다. 활성 SQL Server 세션에서 쓰기가 발생할 수 있으므로 대량 로드는 예외이다.
· 쓰기 속도를 늘릴수 있는 경우 -T1805를 사용하면 데이터베이스가 쓰기 및 확장 중에 데이터파일 공간을 스탬핑 되도록 할 수 있다. 스탬핑은 큰 청크로 최적화되어 있으며 첫 번째 쓰기 데이터 및 메타 데이터 작업이 발생하는 쓰기 경로가 된다. 위치가 기록(스탬프) 되면 더 이상 추가 메타 데이터 쓰기가 필요하지 않다.
참고 : 파일 시스템이 fallocate를 지원하지 않으면 SQLPAL에 의해 파일에 0이 기록된다. 로그 파일(LDF)은 알려진 패턴(0으로 작성)을 표시하며 SQLPAL 공간을 0으로 채울때 메타데이터가 이미 업데이트 되었으므로 데이터 파일에 대한 인스턴스 파일 초기화를 안전하게 유지할 수 있다.
[참고자료]
2019-09-13 / Sungwook Kang / http://sungwookkang.com
SQL Server, SQL Linux, File System, Windows, Linux, SetFileValidData (Windows) vs fallocate (Linux), T1805, SetEndOfFile, SetFileValidData, VDL
'SQL Server > SQL Server Tip' 카테고리의 다른 글
SQL Server Worker Thread 기본 계산 (0) | 2019.09.18 |
---|---|
SQL Linux의 fsync 및 버퍼된 IO (버퍼된 쓰기중 오류가 발생하였을때 파일은 유효할까?) (0) | 2019.09.17 |
BCP 실행시 동일 세션에서 여러개의 BULK INSERT 문으로 표시되는 이유 (0) | 2019.09.13 |
삭제된 AD 그룹 계정으로 SQL Server 로그인 사례 (로그인 그룹 삭제 후 조치해야할 사항) (1) | 2019.09.12 |
QPI(Query Performance Insights) 라이브러리를 사용하여 Azure SQL Managed Instance의 로그쓰기 사용량 확인 (0) | 2019.09.11 |