管理 FileTables

适用范围:SQL Server

说明用于管理 FileTable 的常见管理任务。

如何获取 FileTable 和相关对象的列表

若要获取 FileTable 的列表,请查询下列目录视图之一:

SELECT * FROM sys.filetables;  
GO  
  
SELECT * FROM sys.tables WHERE is_filetable = 1;  
GO  

要获取在创建关联的 FileTable 时创建的系统定义对象列表,请查询目录视图 sys.filetable_system_defined_objects (Transact-SQL)

SELECT object_id, OBJECT_NAME(object_id) AS 'Object Name'  
FROM sys.filetable_system_defined_objects;  
GO  

禁用和重新启用数据库级别的非事务性访问权限

若要获取执行某些管理任务所需的独占访问权限,可能必须暂时禁用非事务性访问权限。

更改非事务性访问级别时 ALTER DATABASE 语句的行为

  • 将非事务性访问设置为 READ_ONLY 或 OFF 时,只要存在与请求的操作冲突的打开文件句柄, ALTER DATABASE 该命令不会向用户返回控制权。 与此操作冲突的文件句柄包括下列内容:

    • 将访问权限设置为 NONE 时,则包括所有打开的文件句柄。

    • 将访问权限设置为 READ_ONLY 时,则包括打开以供写入访问的所有文件句柄。

    有关终止开放文件句柄的信息,请参阅本主题中的 终止与 FileTable 关联的开放文件句柄

    ALTER DATABASE如果命令被取消或以超时结束,则事务访问级别不会更改。

  • 如果使用带有 WITH <终止>子句(ROLLBACK AFTER integer [ SECONDS ] | ROLLBACK IMMEDIATE | NO_WAIT)来调用 ALTER DATABASE 语句,则所有打开的非事务性文件句柄都将被终止。

警告

终止打开的文件句柄可能会导致用户丢失未保存的数据。 此行为与文件系统自身的行为一致。

禁用非事务性访问的影响

更改数据库级别的非事务性访问级别会对数据库级别目录下的 FileTable 目录产生下列影响:

  • 当您将访问权限设置为 NONE时,将不再能够访问或看到所有 FileTable 目录及其内容。

  • 将访问权限设置为 READ_ONLY时,所有 FileTable 目录及其内容还是只读的。

在实例级别禁用 FILESTREAM 将会对该实例上的数据库级别目录及其下的 FileTable 目录产生下列影响:

  • 如果在实例级别禁用 FILESTREAM,将看不到该实例上的任何数据库级别目录。

如何禁用和重新启用数据库级别的非事务性访问权限

有关详细信息,请参阅ALTER DATABASE SET选项(Transact-SQL)。

禁用完全非事务性访问权限
调用ALTER DATABASE语句,并将SETNON_TRANSACTED_ACCESS的值设置为READ_ONLYOFF

-- Disable write access.  
ALTER DATABASE database_name  
SET FILESTREAM ( NON_TRANSACTED_ACCESS = READ_ONLY );  
GO  
  
-- Disable non-transactional access.  
ALTER DATABASE database_name  
SET FILESTREAM ( NON_TRANSACTED_ACCESS = OFF );  
GO  

重新启用完全非事务性访问权限
调用 ALTER DATABASE 语句,并将 SETNON_TRANSACTED_ACCESS 的值设置为 FULL

ALTER DATABASE database_name  
SET FILESTREAM ( NON_TRANSACTED_ACCESS = FULL );  
GO  

如何确保数据库中的 FileTable 的可见性

当满足以下所有条件时,则可看到数据库级别目录及其下的 FileTable 目录:

  1. 在实例级别启用 FILESTREAM。

  2. 在数据库级别启用非事务性访问。

  3. 在数据库级别指定了有效目录。

在表级别禁用和重新启用 FileTable 命名空间

禁用 FileTable 命名空间将禁用随 FileTable 一起创建的所有系统定义的约束和触发器。 在需要使用 Transact-SQL 操作对 FileTable 进行大规模重组,同时又无需承担强制实施 FileTable 语义所带来的开销的情况下,这很有用。 但是,这些操作会将 FileTable 置于不一致的状态,会阻止重新启用 FileTable 命名空间。

禁用 FileTable 命名空间具有下列结果:

  • 不会从表中实际删除 FileTable 列和数据。

  • FileTable 目录及其包含的文件和目录不再出现在文件系统中,且不可用于文件 I/O 访问。

  • 无法删除和重新创建系统定义的 FileTable 列;但是,对于 DML 操作,它们的行为与普通列无异。

  • 打开的文件句柄可防止 FileTable 约束被禁用,因为此操作需要使用表上的架构锁。

  • 在 FileTable 命名空间被禁用后,对所有 FileTable 语义(包括系统定义的约束和触发器)的强制执行将停止。

重新启用 FileTable 命名空间会产生下列结果:

  • 对 FileTable 进行一致性检查。 如果找到不一致处,则引发错误且 FileTable 保持禁用状态;否则,将重新启用 FileTable。

  • 对 FileTable 语义的强制实施已恢复,包括系统定义的约束和触发器。

  • FileTable 目录及其包含的文件和目录将在文件系统中再次可见,且可用于文件 I/O 访问。

