SQL Server

實現 SQL Server 的高可用性

Zach Nichter

 

摘要:

  • 鏡像
  • 資料庫快照集
  • 記錄傳送
  • 叢集
  • 複寫

下載本文程式碼: NichterHA2007_03.exe (151KB)

高可用性是每一位資料庫管理員都應該了解的概念。它是指系統的回應性和存取性。高可用性有時候表示回應時間必須在數秒之內,有些情況的回應時間則需要

快到幾分之一秒。我曾經擔任過顧問的一家公司,其 Web 伺服器要求 SQL 查詢的來回時間要以毫秒為單位;如果回應時間超過該限制,會認為資料庫系統當機,而 Web 伺服器就會重新連接下一個可用的資料庫伺服器。

由於使用者不斷要求更快的應用程式,所以知道如何達成高可用性和快速回應時間,可幫助您更聰明地規劃相依於資料的應用程式。

還好 SQL Server™ 2005 有許多改進可用性的選項,包括複寫、叢集、資料庫鏡像、資料庫快照集和資料庫記錄傳送。我會探討這些功能,提供一些看法,讓您了解如何決定適合您環境的功能。讓我們先從 [圖 1] 開始,其中說明 SQL Server 2005 的可用性選項。

Figure 1 高可用性選項

技術屬性 複寫 資料庫鏡像 叢集 資料庫快照集 記錄傳送
高可用性選項  
容許高交易需求  
即時資料可用性  
資料映像為唯讀    
唯一硬體組態        
低成本  
提供資料復原  
自動容錯移轉      
實作/管理可能較為複雜    
可能要注意的效能考量    

定義高可用性

在規劃高可用性應用程式時,首要目標之一,就是要定義高可用性在您環境中代表的意義。對於某些組織而言,高可用性表示必須有相當於實際執行硬體的備援硬體,需要資料和硬體都達到 99.995% 以上的正常運作時間和可用性。有些組織只需要資料本身隨時可用,萬一需要容錯移轉時,對於實際執行層級效能較不在乎。在判斷適合您的解決方案時,高可用性的定義很重要。

您也需要識別可能遭遇到的運轉中斷類型,並指出它們對於服務等級協定 (SLA) 有何影響。會影響可用性的運轉中斷類型包括:計劃中的運轉中斷、非計劃中的運轉中斷,以及過低的執行效能。

計劃中的運轉中斷通常是排定的維護時間,系統使用者會事先接獲通知。非計劃中的運轉中斷通常是硬體或軟體失敗的結果,造成資料無法存取。過低的執行效能也會造成運轉中斷,通常是以一般使用者回應時間來衡量,標準則是由企業和 IT 組織以某種形式的 SLA 事先達成共識。

除了識別運轉中斷的可能原因之外,您還必須決定資料的活動層級,亦即是否一定要維持在線上、僅有時候需要在線上,或是可以離線。您也必須決定可用性選項 (備援系統) 要架設在相同地理位置或遠端位置。預算限制在您的決策中也可能扮演一定的角色。現在我們來看看每一個可用性選項。

資料庫鏡像

在探究資料庫鏡像之前,我應該先定義術語。

主體 (Principal) 是存放資料庫的主要實際執行伺服器,它會將其交易記錄檔連續傳送到鏡像伺服器和資料庫。

鏡像 (Mirror) 是存放資料庫備份副本的次要伺服器。鏡像副本與主要資料庫會持續同步處理。

角色 (Role) 指出特定伺服器的用途 -- 亦即做為主體或鏡像。

見證 (Witness) 是在主體伺服器和鏡像伺服器執行任務時,用於監督它們的執行個體,而且可起始自動容錯移轉。

夥伴 (Partner) 可以是主體伺服器或鏡像伺服器。

在一般環境中,主體資料庫會備份在主體執行個體上,備份則會在鏡像執行個體上還原 (請參閱 [圖 2])。還原資料庫之後,必須使用 SQL Server Management Studio (SMSS) 中的主體資料庫屬性視窗,或使用 T-SQL 指令碼,在主體伺服器上設定鏡像。

