LaB*_*cca 5 sql-server garbage-collection filestream sql-server-2008
在询问了这个问题之后,我很清楚我需要能够在最快的时间内执行垃圾收集.
如何告诉SQL Server文件流的垃圾收集器删除所有具有高优先级的文件?
我尝试使用CHECKPOINT语句,甚至通过设置持续时间(CHECKPOINT 100),但没有任何变化.
删除40000文件流记录后,我发现垃圾收集器每秒删除4-5个文件.如何告诉他"现在全部删除"?
Paw*_*iak 17
不幸的是,目前没有办法强制文件流数据的垃圾收集(GC).它由异步后台任务处理,该任务仅经常被调用,并且在单个调用中可以处理的文件数量有限制.其他人已经抱怨过这个问题,微软承诺在未来的版本中解决这个问题.
话虽如此,您可以主动做一些事情来确保所有已删除的文件都符合垃圾回收的条件.从数据库中删除文件时,文件不会自动符合垃圾回收条件 - 必须满足某些附加条件.
这些条件取决于数据库的恢复模型,因此了解数据库所处的恢复模型非常重要.请注意,即使恢复模型(由sys.databases指定)已满,但您尚未执行db/log备份自启用完整恢复模型(或自创建数据库)以来,数据库将在许多方面表现,就好像它仍处于简单恢复模型中一样.
在简单恢复模式下,文件有资格删除的所有必要条件是当前检查点LSN(最后一个检查点的LSN)大于删除该文件的删除操作的LSN.因此,删除40,000行后所能做的就是发出一个CHECKPOINT语句并等待.
当数据库处于"真正完整"的恢复模型时,事情变得更加复杂.如果是这种情况,那么除了检查点LSN之外,备份LSN(上次日志备份的LSN)必须超过删除LSN.此外,GC分两个阶段工作:在第一次传递时,它仅标记要删除的文件,但不会物理删除它.只有当GC第二次处理该文件时,该文件才会从磁盘中物理删除.为了使事情变得更有趣,GC的第一遍"重置"了删除LSN,因此第二遍只能在检查点LSN和备份LSN大于第一个GC通道的LSN时处理该文件.
如果您想确切知道系统中发生了什么,可以通过查看特殊的内部"墓碑"表来跟踪当前的GC进度.每次从数据库中删除文件流值时,都会在此表中插入一个逻辑删除.只有在从磁盘中删除文件后才会删除逻辑删除.墓碑表的名称是sys.filestream_tombstone_,其中有一些数字.您可以使用以下查询获取确切的名称:
select name from sys.internal_tables where name like '%tombstone%'
Run Code Online (Sandbox Code Playgroud)
由于它是一个内部表,要查询它,您需要使用DAC(专用管理连接)登录.
例如,假设我删除了一个包含单个文件流值的行.现在我可以通过发出以下查询(来自DAC)来查看逻辑删除的状态:
select * from sys.filestream_tombstone_2073058421
Run Code Online (Sandbox Code Playgroud)
oplsn_fseqno | oplsn_bOffset | oplsn_slotid | file_id | rowset_guid | column_guid | filestream_value_name | transaction_sequence_num | status
31 | 239 | 2 | 65537 | CBA21DD0-C36F-4D19-A59B-F5312712A8F6 | 6D2AA35E-692C-4F7D-8412-94475E76AC25 | 0000001f-000000eb-0002 | 0 | 17
前3个字段表示删除操作的LSN,但最重要的是观察状态.发出日志备份+检查点并让它运行几秒后,我再次查询逻辑删除表,得到:
oplsn_fseqno | oplsn_bOffset | oplsn_slotid | file_id | rowset_guid | column_guid | filestream_value_name | transaction_sequence_num | status
31 | 265 | 2 | 65537 | CBA21DD0-C36F-4D19-A59B-F5312712A8F6 | 6D2AA35E-692C-4F7D-8412-94475E76AC25 | 0000001f-000000eb-0002 | 0 | 18
请注意,状态已更改(最后2位从1更改为2),表示文件已由第一个GC传递处理.此外,LSN已经更新了第一GC通的LSN,所以为了使第二GC通行证才能够最终删除的文件,我们需要将检查点LSN和备份LSN上述新的LSN.我发出另一个检查点+日志备份,等待几秒钟并重新查询tombstones表.它现在为空,文件已从磁盘中消失.
请记住,(如已启用版本控制如复制,其他交易)还有其他的东西,可能会阻止特定的文件被垃圾回收,但在大多数情况下,检查点和日志备份是2分主要的.
哎呀,我想我可能已经深入细节,但也许这将有助于理解GC行为.
显然现在有一种方法,通过使用
sp_filestream_force_garbage_collection
Run Code Online (Sandbox Code Playgroud)
在 SQL Server 2012 中