2023年12月29日 星期五

如何在 SQL SERVER 標準版上架設 AlwaysOn 的唯讀複本-超級省錢架構

        在 SQL SERVER 的標準版,AlwaysOn 基本上只有支援二個節點,只有 SQL SERVER 企業版才有與作業系統的節點數量有相同的支援,而且標準版的第二個節點,無法設定為唯讀複本,所以如果要設定唯讀複本時,只能升級到企業版。

Editions and supported features of SQL Server 2019
https://learn.microsoft.com/en-us/sql/sql-server/editions-and-components-of-sql-server-2019?view=sql-server-ver16

許多公司由於在標準版與企業版在價格上的差異,許多企業版的功能上並沒有使用到,所以仍會先採用 SQL SERVER 標準版進行,但問題來了,如果希望增加一個節點來進行唯讀分攤負載時,除了升級到企業版之外,本篇就來提供一個不同的方式給大家參考。

SQL Server 2022 pricing and licensing
https://www.microsoft.com/en-us/sql-server/sql-server-2022-pricing

本篇我會透過 SQL SERVER AlwasyOn 標準版與交易式複寫(Transaction Replication)來達到上述的需求,在這個架構下,重點就是當 AlwaysOn 進行角色轉移 (Failover) 後,如何讓原本的交易式複寫仍可以正常的運作,就是本篇介紹的重點。

在介紹之前,我還是要先說一下這個架構的缺點,大家可以再考慮後是否合適,再進行考慮。

  • 無法透過 AlwaysOn Listener 進行讀寫/唯讀的路由。
  • 唯讀複本由於是透過交易式複寫進行,所以該節點不是真的唯讀,當用戶端不小心將資料寫入至該節點的話,造成資料衝突時,只能重新進行交易式複寫的設定(打掉重作)。
  • 如果在後續資料傳輸過慢的問題需進行排除時,由於多重的架構,所以比較不容易查出問題瓶頸,但大神們可以忽略此問題。
  • 管理時,需同時確認 AlwaysOn 與交易式複寫的情況,無法單純的透過 AlwaysOn 的 Dashboard 進行確認。

環境說明:

  • SQLAGNode1: Windows 2019 + SQL Server 2019 Standard
  • SQLAGNode2: Windows 2019 + SQL Server 2019 Standard
  • SQLRep1: Windows 2019 + SQL Server 2019 Standard

複寫角色對應:

  • 散發 (Distribution): SQLRep1
  • 發行 (Publishing): SQLAGNode1 + SQLAGNode2
  • 訂閱 (Subscription): SQLRep1

開始安裝設定:

1. 一開始請先依照先前的文件,將 SQLAGNode1 + SQLAGNode2 設定安裝 SQL SERVER,並啟用 AlwaysOn 的功能,最後也建議進行 Failover 測試確認可以正常的完成節點的切換。

SQL Server 2012 新功能 - AlwaysOn安裝與設定
https://caryhsu.blogspot.com/2012/04/sql-server-2012-alwayson.html


2. 設定散發主機 (SQLRep1)

散發的部份一樣可以設定在不同的主機上,此部份是與訂閱者設定在同一台的機器上。

2-1 請將第三台主機(SQLRep1)安裝好 SQL SERVER 單機環境,而且安裝時需增加勾選 SQL Server Replication 的功能。

2-2 安裝完成後,加入同網域,不用加入叢集,也不用加入 AlwaysOn 中(也無法加入,因為 SQL Server 標準版的限制)。

2-3 設定散發初使設定。









2-4 由於二台發行的資料,都要透過散發來進行,所以在此主機上,要手動設定散發並指定二台發行可以透過此台主機進行散發。



3. 設定第一台發行集

這個需確認 AlwaysOn 的主要節點在那一台上,目前假設在 SQLAGNode1,所以我們就以此台進行。

3-1 新增發行集,基本上動作都相同,只是在散發主機的部份,必須指定到 SQLRep1。














3-2 第二台的發行集不用特別設定,當進行 Failover 時,你就會發現該發行會切換到第二台上。


4. 設定訂閱者 (SQLRep1)

這部份只需注意先指定到主要節點的部份,目前假設在 SQLAGNode1上。












5. 這時候已完成初步的可讀複本的部份,請先嘗試新增一筆資料至主要節點中,目前假設在 SQLAGNode1上,然後確認可以正確的將資料複寫至 SQLRep1 的節點中。


6. 設定重新導向發行端於散發主機上 (SQLRep1)