操作指南:在表级别禁用和重新启用 FileTable 命名空间

使用 { ENABLE | DISABLE } FILETABLE_NAMESPACE 选项调用 ALTER TABLE 语句。

禁用 FileTable 命名空间

ALTER TABLE filetable_name  
DISABLE FILETABLE_NAMESPACE;  
GO  

重新启用 FileTable 命名空间

ALTER TABLE filetable_name  
ENABLE FILETABLE_NAMESPACE;  
GO  

终止与 FileTable 关联的打开的文件句柄

FileTable 中存储的文件的打开句柄可以阻止某些管理任务所需的独占访问。 若要启用紧急任务,可能要终止与一个或多个 FileTables 关联的打开的文件句柄。

警告

终止打开的文件句柄可能会导致用户丢失未保存的数据。 此行为与文件系统自身的行为一致。

如何获取与 FileTable 关联的打开的文件句柄的列表

查询目录视图 sys.dm_filestream_non_transacted_handles (Transact-SQL)

SELECT * FROM sys.dm_filestream_non_transacted_handles;  
GO  

如何终止与 FileTable 关联的打开的文件句柄

使用相应参数调用存储过程 sp_kill_filestream_non_transacted_handles (Transact-SQL) 以终止数据库或 FileTable 中所有打开的文件句柄或终止特定句柄。

USE database_name;  
  
-- Kill all open handles in all the filetables in the database.  
EXEC sp_kill_filestream_non_transacted_handles;  
GO  
  
-- Kill all open handles in a single filetable.  
EXEC sp_kill_filestream_non_transacted_handles @table_name = 'filetable_name';  
GO  
  
-- Kill a single handle.  
EXEC sp_kill_filestream_non_transacted_handles @handle_id = integer_handle_id;  
GO  

如何识别 FileTable 持有的锁

FileTables 获取的大多数锁都对应于由应用程序打开的文件。

识别打开的文件及相关锁
将动态管理视图 sys.dm_tran_locks (Transact-SQL) 中的 request_owner_id 字段与 sys.dm_filestream_non_transacted_handles (Transact-SQL)中的 fcb_id 字段进行联接。 在某些情况下,锁并不对应单个打开的文件句柄。

SELECT opened_file_name  
FROM sys.dm_filestream_non_transacted_handles  
WHERE fcb_id IN  
    ( SELECT request_owner_id FROM sys.dm_tran_locks );  
GO  

FileTable 安全性

存储在 FileTable 中的文件和目录仅受 SQL Server 安全机制的保护。 对文件系统访问和 Transact-SQL 访问强制实施基于表和列的安全性。 不支持 Windows 文件系统安全 API 和 ACL 设置。

由于文件数据作为 FILESTREAM 列存储在 FileTable 中,因此还将对 FileTable 应用 FILESTREAM 文件组和容器所适用的安全性和访问权限。

FileTable 安全性和 Transact-SQL 访问
按照与任何其他表相同的方式保护 Transact-SQL 对 FileTable 中数据的访问。 对访问或更改数据的每个操作进行相应的表级别和列级别安全检查。

FileTable 安全性和文件系统访问
文件系统 API 需要对 FileTable 中整个行的相应 SQL Server 权限(表级别权限)来打开存储在 FileTable 中的文件或目录的句柄。 如果用户对 FileTable 中的任何列没有相应的 SQL Server 权限,则将对文件系统的访问将被拒绝。

备份和 FileTables

使用 SQL Server 备份 FileTable 时,FILESTREAM 数据将与数据库中的结构化数据一起备份。 如果您不想将 FILESTREAM 数据与关系数据一起备份,则可以使用部分备份将 FILESTREAM 文件组排除在外。

FileTable 备份的事务一致性

很多管理工具和操作(包括备份、日志备份和事务性复制)通过读取事务日志来读取事务上一致的数据。 此时,它们读取作为事务的一部分更新的任意 FILESTREAM 数据。 未在数据库级别启用非事务性访问时,这些工具和操作在确保完全事务一致性下工作。

但是,当启用完全非事务性访问时,FileTable 中可能包含比工具或进程从事务日志中读取的事务更新时间更晚的数据(通过非事务性更新)。 这意味着对特定事务进行的“时间点”还原操作包含的 FILESTREAM 数据可能比该事务更新。 在 FileTable 上允许非事务性更新时,这是预期的行为。

SQL Server Profiler 与 FileTables

SQL Server Profiler 可以在跟踪输出中捕获存储在 FileTable 中的文件的 Windows 文件打开和关闭操作。

审核和 FileTables

可以像对任何其他表一样对 FileTable 进行审核。 但是,Win32 的访问模式不是集合式操作。 将文件系统中的单个操作转换为多个 Transact-SQL DML 操作。 例如,在 Microsoft Word 中打开文件将转换为多个打开/关闭/创建/重命名/删除操作和相应的 Transact-SQL DML 活动。 这将导致冗长的审核记录,很难将文件系统操作和相应的 Transact-SQL DML 审核记录关联。

DBCC 和 FileTable

可以使用 DBCC CHECKCONSTRAINTS 验证 FileTable 上的约束,包括系统定义的约束。

另请参阅

FileTable 与其他 SQL Server 功能的兼容性
FileTable DDL、函数、存储过程和视图