Figure 2 Database mirroring architecture

Figure 2** Database mirroring architecture **(按影像可放大)

在設定鏡像及建立鏡像工作階段之後,主體資料庫和鏡像資料庫將同步處理。然後主體資料庫會將自從上一次在鏡像伺服器上套用備份之後,所發生的事件之交易記錄檔傳送給鏡像伺服器。鏡像伺服器將接收此記錄檔,並嘗試儘快套用它。如果您使用 SQL Server 2005 Enterprise Edition,則此處理序為多執行緒;否則,它是單一執行緒作業。當這些記錄檔套用至鏡像之後,即達到資料庫的同步處理,並且會保持同步處理,直到鏡像工作階段中斷為止。

當用戶端執行新交易時,主體伺服器會對主體資料庫執行交易,同時從主體資料庫傳送交易記錄檔記錄至鏡像資料庫的重做記錄檔或記錄檔佇列,以便由鏡像套用至鏡像資料庫。在鏡像資料庫上套用並認可交易之後,會傳送回覆至主體,宣告該交易已在鏡像上認可。主體從鏡像接收到認可之前,不會確認其他系統接收到的新交易。

萬一失敗,鏡像可起始自動失敗,並由見證伺服器判斷主體資料庫是否可用,以支援該程序。萬一發生失敗,在鏡像夥伴可重新變成主體的夥伴之前,必須先解決鏡像夥伴的問題。在解決鏡像夥伴的問題之後,系統就會恢復鏡像夥伴的角色,且資料庫會再度同步處理。同步處理之後,鏡像工作階段就可以重新開始。

此特定鏡像模式為高安全模式,其中會開啟交易安全性來提供同步交易作業,但它不需要見證伺服器,因為它不利用自動容錯移轉;所有容錯移轉都是以手動方式起始。另一種類型的鏡像模式則提供同步交易作業,即高可用性模式。其中不但要求開啟交易安全性,而且還要求使用見證伺服器,以便在失敗時進行自動容錯移轉。

第三種,也是最後一種鏡像模式為高效能模式。其中要求關閉交易安全性,以進行非同步作業支援,此支援讓主體夥伴的交易能夠進行認可,而不必等待交易記錄寫入鏡像。高效能模式不需要組態中有見證伺服器。

請注意,鏡像功能需要主體和鏡像都執行同一個 SQL Server 版本,但見證伺服器則不一定要使用同一個版本,亦即可以是 SQL Server Express Edition。此外,主體資料庫必須處於完整復原模式。

ADO.NET 2.0 與 SQL Server 2005 整合在一起,並包括支援資料庫鏡像的能力,以及為應用程式提供鏡像環境的透明容錯移轉。如此一來,萬一無法建立主體資料庫的連線時,ADO.NET 應用程式才能夠自動容錯移轉,而不需要編寫其他程式碼或組態。組態設定很簡單,只要在兩個環境之間指定共同使用者,並在連線字串中指定容錯移轉夥伴即可。以下是 ADO.NET 連線字串的範例,其中可識別鏡像資料庫環境的容錯移轉夥伴:

"Provider=SQLNCLI.1;Data Source=MirrorDB;Failover Partner=SQL03;
 Initial Catalog=AdventureWorks;
Persist Security Info=True;User ID=TestUser; Password=TestPswd; Pooling=True;
Connect Timeout=5;Application Name=ADOMirrorTest"

視您的應用程式和資料需求而定,資料庫鏡像可能是貴公司的理想選項,但要達到最佳效能,仍有許多因素需要考量。例如,系統的交易速率有多高,亦即資料的變更量有多大?在考量資料庫鏡像時,一定要先判斷是否有足夠的頻寬和網路速度,以處理資料量和交易處理速率。同時也要考量連結的飽和度。尤其如果鏡像是在不同的地理位置時,這點特別重要。您必須事先監視系統,以判斷是否有任何環境限制會防止鏡像的有效運作。