在散發主機上,執行下列的語法,主要就是將目前指定到第一台的發行,重新導向,指定到 SQL Server Listener上。

USE distribution;  

GO  

EXEC sp_redirect_publisher   

@original_publisher = 'SQLAGSTD1',  

@publisher_db = 'carytestdb',  

@redirected_publisher = 'sqlstdaglst';

7. 測試 Failover 後,確認是否可以正常的透過複寫將資料寫到訂閱端。

此時,我們第二台其實都還沒有設定發行端,但其實你在主要節點進行 Failover 切換後,您就會發現訂閱就會顯示在第二台的節點上,所以您可以嘗試在第二台也新增資料,確認資料也是有複寫到訂閱端,這樣就都完成了。

最後補充,許多文章提到可以透過 sys.sp_validate_replica_hosts_as_publishers 進行驗證,但因為驗證時,會同時到主節點與備援節點進行確認,而由於 SQL SERVER 標準版 上的第二個節點是無法設定為可讀取的,所以如果有遇到下列的錯誤,其實是可以忽略的。

USE distribution;  

GO

EXEC sys.sp_validate_replica_hosts_as_publishers  

    @original_publisher = 'SQLAGSTD1',  

    @publisher_db = 'carytestdb',  

    @redirected_publisher = 'sqlstdaglst';

錯誤訊息:

OLE DB provider "MSOLEDBSQL" for linked server "[F9C2EDD8-1050-488F-97D3-BD64AFE91CCA]" returned message "Deferred prepare could not be completed.".

Msg 21899, Level 11, State 1, Procedure sys.sp_hadr_verify_subscribers_at_publisher, Line 109 [Batch Start Line 2]

The query at the redirected publisher 'SQLAGSTD1' to determine whether there were sysserver entries for the subscribers of the original publisher 'SQLAGSTD1' failed with error '976', error message 'Error 976, Level 14, State 1, Message: The target database, 'carytestdb', is participating in an availability group and is currently not accessible for queries. Either data movement is suspended or the availability replica is not enabled for read access. To allow read-only access to this and other databases in the availability group, enable read access to one or more secondary availability replicas in the group.  For more information, see the ALTER AVAILABILITY GROUP statement in SQL Server Books Online.'.

One or more publisher validation errors were encountered for replica host 'SQLAGSTD1'.

2023年12月27日 星期三

如何設定 SQL Server Merge Replication 透過 HTTPS/SSL 進行遠端同步

        SQL SERVER 合併式複寫,可以讓二台 SQL Server 進行資料的同步,此技術非常的適合許多跨地區的資料庫進行,通常許多公司會透過 VPN 的方式進行綁定不同的網路(路由),所以其實基本上還是有互通的,所以當資料庫同步時,都是通過預設的 1433 Port 進行同步,但如果彼此之間因為網路的不同時,如果要進行資料同步時,由於異質網路的關於,所以就需要在防火牆開啟 1433 Port,這對許多公司的政策都是不允許的,因為會有安全性的問題。

本篇介紹的,就是要解決這個問題,其實就是散發的資料/數據,透過網頁 HTTPS/SSL 進行同步的動作,本篇測試時雖然有許多參考資料,但其實在自已進行測試時,你會發現有許多的問題,所以我才會特別的整理此篇,希望提供給大家參考。

環境說明:

  • SQL Server 2019 為發行與散發
  • SQL Server 2017 為訂閱端

在選擇 IIS 進行同步的部份,基本上可以不用與 SQL Server 在同一台上,但此次我是與 SQL Server 設定在同一台上進行。

1. 預用 Web Server (IIS) 的功能,在啟用時,除了預設的項目外,也需要啟用下列的項目。

  • Web Server (IIS) -> Web Server -> Security -> Basic Authentication 
  • Web Server (IIS) -> Web Server -> Application Development -> .Net Extensibility 3.5
  • Web Server (IIS) -> Web Server -> Application Development -> .Net Extensibility 4.7
  • Web Server (IIS) -> Web Server -> Application Development -> ISAPI Extensions
  • Web Server (IIS) -> Web Server -> Application Development -> ISAPI Filters 


2. 設定 Web 複寫目錄

在設定 Web Synchronization 的部份,其實也是可以透過 SSMS 的工具來進行設定,但在設定後發現仍有問題,而且其中有一些限制,所以我還是手把手的逐一設定,至少那一個部份有錯,也比較好找出錯誤的部份,下列是一些例圖,所以大家在參考一下就好,當然要用這個進行也是可以的。


