다음을 통해 공유


FILESTREAM [SQL Server]

적용 대상: SQL Server - Windows만 해당

FILESTREAM을 사용하면 SQL Server 기반 애플리케이션에서 문서 및 이미지와 같은 구조화되지 않은 데이터를 파일 시스템에 저장할 수 있습니다. 애플리케이션은 파일 시스템의 풍부한 스트리밍 API와 성능을 사용할 수 있으며 동시에 구조화되지 않은 데이터와 해당 구조화된 데이터 간의 트랜잭션 일관성을 유지할 수 있습니다.

FILESTREAM은 varbinary(max) BLOB(Binary Large Object) 데이터를 파일 시스템의 파일로 저장하여 SQL Server 데이터베이스 엔진을 NTFS 또는 ReFS 파일 시스템과 통합합니다. Transact-SQL 문은 FILESTREAM 데이터를 삽입, 업데이트, 쿼리, 검색 및 백업할 수 있습니다. Win32 파일 시스템 인터페이스는 데이터에 대한 스트리밍 액세스를 제공합니다.

FILESTREAM은 파일 데이터를 캐시하기 위해 NT 시스템 캐시를 사용합니다. 시스템 캐시에서 파일을 캐싱하면 FILESTREAM 데이터가 데이터베이스 엔진 성능에 미칠 수 있는 영향을 줄일 수 있습니다. SQL Server 버퍼 풀이 사용되지 않으므로 이 메모리는 쿼리 처리용으로 사용할 수 있습니다.

SQL Server를 설치하거나 업그레이드할 때 FILESTREAM이 자동으로 사용하도록 설정되지는 않습니다. SQL Server 구성 관리자 및 SQL Server Management Studio를 사용하여 FILESTREAM을 사용하도록 설정해야 합니다. FILESTREAM을 사용하려면 특수 형식의 파일 그룹을 포함하도록 데이터베이스를 만들거나 수정해야 합니다. 그런 다음 FILESTREAM 특성이 있는 varbinary(max) 열을 포함할 수 있도록 테이블을 만들거나 수정합니다. 이러한 작업을 완료한 후 Transact-SQL 및 Win32를 사용하여 FILESTREAM 데이터를 관리할 수 있습니다.

FILESTREAM을 사용하는 경우

SQL Server에서 BLOB는 테이블에 데이터를 저장하는 표준 varbinary(max) 데이터 또는 파일 시스템에 데이터를 저장하는 FILESTREAM varbinary(max) 개체가 될 수 있습니다. 데이터의 크기와 사용은 데이터베이스 스토리지 또는 파일 시스템 스토리지를 사용해야 하는지 여부를 결정합니다. 다음 조건이 충족되면 FILESTREAM을 사용하는 것이 좋습니다.

  • 저장되는 개체는 평균적으로 1MB보다 큽다.
  • 빠른 읽기 액세스가 중요합니다.
  • 애플리케이션 논리에 중간 계층을 사용하는 애플리케이션을 개발하고 있습니다.

더 작은 개체의 경우 데이터베이스에 varbinary(max) BLOB을 저장하면 스트리밍 성능이 향상되는 경우가 많습니다.

FILESTREAM 스토리지

FILESTREAM 스토리지는 데이터가 파일 시스템에 BLOB으로 저장되는 varbinary(max) 열로 구현됩니다. BLOB의 크기는 파일 시스템의 볼륨 크기에 의해서만 제한됩니다. 2GB 파일 크기의 표준 varbinary(max) 제한은 파일 시스템에 저장된 BLOB에는 적용되지 않습니다.

열이 파일 시스템에 데이터를 저장하도록 지정하려면 varbinary(max) 열에 FILESTREAM 특성을 지정합니다. 이 특성으로 인해 데이터베이스 엔진 해당 열에 대한 모든 데이터를 데이터베이스 파일에 저장하지 않고 파일 시스템에 저장합니다.

FILESTREAM 데이터는 FILESTREAM 파일 그룹에 저장되어야 합니다. FILESTREAM 파일 그룹은 파일 자체가 아닌 파일 시스템 디렉터리를 포함하는 특수 파일 그룹입니다. 이러한 파일 시스템 디렉터리를 데이터 컨테이너라고 합니다. 데이터 컨테이너는 데이터베이스 엔진 스토리지와 파일 시스템 스토리지 간의 인터페이스입니다.