尤其當您希望降低成本時,資料庫鏡像更是一個理想的選項。事實上,資料庫鏡像架構不需要共用磁碟,也不需要進階或特殊技巧,就可以執行環境。和叢集不同,資料庫鏡像並不需要兩個夥伴都具備相同硬體。而且,使用 [資料庫屬性] 視窗的 [鏡像] 索引標籤上的 [安裝精靈],即可輕易實作鏡像 (請參閱 [圖 3])。我也建議您閱讀 Database Mirroring Best Practices and Performance Considerations 白皮書 (go.microsoft.com/fwlink/?LinkId=80897),以取得更多有用資訊。

Figure 3 Mirroring setup wizard

Figure 3** Mirroring setup wizard **(按影像可放大)

資料庫快照集

資料庫快照集是 SQL Server 2005 Enterprise Edition 所提供的新技術,但不算是高可用性的選項。資料庫快照集與其他技術一起使用時,應該做為復原或可行性報告選項使用。快照集就是資料庫在特定時間點的唯讀檢視。

快照集是使用如下的 CREATE DATABASE 命令所建立:

CREATE DATABASE SnapDB_20061028_2030 ON
(NAME = SnapDB_Data, FILENAME = 
    'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\SnapDB_20061028_2030.snp')
AS SNAPSHOT OF SnapDB;
GO

建立資料庫快照集時,它會使用一個或多個檔案,稱為疏鬆檔案,而非一般資料庫使用的資料檔案。這些疏鬆檔案基本上是虛擬保留位置,一開始並不佔用任何資料。唯有當來源資料庫中的資料變更或刪除時,才會使用它們來保留資料。資料會一次以一個資料頁地寫入至疏鬆檔案,而實際的資料庫快照集只會顯示自從產生快照集之後所變更的資料。其餘資料是來自來源資料庫的資料頁。

產生快照集時,資料庫快照集檔案會依資料庫大小進行配置。您無法從配置大小得知其中實際保留有多少資料。若要取得此資訊,請執行如下的 T-SQL 陳述式:

