在談到SQL Server的高可用性以前,咱們首先要談一談單實例的高可用性。在單實例的高可用性中,不可忽略的就是文件和文件組的高可用性。SQL Server容許在某些文件損壞或離線的狀況下,容許數據庫依然保持部分在線,從而保證了高可用性。html
有關文件和文件組的基本概念,有不少文章已經闡述過了。這裏我只是提一下,文件組做爲SQL Server訪問文件的一個抽象層而存在。所以SQL Server上所作的操做不是直接針對文件,而是針對文件組。sql
使用多個文件組和文件不只僅是爲了分散IO和提升性能,還有高可用性方面的緣由。有關一個數據庫應該包含幾個文件或文件組,Paul Randal已經作過很是棒的闡述,請參閱:http://www.sqlskills.com/blogs/paul/files-and-filegroups-survey-results/。數據庫
數據庫中使用多個文件或文件組在高可用性方面的好處包括:架構
文件併發
在SQL Server中,文件分爲三類,分別爲:ide
其中,主數據文件默認以擴展名mdf結尾,輔助數據庫文件默認以ndf結尾,日誌文件以ldf結尾。雖然擴展名是能夠修改的,但強烈建議不要去改擴展名。函數
上面提到文件名值得是物理文件名,可是實際上在SQL Server中進行操做,操做的是邏輯文件名。高併發
任什麼時候間,文件都會處於某一種狀態,這些狀態包括:sqlserver
能夠經過sys.database_files這個DMV來查看數據庫文件中包含狀態在內的相關信息,如圖1所示。性能
圖1.查看數據庫中文件的狀態等相關信息
你甚至能夠在數據庫缺乏NDF文件時附加數據庫,具體細節,請參閱MCM黃大師的一篇文章:http://www.sqlnotes.info/2013/05/07/attach-database-with-missing-ndf-file/。
文件組
在SQL Server中,文件組中某個文件的狀態決定了整個文件組的狀態。但文件的狀態獨立於數據庫的狀態,好比說文件的狀態是離線,但數據庫依然能保證在線,這也就是所謂的數據庫部分在線,舉個例子,某個文件包含了名爲selldata的表,若是該文件離線,但數據庫在線,全部針對該selldata的表上的操做都會失敗。
若是須要數據庫中的某個文件組在線,該文件組中的全部文件都應該處於在線狀態。
表分區是自SQL Server 2005以後出現的一個概念,我以前已經寫過一篇關於表分區的文章。表分區的概念雖然很老了,可是不少地方對於表分區的使用依然處於很是初級的階段。
我見過大部分想到使用表分區的例子是出現性能問題,從而考慮分散大表的IO。但實際上,表分區還會提升可用性。使用表分區的好處還包括:
值得注意的是,對錶分區後,也要對錶上的非彙集索引進行索引分區。不然有可能形成性能方面的例子。
DEMO1 :僅重建某個分區
下面例子是一個簡單的分區表,並對索引進行分區後,僅僅重建某個分區,而不是整個索引。好比說表中按照數據冷熱進行分區,能夠僅僅對熱數據進行重建,從而大大減小了重建索引所需的時間,如代碼清單1所示。
--建立分區函數 CREATE PARTITION FUNCTION [t](int) AS RANGE LEFT FOR VALUES (100, 500) --分區架構 CREATE PARTITION SCHEME [x] AS PARTITION [t] TO ([PRIMARY], [FileGroup1], [FileGroup1]) --建立表 CREATE TABLE [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] [uniqueidentifier] ROWGUIDCOL NOT NULL, [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] go --建立索引分區 CREATE NONCLUSTERED INDEX test_partition_idx ON [Sales].[SalesOrderDetailPartition](ProductID) on x(SalesOrderID) --僅僅重建某個分區 ALTER INDEX test_partition_idx ON [Sales].[SalesOrderDetailPartition] REBUILD Partition = 1
代碼清單1.僅僅重建某個分區,而不是整個索引
關於這裏,更深刻的文章能夠參閱:http://www.mssqltips.com/sqlservertip/1621/sql-server-partitioned-tables-with-multiple-filegroups-for-high-availability/
DEMO2:數據庫部分在線和文件還原
--建立測試數據庫 CREATE DATABASE test GO --改爲完整恢復模式 ALTER DATABASE test SET RECOVERY FULL --添加一個文件組 ALTER DATABASE test ADD FILEGROUP WW_GROUP GO --向文件組中添加文件 ALTER DATABASE test ADD FILE ( NAME = ww, FILENAME = 'D:\wwdat1.ndf', SIZE = 5MB, MAXSIZE = 100MB, FILEGROWTH = 5MB) TO FILEGROUP ww_Group --在不一樣文件組上分別建立兩個表 CREATE TABLE test..test ( id INT IDENTITY ) ON [primary] CREATE TABLE test..test_GR ( id INT IDENTITY ) ON ww_Group --作完整備份 BACKUP DATABASE test TO DISK='D:\Test_backup.bak'WITH INIT --作文件備份 BACKUP DATABASE test FILE = 'ww', FILEGROUP = 'ww_Group' TO DISK='D:\CROUPFILES.bak'WITH INIT --備份日誌 BACKUP LOG test TO DISK='D:\Test__log.ldf'WITH INIT --刪除文件組中的表內的數據 TRUNCATE TABLE test..test_GR --還原備份,日誌僅僅被應用於那個還原狀態的文件 RESTORE DATABASE test FILE = 'ww', FILEGROUP = 'ww_Group' FROM DISK ='D:\CROUPFILES.bak' WITH FILE = 1,NORECOVERY RESTORE LOG test FROM DISK='D:\Test__log.ldf' WITH FILE = 1, NORECOVERY --備份尾端日誌 BACKUP LOG test TO DISK='D:\Test__log.ldf' WITH NOINIT,NO_TRUNCATE --還原尾端日誌 RESTORE LOG test FROM DISK='D:\Test__log.ldf' WITH FILE = 2, RECOVERY GO --查看數據,刪除數據的操做被成功恢復 SELECT * FROM test..test_GR --清除數據庫 DROP DATABASE test
代碼清單2.備份還原單個文件
代碼清單2很好的闡述了整個文件備份還原的過程,其中,在文件還原的過程當中咱們能夠看到數據庫自己是在線的,但數據庫中有一個文件處於還原狀態,如圖2所示。
圖2.ww文件處於還原中狀態
此時對於表test_GR作操做的話,會提示因文件組沒有聯機而失敗,如圖3所示。
圖3.由於文件組沒有聯機而致使操做失敗
再對尾端日誌進行備份還原以後,該文件組成功上線。
本篇文章闡述了文件和文件組在高可用性中的做用。瞭解這些特性對於下降還原時間很是有必要。在數據庫開始上線以前,儘可能合理的把一個數據庫分爲多個文件組和文件,不只僅提高性能和併發性,還可使得DR更加容易。