FILESTREAM 스토리지를 사용하는 경우 다음을 고려합니다.

  • 테이블에 FILESTREAM 열이 있을 경우 각 행에는 Null이 아닌 고유한 행 ID가 있어야 합니다.
  • FILESTREAM 파일 그룹에는 여러 개의 데이터 컨테이너를 추가할 수 있습니다.
  • FILESTREAM 데이터 컨테이너는 중첩할 수 없습니다.
  • 장애 조치(failover) 클러스터링을 사용하는 경우 FILESTREAM 파일 그룹은 공유 디스크 리소스에 있어야 합니다.
  • FILESTREAM 파일 그룹은 압축된 볼륨에 있을 수 있습니다.

통합 관리

FILESTREAM이 varbinary(max) 열로 구현되어 데이터 엔진으로 바로 통합되었으므로 대부분의 SQL Server 관리 도구 및 기능이 FILESTREAM 데이터를 수정하지 않고 수행됩니다. 예를 들어 FILESTREAM 데이터와 함께 모든 백업 및 복구 모델을 사용할 수 있으며 FILESTREAM 데이터는 데이터베이스의 구조화된 데이터로 백업됩니다. 관계형 데이터로 FILESTREAM 데이터를 백업하지 않으려면 부분 백업을 사용하여 FILESTREAM 파일 그룹을 제외할 수 있습니다.

Integrated Security

SQL Server에서 FILESTREAM 데이터는 다른 데이터와 마찬가지로 테이블 또는 열 수준에서 사용 권한을 부여하여 보안이 설정됩니다. 사용자가 테이블의 FILESTREAM 열에 대한 권한이 있는 경우 사용자는 연결된 파일을 열 수 있습니다.

참고 항목

암호화는 FILESTREAM 데이터에서 지원되지 않습니다.

SQL Server 서비스 계정이 실행되는 계정에만 FILESTREAM 컨테이너에 대한 권한이 부여됩니다. 다른 계정에는 데이터 컨테이너에 대한 사용 권한을 부여하지 않는 것이 좋습니다.

참고 항목

SQL 로그인은 FILESTREAM 컨테이너에서 작동하지 않습니다. NTFS 또는 ReFS 인증만 FILESTREAM 컨테이너에서 작동합니다.

Transact-SQL 및 파일 시스템 스트리밍 액세스를 사용하여 BLOB 데이터 액세스

FILESTREAM 열에 데이터를 저장한 후 Transact-SQL 트랜잭션 또는 Win32 API를 사용하여 해당 파일에 액세스할 수 있습니다.

Transact-SQL 액세스

Transact-SQL을 사용하여 FILESTREAM 데이터를 삽입, 업데이트 및 삭제할 수 있습니다.

  • 삽입 작업을 사용하여 Null 값, 빈 값 또는 상대적으로 짧은 인라인 데이터로 FILESTREAM 필드를 미리 채울 수 있습니다. 그러나 크기가 큰 데이터는 Win32 인터페이스를 사용하는 파일로 좀 더 효율적으로 스트리밍됩니다.
  • FILESTREAM 필드를 업데이트할 때 파일 시스템의 기본 BLOB 데이터를 수정합니다. FILESTREAM 필드를 NULL로 설정하면 이 필드와 연결된 BLOB 데이터가 삭제됩니다. UPDATE**.**Write()로 구현된 Transact-SQL 청크 업데이트를 사용하여 데이터에 대한 부분 업데이트를 수행할 수 없습니다.
  • 행을 삭제하거나 FILESTREAM 데이터가 포함된 테이블을 삭제하거나 자르면 파일 시스템에서 기본 BLOB 데이터를 삭제합니다.

파일 시스템 스트리밍 액세스

Win32 스트리밍 지원은 SQL Server 트랜잭션의 컨텍스트에서 작동합니다. 트랜잭션 내에서 FILESTREAM 함수를 사용하여 파일의 논리적 UNC 파일 시스템 경로를 가져올 수 있습니다. 그런 다음 OpenSqlFilestream API를 사용하여 파일 핸들을 얻습니다. 그런 다음, ReadFile() 및 WriteFile()과 같은 Win32 파일 스트리밍 인터페이스에서 이 핸들을 사용하여 파일 시스템을 통해 파일에 액세스하고 업데이트할 수 있습니다.

