FILESTREAM (SQL Server)

Применимо к: даSQL Server (все поддерживаемые версии)  — только Windows

FILESTREAM позволяет приложениям на основе SQL Serverхранить в файловой системе неструктурированные данные, например документы и изображения. Приложения могут одновременно использовать многопоточные API-интерфейсы и производительность файловой системы, тем самым обеспечивая транзакционную согласованность между неструктурированными и соответствующими им структурированными данными.

Хранилище FILESTREAM объединяет компонент Компонент SQL Server Database Engine с файловыми системами NTFS или ReFS, размещая данные больших двоичных объектов (BLOB) типа varbinary(max) в файловой системе в виде файлов. Transact-SQL можно вставлять, обновлять, запрашивать, искать и создавать резервные копии данных FILESTREAM. Интерфейсы файловой системы Win32 предоставляют потоковый доступ к этим данным.

Для кэширования данных файлов в хранилище FILESTREAM используется системный кэш NT. Это позволяет снизить возможное влияние данных FILESTREAM на производительность компонента Компонент Database Engine . Буферный пул SQL Server не используется, поэтому эта память доступна для обработки запросов.

FILESTREAM не включается автоматически при установке или обновлении SQL Server. FILESTREAM необходимо включить с помощью диспетчера конфигурации SQL Server и среды SQL Server Management Studio. Для использования FILESTREAM нужно создать или изменить базу данных, которая будет содержать заданный тип файловой группы. После этого следует создать или изменить таблицу, чтобы она содержала столбец varbinary(max) с атрибутом FILESTREAM. После завершения выполнения этих задач можно будет пользоваться Transact-SQL и Win32 для управления данными FILESTREAM.

Условия использования FILESTREAM

В SQL Serverбольшие двоичные объекты могут представлять собой либо стандартный тип varbinary(max) , где данные хранятся в таблице базы данных, либо объекты FILESTREAM типа varbinary(max) , где данные хранятся в файловой системе. Выбор в качестве хранилища базы данных или файловой системы определяется размером и назначением данных. Объекты FILESTREAM следует использовать в следующих случаях:

  • средний размер сохраняемых объектов превышает 1 МБ;
  • важен быстрый доступ для чтения;
  • в разрабатываемых приложениях для логики приложений используется средний уровень.

При работе с объектами меньшего размера сохранение больших двоичных объектов типа varbinary(max) в базе данных часто позволяет добиться лучшей производительности потоков.

Хранилище FILESTREAM

Хранилище FILESTREAM реализовано в виде столбца типа varbinary(max) , данные которого хранятся в файловой системе как большие двоичные объекты. Размеры объектов BLOB ограничены только размером тома файловой системы. Стандартное ограничение типа varbinary(max) , согласно которому размер файла не должен превышать 2 ГБ, не применяется к большим двоичным объектам, сохраняемым в файловой системе.

Чтобы указать необходимость сохранения данных столбца в файловой системе, укажите атрибут FILESTREAM для столбца varbinary(max) . В результате компонент Компонент Database Engine будет сохранять все данные этого столбца в файловой системе, а не в файле базы данных.

Данные FILESTREAM должны сохраняться в файловых группах FILESTREAM. Файловая группа FILESTREAM представляет собой особую файловую группу, в которой вместо самих файлов содержатся системные каталоги файлов. Данные системные каталоги файлов называются контейнерами данных. Они являются интерфейсом между хранилищем компонента Компонент Database Engine и хранилищем файловой системы.

При использовании хранилища FILESTREAM обратите внимание на следующие аспекты:

  • если в таблице присутствует столбец FILESTREAM, каждая строка должна иметь уникальный идентификатор строки (не равен NULL);
  • в файловую группу FILESTREAM можно добавить несколько контейнеров данных;
  • вложенность контейнеров данных FILESTREAM не допускается;
  • при использовании отказоустойчивого кластера файловые группы FILESTREAM должны находиться в ресурсах общего диска;
  • файловые группы FILESTREAM могут размещаться на сжатых томах.

Интегрированное управление

Так как FILESTREAM реализуется в виде столбца типа varbinary(max) и интегрируется непосредственно в компонент Компонент Database Engine, большинство функций и средств управления SQL Server не требуют изменения для работы с данными FILESTREAM. Так, например, с данными FILESTREAM можно использовать любые модели резервного копирования и восстановления, а резервное копирование данных FILESTREAM осуществляется при помощи структурированных данных в базе данных. Если резервное копирование данных FILESTREAM при помощи реляционных данных выполнять нежелательно, для исключения файловых групп FILESTREAM можно воспользоваться частичным резервным копированием.

Встроенные функции безопасности

В SQL Serverзащита данных FILESTREAM осуществляется таким же образом, как и защита любых других данных: посредством предоставления разрешений на уровнях таблицы или столбца. Пользователь, у которого имеется разрешение на столбец FILESTREAM в таблице, может открыть связанные файлы.

Примечание

В данных FILESTREAM не поддерживается шифрование.