SELECT *
FROM fn_virtualfilestats(DB_ID(N'SnapDB_20061028_
    2030'), 1);
GO

由於資料儲存在疏鬆檔案和來源資料庫的方式,存取資料庫快照集時,會同時擷取原始資料庫資料檔案中的資料頁以及快照集的疏鬆檔案中的資料頁。因為有共用資料頁的需求,所以快照集只能存留在產生快照集的來源資料庫所在的伺服器上。此架構未能減輕來源資料庫上的 I/O,所以快照集不是值得使用的有效報告選項,因為它們並未代表資料庫的真正狀態。

讓我們探討同時使用資料庫鏡像與快照集的案例。這樣可讓報告資料、鏡像和快照集資料庫與主體資料庫實體分開。資料庫快照集是使用 SQL Server Agent 和自訂指令碼進行排程,在固定的時間間隔會重新整理快照集。[圖 4] 中的範例指令碼顯示用來完成此動作的預存程序。它是設計在工作內使用,用於環境內管理特定資料庫快照集之建立及卸除。這樣可產生可接受的報告解決方案,因為報告資料會與實際執行資料隔離。

Figure 4 快照集排程的預存程序

use msdb;
GO
set nocount on
GO

CREATE PROCEDURE usp_snaprefresh 
     @database    sysname = NULL    --name of the database to snapshot
    ,@keepsnap    int        = 24   --# of hours to keep a snapshot 
                                    --after it was created 
                                    --use a value of '0' to keep all
                                    --existing snapshots
    ,@fileloc    sysname            --location for snapshot
        = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\'    
AS

DECLARE 
     @dt            datetime        ,@cnt          int
    ,@databaseid    int             ,@snap         sysname
    ,@sql           nvarchar(1000)  ,@yy           varchar(4)
    ,@mm            varchar(2)      ,@dd           varchar(2)
    ,@h             varchar(2)      ,@m            varchar(2)
    ,@lname         sysname         ,@pname        sysname
    ,@file          sysname         ,@pos1         int
    ,@pos2          int

-- initialize variables
SELECT 
     @dt = getdate()
    ,@cnt = 0, @pos1 = 0, @pos2 = 0
    ,@databaseid = db_id(@database)

-- check if valid database was provided
IF @databaseid IS NULL
BEGIN
    RAISERROR ('Missing database name. Rerun the procedure specifying a
       valid database name.',16,1)
    RETURN (0) 
END

--determine if snapshots should be kept
IF @keepsnap <> 0
BEGIN
    -- determine if other snapshots exist for this server older than @
    -- keepsnap value hrs
    SELECT ROW_NUMBER() OVER(ORDER BY name DESC) AS [RowNum], 
        name INTO #t1 
    FROM master.sys.databases 
    WHERE source_database_id = @databaseid
        AND create_date < dateadd(hh,-(@keepsnap),getdate())

    IF (SELECT max(RowNum) FROM #t1 where name is not null) > 0
    BEGIN
        WHILE @cnt <= (SELECT max(RowNum) FROM #t1)
        BEGIN
            SELECT @snap = name FROM #t1 WHERE RowNum = @cnt

            PRINT 'Dropping snapshot ''' + @snap + ''''

            SET @sql = 'DROP DATABASE ' + @snap

            EXEC(@sql)
            SELECT @cnt = @cnt + 1
        END
    END
END

-- break apart point in time date time information for file name
SELECT @yy = convert(varchar(4),year(@dt)),@mm = convert(varchar(2),
   month(@dt))
    ,@dd = convert(varchar(2), day(@dt)),@h = convert(varchar(2),
         datepart(hh,@dt)) 
    ,@m = convert(varchar(2), datepart(mi,@dt))

-- piece together the database snapshot name and the file name
SELECT @file = @database + '_' + @yy + @mm + @dd + '_' + @h + @m

-- identify logical file name of primary data file
SET @sql = 'SELECT name INTO tempdb..t1
FROM ' + @database + '.sys.database_files 
WHERE file_id = 1'

EXEC(@sql)

--setting logical filename for the snap
SELECT @lname = name FROM tempdb..t1

-- making sure the file location ends with '\'
IF substring(@fileloc, len(@fileloc), 1) <> '\'
BEGIN
    SET @fileloc = @fileloc + '\'
END

-- build sql statement to be run
SET @sql = N'CREATE DATABASE ' + @file + ' ON
(NAME = ' + @lname + ', FILENAME = ''' + @fileloc + @file + '.snp'')
AS SNAPSHOT OF ' + @database

EXEC(@sql)

-- cleanup
DROP TABLE tempdb..t1;
GO

不過請記住,資料庫快照集是暫時的,因為快照集無法備份,且若沒有來源資料庫就無法存在。如果疏鬆檔案的空間不夠,就會認為快照集毀損而必須加以卸除。

此外,使用資料庫快照集時系統效能會降低,是因為在來源資料庫上修改資料期間,資料頁會寫入來源資料庫資料檔之每一個快照集的疏鬆檔案中,而且寫入次數還要乘以資料庫含有的快照集數量。

讀取權是由來源資料庫在建立快照集時所定義,無法變更。快照集必須位於與來源資料庫相同的執行個體中,因為它們共用資料頁及相同的緩衝區快取。

唯有當您也使用鏡像時,才應該考慮使用快照集做為報告解決方案;否則,對於環境的效能沒有助益。在系統上執行可能有問題的作業之前,資料庫快照集或許是保留資料的最快方式。資料庫可還原為快照集的狀態,或從快照集內取出資料來取代來源資料庫中的資料。

您需要決定快照集資料庫的命名標準。我使用的標準是 originaldatabasename_date_time.snp。它先指定來源資料庫,然後指定產生快照集的日期和時間 (使用 24 小時制)。

記錄傳送

記錄傳送是有限的高可用性選項,它利用備份和復原來建立成本低廉的解決方案。記錄傳送會在排定的時間間隔利用交易記錄備份,使次要資料庫保持在最新狀態。

SQL Server 2005 中的記錄傳送會使用精靈來進行安裝、排程、初始化及監督的程序 (請參閱 [圖 5])。此程序很簡單,只要幾分鐘即可完成。

Figure 5 Log shipping setup wizard

Figure 5** Log shipping setup wizard **(按影像可放大)

在識別主要資料庫之後,會建立排程以及判斷備份檔案的檔案存在時間。接下來,必須建立備份檔案的檔案共用。在安裝檔案共用之後,必須建立次要資料庫檔案位置,且必須完成主要資料庫的還原來初始化資料庫。最後,必須為備份檔案的副本以及交易記錄檔備份的還原設定排程,並為每一個步驟設定所需的警示或延遲。

完成安裝之後,記錄傳送會定期將資料庫的交易記錄檔備份到共用網路位置。當檔案傳送到共用之後,備份會依設定排程套用到次要資料庫。

記錄傳送因為很簡單,所以在許多情況中都可以順暢運作。它是高可用性的理想選項,因為成本低廉且適用於高交易量的系統。運用在記錄傳送中的次要資料庫可使用於唯讀模式,所以對報告資料庫很方便。記錄傳送的負荷低,但萬一處理失敗,則必須使用警示原則。

如果您想要在環境中使用記錄傳送,考量因素包括其安裝和管理的簡易性,以及這不需要特殊技能。不過,雖然記錄傳送可以與資料庫鏡像合併而成為高可用性解決方案,但它並不是一個即時高可用性解決方案。它會受限於排程以及備份、檔案複製及還原之類的作業。它也需要手動容錯移轉。基於這些原因,記錄傳送僅能為不那麼重視時間需求的環境提供簡單的解決方案。

SQL Server 叢集

伺服器叢集會在 OS 層級運作,其中涉及重複的硬體及共用磁碟資源,以供叢集存取。對一般使用者而言,叢集可能是最不影響正常作業的,但也可能是成本最高的。它需要的硬體數量至少是執行非叢集執行個體所需數量的兩倍以上。

叢集的主題牽涉很廣,因此,我不在這裡探究所有細節,只會提供一個概觀。叢集需要兩部以上的伺服器,它們全部都必須安裝同一版的 Windows® 2000 Advanced Edition 或 Datacenter Edition,或 Windows Server® 2003 Enterprise Edition 或 Datacenter Edition。其中也需要安裝 Microsoft® Cluster Services (MSCS),來處理伺服器之間的共用資源擁有權,以及管理 IP 位址、共用磁碟和網路名稱。叢集也需要共用磁碟資源,通常是存放區域網路 (SAN) 或透過 SCSI 連接的儲存裝置。

SQL Server 執行個體也是資源,且 SQL Server 2005 的 Standard Edition 和 Enterprise Edition 都可以安裝在叢集組態中。如需 SQL Server 2005 支援的功能清單,請參閱 Feature Comparison Chart for SQL Server 2005 (microsoft.com/sql/prodinfo/features/compare-features.mspx)。

在叢集上建立資源之後,叢集的次要節點會透過在叢集中兩個節點之間的私人網路上建立的活動訊號,與叢集的主要節點定期保持通訊。活動訊號是間隔檢查點,用來判斷主要節點是否失敗。

萬一主要節點失敗,資源會移到次要節點,同時仍保持邏輯伺服器的原來狀態。這可讓用戶端只暫停一下互動就可以繼續運作。在某些情況下,整個容錯移轉程序所花費的時間從 5 秒以下到 30 秒以上不等,視叢集需要的硬體、軟體和網路元件而定。

叢集是昂貴而複雜的技術,需要特殊技巧才能解決系統的失敗問題;不過,相較於其他任何自動容錯移轉選項,這可以為一般使用者提供最順利的容錯移轉功能。每一個應用程式都有所不同,有些應用程式可能無法感知叢集或與叢集不相容,在最壞的情況下會需要應用程式重新連接。

複寫

SQL Server 2005 複寫也可以使用於高可用性架構。它提供四種複寫類型:快照集、交易、對等式及合併。對等式實際上就是一種交易式複寫,所以我在這裡不予討論。

有了複寫,您便擁有可達到高可用性的次要站台和資料庫的選項,與主要資料庫的功能完全相同。這可使用合併式複寫來達成,它會從主要資料庫和次要資料庫取得交易,並將兩者的變更合併到對方。可想而知,此組態需要衝突解決程序。

交易式複寫的邏輯設計與資料庫鏡像十分類似。套用至主要資料庫的交易會傳送到次要資料庫,以確保環境保持一致。當交易抵達時,會套用至次要資料庫,然後等待下一筆交易套用至系統上。

快照式複寫十分類似記錄傳送,因為它們都依排定的時間間隔執行,並以大量變更的方式更新次要資料庫,不會在進行認可時就將每一筆交易套用至兩個系統。這兩種技術的利用方式大同小異。

複寫需要特殊知識,這對於沒有專屬 DBA 的環境而言是一大考量。在疑難排解方面,複寫有點複雜,如果要將它做為高可用性選項,則需要更詳盡的設計。

複寫可適度滿足高可用性解決方案的需求。此技術使用交易式複寫,在記錄層級執行有如資料庫鏡像的動作,但沒有自動容錯移轉的選項。只要有足夠的資源和一點點創造力,編寫自動容錯移轉的解決方案指令碼並不難。

和資料庫鏡像不同的是,其來源和目標資料庫完全可供用戶端應用程式存取。若使用快照式複寫,則複寫可提供與記錄傳送相同的功能。

值得注意的是,複寫技術已通過考驗且有豐富的參考文件。對於高可用性解決方案使用複寫有一些缺點,效能也是個問題,但整體而言與資料庫鏡像不相上下。您利用複寫所設計的任何高可用性選項很可能會有更複雜的架構;它不一定更先進,但一定更複雜。此外,需要考慮的其中一個最大障礙,是萬一資料庫資料表結構有所變更,或您想要新增要複寫的資料表時,您必須中斷發行並重新定義,使所做的變更能夠呈現在兩個資料庫中。

結論

現在您可以了解,要為環境建立高可用性解決方案是需要創造力的。每一項 SQL Server 2005 高可用性技術都有它的優點和缺點,各自適合不同的情況。

當主要 Web 資料庫與次要資料庫環境的地理位置分開時,高效能模式的記錄傳送、快照式複寫、甚至資料庫鏡像都是很好的選擇 (尤其如果它們不需要即時取得次要資料的話)。

相反地,如果需要存取即時資料的次要資料庫,且主要伺服器上的交易率較低,還有兩個環境站台之間的連結快速不飽和,則交易式複寫或資料庫鏡像就可以擔當重任。

同時也要考慮您對這些技術的熟悉度。如果您對這些技術已經有一些使用經驗,會比較容易上手。如果您是一位主管但沒有專屬的 DBA,請盡量避開像複寫之類較複雜的技術,因為會有許多細節造成疑難排解較為複雜。您也可以考慮聘用有經驗的 SQL Server 顧問協助您設計、實作及訓練員工,以管理適合您環境的嶄新高可用性解決方案。

如果您的組織對於高可用性的定義是,資料要隨時可用、一旦無法存取資料就會有很嚴重的後果,則叢集會是較理想的選擇。

總而言之,SQL Server 2005 所提供的嶄新選項,可以為您量身訂做高可用性解決方案,以服務不同類型的環境。單一可用性選項或許就足以符合您的需求,但您也可以選擇多項技術的組合,誠如您所見,這裡有各種不同的選擇可供挑選。

Zach Nichter 是擁有 10 年以上經驗的 SQL Server 專家。他扮演過許多 SQL Server 支援角色,包括 DBA、小組組長、經理和顧問。目前 Zach 受雇於 Levi Strauss & Co.,擔任 DBA 設計師,專注於 SQL Server 效能、監督、架構和其他策略方針。

© 2008 Microsoft Corporation and CMP Media, LLC. 保留所有權利;未經允許,嚴禁部分或全部複製.