《Microsoft Sql server 2008 Internal》读书笔记--第七章Special Storage(4)

《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语句立刻移走所有的文件夹和文件,因为我们没有任何机会进行后续日志操作。然后增加三行数据,并删除其中的一条。

 

代码
USE master;
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'),
                      
10000as varbinary(max))),
           (newid(), 2,
               
CAST (REPLICATE (CONVERT(varchar(MAX), 'New Data'),
                      
10000as   varbinary(max))),
       (newid(), 3, 0x);
GO
BACKUP DATABASE MyFileStreamDB to disk = 'D:\BackupDb\FBDB.bak';
GO
此时我们删除一条记录

DELETE dbo.Records
WHERE SerialNumber = 2;
GO

此时,还有三个文件。

邀月工作室 

 在5 秒内赶紧备份:

BACKUP LOG  MyFileStreamDB to disk = 'D:\BackupDb\FBDB_log.bak';CHECKPOINT;

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>

 SELECT Chart_Primary, Chart_Primary.PathName()
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)。睡觉。呵呵。

 

 

posted @ 2010-05-08 00:22 邀月 阅读(...) 评论(...) 编辑 收藏