2-1 IIS 啟用後,請在下列的位置下新增一個目錄,名稱為 "SQLReplication"

C:\inetpub\wwwroot\

請盡可能的將資料夾建立在此,要不然後面要設定相關的安全性,問題有點多會不好排除問題。

2-2 我的 SQL Server 版本為 2019,所以請至下列的目錄,將 "replisapi.dll" 的檔案複制到 2-1 中的 "SQLReplication" 中。

C:\Program Files\Microsoft SQL Server\150\COM\

由於 SQL Server 2019 為 64位元,所以此元件也是 64 位元的,這 "非常" "非常" "非常" 的重要,千萬不要搞錯了。

2-3 請透過系統管理者的權限開啟一個 Dos Command 視窗後,然後輸入下列的指令註冊此元件。

regsvr32 C:\inetpub\wwwroot\SQLReplication\replisapi.dll

3. 設定 IIS 站台目錄

3-1 請先確認 IIS 的預設站台可以正常瀏覽。

https://cary-sql2019/iisstart.htm

3-2 新增一個目錄針對此 SQLReplication

3-3 新增時,請點選 "Test Settings" 確認沒有任何的錯誤。

4. 設定 IIS 站台目錄(SQLRrplication) 啟用 HTTPS/SSL 的功能,這部份可以透過申請的 SSL 憑證或憑證伺服器進行,但這部份我透過自我簽署的憑證進行。

4-1 請至 主機 -> Server Certificates -> Create Self-Signed Certificates


4-2 請至預設站台 (Default Web Site) -> Bindings -> Add -> https

4-3 設定 SSL Settings,勾選 Require SSL 的設定,當使用者存取網頁都必須透過 HTTPS/SSL 進行存取。


5. 設定站台目錄(SQLRrplication)的驗證項目,為了安全性,所以必須啟用 Basic Authentication,並停用 Anonymous Authentication。

6. 設定 replisapi.dll 模組對應至此站台目錄(SQLReplication)中。


7. 測試是否可以正常的執行模組 (replisapi.dll)

https://cary-sql2019/SQLReplication/replisapi.dll

https://cary-sql2019/SQLReplication/replisapi.dll?diag

請確認 "Class Initialization test" 的狀態 (Status) 都是 SUCCESS 而且沒有任何的錯誤,要不然後續在進行同步時,會有問題。

8. 由於是自我簽署的憑證,所以在訂閱端透過瀏覽器進行訪問時,會出現如下列的錯誤訊息,所以一定要把憑證匯出從 IIS 端後,再匯入至用戶端(訂閱端),確認此錯誤訊息不會出現,要不然後續進行資料同步時,就會發生問題。

8-1 憑證匯出

請至 IIS -> Server Certificates -> Export,建議設定密碼進行保護。

8-2 憑證匯入

請將匯出的憑證複制至用戶端(訂閱端),然後選擇 "Install PFX"


匯入的位置,請手動選擇,將憑證匯入至 "Trusted Root Certification Authorities" 中即可,我選擇第一項時,其實無效,透過瀏覽器確認時,仍有錯誤,所以請選擇手動匯入。

另外在匯入時,選擇 Current User or Local Machine 都可以,我這邊是選擇匯入至 Current User.

完成上述的設定後,基本上就完成大半部,後續的複寫的部份,簡單的透過介面進行 SQL Replication 的建立就可以了。

9. 建立合併式複寫 (Merge Replication) 的發行與散發的部份,這部份沒有特別需要注意的,所以我就不特別截圖說明。

10. 針對剛剛建立好的合併式複寫設定 Web Synchronization 的功能,請將網址填入至下列的欄位中。

11. 建立訂閱端設定,基本上也透過介面進行設定,我就將特別的幾個畫面整理如下。

11-1 請選擇 pull subscriptions 的方式

11-2 請勾選 Use Web Synchronization 的方式

11-3 設定透過 Web Synchronization 時,相關的設定

12. 設定完成,可以發現在同步後,可以透過訂閱端上的 SQL Agent -> Job History 來進行確認,訂閱端是如何進行同步,如下列的資訊。


Date 12/26/2023 5:44:38 PM

Log Job History (CARY-SQL2019-db-replication-nodomain-replication-WIN-VB0R8UQVUA2-db-replication- 0)


Step ID 1

Server WIN-VB0R8UQVUA2

