SQL Server AlwaysON從入門到進階(6)——分析和部署AlwaysOn Availability Group


前言:

 
本節是整個系列的重點文章,到現在,讀者應該已經對整個高可用架構有一定的了解,知道獨立的SQL Server實例和基於群集的SQL Server FCI的區別。上一節已經介紹了如何安裝SQL Server Failover Cluster Instance(FCI)及其要求。
本節會深入AlwaysOn 可用組的內容,以演示部署為主線,包括如何啟用只讀路由和使用AlwaysOn組偵聽器。並在最后演示故障轉移。
在前面文章中對FCI和AlwaysOn可用組有了一定的平台要求。這里對其進行簡要的回顧。
  • Windows Server AD域
  • DNS基礎設施
  • DHCP(如需)
  • Windows Server Failover Cluster(WSFC)
  • WSFC上的節點
下面開始深入探討AlwaysOn及實操。
 
 

為什么使用AlwaysOn可用組?

 
在過去,通常會使用SQL Server FCI來實現SQL Server的高可用,這個要么基於Microsoft Cluster Services(Windows 2003)或WSFC(Windows 2008/2012)作為基礎。在群集中使用下面功能使得服務器在硬件故障時能夠完整遷移:
  • 多網卡及TCP/IP網絡用於網絡冗余。
  • 新的多數節點集仲裁模型 (從 Windows server 2003 SP1 開始) 移除磁盤依賴項,並增加對多站點群集的支持。
  • 使用多個計算機節點以抵消核心節點硬件故障(如主板等)。
正如前面提到,唯一的弱點就是FCI依賴於共享存儲。雖然有很多方式可以對其冗余,但是通常帶來高開銷及高配置、維護難度。另外,FCI僅僅遷移服務器硬件,並不提供單個甚至多個次要數據庫副本。
當使用FCI是,WSFC對其之上的SQL Server實例提供高可用。所有的FCI節點實際上作為一個群及資源進行對外服務,當其中一個伙伴節點故障,另外一個節點會進行故障轉移並重啟SQL Server服務。
當使用另外一個高可用技術——鏡像時,僅提供一個不可讀的次要數據庫副本(除非使用了快照)。同時鏡像是單一數據庫層面,甚至不可以進行多個庫一起鏡像。你可以組合FCI和鏡像技術來作為一個新的高可用技術,但是明顯增加了復雜度。但是鏡像可以在完全獨立的兩個服務器,不需要共享存儲,鏡像的問題就是鏡像數據庫不可讀。
還有一個高可用技術——日志傳送(Log Shipping)。對於復制一個數據庫進行讀訪問來說是一個很好的方式,但是有兩個問題:次要數據庫會落后於主庫,並且在日志還原過程中用戶要斷開連接。但是它有可以提供一對多的主次數據庫功能。
分析了上面幾種微軟自帶的高可用技術之后,讀者應該就明白,AlwaysOn的出現很大程度是為了彌補這些技術的不足。
 

什么是AlwaysOn可用組:

 
AlwaysOn可用組(下稱AG)是將數據庫的全部內容復制到一組預定義的SQL Server伙伴實例中,也稱副本,用於備用或只讀訪問。這個功能通過創建一個包含最少兩個副本和最少一個數據庫的AlwaysOn可用組來實現。每個數據庫僅能屬於一個AG,但是副本之間可以有多個AG。每當創建一個新組並添加數據庫時,會有一系列的預校驗操作。如下圖:(注意,某些圖是作者原圖,在后續部署過程中會使用本人實操的截圖)
 
 
 
在數據庫參與到AlwaysOn可用組之前,必須滿足這些先決條件。完整的先決條件列表可以看:針對 AlwaysOn 可用性組的先決條件、限制和建議 (SQL Server)。然后我們就可以復制數據庫到一組預定義伙伴實例中,用於讀取連接。
但是,AG也有一些限制:
  • 副本數量:SQL 2012中最大5個:1主4次要副本。SQL 2014中為1主8次要共9個副本。
  • 同步復制的設置:最大3個,其他副本只能使用異步模式。
  • 自動故障轉移數量:最多2個,並且必須為同步模式。