파일 작업은 트랜잭션이므로 파일 시스템을 통해 FILESTREAM 파일을 삭제하거나 이름을 바꿀 수 없습니다.

Warning

FILESTREAM 컨테이너는 SQL Server에서 관리하는 폴더입니다. FILESTREAM 폴더에서 수동으로 또는 다른 애플리케이션을 통해 파일을 추가하거나 제거하지 마세요. 이렇게 하면 백업 및 불일치 오류가 발생합니다. 자세한 내용은 MSSQLSERVER_3056, MSSQLSERVER_7908, 및 MSSQLSERVER_7906을 참조하세요.

문 모델

FILESTREAM 파일 시스템 액세스는 파일 열기 및 닫기를 사용하여 Transact-SQL 문을 모델화합니다. 이 문은 파일 핸들이 열릴 때 시작되고 핸들이 닫혀 있을 때 끝납니다. 예를 들어 쓰기 핸들이 닫히면 UPDATE 문이 완료된 경우와 같이 테이블에 등록된 가능한 모든 AFTER 트리거가 실행됩니다.

Storage 네임스페이스

FILESTREAM에서 데이터베이스 엔진 BLOB 물리적 파일 시스템 네임스페이스를 제어합니다. 새 내장 함수인 PathName은 테이블의 각 FILESTREAM 셀에 해당하는 BLOB의 논리적 UNC 경로를 제공합니다. 애플리케이션은 이 논리 경로를 사용하여 Win32 핸들을 가져오고 일반 Win32 파일 시스템 인터페이스를 사용하여 BLOB 데이터에서 작동합니다. FILESTREAM 열의 값이 NULL이면 함수는 NULL을 반환합니다.

트랜잭션된 파일 시스템 액세스

새 내장 함수인 GET_FILESTREAM_TRANSACTION_CONTEXT()는 세션이 연결된 현재 트랜잭션을 나타내는 토큰을 제공합니다. 트랜잭션이 시작되었고 아직 중단되거나 커밋되지 않았어야 합니다. 토큰을 가져오면 애플리케이션은 FILESTREAM 파일 시스템 스트리밍 작업을 시작된 트랜잭션과 바인딩합니다. 명시적으로 시작된 트랜잭션이 없는 경우 함수는 NULL을 반환합니다.

트랜잭션이 커밋되거나 중단되기 전에 모든 파일 핸들을 닫아야 합니다. 핸들이 트랜잭션 범위를 벗어나 열린 상태로 유지되면 핸들에 대한 추가 읽기로 인해 오류가 발생합니다. 핸들에 대한 추가 쓰기는 성공하지만 실제 데이터는 디스크에 기록되지 않습니다. 마찬가지로 데이터베이스 엔진 데이터베이스 또는 인스턴스가 종료되면 열려 있는 모든 핸들이 무효화됩니다.

트랜잭션 내구성

FILESTREAM을 사용하면 트랜잭션 커밋 시 데이터베이스 엔진 파일 시스템 스트리밍 액세스에서 수정된 FILESTREAM BLOB 데이터에 대한 트랜잭션 내구성을 보장합니다.

격리 의미 체계

격리 의미 체계는 데이터베이스 엔진 트랜잭션 격리 수준에 의해 제어됩니다. Transact-SQL 및 파일 시스템 액세스에는 커밋된 읽기 격리 수준이 지원됩니다. 반복 가능한 읽기 작업, 직렬화 가능 및 스냅샷 격리 수준이 지원됩니다. 더티 읽기는 지원되지 않습니다.

파일 시스템 액세스 열기 작업은 잠금을 기다리지 않습니다. 대신 트랜잭션 격리로 인해 데이터에 액세스할 수 없는 경우 열린 작업이 즉시 실패합니다. 격리 위반으로 인해 열린 작업을 계속할 수 없는 경우 ERROR_SHARING_VIOLATION 스트리밍 API 호출이 실패합니다.