Разрешения для доступа к контейнеру FILESTREAM предоставляются только той учетной записи, под которой выполняется служба SQL Server . Другим учетным записям разрешения на доступ к контейнеру данных предоставлять не рекомендуется.

Примечание

Имена входа SQL не работают с контейнерами FILESTREAM. С контейнерами FILESTREAM работает только проверка подлинности NTFS или ReFS.

Доступ к данным BLOB с помощью Transact-SQL и потокового доступа к файловой системе

После сохранения данных в столбце FILESTREAM доступ к файлам возможен в транзакциях Transact-SQL или через API-интерфейсы Win32.

Доступ с помощью Transact-SQL

Язык Transact-SQLпозволяет вставлять, обновлять и удалять данные FILESTREAM:

  • Операция вставки позволяет выполнить предварительное заполнение поля FILESTREAM значением NULL, пустым значением или встроенными данными относительно небольшого размера. Однако при работе с большими объемами данных большей эффективности потока можно добиться при помощи файла, использующего интерфейсы Win32.
  • При обновлении поля FILESTREAM происходит изменение базовых данных BLOB в файловой системе. Если в поле FILESTREAM содержится значение NULL, данные BLOB, связанные с этим полем, удаляются. Обновление фрагмента данных на языке Transact-SQL , реализованное в виде конструкции UPDATE . Write(), использовать для частичного обновления данных нельзя.
  • При удалении строки или удалении или усечении таблицы, содержащей данные FILESTREAM, удаляются базовые данные BLOB в файловой системе.

Потоковый доступ к файловой системе

Поддержка потоков в Win32 запускается в контексте транзакций SQL Server . В рамках транзакции функции FILESTREAM позволяют получить логический UNC-путь к файлу в файловой системе. API-интерфейс OpenSqlFilestream позволяет получить дескриптор файла. Затем этот дескриптор может использоваться интерфейсами файловых потоков Win32, например ReadFile() и WriteFile(), для доступа и обновления файла посредством файловой системы.

Поскольку операции над файлами являются транзакционными, удалить или переименовать файлы FILESTREAM с помощью файловой системы невозможно.

Модель инструкции

Доступ к файловой системе FILESTREAM моделирует инструкцию на языке Transact-SQL , используя операции открытия и закрытия файлов. Эта инструкция запускается при открытии дескриптора файла и завершается при закрытии этого дескриптора. Например, при закрытии обработчика записи срабатывают все возможные триггеры AFTER, зарегистрированные в таблице, как если бы была выполнена инструкция UPDATE.

Пространство имен хранилища

В хранилище FILESTREAM компонент Компонент Database Engine управляет пространством имен физической файловой системы объектов BLOB. Новая встроенная функция, PathName, предоставляет логический UNC-путь объекта BLOB, соответствующего каждой ячейке FILESTREAM в таблице. В приложении этот логический путь используется для получения дескриптора Win32 и работы с данными BLOB посредством обычных интерфейсов файловой системы Win32. Эта функция возвращает значение NULL, если значением столбца FILESTREAM является NULL.

Доступ к транзакционной файловой системе

Новая встроенная функция GET_FILESTREAM_TRANSACTION_CONTEXT()возвращает токен, представляющий актуальную транзакцию, с которой связан сеанс. Эта транзакция должна быть запущена, не прервана и не зафиксирована. Получение токена позволяет приложению связать потоковые операции файловой системы FILESTREAM с запущенной транзакцией. Эта функция возвращает значение NULL в случае отсутствия явно запущенной транзакции.

Прежде чем транзакция будет зафиксирована или прервана, все дескрипторы файлов должны быть закрыты. Если дескриптор остается открытым за пределами области действия транзакции, дополнительные операции чтения, применяемые к этому дескриптору, завершатся ошибкой; дополнительные операции записи, применяемые к этому дескриптору, будут выполнены успешно, но фактические данные не будут записаны на диск. Аналогичным образом, если работа базы данных или экземпляра компонента Компонент Database Engine завершается, все открытые дескрипторы становятся недопустимыми.

Надежность транзакций

При работе с FILESTREAM до момента фиксации транзакции надежность транзакций для данных FILESTREAM объектов BLOB, измененных на основе потокового доступа к файловой системе, обеспечивает компонент Компонент Database Engine .

Семантика изоляции

Управление семантикой изоляции осуществляется уровнями изоляции транзакций компонента Компонент Database Engine . Для доступа к Transact-SQL и файловой системе поддерживается только уровень изоляции READ COMMITTED. Поддерживаются операции чтения с возможностью повторения, а также сериализуемая изоляция и изоляция моментальных снимков. «Грязные» чтения не поддерживаются.

Открытые операции доступа к файловой системе не ожидают никаких блокировок. Вместо этого открытые операции моментально завершаются ошибкой, если вследствие изоляции транзакции не удается получить доступ к данным. Потоковые вызовы API завершаются ошибкой ERROR_SHARING_VIOLATION, если вследствие нарушения изоляции невозможно продолжение открытой операции.