可用組的限制可以看下圖【新建可用組】向導。其中綠圈中【添加副本】選項在SQL 2012中顯示灰色,因為在SQL 2012中,最多只能有5個副本。藍圈標明了最大同步副本數量。紅圈顯示自動故障轉移的副本數。
 
 
 

行版本的影響:

 
當啟用只讀的次要副本時,行版本會自動開啟並對每一樣添加14byte的標識。實際上所有隔離級別都透明地映射到快照隔離級別從而避免重做線程阻塞。如果沒有這個,那么報表負載將受重做線程干擾。
主副本的行版本數據的添加依賴於主庫上的快照隔離級別或已提交讀快照隔離級別的設置。組中的庫如果使用了行版本控制,那么主副本上的也會有這方面的開銷(也就是比如組中多個庫只有一個庫使用了行版本存儲,那么整個副本都會受到影響)。
通過查詢“sys.dm_db_index_physical_stats”這個DMV中的“max_record_size_in_bytes”列,就可以看到這樣的開銷。下表描述了基於磁盤的表(非SQL 2014引入的內存表)不同設置下,可讀副本數據庫的版本控制行為:
 
可讀輔助副本? 啟用了快照隔離或 RCSI 級別隔離? 主數據庫 輔助數據庫
無行版本或 14 個字節的系統開銷 無行版本或 14 個字節的系統開銷
行版本和 14 個字節的系統開銷 無行版本但有 14 個字節的系統開銷
無行版本但有 14 個字節的系統開銷 行版本和 14 個字節的系統開銷
行版本和 14 個字節的系統開銷 行版本和 14 個字節的系統開銷
 
 

缺少統計信息的影響:

 
任何可讀次要副本數據庫都會遇到缺少統計信息引起只讀負載相關的問題。所有在主庫上創建或更新的統計信息都會同步並駐留到次要數據庫中。所有運行在次要數據庫的負載會產生臨時統計信息並存儲在TempDB中。這樣會使得TempDB有潛在壓力。這也是對TempDB要細心監控的原因之一。更多的信息可以看官方文檔:活動次要副本:可讀次要副本(AlwaysOn 可用性組)
 

優點:

 
盡管有所限制,AlwaysOn還是提供了一個新層次的高可用功能:
  • 沒有共享存儲:每個服務器\實例都使用本地存儲,並且移除了共享存儲的單點故障風險。
  • AlwaysOn偵聽器服務用於接受集中請求到HA數據庫組。
  • 多個可用可用數據庫取代了傳統的一主一備(往往是不可讀)。
  • 更合理的Failover功能。
  • 在副本層面掛起數據移動。
  • 支持多IP子網。
  • 可以把備份負載分攤到次要數據庫。
通過把備份操作運行在只讀副本數,可以降低主副本的系統壓力,特別是I/O壓力。多個次要副本同時可以提供DR和報表服務,當然也引入了費用的問題。其中一個需要注意的問題是AlwaysOn依舊使用數據庫鏡像端點作為實例間的通訊。所以和鏡像一樣,需要使用Windows身份驗證或者證書來作為訪問。所以當你需要多個AlwaysOn可用組的時候,你要記得共享相同的鏡像端點。
現在可以創建一個高可用的偵聽器服務,用於接受傳入到可用組的請求連接。偵聽器包含一個唯一虛擬IP地址和一個唯一虛擬網絡名。這是目前位置數據庫高可用組中最明顯的變動。
通過提供一個到可用組的集中的訪問點 ,客戶可以減輕在數據庫故障轉移過程中連接字符串配置方面的問題。可以通過只讀路由配置AlwaysOn組的副本,允許次要副本的數據庫支持只讀請求,從而移除在主副本中的並發問題。
通過AlwaysOn,你還可以選擇傳統的同步后者異步模式(和數據庫鏡像一樣),同步提交模式會在主庫事務傳輸到次要數據庫並把事務恢復到次要數據庫之后,主庫事務才提交。對於異步提交模式,如果主次兩副本的庫之間的會話被打斷,可能導致次要數據庫的事務丟失(也就是數據丟失)。同時,異步副本僅支持手動故障轉移,而同步模式支持自動或手動故障轉移。
對於偵測故障,可以使用AlwaysOn的【顯示面板】和SQL Server、Windows日志。而由向導驅動的部署是最簡單的方法,盡管會有很多用戶交互。盡管如此,基礎的AO組配置和配置依舊是相當簡單。
在你開始部署AlwaysOn可用組之前,首先必須啟用SQL Server實例上的這個功能,確保所有參與者都要啟用。同時這些節點實例都必須已經成功加入WSFC中。如下圖,可以在WSFC節點上的SQL Server配置管理器中啟用:
 
 
這一步需要重啟SQL Server實例。
 
 