부분 업데이트가 수행되도록 허용하려면 애플리케이션이 디바이스 FS 컨트롤(FSCTL_SQL_FILESTREAM_FETCH_OLD_CONTENT)을 실행하여 이전 내용을 열려 있는 핸들이 참조하는 파일로 인출할 수 있습니다. 이렇게 하면 서버 쪽 이전 콘텐츠 복사본이 트리거됩니다. 애플리케이션 성능을 향상시키고 매우 큰 파일로 작업할 때 잠재적인 시간 초과가 발생하지 않도록 하려면 비동기 I/O를 사용하는 것이 좋습니다.

핸들을 쓴 후 FSCTL이 실행되면 마지막 쓰기 작업이 유지되고 핸들에 대해 만들어진 이전 쓰기가 손실됩니다.

파일 시스템 API 및 지원되는 격리 수준

격리 위반으로 인해 파일 시스템 API에서 파일을 열 수 없는 경우 ERROR_SHARING_VIOLATION 예외가 반환됩니다. 이 격리 위반은 두 트랜잭션이 동일한 파일에 액세스하려고 할 때 발생합니다. 액세스 작업의 결과는 파일이 열린 모드와 트랜잭션이 실행 중인 SQL Server 버전에 따라 달라집니다. 다음 표에서는 동일한 파일에 액세스하는 두 트랜잭션에 대한 가능한 결과를 간략하게 설명합니다.

거래 1 거래 2 SQL Server 2008(10.0.x)의 결과 SQL Server 2008 R2(10.50.x) 및 이후 버전에서의 결과
읽기를 위해 열기 읽기를 위해 열기 두 경우 모두 성공합니다. 두 경우 모두 성공합니다.
읽기를 위해 열기 쓰기를 위해 엽니다. 두 경우 모두 성공합니다. 트랜잭션 2에서 수행하는 쓰기 작업은 트랜잭션 1에서 수행하는 읽기 작업에 영향을 미치지 않습니다. 두 경우 모두 성공합니다. 트랜잭션 2에서 수행하는 쓰기 작업은 트랜잭션 1에서 수행하는 읽기 작업에 영향을 미치지 않습니다.
쓰기를 위해 엽니다. 읽기를 위해 열기 트랜잭션 2에 대해 열기가 실패하고 ERROR_SHARING_VIOLATION 예외가 발생합니다. 두 경우 모두 성공합니다.
쓰기를 위해 엽니다. 쓰기를 위해 엽니다. 트랜잭션 2에 대해 열기가 실패하고 ERROR_SHARING_VIOLATION 예외가 발생합니다. 트랜잭션 2에 대해 열기가 실패하고 ERROR_SHARING_VIOLATION 예외가 발생합니다.
읽기를 위해 열기 SELECT를 위해 엽니다. 두 경우 모두 성공합니다. 두 경우 모두 성공합니다.
읽기를 위해 열기 UPDATE 또는 DELETE를 위해 엽니다. 두 경우 모두 성공합니다. 트랜잭션 2에서 수행하는 쓰기 작업은 트랜잭션 1에서 수행하는 읽기 작업에 영향을 미치지 않습니다. 두 경우 모두 성공합니다. 트랜잭션 2에서 수행하는 쓰기 작업은 트랜잭션 1에서 수행하는 읽기 작업에 영향을 미치지 않습니다.
쓰기를 위해 엽니다. SELECT를 위해 엽니다. 트랜잭션 2는 트랜잭션 1이 트랜잭션을 커밋하거나 종료하거나 트랜잭션 잠금 시간이 초과될 때까지 차단됩니다. 두 경우 모두 성공합니다.
쓰기를 위해 엽니다. UPDATE 또는 DELETE를 위해 엽니다. 트랜잭션 2는 트랜잭션 1이 트랜잭션을 커밋하거나 종료하거나 트랜잭션 잠금 시간이 초과될 때까지 차단됩니다. 트랜잭션 2는 트랜잭션 1이 트랜잭션을 커밋하거나 종료하거나 트랜잭션 잠금 시간이 초과될 때까지 차단됩니다.
SELECT를 위해 엽니다. 읽기를 위해 열기 두 경우 모두 성공합니다. 두 경우 모두 성공합니다.
SELECT를 위해 엽니다. 쓰기를 위해 엽니다. 두 경우 모두 성공합니다. 트랜잭션 2의 쓰기 작업이 트랜잭션 1에 영향을 주지 않습니다. 두 경우 모두 성공합니다. 트랜잭션 2의 쓰기 작업이 트랜잭션 1에 영향을 주지 않습니다.
UPDATE 또는 DELETE를 위해 엽니다. 읽기를 위해 열기 트랜잭션 2에 대한 열기 작업이 ERROR_SHARING_VIOLATION 예외로 실패합니다. 두 경우 모두 성공합니다.
UPDATE 또는 DELETE를 위해 엽니다. 쓰기를 위해 엽니다. 트랜잭션 2에 대한 열기 작업이 ERROR_SHARING_VIOLATION 예외로 실패합니다. 트랜잭션 2에 대한 열기 작업이 ERROR_SHARING_VIOLATION 예외로 실패합니다.
반복 가능한 읽기를 사용하여 SELECT를 위해 엽니다. 읽기를 위해 열기 두 경우 모두 성공합니다. 두 경우 모두 성공합니다.
반복 가능한 읽기를 사용하여 SELECT를 위해 엽니다. 쓰기를 위해 엽니다. 트랜잭션 2에 대한 열기 작업이 ERROR_SHARING_VIOLATION 예외로 실패합니다. 트랜잭션 2에 대한 열기 작업이 ERROR_SHARING_VIOLATION 예외로 실패합니다.

