《Microsoft Sql server 2008 Interna》读书笔记订阅地址:
http://www.cnblogs.com/downmoon/category/230397.html/rss
《Microsoft Sql server 2008 Interna》索引目录:
《Microsoft Sql server 2008 Internal》读书笔记--目录索引
上文简单介绍了 filestream数据的基础,本文继续了解 FileStream的一些特性。
■ 更新FileStream数据
当使用 Updte修改一个fileStream列时,包含数据的文件被修改,文件相应增加或减少。特别是,设置一个列为空时,零值引起文件大小为0。而且,在第 一次释放时,T-SQL的(用.Write子句 定义的)分 块更新(Chunked update)不被支持。(邀月注:Write子句,参看MSDN: http://msdn.microsoft.com/en-us/library/ms177523.aspx ) 推荐使用文件系统流访问来操作(包含insert和Update)你的Filestream数据。针对Filestream的Update通常被执行为 Delete+Insert操作。因此,在这个列更新后将在目录下看到一个新的行。
当一个 filestream单元格被设置为null时,与这个单元格相关的filestream文件在GC运行时被删除。
■ 删除FileStream数据
当使用delete或truncate table语句删除一行时,任何与这行相关的文件都被删除。但这两个删除并不是同步进行的。文件被GC线程删除。有时候说delete是update的一 部分也是对的。一个新行增加,但旧行直到GC运行时才会被物理移走。
注意:数据操作 (包括insert,update,delete,merge)的 output子句像它在列修改中一样被支持。但是,如果你使用output子句往一个带有varbinary(max)的列(该列没有使用 filestream定义)的表中插入数据时,如果数据大于2GB时,可能会报运行时错误。
■ FileStream数据和事务
Filestream 数据操作基于完全事务的。但是在你操作 filestream时,不是所有的隔离等级都被支持的。
Isolation level | Transact SQL access | File system access |
---|---|---|
Read uncommitted |
SQL Server 2008 |
Unsupported |
Read committed |
SQL Server 2008 |
SQL Server 2008 |
Repeatable read |
SQL Server 2008 |
Unsupported |
Searializable |
SQL Server 2008 |
Unsupported |
Read committed snapshot |
SQL Server 2008 R2 |
SQL Server 2008 R2 |
Snapshot |
SQL Server 2008 R2 |
SQL Server 2008 R2 |
更详细的资料, 请看MSDN: http://msdn.microsoft.com/en-us/library/ms173763%28SQL.105%29.aspx
■ 记录FileStream变化
正如前文提到,每个fielstream文件组都有一个$FSLOG文件夹,它的作用就是跟踪对所有与文件组相关的filestream活动。这些数据在你执行事务日志备份 (backup)与还原(restore)操作时使用,在恢 复(recover)进程中也用。
$FSLOG文件夹主要跟踪对增加到filestream文件组的新信息。下列操作引起日志文件夹的增加:
1、一个包含 fielstream数据的新表被创建
2、一个 fielstream列被定义
3、一个在 filestream列中包含not-null值数据的行被 insert
4、一个 filestream值被update
5、一个事务 提交(Commit)发生
这儿是一些例子:
■ 如果你创建一个包含两个filestream列的表,4个文件被加到$FSLOG文件夹---一个是 表,两个对应列,一个对应Commit
■ 如果你在一个自动提交事务中插入一个包含filestream数据的行,2个文件被加到$FSLOG文件夹---一个对应Insert,一 个对应Commit
■如果你在一 个明确事务中插入一个5 行,6个文件被加到$FSLOG文件 夹
当数据被删除或 表被truncate或drop时, 文件并没有被加到 $FSLOG文件夹 ,然而,SQL Server保持了对这些操作的日志跟踪。一个新的元数据(metadata)表包含被移走的数据的信息。
■ FileStream 的垃圾回收器(Garbage Collection)
特别,对日志备份,既 然事务日志不包含实 际filestream数据,所有新的filestream内容必须被备份。仅仅filestream数据才有对于实际 filestream内容的redo信息。 通常,如果你的数据库没有处于简单恢复模式,你 需要在GC从你的filestream文件夹中移走不需要的数据文件前备份两次日志。
我们看一个例子, 删除并reCreate MyFileStreamDB数据库,一个drop语句立刻移走所有的文件夹和文件,因为我们没有任何机会进行后续日志操作。然后增加三行数据,并删除其中的一条。
GO
DROP DATABASE MyFilestreamDB;
GO
CREATE DATABASE MyFilestreamDB ON PRIMARY
(NAME = N'Rowdata1', FILENAME = N'd:\data2\Rowdata1.mdf' , SIZE = 2304KB ,
MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ),
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM DEFAULT
(NAME = N'FSData1', FILENAME = N'd:\data2\filestream1' ),
FILEGROUP FileStreamGroup2 CONTAINS FILESTREAM
(NAME = N'FSData2', FILENAME = N'd:\data2\filestream2' )
LOG ON
(NAME = N'FSDBLOG', FILENAME = N'c:\data2\FSDB_log.ldf' , SIZE = 1024KB ,
MAXSIZE = 2048GB , FILEGROWTH = 10%);
GO
USE MyFilestreamDB;
GO
CREATE TABLE dbo.Records
(
Id [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE,
SerialNumber INTEGER UNIQUE,
Chart_Primary VARBINARY(MAX) FILESTREAM NULL
)
FILESTREAM_ON FileStreamGroup1;
GO
INSERT INTO dbo.Records
VALUES (newid(), 1,
CAST (REPLICATE (CONVERT(varchar(MAX), 'Base Data'),
10000) as varbinary(max))),
(newid(), 2,
CAST (REPLICATE (CONVERT(varchar(MAX), 'New Data'),
10000) as varbinary(max))),
(newid(), 3, 0x);
GO
BACKUP DATABASE MyFileStreamDB to disk = 'D:\BackupDb\FBDB.bak';
GO
此时我们删除一条记录
DELETE dbo.Records
WHERE SerialNumber = 2;
GO
此时,还有三个文件。
在5 秒内赶紧备份:
5秒后文件变成了两个。
■ FileStream 的元数据
在SQL Server表中。针对filestream需要的存储并不复杂。在行自身,每个filestream列包含一个48字节的文件指针。即便你用DBCC Page命令,也没有更多的关于此文件的信息。然而,SQL Server提供了一个新函数以转换这个文件指针为一个UNC路径名。UNC值格式大致如下:
\\<Server_name>\<share_name>\v1\<db_name>\<object_schema>\<table_Name>\<column_name>\<GUID>
FROM dbo.Records
WHERE SerialNumber = 1;
GO
--\\AP4\AGRONET08\v1\MyFilestreamDB\dbo\Records\Chart_Primary\8D43AD9A-B755-4AA1-9D73-4B7FAD317289
关于PathName函数的更多用法,请看MSDN:http://msdn.microsoft.com/en-us/library/bb895239.aspx
■ FileStream 的性能考虑
作为Filestream存储的权威指南,可以看这篇文章:http://msdn.microsoft.com/en-us/library/cc949109.aspx
以下是一些要点:
■确认你在用正确的方式存储合适的数据。Jim gray曾经在两年前发表过一篇《To BLOB or not to BLOB》。一般而言,小于256KB应该存储在数据库,大于1M,则应该存储在文件系统中。这之间的数据根据测试应用程序来选择。如果你使用filestream不存储一些过小的large 对象将不会有一个好的性能体验。
■针对NTFS卷(存放fielstream数据的容器)使用合适的RAID级别,如RAID5用于写敏感工作模式。
■使用合适的磁盘技术,SCSI通常比SATA/IDE要快,因为有更高的转速,更低的热量和寻道次数。同时SCSI要更多的money
■无论使用什么磁盘技术。如果是SATA,确认它支持NCQ。如果是SCSI,确保它支持CTQ,这两者都允许多线程,并发I/O访问。
■在设置filestream前,如果需要,请整理NTFS卷,定期整理会保持好的查询性能。
■在NTFS卷使用命令行fsutil关闭8.3命名限制。否则检测文件是否存在将会使insert和update执行时性能下降很多。
■使用fsutil关闭最后一次访问时间跟踪。
■设置合适的NTFS簇大小。对于大于1M的larger 对象,使用64KB大小的簇会有助于减少整理。
■一个filestream的局部更新会创建一个新文件,批量小数据的更新合并到一个大的更新会减少碎片。
■当一个流数据到客户端时,使用SMB缓存大小最好为60KB左右,l因为TCP/IP缓存为64KB。
本文主要介绍了filestream的相关入门知识,下文将介绍稀疏列(Sparse columns)。睡觉。呵呵。