部署可用組:

 
下面先在前面提到的5個節點中都安裝SQL Server,注意相同版本。在啟用了AlwaysOn組之后,可以開始部署了。我們使用的是獨立安裝SQL Server。為了速度,這里使用命令行安裝SQL Server。具體詳見:從命令提示符安裝 SQL Server 2014
加載完安裝文件之后,在cmd命令中,切換當前盤符到安裝文件所在的盤,本例是D盤。然后輸入以下命令執行即可,注意要有足夠的權限。安裝之后需要檢查一下是否合符條件,當然要是覺得麻煩也可以用圖形化安裝,只是交互操作略多。
如果用圖形化界面安裝請勾選上圖部分
 
 
另外,為了后續的批量操作,也先把所有服務器添加到注冊服務器中,注意關閉防火牆:
 
然后把SQL Server配置管理器中的AlwaysON 可用組開啟:
 
然后還原微軟示例數據庫AdventureWorks2014。然后在clusternode1的SSMS中,選擇“AlwaysOn高可用性”→右鍵下一級文件夾的“可用性組”→【新建可用性組向導】:
 
 
第一個界面:顯示了完成一次可用性組配置所需的內容。如果是第一次搭建,請先檢查是否滿足要求
 
注意:除此之外,你還需要跟相應的管理人員獲取足夠的賬號信息、虛擬網絡名和虛擬IP地址。
 
接下來定義一個AlwaysOn可用性組名。這個名字會成為在WSFC內創建的群集名,並且群集內必須唯一,然后選擇下一步:
 
 
然后會看到下圖,為了繼續進行,先手工修改恢復模式然后對數據庫做一次完整備份,然后刷新一下:
 
刷新之后就變成下圖:
 
 
在【指定副本】對話框中,可以看到向導已經幫你初始化了當前的SQL Server實例。在這里可以添加副本,也必須添加1~4(SQL 2012)/8(SQL 2014)個副本。
 
 
 
最后配置會是下圖樣子,但是目前,我們先不使用自動故障轉移,接下來點開【端點】選項頁:
 
 
 
下面開始端點的配置,如果你使用默認賬號安裝和配置SQL Server服務,可以看到下面端點配置:另外注意默認使用的端口號是5022(跟數據庫鏡像使用的一樣,但是可以改變)
 
當通過SQL Server配置管理器變更SQL Server服務帳號(比如改成localsystem),再在這個界面刷新並點下一步的時候就會出現下圖的警告:
 
為了方便搜索引擎搜索,下面把文字貼出:
中文: “端點”選項卡列出至少一個僅使用 Windows 身份驗證的端點。但是,該服務器實例可能正以某一非域帳戶運行。若要使用列出的端點,請將相應的 SQL Server 服務帳戶更改為域帳戶。若要繼續使用該非域帳戶,請更改該端點以便使用證書。
是否要使用列出的端點?
 
英文:
The Endpoints tab lists at least one endpoint that uses only Windows Authentication. However, the server instance might be running under a nondomain account. To use the listed endpoint, change the corresponding SQL Server service account to a domain account. To continue using the nondomain account, alter the endpoint to use a certificate. Do you want to use the listed endpoints?
對於這種警告,通常有兩種方式:
  1. 最合理:各節點使用同一個域賬號啟動SQL Server,可以使用較低權限的域用戶賬號。
  2. 權宜之計:在有些情況下,賬號並非隨你操作,所以你可以使用類似語句授權:
  1. GRANT CONNECT ON endpoint::hadr_endpoint  
  2. TO [domain\servername$]  
