在以前的博客中,我曾经介绍过如何在SharePoint 2010系统中安装和配置RBS FILESTREAM Provider,实现将SharePoint中的文件存储到磁盘文件系统中。但是当用户在SharePoint中上载文件时,文件的二进制内容就会通过RBS FILESTREAM Provider,写入到指定的磁盘文件夹之中。通过RBS可以极大的提高SharePoint存储文件的能力,也有效的使SharePoint的内容数据库不会跟着文件数量的增多而不断膨胀。
但是当用户从SharePoint网站上删除一个文件时(并且已经将文件彻底的从SharePoint回收站中删除),RBS FILESTREAM Provider并不会“真正”的从磁盘文件系统把相应的文件也删除掉。为了提高性能,RBS FILESTREAM Provider只会记录下有一个文件被“删除”了,但是要想真正从磁盘文件系统上删除这个物理文件,就需要一些额外的步骤,来完成“垃圾收集”的工作。
RBS FILESTREAM Provider内置了一个命令行维护工具,这个工具就能够实现“垃圾收集”。除此之外,实际上它还可以进行一致性检查、数据维护等诸多工作。但今天我们要讲的,还是集中在如何使用这个维护工具实现“垃圾收集”,来将那些垃圾物理文件从磁盘文件系统上彻底删除。
当RBS FILESTREAM Provider被安装到机器上时,在默认的安装目录中(Program Files\Microsoft SQL Remote Blob Storage 10.50),有一个“Maintainer”文件夹。里面有2个文件:Microsoft.Data.SqlRemoteBlobs.Maintainer.exe和Microsoft.Data.SqlRemoteBlobs.Maintainer.exe.config,前者就是那个命令行维护工具,后者则是维护工具的配置文件。
在使用维护工具之前,需要打开那个配置文件,在配置文件中指定启用了RBS功能的SharePoint内容数据库的连接字符串。每个内容数据库都需要分别指定一个连接字符串。如果你是第一次打开配置文件,会发现里面的连接字符串默认是使用加密方式保存的。嗯,我个人觉得这实在是一件没有必要的事情,因为维护工具本来就需要直接运行在SharePoint服务器上,这是一件需要服务器管理员权限才能干的事情,所以似乎把服务器上配置文件中的连接字符串进行加密,未免过分小心了…当然,如果你是使用混合认证方式连接到数据库,那把连接字符串加密一下也未尝不可。加密连接字符串的方式是使用aspnet_regiis.exe这个命令行工具。不过在这篇文章中,我就只演示用明文保存连接字符串好了。
下图就是在我的机器上,配置文件的内容。里面只定义了一个连接字符串。连接字符串的名称是“WSS_Content_ConnStr”,连接字符串的内容是“Data Source=sp2010;Initial Catalog=WSS_Content;Integrated Security=True”。这些都需要感觉实际环境中的情况进行修改。如果有多个SharePoint内容数据库都启用了RBS,那么就需要针对它们分别添加多个连接字符串,给每个连接字符串一个不同的名称。
接下来就可以在命令行中执行维护工具了。输入如下指令并运行:
Microsoft.Data.SqlRemoteBlobs.Maintainer.exe -ConnectionStringName WSS_Content_ConnStr -Operation GarbageCollection -GarbageCollectionPhases rdo
指令中绿色标记的部分,需要等同于配置文件中所指定的连接字符串名称。维护工具在执行时,会输出一些文字信息,显示出它收集了多少个垃圾文件。
如果你在自己的实验环境中执行了上面的指令,很可能发现它并没有删除一个垃圾文件,而如果你重复执行它,它甚至会告诉你,由于间隔时间太短,它“拒绝”频繁运行。这是因为每个SharePoint内容数据库在启用了RBS之后,都会多3个与维护工具相关的时间间隔参数:“delete_scan_period”、“orphan_scan_period”和“garbage_collection_time_window”,它们指定了诸如最小允许的扫描周期、清除垃圾文件周期等等设置。这3个参数会共同影响维护工具的扫描和清除垃圾文件的过程。
在通常情况下,是不需要修改这3个参数的。在实验环境中,为了检验垃圾收集的效果,可以尝试修改这3个参数。打开SQL Server 2008 Management Studio,选中一个SharePoint内容数据库,然后执行:
exec mssqlrbs.rbs_sp_set_config_value 'delete_scan_period','time 00:00:00'
exec mssqlrbs.rbs_sp_set_config_value 'orphan_scan_period','time 00:00:00'
exec mssqlrbs.rbs_sp_set_config_value 'garbage_collection_time_window','time 00:00:00'
上面3条SQL指令将这3个时间间隔参数都设置为0。如果维护工具发现有垃圾文件,在它输出到屏幕的信息中会显示相应的信息。
到现在为止,上面所讲的整个过程就是RBS FILESTREAM Provider的垃圾收集。但是由于RBS FILESTREAM Provider使用了SQL Server 2008中的FILESTREAM特性,而FILESTREAM组件自己对于垃圾文件,也有自己的一套管理方法。换句话说,在RBS的层次,RBS会通过自己的垃圾收集来删除垃圾文件,但这并不会影响到FILESTREAM的层次。即使在RBS层次已经完成了“垃圾收集”,并认为已经把一个文件删除了,但在FILESTREAM层次,却可能仍然不会将文件从磁盘文件系统上删除,除非FILESTREAM组件自己进行一次“垃圾收集”。
强制FILESTREAM进行“垃圾收集”最简单的方法就是在数据库上执行下面这个SQL指令:
CHECKPOINT
最后,对于RBS FILESTREAM Provider维护工具,由于它是一个命令行工具,所以可以使用Windows计划任务来定时执行它。对于FILESTREAM的SQL指令,可以通过SQL Server的作业来定时执行。
参考: