欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

SQL Server中的高可用性(2)----文件与文件组

程序员文章站 2022-06-05 12:38:21
...

在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性。在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性。SQL Server允许在某些文件损坏或离线的情况下,允许数据库依然保持部分在线,从而保证了高可用性。 文件和文件组 有关文

    在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性。在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性。SQL Server允许在某些文件损坏或离线的情况下,允许数据库依然保持部分在线,从而保证了高可用性。

 

文件和文件组

    有关文件和文件组的基本概念,有很多文章已经阐述过了。这里我只是提一下,网站空间,文件组作为SQL Server访问文件的一个抽象层而存在。因此SQL Server上所做的操作不是直接针对文件,而是针对文件组。

    使用多个文件组和文件不仅仅是为了分散IO和提高性能,还有高可用性方面的原因。有关一个数据库应该包含几个文件或文件组,Paul Randal已经做过非常棒的阐述,请参阅:。

    数据库中使用多个文件或文件组在高可用性方面的好处包括:

 

文件

    在SQL Server中,文件分为三类,分别为:

    其中,主数据文件默认以扩展名mdf结尾,香港虚拟主机,美国服务器,辅助数据库文件默认以ndf结尾,日志文件以ldf结尾。虽然扩展名是可以修改的,但强烈建议不要去改扩展名。

    上面提到文件名值得是物理文件名,但是实际上在SQL Server中进行操作,操作的是逻辑文件名。

    任何时间,文件都会处于某一种状态,这些状态包括:

    可以通过sys.database_files这个DMV来查看数据库文件中包含状态在内的相关信息,如图1所示。

   

SQL Server中的高可用性(2)----文件与文件组

图1.查看数据库中文件的状态等相关信息

 

   你甚至可以在数据库缺少NDF文件时附加数据库,具体细节,请参阅MCM黄大师的一篇文章:。

 

文件组

    在SQL Server中,文件组中某个文件的状态决定了整个文件组的状态。但文件的状态独立于数据库的状态,比如说文件的状态是离线,但数据库依然能保证在线,这也就是所谓的数据库部分在线,举个例子,某个文件包含了名为selldata的表,如果该文件离线,但数据库在线,所有针对该selldata的表上的操作都会失败。

   如果需要数据库中的某个文件组在线,该文件组中的所有文件都应该处于在线状态。

 

表分区

    表分区是自SQL Server 2005之后出现的一个概念,我之前已经写过一篇关于表分区的文章。表分区的概念虽然很老了,但是很多地方对于表分区的使用依然处于非常初级的阶段。

    我见过大部分想到使用表分区的例子是出现性能问题,从而考虑分散大表的IO。但实际上,表分区还会提高可用性。使用表分区的好处还包括:

 

    值得注意的是,对表分区后,也要对表上的非聚集索引进行索引分区。否则有可能造成性能方面的例子。

 

DEMO

DEMO1 :仅重建某个分区

    下面例子是一个简单的分区表,并对索引进行分区后,仅仅重建某个分区,而不是整个索引。比如说表中按照数据冷热进行分区,可以仅仅对热数据进行重建,从而大大减少了重建索引所需的时间,如代码清单1所示。

(100, 500) --分区架构 CREATE PARTITION SCHEME [x] AS PARTITION [t] TO ([PRIMARY], [FileGroup1], [FileGroup1]) [Sales].[SalesOrderDetailPartition]( [SalesOrderID] [int] NOT NULL, [SalesOrderDetailID] [int] IDENTITY(1,1) NOT NULL, [CarrierTrackingNumber] [nvarchar](25) NULL, [OrderQty] [smallint] NOT NULL, [ProductID] [int] NOT NULL, [SpecialOfferID] [int] NOT NULL, [UnitPrice] [money] NOT NULL, [UnitPriceDiscount] [money] NOT NULL, [LineTotal] AS (isnull(([UnitPrice]*((1.0)-[UnitPriceDiscount]))*[OrderQty],(0.0))), [rowguid] [, [ModifiedDate] [datetime] NOT NULL, ) ON x(SalesOrderID) INSERT INTO [Sales].[SalesOrderDetailPartition]([SalesOrderID], [CarrierTrackingNumber], [OrderQty] , [ProductID] , [SpecialOfferID], [UnitPrice], [UnitPriceDiscount],ModifiedDate,rowguid) SELECT [SalesOrderID], [CarrierTrackingNumber], [OrderQty] , [ProductID] , [SpecialOfferID], [UnitPrice], [UnitPriceDiscount],ModifiedDate,rowguid FROM [Sales].[SalesOrderDetail] test_partition_idx ON [Sales].[SalesOrderDetailPartition](ProductID) on x(SalesOrderID) test_partition_idx ON [Sales].[SalesOrderDetailPartition] REBUILD Partition = 1