GRANT CONNECT ON endpoint::hadr_endpoint
TO [domain\servername$]
如果沒有端點,你還要手動創建:
  1. CREATE ENDPOINT [Hadr_endpoint]  
  2.     STATE=STARTED  
  3.     AS TCP (LISTENER_PORT = 5022, LISTENER_IP = ALL)  
  4.     FOR DATA_MIRRORING (ROLE = ALL  
  5. , AUTHENTICATION = WINDOWS NEGOTIATE  
  6. , ENCRYPTION = REQUIRED ALGORITHM AES)  
CREATE ENDPOINT [Hadr_endpoint]
    STATE=STARTED
    AS TCP (LISTENER_PORT = 5022, LISTENER_IP = ALL)
    FOR DATA_MIRRORING (ROLE = ALL
, AUTHENTICATION = WINDOWS NEGOTIATE
, ENCRYPTION = REQUIRED ALGORITHM AES)
但是基於很多原因,還是盡量使用相同的、有足夠權限的域賬號進行配置。關於這部分的內容可以查閱官方文檔:可用性組偵聽器和服務器主體名稱 (SPN)
 
必須由域管理員在 Active Directory 中為每個可用性組偵聽器名稱配置服務器主體名稱 (SPN),才能為到可用性組偵聽器的客戶端連接啟用 Kerberos。 注冊 SPN 時,必須使用托管可用性副本的服務器實例的服務帳戶。 對於跨所有副本工作的 SPN,必須為承載可用性組的 WSFC 群集中的所有實例使用相同的服務帳戶。 使用 Windows 命令行工具 setspn 配置 SPN。 例如,要為一組 SQL Server 實例上承載的名為 AG1listener.Adventure-Works.com 的可用性組配置 SPN,所有實例都應被配置為在域帳戶 corp/svclogin2下運行:
  1. setspn -A MSSQLSvc/AG1listener.Adventure-Works.com:1433 corp/svclogin2  
setspn -A MSSQLSvc/AG1listener.Adventure-Works.com:1433 corp/svclogin2
接下來是【備份首選項】,如下圖:
 
 
 
在這里可以選擇備份操作發生在什么副本中。這里我希望選擇節點4作為備份用的副本,可以像上圖那樣把排除副本勾選。然后轉到【偵聽器】頁。
在【偵聽器】頁,選擇之前配置好的偵聽器。如果之前沒創建,可以在這里創建,但是必須是唯一的虛擬網絡名,TCP端口和虛擬IP地址(如果沒有使用DHCP)。然后添加靜態IP。接下來選擇【添加】。最后選擇【下一步】。
 
 
 
 
 
在【選擇數據同步】界面中,選擇符合條件的同步模式,前面演示過,在初始化次要數據庫時,需要做完整備份和日志備份。由於前面已經做了,所以這里選擇【僅聯接】。下面簡單解釋一下:
  • FULL:完整,其字面解釋如下圖,這個選項要求完整和日志備份,並把備份還原到每個次要副本中。
  • Join Only:僅聯接,已經以【NORECOVERY】模式還原數據庫,這個選項直接把庫加入可用組中。
  • Skip initial data synchronisation:跳過初始化數據同步,這個選項可以讓你在完成向導之后還原數據庫和把次要副本加入AlwaysON可用性組中。
 
然后點擊下一步。在【驗證】對話框中會看到類似下圖樣子:
 
 
在沒有報錯的情況下,點擊下一步並完成創建AlwaysON可用性組的配置:
 
 
完成之后可以查看結果,如無問題可以點擊關閉,配置完成之后可以看到下圖樣子:
 
 
 
到目前為止,AlwaysON組已經成功創建。檢查WSFC的配置,可以看到一個新的群集角色和資源分配。這里的AlwaysON群集角色表名,有一個AlwaysON組和一個已群集的AlwaysON資源,使用的是在部署向導中定義的名字。對於偵聽器,我們分配了一個已群集的虛擬網絡名和虛擬IP地址。需要注意的是截至到SQL 2014為止,AlwaysON都要求所有參與節點基於同一個群集,因為如果不在同一個群集,那么在發生故障轉移的時候,又怎么轉移群集資源呢?
注意:不要嘗試去手動修改組的首選所有者或資源的可能所有者列表。任何這種修改都是徒勞無功的,因為這些在故障轉移過程中,依賴於副本配置,會動態變更AlwaysON組的群集配置。
 
 
 
 
如果想查詢當前AlwaysON組的主副本,可以使用下面的PowerShell命令實現:
  1. get-clusterresource -cluster "WindowsClusterName" | where-object{$_.ResourceType -ilike "SQL Server Availability Group"} | ft  
