FILESTREAM (SQL Server)

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

Хранилище FILESTREAM объединяет компонент Компонент SQL Server Database Engine с файловой системой NTFS, размещая данные больших двоичных объектов (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 см. в списке Связанные задачи.

В этом разделе

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

  • Хранилище FILESTREAM

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

  • Связанные задачи

  • См. также

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

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

  • средний размер сохраняемых объектов превышает 1 МБ;

  • важен быстрый доступ для чтения;

  • в разрабатываемых приложениях для логики приложений используется средний уровень.

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

[В начало]

Хранилище FILESTREAM

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

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

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

ПримечаниеПримечание

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

Доступ к данным 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 не может гарантировать согласованность и надежность данных или целостность базы данных.

[В начало]

Связанные задачи

[В начало]

См. также