Job Name CARY-SQL2019-db-replication-nodomain-replication-WIN-VB0R8UQVUA2-db-replication- 0

Step Name Run agent.

Duration 00:00:01

Retries Attempted 0


Message

-XSERVER WIN-VB0R8UQVUA2

-XCMDLINE 0

-XCancelEventHandle 0000000000001ADC

-XParentProcessHandle 0000000000001CE4

2023-12-26 09:44:38.896 Connecting to Subscriber 'WIN-VB0R8UQVUA2'

2023-12-26 09:44:38.943 The upload message to be sent to Publisher 'CARY-SQL2019' is being generated

2023-12-26 09:44:38.943 The merge process is using Exchange ID '947521E2-682C-429A-B87A-8CD68F331656' for this web synchronization session.

2023-12-26 09:44:38.990 Uploading data changes to the Publisher

2023-12-26 09:44:39.068 No data needed to be merged.

2023-12-26 09:44:39.068 Request message generated, now making it ready for upload.

2023-12-26 09:44:39.068 Upload request size is 2058 bytes.

2023-12-26 09:44:39.397 Uploaded a total of 1 chunks.

2023-12-26 09:44:39.397 The request message was sent to 'https://cary-sql2019/SQLReplication/replisapi.dll'

2023-12-26 09:44:39.397 Downloaded a total of 3 chunks.

2023-12-26 09:44:39.397 The response message was received from 'https://cary-sql2019/SQLReplication/replisapi.dll' and is being processed.

2023-12-26 09:44:39.397 Connecting to Subscriber 'WIN-VB0R8UQVUA2'

2023-12-26 09:44:39.412 The changes contained in the message downloaded from Publisher 'CARY-SQL2019' will be applied after having collected and displayed the upload statistics.

2023-12-26 09:44:39.412 Downloading data changes to the Subscriber

2023-12-26 09:44:39.694 [100%] Downloaded 1 change(s) in 'test-db1' (1 insert): 1 total

2023-12-26 09:44:39.709 [100%] Web synchronization progress: 99% complete.

=============================================================


Article Download Statistics:

============================


test-db1:

Inserts: 1

Relative Cost: 100.00%


Session Statistics:

============================

Download Inserts: 1


Change Delivery Time: 0 sec

Schema Change and Bulk Insert Time: 0 sec

Delivery Rate: 0.00 rows/sec

Total Session Duration: 0 sec


=============================================================

2023-12-26 09:44:39.709 Connecting to Subscriber 'WIN-VB0R8UQVUA2'

2023-12-26 09:44:39.709 The upload message to be sent to Publisher 'CARY-SQL2019' is being generated

2023-12-26 09:44:39.709 The merge process is using Exchange ID '63480F83-5715-4207-8BF7-9E94D78F0A86' for this web synchronization session.

2023-12-26 09:44:39.756 Uploading data changes to the Publisher

2023-12-26 09:44:39.756 [100%] Request message generated, now making it ready for upload.

2023-12-26 09:44:39.756 [100%] Upload request size is 2073 bytes.

2023-12-26 09:44:39.803 [100%] Uploaded a total of 1 chunks.

2023-12-26 09:44:39.803 [100%] The request message was sent to 'https://cary-sql2019/SQLReplication/replisapi.dll'

2023-12-26 09:44:39.803 [100%] Downloaded a total of 3 chunks.

2023-12-26 09:44:39.803 [100%] The response message was received from 'https://cary-sql2019/SQLReplication/replisapi.dll' and is being processed.

2023-12-26 09:44:39.803 Connecting to Subscriber 'WIN-VB0R8UQVUA2'

2023-12-26 09:44:39.819 The changes contained in the message downloaded from Publisher 'CARY-SQL2019' will be applied after having collected and displayed the upload statistics.

2023-12-26 09:44:39.819 [100%] Downloading data changes to the Subscriber

2023-12-26 09:44:39.819 [100%] Web synchronization progress: 99% complete.

2023-12-26 09:44:39.834 [100%] Merge completed after processing 1 data change(s) (1 insert(s), 0 update(s), 0 delete(s), 0 conflict(s)).

=============================================================


Article Download Statistics:

============================


test-db1:

Inserts: 1

Relative Cost: 100.00%


Session Statistics:

============================

Download Inserts: 1

Change Delivery Time: 0 sec

Schema Change and Bulk Insert Time: 0 sec

Delivery Rate: 0.00 rows/sec

Total Session Duration: 0 sec

=============================================================