get-clusterresource -cluster "WindowsClusterName" | where-object{$_.ResourceType -ilike "SQL Server Availability Group"} | ft
注意替換上面的WindowsClusterName。
在完成之后,我們可以使用SSMS的界面進行手動故障轉移,或者使用下面的腳本進行手動故障轉移:
 
  1. ALTER AVAILABILITY GROUP [YourAG] FAILOVER  
ALTER AVAILABILITY GROUP [YourAG] FAILOVER

配置只讀路由:

 
在創建完帶有偵聽器的AlwaysON可用性組之后,可以配置只讀路由以便更好地管理只讀請求。在把客戶端的意向只讀請求重定位之前,必須先創建一個偵聽器。然后配置只讀路由列表用於訪問AlwaysON副本。在上面的部署過程中已經創建了偵聽器,所以現在可以開始配置只讀路由。下面的T-SQL代碼是用於在本機中配置,第一個代碼塊配置了一個次要角色用於可能被用來做只讀路由的各個副本之用。替換代碼中紅色部分,這些是SQL 實例名的路由URL,注意不是鏡像端點URL或者偵聽器URL:
 
ALTER AVAILABILITY GROUP [STOKEAG_1]MODIFY REPLICA ON
 N'STOKECSCLNODE1\INST1' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY)); ALTER AVAILABILITY GROUP [STOKEAG_1]MODIFY REPLICA ON  N'STOKECSCLNODE1\INST1' WITH(SECONDARY_ROLE (READ_ONLY_ROUTING_URL =N'TCP://stokecsclnode1.stokecs2.co.uk:58001')); ALTER AVAILABILITY GROUP [STOKEAG_1]MODIFY REPLICA ON N'STOKECSCLNODE2\INST1' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY)); ALTER AVAILABILITY GROUP [STOKEAG_1]MODIFY REPLICA ON  N'STOKECSCLNODE2\INST1' WITH(SECONDARY_ROLE (READ_ONLY_ROUTING_URL =N'TCP://stokecsclnode2.stokecs2.co.uk:58001')); ALTER AVAILABILITY GROUP [STOKEAG_1]MODIFY REPLICA ON N'STOKECSCLNODE3\INST1' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY)); ALTER AVAILABILITY GROUP [STOKEAG_1]MODIFY REPLICA ON N'STOKECSCLNODE3\INST1' WITH(SECONDARY_ROLE (READ_ONLY_ROUTING_URL =N'TCP://stokecsclnode3.stokecs2.co.uk:58001'));
比如我本機環境改成:
 
  1. ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON  
  2.  N'CLUSTERNODE1' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));  
  3.   
  4. ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON  
  5.  N'CLUSTERNODE1' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://CLUSTERNODE1.george.com:1433'));  
  6.   
  7. ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON  
  8.  N'CLUSTERNODE2' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));  
  9.   
  10. ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON  
  11.  N'CLUSTERNODE2' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://CLUSTERNODE2.george.com:1433'));  
  12.    
  13. ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON  
  14.  N'CLUSTERNODE3' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));  
  15.   
  16. ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON  
  17.  N'CLUSTERNODE3' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://CLUSTERNODE3.george.com:1433'));  
ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON
 N'CLUSTERNODE1' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));

ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON
 N'CLUSTERNODE1' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://CLUSTERNODE1.george.com:1433'));

ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON
 N'CLUSTERNODE2' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));

ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON
 N'CLUSTERNODE2' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://CLUSTERNODE2.george.com:1433'));
 
ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON
 N'CLUSTERNODE3' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));

ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON
 N'CLUSTERNODE3' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://CLUSTERNODE3.george.com:1433'));
 
 
下一步是指定在每個副本在作為主角色的時候路由首選項:
 
