SQL Server Filestream - 删除“速度”

8
我第一次使用filestream数据类型(SQL Server 2008),在进行快速插入/删除时遇到了问题。基本上,文件从文件系统中实际删除的速度远远慢于插入/删除速度,即使我手动调用垃圾回收器(据我所知,CHECKPOINT应该调用垃圾回收器)。
下面的代码说明了问题-执行大约需要30秒,但您必须等待几分钟才能从文件系统中删除最后一个文件(当我查找C:\ FSTest \ Files文件夹时)。
有没有办法加快垃圾回收器的速度?(它似乎每10秒钟大约删除20个文件-这使我相信,如果我每秒存储/删除超过2个记录,最终将填满硬盘)
谢谢
CREATE DATABASE FSTest ON PRIMARY
    (NAME = FSTest_data, FILENAME = N'C:\FSTest\FSTest_data.mdf'),
FILEGROUP FSTestFileGroup CONTAINS FILESTREAM
    (NAME = FSTestFiles,FILENAME = N'C:\FSTest\Files')
LOG ON 
    (NAME = 'FSTest_log', FILENAME = N'C:\FSTest\FSTest_log.ldf');
GO

USE FSTest;
GO

CREATE TABLE FSTest (
    Guid UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE DEFAULT NEWSEQUENTIALID(),
    Name VARCHAR (25),
    Data VARBINARY(MAX) FILESTREAM);
GO

ALTER DATABASE FSTest SET RECOVERY SIMPLE;
GO

SET NOCOUNT ON
DECLARE @test int
SET @test=0
WHILE @test<1000 BEGIN
    INSERT INTO FSTest(Name,Data) VALUES('test',CAST('abc' AS VARBINARY(MAX)))
    DELETE FROM FSTest WHERE Name='test'
    CHECKPOINT
    SET @test = @test+1
END

更新:

我尝试以更接近我的需求的插入/删除速度进行更长时间的测试,执行了30分钟后,情况是相同的: 文件创建比删除要快得多。

SET NOCOUNT ON
DECLARE @test int
SET @test=0
WHILE @test<100000 BEGIN
    INSERT INTO FSTest(Name,Data) VALUES('test',CAST('abc' AS VARBINARY(MAX)))
    DELETE FROM FSTest WHERE Name='test'
    WAITFOR DELAY '00:00:00:200'
    CHECKPOINT
    SET @test = @test+1
END

你可以试试真实大小的文件吗?使用文件流通常不推荐处理小于1MB的任何文件。 - Pawel Marciniak
3个回答

5
经过更多的研究(感谢 Paul Randal 的博客——提供了许多关于 filestream 和垃圾回收的详细信息),一旦行被删除并执行检查点,文件将被放入系统表(墓碑表)中,然后每 10 秒钟运行一个进程(Ghost Cleanup)并从该表中删除一些项目(确切地说是 20 个)。因此,我们基本上只能进行 2 次删除/秒,并且似乎还没有办法改变这种行为。

由于我需要持续进行 4 次删除/秒,所以我需要找到一个替代 filestream 的方法。

感谢大家的贡献。


2
正如Remus所说,如果您使用完整恢复模型,则情况会复杂。但即使在简单恢复模型下,您也需要记住CHECKPOINT会调用垃圾收集器(GC),但它不能保证GC将在单个传递中删除所有文件。目前,GC对于单个调用可以执行的操作数量有限制。此外,文件是使用FILE_DELETE_ON_CLOSE选项删除的,因此只要文件有打开的句柄,您仍然会看到它,即使GC可能已经删除了它。这些打开的句柄可能由防病毒程序或其他文件系统过滤驱动程序持有。
最后,除非您真正的磁盘空间不足,否则我不会太担心过期的文件-它们最终将作为自动数据库检查点的一部分被删除。我相信(尽管“相信”是关键词),即使它可能具有缓慢的“启动时间”,如果您连续运行测试较长时间(几分钟?),GC也将跟上物理删除文件。
如果您关心性能,将filestream容器保留在系统驱动器上可能并不是一个好主意。有关filestream性能提示,请参见此处

我想你说得对,我会使用更持久的负载来测试它,并查看其反应如何。至于“单次调用中可执行操作的限制”,我们是否知道此限制,是否有办法提高该限制?我只是希望将来不会遇到瓶颈。 - Benoittr
我尝试了持续运行的情况,在40分钟的运行时间后,同样的问题仍然存在。文件数量约为5000:文件创建比删除更快。(我已在主贴中更新了观察结果)。 - Benoittr

1

事情比简单的检查点要复杂一些。当包含有关文件创建的日志记录的最后一个VLF处于非活动状态时,该文件可以被删除。请参见FILESTREAM垃圾回收


事实上,在提出这个问题之前,我就偶然看到了这篇文章,并理解在“简单”恢复模式下,我只需要触发检查点以进行垃圾回收。话虽如此,我对VLF等方面知之甚少,可能错过了重要的信息。 - Benoittr
1
Remus,你链接的博客文章并不完全准确。垃圾回收与虚拟日志文件(VLF)无关。它只需要一个CHECKPOINT-LOG BACKUP-等待几秒钟-CHECKPOINT-LOG BACKUP序列,这可能会导致VLF切换,但这不是垃圾回收器寻找的内容。 - Pawel Marciniak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接