Чтобы разрешить выполнение частичных обновлений, приложение может издать команду FSCTL_SQL_FILESTREAM_FETCH_OLD_CONTENT для выборки старого содержимого в файл, открытый с помощью ссылки на дескриптор. Это приведет к началу копирования старого содержимого на стороне сервера. Чтобы добиться лучшей производительности приложения и избежать потенциальных сбоев из-за времени ожидания при работе с очень большими файлами, рекомендуется использовать асинхронные операции ввода-вывода.

Если формирование команды FSCTL произошло после записи в дескриптор, сохраняется последняя операция записи, а результаты предыдущих операций записи в дескриптор теряются.

API-интерфейсы файловой системы и поддерживаемые уровни изоляции

Если API-интерфейсу файловой системы не удается открыть файл из-за нарушения изоляции, то возвращается исключение ERROR_SHARING_VIOLATION. Это нарушение изоляции возникает в том случае, когда две транзакции пытаются получить доступ к одному и тому же файлу. Результат операции доступа зависит от режима, в котором файл был открыт, и версии SQL Server , в которой выполняется транзакция. В следующей таблице приведены возможные результаты обращения двух транзакций к одному и тому же файлу.

Транзакция 1 Транзакция 2 Результат на сервере SQL Server 2008 Результат на SQL Server 2008 R2 и более поздних версиях
Открыта для чтения. Открыта для чтения. Обе завершаются успешно. Обе завершаются успешно.
Открыта для чтения. Открыта для записи. Обе завершаются успешно. Операции записи в рамках транзакции 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 не поддерживается. Если для данных FILESTREAM используется отображение в памяти, то компонент Компонент Database Engine не может гарантировать согласованность и надежность данных или целостность базы данных.

Рекомендации по повышению производительности FILESTREAM

Функция FILESTREAM SQL Server позволяет хранить данные больших двоичных объектов типа varbinary(max) в виде файлов в файловой системе. При наличии большого количества строк в контейнерах FILESTREAM, которые являются базовым хранилищем для столбцов FILESTREAM и FileTable, можно создать том файловой системы, содержащий большое количество файлов. Чтобы обеспечить лучшую производительность при обработке интегрированных данных из базы данных, а также из файловой системы, важно обеспечить оптимальную настройку файловой системы. Ниже приведены некоторые доступные параметры настройки файловой системы.

  • Проверка высоты для драйвера фильтра FILESTREAM SQL Server [например, rsfx0100.sys]. Оцените все драйверы фильтров, загруженные для стека хранилища, связанного с томом, в котором компонент FILESTREAM хранит файлы, и убедитесь, что драйвер RsFx находится в нижней части стека. Для перечисления драйверов фильтров для определенного тома можно использовать программу управления FLTMC.EXE. Ниже приведен пример выходных данных служебной программы FLTMC: фильтры C:\Windows\System32>fltMC.exe

    Имя фильтра Число экземпляров Высота над уровнем моря 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 и более поздних версий в файловой группе FILESTREAM можно использовать несколько контейнеров или файлов, а также будет применяться схема распределения с циклическим перебором. Таким образом, количество файлов NTFS на каталог будет меньше.

  • Резервное копирование и восстановление можно ускорить с помощью нескольких контейнеров FILESTREAM, если для хранения контейнеров используются несколько томов.

    SQL Server 2012 поддерживает несколько контейнеров для каждой файловой группы и может значительно упростить работу. Для управления большим числом файлов не требуются сложные схемы секционирования.

  • Файл MFT файловой системы NTFS может стать фрагментированным, что может вызвать проблемы с производительностью. Зарезервированный размер MFT зависит от размера тома, поэтому вы можете и не столкнуться с этой проблемой.

    • Можно проверить фрагментацию MFT с помощью defrag /A /V C: (измените C: на фактическое имя тома).

    • Можно зарезервировать дополнительное пространство MFT с помощью команды fsutil behavior set mftzone 2.

    • Файлы данных FILESTREAM должны быть исключены из проверки антивирусным ПО.

      Примечание

      Windows Server 2016 автоматически включает Защитник Windows. Убедитесь, что Защитник Windows настроен для исключения файлов FILESTREAM. Невыполнение этого действия может привести к снижению производительности операций резервного копирования и восстановления.

      Дополнительные сведения см. в разделе Настройка и проверка исключений для проверок антивирусной программой "Защитник Windows".

Включение и настройка FILESTREAM
Создание базы данных с поддержкой FILESTREAM
Создание таблицы для хранения данных FILESTREAM
Обращение к данным FILESTREAM с помощью Transact-SQL Создание клиентских приложений для данных FILESTREAM
Доступ к данным FILESTREAM с OpenSqlFilestream
Создание частичных обновлений данных FILESTREAM
Избегание конфликтов в операциях баз данных в приложениях FILESTREAM
переместить базу данных с поддержкой FILESTREAM
Установка FILESTREAM в отказоустойчивом кластере
Настройка брандмауэра для доступа к FILESTREAM

Совместимость FILESTREAM с другими компонентами SQL Server
Динамические административные представления Filestream и FileTable (Transact-SQL)
Представления каталога Filestream и FileTable (Transact-SQL)
Системные хранимые процедуры Filestream и FileTable (Transact-SQL)