ALTER AVAILABILITY GROUP [STOKEAG_1]MODIFY REPLICA ON
 N'STOKECSCLNODE1\INST1'WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST = ('STOKECSCLNODE3\INST1', 'STOKECSCLNODE2\INST1', 'STOKECSCLNODE1\INST1'))); ALTER AVAILABILITY GROUP [STOKEAG_1]MODIFY REPLICA ON  N'STOKECSCLNODE2\INST1'WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST = ('STOKECSCLNODE3\INST1', 'STOKECSCLNODE1\INST1', 'STOKECSCLNODE2\INST1'))); ALTER AVAILABILITY GROUP [STOKEAG_1]MODIFY REPLICA ON N'STOKECSCLNODE3\INST1'WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST = ('STOKECSCLNODE2\INST1', 'STOKECSCLNODE1\INST1', 'STOKECSCLNODE3\INST1')));
本機改成:
 
  1.  ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON   
  2.  N'CLUSTERNODE1' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST = ('CLUSTERNODE3', 'CLUSTERNODE2', 'CLUSTERNODE1')));  
  3.   
  4. ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON   
  5.  N'CLUSTERNODE2' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST = ('CLUSTERNODE3', 'CLUSTERNODE1', 'CLUSTERNODE2')));  
  6.   
  7. ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON   
  8.  N'CLUSTERNODE3' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST = ('CLUSTERNODE2', 'CLUSTERNODE1', 'CLUSTERNODE3')));  
 ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON 
 N'CLUSTERNODE1' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST = ('CLUSTERNODE3', 'CLUSTERNODE2', 'CLUSTERNODE1')));

ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON 
 N'CLUSTERNODE2' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST = ('CLUSTERNODE3', 'CLUSTERNODE1', 'CLUSTERNODE2')));

ALTER AVAILABILITY GROUP GeorgeAG MODIFY REPLICA ON 
 N'CLUSTERNODE3' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST = ('CLUSTERNODE2', 'CLUSTERNODE1', 'CLUSTERNODE3')));
 
最后一段代碼配置每個指定的副本的主角色,包括你想分攤負載到read intent所需要連接的副本。通常需要配置所有的副本,但是也並不是強制的。如果指定了所有副本,理想情況下主副本應該作為路由列表的最后一個連接。術語“READ_ONLY_ROUTING_LIST”是從左到右枚舉,優先級也是從左到右。
現在只讀路由列表已經配置完成,可以通過偵聽器測試。主副本是節點1,然后使用一個SQLCMD並帶有意向只讀去查詢,可以看到當前實例名是節點三。
 
 
 
 
 
只讀路由配置看上去跟之前會有點混亂。實際上,一旦你確定需要的副本,那么這個腳本是很容易配置的。但是要注意的是,只讀URL是數據庫引擎本身的URL。不是數據庫鏡像端口URL或偵聽器URL。
 
 

掛起數據移動:

 
這個功能需求是非常常見的,AlwaysON組提供在主次副本層面上對加入AlwaysON數據庫進行數據移動掛起功能。在某些場景下會自動觸發這 種掛起。如果在AlwaysON環境下,主副本發生故障同時又沒有可用的“自動轉移”的次要副本,那么次要副本會進入“Resolving(正在解析)”狀態,這時候就要使用手動或者強制故障轉移到一個異步同步副本中。當執行強制轉移時,數據移動就會自動變成掛起,這時候要重新連接到新的異步主副本的數據庫。這個在接下來的測試環節會看到。
注意:當一個異步副本被強制作為主副本時,事務會發送到新的次要異步副本。
在主副本和次要副本之間掛起數據移動會停止數據同步。但是主副本的數據庫依舊聯機和可用。此時繁忙數據庫中的事務日志的增長就會成為隱患,所以在這種情況下要小心,哪怕配置合理。
在次要副本的數據移動掛起會使得其上面的數據庫狀態變成“未同步(Not Synchronising)”,並且次要數據庫會變成不可用。當恢復數據移動以后在主副本的積壓的日志會繼續同步到次要數據庫並使得次要數據庫恢復可用。
小心另外一個引起數據移動掛起的情況,當可用性組從SQL 2012的副本中轉移到一個高版本的副本,比如2014上時,和其他SQL Server高可用技術一樣,這種過程是不可逆的。不過這種方式可以用於數據庫從低版本遷移到高版本的情景。
 