원격 클라이언트에서 쓰기

FILESTREAM 데이터에 대한 원격 파일 시스템 액세스는 SMB(서버 메시지 블록) 프로토콜을 통해 사용할 수 있습니다. 클라이언트가 원격인 경우 클라이언트 쪽에서 쓰기 작업을 캐시하지 않습니다. 쓰기 작업은 항상 서버로 전송되고, 데이터는 서버 쪽에서 캐시할 수 있습니다. 원격 클라이언트에서 실행되는 애플리케이션은 작은 쓰기 작업을 더 큰 크기 작업으로 통합하는 것이 좋습니다. 목표는 적은 쓰기를 수행하는 것입니다.

FILESTREAM 핸들을 사용하여 메모리 매핑된 뷰(메모리 매핑된 I/O)를 만드는 것은 지원되지 않습니다. FILESTREAM 데이터에 메모리 매핑을 사용하는 경우 데이터베이스 엔진 데이터의 일관성과 내구성 또는 데이터베이스의 무결성을 보장할 수 없습니다.

FILESTREAM 성능 향상을 위한 권장 사항 및 지침

SQL Server FILESTREAM 기능을 사용하면 varbinary(max) BLOB(Binary Large Object) 데이터를 파일로 파일 시스템에 저장할 수 있습니다. FILESTREAM 열과 FileTable 모두에 대한 기본 스토리지인 FILESTREAM 컨테이너에 많은 수의 행이 있는 경우 많은 수의 파일이 포함된 파일 시스템 볼륨으로 끝날 수 있습니다. 데이터베이스 및 파일 시스템에서 통합 데이터를 처리할 때 최상의 성능을 얻으려면 파일 시스템을 최적으로 조정해야 합니다. 다음은 파일 시스템 관점에서 사용할 수 있는 몇 가지 튜닝 옵션입니다.

  • SQL Server FILESTREAM 필터 드라이버(예: rsfx0100.sys)에 대한 고도 확인. FILESTREAM 기능에서 파일을 저장하는 볼륨과 연결된 스토리지 스택에 대해 로드된 모든 필터 드라이버를 평가하고 rsfx 드라이버가 스택의 맨 아래에 있는지 확인합니다. FLTMC.EXE 컨트롤 프로그램을 사용하여 특정 볼륨에 대한 필터 드라이버를 열거할 수 있습니다. FLTMC 유틸리티의 샘플 출력은 C:\Windows\System32>fltMC.exe 필터와 같습니다.

    필터 이름 Num 인스턴스 고도 Frame
    Sftredir 1 406000 0
    MpFilter 9 328000 0
    luafv 1 135000 0
    FileInfo 9 45000 0
    RsFx0103 1 41001.03 0
  • 서버에서 파일에 대해 “마지막 액세스 시간” 속성을 사용하지 않도록 설정했는지 확인합니다. 이 파일 시스템 특성은 레지스트리에서 유지 관리됩니다. 키 이름: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem
    이름: NtfsDisableLastAccessUpdate
    유형: REG_DWORD
    값: 1

  • 서버에서 8.3 명명을 사용하지 않도록 설정했는지 확인합니다. 이 파일 시스템 특성은 레지스트리에서 유지 관리됩니다. 키 이름: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem
    이름: NtfsDisable8dot3NameCreation
    유형: REG_DWORD
    값: 1

  • 이러한 파일에 액세스할 때 오버헤드 수준이 발생할 수 있으므로 FILESTREAM 디렉터리 컨테이너에 파일 시스템 암호화 또는 파일 시스템 압축이 활성화되어 있지 않은지 확인합니다.

  • 관리자 권한 명령 프롬프트에서 fltmc 인스턴스를 실행하고 복원하려는 볼륨에 필터 드라이버가 연결되어 있지 않은지 확인합니다.

  • FILESTREAM 디렉터리 컨테이너에 300,000개 이상의 파일이 없는지 확인합니다. sys.database_files 카탈로그 뷰의 정보를 사용하여 파일 시스템 저장소 FILESTREAM-related 파일의 디렉터리를 확인할 수 있습니다. 여러 컨테이너를 포함하면 이 문제를 방지할 수 있습니다. (자세한 내용은 다음 항목을 참조하세요.)

  • FILESTREAM 파일 그룹이 하나만 있으면 모든 데이터 파일이 동일한 폴더 아래에 만들어집니다. 매우 많은 수의 파일을 만드는 파일은 큰 NTFS 인덱스의 영향을 받을 수 있으며 조각화될 수도 있습니다.

    • 일반적으로 파일 그룹이 여러 개 있는 경우 애플리케이션에서 분할을 사용하거나 각각 고유한 파일 그룹으로 이동하는 여러 개의 테이블을 사용하면 도움이 됩니다.

    • SQL Server 2012(11.x) 이상 버전을 사용하면 FILESTREAM 파일 그룹에 여러 컨테이너 또는 파일을 포함할 수 있으며 라운드 로빈 할당 체계가 적용됩니다. 따라서 디렉터리당 NTFS 파일 수는 더 작아집니다.

  • 컨테이너를 저장하는 여러 볼륨이 사용되는 경우 여러 FILESTREAM 컨테이너를 사용하여 백업 및 복원이 더 빨라질 수 있습니다.

    SQL Server 2012(11.x)는 파일 그룹당 여러 컨테이너를 지원하며 작업을 더 쉽게 수행할 수 있습니다. 더 많은 수의 파일을 관리하기 위해 복잡한 분할 체계가 필요하지 않을 수 있습니다.

  • SQL 인스턴스에 FILESTREAM 컨테이너가 매우 많은 경우 FILESTREAM 컨테이너가 많은 데이터베이스를 시작하면 FILESTREAM 필터 드라이버에 등록하는 데 시간이 오래 걸릴 수 있습니다. 여러 볼륨으로 분산하면 데이터베이스 시작 시간을 개선하는 데 도움이 됩니다.

  • NTFS MFT가 조각화되어 성능 문제가 발생할 수 있습니다. MFT 예약 크기는 볼륨 크기에 따라 달라지므로 이 문제가 발생할 수도 있고 그렇지 않을 수도 있습니다.

    • defrag /A /V C:(C: 실제 볼륨 이름으로 변경)을 사용하여 MFT 조각화를 확인할 수 있습니다.

    • fsutil 동작 집합 mftzone 2를 사용하여 더 많은 MFT 공간을 예약할 수 있습니다.

    • FILESTREAM 데이터 파일은 바이러스 백신 소프트웨어 검사에서 제외되어야 합니다.

      참고 항목

      Windows Server 2016은 Windows Defender를 자동으로 사용하도록 설정합니다. Windows Defender가 Filestream 파일을 제외하도록 구성되어 있는지 확인합니다. 그러지 않으면 백업 및 복원 작업의 성능이 저하될 수 있습니다.

      자세한 내용은 Windows Defender 바이러스 백신 검사에서 제외 구성 및 유효성 검사를 참조하세요.