測試故障轉移場景和觀察結果:

 
下面來測試一下我們的環境是否可用。一方面是測試搭建有沒有問題,另外一方面也可以作為以后在正式環境中校驗的步驟。
 

自動故障轉移:

 
允許自動故障轉移的前提是必須有最少兩個副本,且為同步模式,同時配置了自動故障轉移,否則只能使用手動故障轉移。在這里,使CLUSTERNODE3作為主副本,然后把CLUSTERNODE1作為同步、自動副本。然后把CLUSTERNODE3的網卡關閉,模擬硬件故障,然后理論上會發生自動故障轉移到CLUSTERNODE1中。
 
 
現在在CLUSTERNODE1中打開“故障轉移群集管理器”可以看到以下截圖:
 
 
然后通過Hyper-V控制台,把ClusterNode3這台虛擬機的網卡設為“未連接”,再在ClusterNode1中刷新故障轉移群集管理器的界面,可以看到下圖:
 
 
 
CLUSTERNODE1已經變成了主副本。同時群集管理器中的角色所有者也變成了CLUSTERNODE1。如果沒做任何干預就能實現上圖情況,那證明自動故障轉移沒有問題。然后我們把NODE3的網卡恢復。

手動和強制故障轉移:

 
當主副本出現故障並切換到同步或異步副本時,會被要求確認故障轉移向導過程中,必須接受數據丟失的風險。然后選擇作為主副本的副本進行接收事務。但是如果失敗的話怎么回滾?原理是什么?
在這個測試中,把可用性組全部設為非自動故障轉移模式,然后在當前主副本(NODE1)中關閉SQLSERVR.EXE進程,模擬軟件故障,此時AlwaysON會變成Resolving狀態,由於這個時候沒有自動故障轉移的伙伴副本存在,所以這種情況下主副本的故障是災難性的。
接下來,在Node4中,作為異步同步的副本,進行強制故障轉移,在轉移過程中,向導會提醒你會有潛在的數據丟失風險。
 
先把AlwaysON配置成以下樣子:
 
 
然后在NODE1中的任務管理器中終止SQL Server進程:
 
 
 
終止進程之后看到主節點已經失敗:
 
 
切換到NODE4,可以看到當前的可用性組的狀態為“正在解析”:
 
在NODE4中的可用性組,右鍵選擇故障轉移,可以看到下面嘆號:
 
 
下一步中有明確的數據丟失風險警告:
 
 
 
轉移成功后,可以看到NODE4中的狀態變成了“主要”:
 
 
同時,在故障轉移群集管理器中可以看到所有者節點現在也變成餓了ClusterNode4:
 
 
從顯示面板看,其他節點均為“未同步”狀態:
 
 
最后我們可以看到次要副本的數據庫是暫停狀態的,也就是掛起了數據移動:
 
 
右鍵數據庫選擇“”:
 
 
在同步完畢之后,數據就變得無丟失。
 
 
 

在故障轉移過程中群集角色資源狀態:

 
有個值得看一下的現象,在故障轉移過程中的群集角色的資源狀態。當把AlwaysOn組故障轉移到一個手動同步的節點時,會修改首選群集角色的所有者到這個節點上。此外在 AlwaysOn 資源上的可能所屬者的列表也設置為只有該節點。比如,下面的情景。當前的AlwaysOn組的主副本活動在節點1,而主副本是同步模式並且手動故障轉移。然后我們看看群集角色和AlwaysOn資源的所有者列表:
 
 
當我們把主節點failover到NODE3之后,再檢查:
 
當AlwaysOn設置為有同步副本且自動故障轉移之后,資源列表又變得不同了。這里重新設置NODE3/4兩個為同步、自動故障轉移,然后再次查看:
 
 
注意:這些屬性都是動態管理的,所以沒有必要干預。

總結:

 
本節延時了AlwaysON可用性組的創建、配置和使用。同時測試了故障轉移的情況。這一節是本系列最重要的一節,希望能反復練習。
在翻譯和實操的過程中,感覺對讀者的實操能力提升並沒有多大的好處,最起碼對於我,所以我想在這個系列過程中插入一篇從0開始搭建整個AlwaysOn的演示文章,文章里面不打算解釋過多,主要以step by step為主。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM