使用指令碼設定連結 - Azure SQL 受控執行個體

適用於:Azure SQL 受控執行個體

本文教會您如何使用 Transact-SQL 和 PowerShell 或 Azure CLI 指令碼來設定 SQL Server 與 Azure SQL 受控執行個體之間的連結。 透過連結,來自初始主要複本的資料庫會以近乎即時的方式複寫到次要複本。

在建立連結之後,您就可以容錯移轉至次要複本,以便進行移轉或災害復原。

注意

概觀

使用連結功能,將資料庫從初始主複本複寫到次要複本。 針對 SQL Server 2022,初始主要複本可以是 SQL Server 或 Azure SQL 受控執行個體。 針對 SQL Server 2019 與舊版,初始主要複本必須是 SQL Server。 在設定連結之後,會將初始主要複本的資料庫複寫到次要複本。

您可選擇在主要與次要複本之間的混合式環境保留連結以便連續複寫資料,也可將資料庫容錯移轉至次要複本、移轉至 Azure 或進行災害復原。 針對 SQL Server 2019 與舊版,容錯移轉至 Azure SQL 受控執行個體會中斷連結,且不支援容錯回復。 當使用 SQL Server 2022 時,您可以選擇維護連結,在兩個復本之間來回容錯回復 - 此功能目前處於預覽狀態。

如果您打算僅使用次要受控執行個體進行災害復原,您可藉由啟用混合式容錯移轉權益來節省授權成本。

使用本文指示,在 SQL Server 與 Azure SQL 受控執行個體之間手動設定連結。 在建立連結之後,來源資料庫就會在目標次要複本產生唯讀複本。

提示

  • 為簡化搭配您環境的正確參數使用 T-SQL 指令碼,強烈建議使用 SQL Server Management Studio (SSMS) 中的受控執行個體連結精靈產生指令碼以建立連結。 在 [新增受控執行個體連結] 視窗的 [摘要] 頁面上,選取 [指令碼] 而不是 [完成]。

必要條件

注意

連結的部分功能已正式推出,但某些功能目前仍為預覽版。 檢閱版本支援性以便深入瞭解。

若要複寫您的資料庫,必須符合下列必要條件:

請考慮下列事項:

  • 連結功能針對每個連結支援一個資料庫。 若要複寫一個執行個體上的多個資料庫,請針對每個資料庫建立一個連結。 例如,若要將 10 個資料庫複寫到 SQL 受控執行個體,請建立 10 個連結。
  • SQL Server 與 SQL 受控執行個體之間的定序應該相同。 定序中的不符可能會導致伺服器名稱大小寫不符,而無法成功從 SQL Server 連線到 SQL 受控執行個體。
  • 初始 SQL Server 主要備份錯誤 1475 表示您必須建立完整備份而不使用 COPY ONLY 選項來啟動新的備份鏈結。

權限

在 SQL Server 上,您應具備 sysadmin 權限。

在 Azure SQL 受控執行個體上,您應為 SQL 受控執行個體參與者的成員,或具備自訂角色的下列權限:

Microsoft.Sql/ resource 必要權限
Microsoft.Sql/managedInstances /read、/write
Microsoft.Sql/managedInstances/hybridCertificate /動作
Microsoft.Sql/managedInstances/databases /read、/delete、/write、/completeRestore/action、/readBackups/action、/restoreDetails/read
Microsoft.Sql/managedInstances/distributedAvailabilityGroups /read、/write、/delete、/setRole/action
Microsoft.Sql/managedInstances/endpointCertificates /read
Microsoft.Sql/managedInstances/hybridLink /read、/write、/delete
Microsoft.Sql/managedInstances/serverTrustCertificates /write、/delete、/read

詞彙和命名慣例

當您執行本使用者指南中的指令碼時,請務必不要將 SQL Server 和 SQL 受控執行個體名稱誤認為其完整網域名稱 (FQDN)。 下表說明各種名稱確切代表的意思,以及如何取得其值:

詞彙 Description 查明方式
初始主要複本 1 您一開始建立連結以將資料庫複寫至次要複本的 SQL Server 或 SQL 受控執行個體。
主要複本 目前裝載主要資料庫的 SQL Server 或 SQL 受控執行個體。
次要複本 從目前主要復本接收近乎即時的複寫資料的 SQL Server 或 SQL 受控執行個體。
SQL Server 名稱 簡短、單字詞的 SQL Server 名稱。 例如:sqlserver1 從 T-SQL 執行 SELECT @@SERVERNAME
SQL Server FQDN SQL Server 的完整網域名稱 (FQDN)。 例如:sqlserver1.domain.com 如果您使用 Azure 虛擬機器 (VM),請參閱您的內部部署網路 (DNS) 設定或伺服器名稱。
SQL 受控執行個體名稱 簡短、單字詞的 SQL 受控執行個體名稱。 例如:managedinstance1 請參閱 Azure 入口網站中的受控執行個體名稱。
SQL 受控執行個體 FQDN SQL 受控執行個體的完整網域名稱 (FQDN)。 例如:managedinstance1.6d710bcf372b.database.windows.net 請參閱 Azure 入口網站中 SQL 受控執行個體概觀頁面上的主機名稱。
可解析的網域名稱 可解析為 IP 位址的 DNS 名稱。 例如,執行 nslookup sqlserver1.domain.com 應傳回 IP 位址,例如 10.0.0.1。 從命令提示字元執行 nslookup 命令。
SQL Server IP SQL Server 的 IP 位址。 如果 SQL Server 有多個 IP,請選擇可從 Azure 存取的 IP 位址。 在執行 SQL Server 的主機 OS 中,從命令提示字元執行 ipconfig 命令。

1 將 Azure SQL 受控執行個體設為初始主要複本目前處於預覽狀態,且僅從 SQL Server 2022 CU10 開始提供支援。

設定資料庫復原和備份

如果您的初始主要複本為 SQL Server,則透過連結複寫的資料庫必須處於完整復原模式,且至少有一個備份。 由於 Azure SQL 受控執行個體會自動進行備份,如果 SQL 受控執行個體是您的初始主要複本,請略過此步驟。 主要

針對您想要複寫的所有資料庫,在 SQL Server 上執行下列程式碼。 將 <DatabaseName> 取代為實際的資料庫名稱。

-- Run on SQL Server
-- Set full recovery model for all databases you want to replicate.
ALTER DATABASE [<DatabaseName>] SET RECOVERY FULL
GO

-- Execute backup for all databases you want to replicate.
BACKUP DATABASE [<DatabaseName>] TO DISK = N'<DiskPath>'
GO

如需詳細資訊,請參閱建立完整資料庫備份

注意

此連結僅支援使用者資料庫的複寫。 不支援系統資料庫的複寫。 若要複寫執行個體層級物件 (儲存在 mastermsdb 資料庫中),建議您透過指令碼找出這些物件,並在目的地執行個體上執行 T-SQL 指令碼。

在執行個體之間建立信任

首先,您必須在兩個執行個體之間建立信任,並保護用來跨網路通訊和加密資料的端點。 分散式可用性群組會使用現有可用性群組的資料庫鏡像端點,而不是擁有自己的專用端點。 因此,必須透過可用性群組資料庫鏡像端點,在兩個執行個體之間設定安全性和信任。

注意

連結以一律開啟可用性群組技術為基礎。 資料庫鏡像是特殊目的之端點,專門由可用性群組用來接收其他伺服器執行個體的連線。 資料庫鏡像端點一詞不應與舊版 SQL Server 資料庫鏡像功能誤用。

憑證式信任是保護 SQL Server 和 SQL 受控執行個體之資料庫鏡像端點的唯一支援方式。 如果您有使用 Windows 驗證的現有可用性群組,您必須將憑證式信任新增至現有的鏡像端點作為次要驗證選項。 如本文稍後所示,您可以使用 ALTER ENDPOINT 陳述式來完成這項作業。

重要

系統會產生具有到期日期和時間的憑證。 這些憑證必須在到期前更新並輪替。

以下列出了保護 SQL Server 和 SQL 受控執行個體上資料庫鏡像端點的程序概觀:

  1. 在 SQL Server 上產生憑證,並取得其公開金鑰。
  2. 取得 SQL 受控執行個體憑證的公開金鑰。
  3. 在 SQL Server 與 SQL 受控執行個體之間交換公開金鑰。
  4. 將 Azure 信任的根憑證授權單位金鑰匯入至 SQL Server

下列各節會詳細描述這些步驟。

在 SQL Server 上建立憑證,並將其公開金鑰匯入至 SQL 受控執行個體

首先,如果 master 資料庫中還沒有資料庫主要金鑰,請建立一個。 在以下指令碼中插入您的密碼代替 <strong_password>,並將密碼存放在機密且安全的地方。 在 SQL Server 上執行此 T-SQL 指令碼:

-- Run on SQL Server
-- Create a master key encryption password
-- Keep the password confidential and in a secure place
USE MASTER
IF NOT EXISTS (SELECT * FROM sys.symmetric_keys WHERE symmetric_key_id = 101)
BEGIN
    PRINT 'Creating master key.' + CHAR(13) + 'Keep the password confidential and in a secure place.'
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<strong_password>'
END
ELSE
    PRINT 'Master key already exists.'
GO

然後,在 SQL Server 上產生驗證憑證。 在下列指令碼中,取代:

  • @cert_expiry_date 取代為所需憑證到期日 (未來日期)。

記錄此日期並設定提醒,以便在 SQL Server 憑證到期日期之前輪替 (更新),確保連結能夠持續作業。

重要

強烈建議您使用從此指令碼自動產生的憑證名稱。 雖然允許在 SQL Server 上自訂您自己的憑證名稱,但此名稱不應包含任何 \ 字元。

-- Create the SQL Server certificate for the instance link
USE MASTER

-- Customize SQL Server certificate expiration date by adjusting the date below
DECLARE @cert_expiry_date AS varchar(max)='03/30/2025'

-- Build the query to generate the certificate
DECLARE @sqlserver_certificate_name NVARCHAR(MAX) = N'Cert_' + @@servername  + N'_endpoint'
DECLARE @sqlserver_certificate_subject NVARCHAR(MAX) = N'Certificate for ' + @sqlserver_certificate_name
DECLARE @create_sqlserver_certificate_command NVARCHAR(MAX) = N'CREATE CERTIFICATE [' + @sqlserver_certificate_name + '] ' + char (13) +
'    WITH SUBJECT = ''' + @sqlserver_certificate_subject + ''',' + char (13) +
'    EXPIRY_DATE = '''+ @cert_expiry_date + ''''+ char (13)
IF NOT EXISTS (SELECT name from sys.certificates WHERE name = @sqlserver_certificate_name)
BEGIN
    PRINT (@create_sqlserver_certificate_command)
    -- Execute the query to create SQL Server certificate for the instance link
    EXEC sp_executesql @stmt = @create_sqlserver_certificate_command
END
ELSE
    PRINT 'Certificate ' + @sqlserver_certificate_name + ' already exists.'
GO

然後,在 SQL Server 上使用下列 T-SQL 查詢來確認已建立憑證:

-- Run on SQL Server
USE MASTER
GO
SELECT * FROM sys.certificates WHERE pvt_key_encryption_type = 'MK'

在查詢結果中,您會看到該憑證已使用主要金鑰進行加密。

現在,您可以取得 SQL Server 上所產生憑證的公開金鑰:

-- Run on SQL Server
-- Show the name and the public key of generated SQL Server certificate
USE MASTER
GO
DECLARE @sqlserver_certificate_name NVARCHAR(MAX) = N'Cert_' + @@servername  + N'_endpoint'
DECLARE @PUBLICKEYENC VARBINARY(MAX) = CERTENCODED(CERT_ID(@sqlserver_certificate_name));
SELECT @sqlserver_certificate_name as 'SQLServerCertName'
SELECT @PUBLICKEYENC AS SQLServerPublicKey;

儲存輸出中的 SQLServerCertNameSQLServerPublicKey 值,因為您將在下一個步驟匯入憑證時需要這項資訊。

首先,請確定您已登入 Azure,並已選取裝載受控執行個體的訂用帳戶。 如果您的帳戶有多個 Azure 訂用帳戶,選取正確的訂用帳戶特別重要。

<SubscriptionID> 取代為您的 Azure 訂用帳戶 ID。

# Run in Azure Cloud Shell (select PowerShell console)

# Enter your Azure subscription ID
$SubscriptionID = "<SubscriptionID>"

# Login to Azure and select subscription ID
if ((Get-AzContext ) -eq $null)
{
    echo "Logging to Azure subscription"
    Login-AzAccount
}
Select-AzSubscription -SubscriptionName $SubscriptionID

然後使用 New-AzSqlInstanceServerTrustCertificate PowerShell 或 az sql mi partner-cert create Azure CLI 命令,將驗證憑證的公開金鑰從 SQL Server 上傳至 Azure,例如下列 PowerShell 範例。

填寫必要的使用者資訊,複製、貼上這些資訊,然後執行指令碼。 將:

  • <SQLServerPublicKey> 取代為二進位格式的 SQL Server 憑證公開部分,這是您在上一個步驟中記錄的資訊。 這是開頭為 0x 的長字串值。
  • <SQLServerCertName> 取代為您在上一個步驟中記錄的 SQL Server 憑證名稱。
  • <ManagedInstanceName> 取代為您的受控執行個體簡短名稱。
# Run in Azure Cloud Shell (select PowerShell console)
# ===============================================================================
# POWERSHELL SCRIPT TO IMPORT SQL SERVER PUBLIC CERTIFICATE TO SQL MANAGED INSTANCE
# ===== Enter user variables here ====

# Enter the name for the server SQLServerCertName certificate – for example, "Cert_sqlserver1_endpoint"
$CertificateName = "<SQLServerCertName>"

# Insert the certificate public key blob that you got from SQL Server – for example, "0x1234567..."
$PublicKeyEncoded = "<SQLServerPublicKey>"

# Enter your managed instance short name – for example, "sqlmi"
$ManagedInstanceName = "<ManagedInstanceName>"

# ==== Do not customize the below cmdlets====

# Find out the resource group name
$ResourceGroup = (Get-AzSqlInstance -InstanceName $ManagedInstanceName).ResourceGroupName

# Upload the public key of the authentication certificate from SQL Server to Azure.
New-AzSqlInstanceServerTrustCertificate -ResourceGroupName $ResourceGroup -InstanceName $ManagedInstanceName -Name $CertificateName -PublicKey $PublicKeyEncoded 

此作業的結果會是已上傳至 Azure 的 SQL Server 憑證摘要。

如果需要查看上傳至受控執行個體的所有 SQL Server 憑證,請在 Azure Cloud Shell 中使用 Get-AzSqlInstanceServerTrustCertificate PowerShell 或 az sql mi partner-cert list Azure CLI 命令。 若要移除上傳至 SQL 受控執行個體的 SQL Server 憑證,請在 Azure Cloud Shell 中使用 Remove-AzSqlInstanceServerTrustCertificate PowerShell 或 az sql mi partner-cert delete Azure CLI 命令。

從 SQL 受控執行個體取得憑證公開金鑰,並將其匯入至 SQL Server

保護連結端點的憑證會在 Azure SQL 受控執行個體上自動產生。 從 SQL 受控執行個體取得憑證公開金鑰,並使用 Get-AzSqlInstanceEndpointCertificate PowerShell 或 az sql mi endpoint-cert show Azure CLI 命令將其匯入 SQL Server,例如下列 PowerShell 範例。

警告

使用 Azure CLI 時,您若在後續步驟中使用 PublicKey 輸出,必須手動新增 0x 至 PublicKey 輸出的前端。 例如,PublicKey 看起來會像 “0x3082033E30...”。

執行下列指令碼。 將:

  • <SubscriptionID> 取代為您的 Azure 訂閱識別碼。
  • <ManagedInstanceName> 取代為您的受控執行個體簡短名稱。
# Run in Azure Cloud Shell (select PowerShell console)
# ===============================================================================
# POWERSHELL SCRIPT TO EXPORT MANAGED INSTANCE PUBLIC CERTIFICATE
# ===== Enter user variables here ====

# Enter your managed instance short name – for example, "sqlmi"
$ManagedInstanceName = "<ManagedInstanceName>"

# ==== Do not customize the following cmdlet ====

# Find out the resource group name
$ResourceGroup = (Get-AzSqlInstance -InstanceName $ManagedInstanceName).ResourceGroupName

# Fetch the public key of the authentication certificate from Managed Instance. Outputs a binary key in the property PublicKey.
Get-AzSqlInstanceEndpointCertificate -ResourceGroupName $ResourceGroup -InstanceName $ManagedInstanceName -EndpointType "DATABASE_MIRRORING" | out-string   

複製整個 PublicKey 輸出 (以 0x 開頭),因為您將在下個步驟中需要這項資訊。

或者,如果您在複製並貼上公開金鑰時遇到問題,您也可以在受控執行個體上執行 T-SQL 命令 EXEC sp_get_endpoint_certificate 4,以取得連結端點的公開金鑰。

接下來,將所取得受控執行個體安全性憑證的公開金鑰匯入至 SQL Server。 在 SQL Server 上執行下列查詢。 將:

  • <ManagedInstanceFQDN> 取代為受控執行個體的完整網域名稱。
  • <PublicKey> 取代為您在上一個步驟中取得的 PublicKey 值 (從 Azure Cloud Shell 取得,以 0x 開頭)。 您不需要使用引號。

重要

憑證的名稱必須是 SQL 受控執行個體 FQDN,且不應修改。 如果使用自訂名稱,連結將無法運作。

-- Run on SQL Server
USE MASTER
CREATE CERTIFICATE [<ManagedInstanceFQDN>]
FROM BINARY = <PublicKey> 

將 Azure 信任的根憑證授權單位金鑰匯入至 SQL Server

您必須將 Microsoft 和 DigiCert 憑證授權單位 (CA) 的公開根憑證金鑰匯入至 SQL Server,您的 SQL Server 才能信任 Azure 針對 database.windows.net 網域所核發的憑證。

警告

確定 PublicKey 以 0x 開頭。 如果還沒有,您可能需要手動將其新增至 PublicKey 的開頭。

首先,在 SQL Server 上匯入 Microsoft PKI 根授權憑證:

-- Run on SQL Server
-- Import Microsoft PKI root-authority certificate (trusted by Azure), if not already present
IF NOT EXISTS (SELECT name FROM sys.certificates WHERE name = N'MicrosoftPKI')
BEGIN
    PRINT 'Creating MicrosoftPKI certificate.'
    CREATE CERTIFICATE [MicrosoftPKI] FROM BINARY = 0x308205A830820390A00302010202101ED397095FD8B4B347701EAABE7F45B3

    --Trust certificates issued by Microsoft PKI root authority for Azure database.windows.net domains
    DECLARE @CERTID int
    SELECT @CERTID = CERT_ID('MicrosoftPKI')
    EXEC sp_certificate_add_issuer @CERTID, N'*.database.windows.net'
END
ELSE
    PRINT 'Certificate MicrosoftPKI already exsits.'
GO

然後,在 SQL Server 上匯入 DigiCert PKI 根授權憑證:

-- Run on SQL Server
-- Import DigiCert PKI root-authority certificate trusted by Azure to SQL Server, if not already present
IF NOT EXISTS (SELECT name FROM sys.certificates WHERE name = N'DigiCertPKI')
BEGIN
    PRINT 'Creating DigiCertPKI certificate.'
    CREATE CERTIFICATE [DigiCertPKI] FROM BINARY = 0x3082038E30820276A0030201020210033AF1E6A711A9A0BB2864B11D0

    --Trust certificates issued by DigiCert PKI root authority for Azure database.windows.net domains
    DECLARE @CERTID int
    SELECT @CERTID = CERT_ID('DigiCertPKI')
    EXEC sp_certificate_add_issuer @CERTID, N'*.database.windows.net'
END
ELSE
    PRINT 'Certificate DigiCertPKI already exsits.'
GO

最後,使用下列動態管理檢視 (DMV) 來確認所有建立的憑證:

-- Run on SQL Server
SELECT * FROM sys.certificates

保護資料庫鏡像端點

如果您在 SQL Server 上沒有現有的可用性群組或資料庫鏡像端點,則下一個步驟是在 SQL Server 上建立資料庫鏡像端點,並使用先前產生的 SQL Server 憑證進行保護。 如果您確實有現有的可用性群組或鏡像端點,請跳至更改現有的端點一節。

在 SQL Server 上建立及保護資料庫鏡像端點

若要確認您尚未建立現有的資料庫鏡像端點,請使用下列指令碼:

-- Run on SQL Server
-- View database mirroring endpoints on SQL Server
SELECT * FROM sys.database_mirroring_endpoints WHERE type_desc = 'DATABASE_MIRRORING'

如果先前的查詢未顯示現有資料庫的鏡像端點,請在 SQL Server 上執行下列指令碼,取得先前產生的 SQL Server 憑證名稱。

-- Run on SQL Server
-- Show the name and the public key of generated SQL Server certificate
USE MASTER
GO
DECLARE @sqlserver_certificate_name NVARCHAR(MAX) = N'Cert_' + @@servername  + N'_endpoint'
SELECT @sqlserver_certificate_name as 'SQLServerCertName'

儲存來自輸出的 SQLServerCertName,因為您將在下一個步驟中需要這項資訊。

使用下列指令碼在連接埠 5022 上建立新的資料庫鏡像端點,並使用 SQL Server 憑證保護該端點。 將:

  • <SQL_SERVER_CERTIFICATE> 取代為您在上一個步驟中取得的 SQLServerCertName 名稱。
-- Run on SQL Server
-- Create a connection endpoint listener on SQL Server
USE MASTER
CREATE ENDPOINT database_mirroring_endpoint
    STATE=STARTED   
    AS TCP (LISTENER_PORT=5022, LISTENER_IP = ALL)
    FOR DATABASE_MIRRORING (
        ROLE=ALL,
        AUTHENTICATION = CERTIFICATE [<SQL_SERVER_CERTIFICATE>],
        ENCRYPTION = REQUIRED ALGORITHM AES
    )  
GO

在 SQL Server 上執行下列指令碼來驗證已建立鏡像端點:

-- Run on SQL Server
-- View database mirroring endpoints on SQL Server
SELECT
    name, type_desc, state_desc, role_desc,
    connection_auth_desc, is_encryption_enabled, encryption_algorithm_desc
FROM 
    sys.database_mirroring_endpoints

成功建立的端點 state_desc 資料行應處於 STARTED 狀態。

已建立新的鏡像端點,並啟用憑證驗證和 AES 加密。

更改現有的端點

注意

如果您剛建立新的鏡像端點,請略過此步驟。 只有在要搭配現有的資料庫鏡像端點使用現有的可用性群組時,才使用此步驟。

如果您針對連結使用現有的可用性群組,或如果有現有的資料庫鏡像端點,請先驗證其符合連結的下列必要條件:

  • 類型必須是 DATABASE_MIRRORING
  • 連線驗證必須是 CERTIFICATE
  • 必須啟用加密。
  • 加密演算法必須是 AES

在 SQL Server 上執行下列查詢,檢視現有資料庫鏡像端點的詳細資料:

-- Run on SQL Server
-- View database mirroring endpoints on SQL Server
SELECT
    name, type_desc, state_desc, role_desc, connection_auth_desc,
    is_encryption_enabled, encryption_algorithm_desc
FROM
    sys.database_mirroring_endpoints

如果輸出顯示現有 DATABASE_MIRRORING 端點的 connection_auth_desc 不是 CERTIFICATE 或 encryption_algorthm_desc 不是 AES,則「必須更改端點以符合需求」。

在 SQL Server 上,會針對可用性群組和分散式可用性群組使用相同的資料庫鏡像端點。 如果您的 connection_auth_desc 端點是 NTLM (Windows 驗證) 或 KERBEROS,而且需要對現有的可用性群組使用 Windows 驗證,則可以將驗證選項切換為 NEGOTIATE CERTIFICATE,藉此更改端點以使用多個驗證方法。 這項變更可讓現有的可用性群組使用 Windows 驗證,同時對 SQL 受控執行個體使用憑證驗證。

同樣地,如果加密不包含 AES,而且您需要 RC4 加密,則可以更改端點以使用這兩種演算法。 如需更改端點的可能選項詳細資料,請參閱 sys.database_mirroring_endpoints 的文件頁面

下列指令碼示範如何更改 SQL Server 上的現有資料庫鏡像端點。 將:

  • <YourExistingEndpointName> 取代為您現有的端點名稱。
  • <SQLServerCertName> 取代為已產生的 SQL Server 憑證名稱 (在上述先前的步驟之一中取得)。

根據您的特定設定,您可能需要進一步自訂指令碼。 您也可以使用 SELECT * FROM sys.certificates 來取得 SQL Server 上建立的憑證名稱。

-- Run on SQL Server
-- Alter the existing database mirroring endpoint to use CERTIFICATE for authentication and AES for encryption
USE MASTER
ALTER ENDPOINT [<YourExistingEndpointName>]   
    STATE=STARTED   
    AS TCP (LISTENER_PORT=5022, LISTENER_IP = ALL)
    FOR DATABASE_MIRRORING (
        ROLE=ALL,
        AUTHENTICATION = WINDOWS NEGOTIATE CERTIFICATE [<SQLServerCertName>],
        ENCRYPTION = REQUIRED ALGORITHM AES
    )
GO

執行 ALTER 端點查詢並將雙重驗證模式設定為 Windows 和憑證之後,請在 SQL Server 上再次使用此查詢來顯示資料庫鏡像端點的詳細資料:

-- Run on SQL Server
-- View database mirroring endpoints on SQL Server
SELECT
    name, type_desc, state_desc, role_desc, connection_auth_desc,
    is_encryption_enabled, encryption_algorithm_desc
FROM
    sys.database_mirroring_endpoints

您已成功修改 SQL 受控執行個體連結的資料庫鏡像端點。

在 SQL Server 上建立可用性群組

如果您沒有現有的可用性群組,下一個步驟是在 SQL Server 上建立一個,不論其是否將為初始主要複本。 如果您的 SQL 受控執行個體是初始主要複本 (從 SQL Server 2022 CU10 才開始支援),則建立可用性群組的命令會有所不同。

雖然可以為同一個資料庫建立多個連結,但連結只支援每個連結複寫一個資料庫。 如果您想要為相同資料庫建立多個連結,請針對所有連結使用相同的可用性群組,然後針對 SQL Server 與 SQL 受控執行個體之間的每個資料庫連結建立新的分散式可用性群組。

如果 SQL Server 是您的初始主要複本,請為連結建立具有下列參數的可用性群組:

  • 初始主要伺服器名稱
  • 資料庫名稱
  • MANUAL 的容錯移轉模式
  • AUTOMATIC 的植入模式

首先,執行下列 T-SQL 陳述式來查明您的 SQL Server 名稱:

-- Run on the initial primary
SELECT @@SERVERNAME AS SQLServerName 

然後,使用下列指令碼在 SQL Server 上建立可用性群組。 將:

  • <AGName> 取代為您的可用性群組名稱。 受控執行個體連結針對每個可用性群組需要一個資料庫。 針對多個資料庫,您必須建立多個可用性群組。 請考慮命名每個可用性群組,使其名稱反映對應的資料庫 (例如 AG_<db_name>)。
  • <DatabaseName> 取代為您要複寫的資料庫名稱。
  • <SQLServerName> 取代為您在上一個步驟中取得的 SQL Server 執行個體名稱。
  • <SQLServerIP> 取代為 SQL Server IP 位址。 您可以使用可解析的 SQL Server 主機電腦名稱作為替代名稱,但必須確定該名稱可從 SQL 受控執行個體虛擬網路進行解析。
-- Run on SQL Server
-- Create the primary availability group on SQL Server
USE MASTER
CREATE AVAILABILITY GROUP [<AGName>]
WITH (CLUSTER_TYPE = NONE) -- <- Delete this line for SQL Server 2016 only. Leave as-is for all higher versions.
    FOR database [<DatabaseName>]  
    REPLICA ON   
        N'<SQLServerName>' WITH   
            (  
            ENDPOINT_URL = 'TCP://<SQLServerIP>:5022',
            AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
            FAILOVER_MODE = MANUAL,
            SEEDING_MODE = AUTOMATIC
            );
GO

重要

若是 SQL Server 2016,請從上述 T-SQL 陳述句中刪除 WITH (CLUSTER_TYPE = NONE)。 若是其他較新 SQL Server 版本,則保持原樣。

接下來,在 SQL Server 上建立分散式可用性群組。 如果您計劃建立多個連結,則即使您是為同一個資料庫建立多個連結,也需要為每個連結建立一個分散式可用性群組。

取代下列值,然後執行 T-SQL 指令碼來建立分散式可用性群組。

  • <DAGName> 取代為您的分散式可用性群組名稱。 由於您可以透過為每個連結建立一個分散式可用性群組來為同一個資料庫設定多個連結,因此請考慮據此命名每個分散式可用性群組,例如 DAG1_<db_name>DAG2_<db_name>
  • <AGName> 取代為您在上一個步驟中建立的可用性群組名稱。
  • <SQLServerIP> 取代為上一個步驟中 SQL Server 的 IP 位址。 您可以使用可解析的 SQL Server 主機電腦名稱作為替代名稱,但請確定該名稱可以從 SQL 受控執行個體虛擬網路解析 (需要針對受控執行個體的子網路設定自訂 Azure DNS)。
  • <ManagedInstanceName> 取代為您的受控執行個體簡短名稱。
  • <ManagedInstanceFQDN> 取代為您的 SQL 受控執行個體完整網域名稱。
-- Run on SQL Server
-- Create a distributed availability group for the availability group and database
-- ManagedInstanceName example: 'sqlmi1'
-- ManagedInstanceFQDN example: 'sqlmi1.73d19f36a420a.database.windows.net'
USE MASTER
CREATE AVAILABILITY GROUP [<DAGName>]
WITH (DISTRIBUTED) 
    AVAILABILITY GROUP ON  
    N'<AGName>' WITH 
    (
      LISTENER_URL = 'TCP://<SQLServerIP>:5022',
      AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
      FAILOVER_MODE = MANUAL,
      SEEDING_MODE = AUTOMATIC,
      SESSION_TIMEOUT = 20
    ),
    N'<ManagedInstanceName>' WITH
    (
      LISTENER_URL = 'tcp://<ManagedInstanceFQDN>:5022;Server=[<ManagedInstanceName>]',
      AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
      FAILOVER_MODE = MANUAL,
      SEEDING_MODE = AUTOMATIC
    );
GO

驗證可用性群組

使用下列指令碼,列出 SQL Server 執行個體上的所有可用性群組和分散式可用性群組。 此時,可用性群組的狀態必須是 connected,而分散式可用性群組的狀態必須是 disconnected。 分散式可用性群組只有在已與 SQL 受控執行個體聯結時,其狀態才會變成 connected

-- Run on SQL Server
-- This will show that the availability group and distributed availability group have been created on SQL Server.
SELECT * FROM sys.availability_groups

或者,您可以使用 SSMS 物件總管來尋找可用性群組和分散式可用性群組。 展開 [Always On 高可用性] 資料夾,然後展開 [可用性群組] 資料夾。

最後,您可以建立連結。 命令會依據作為初始主要複本的執行個體而有所不同。 使用 New-AzSqlInstanceLink PowerShell 或 az sql mi link create Azure CLI 命令來建立連結,例如本節中的 PowerShell 範例。 Azure CLI 目前不支援從 SQL 受控執行個體主要複本建立連結。

如果您需要查看受控執行個體上的所有連結,請在 Azure Cloud Shell 中使用 Get-AzSqlInstanceLink PowerShell 或 az sql mi link show Azure CLI 命令。

為簡化此程序,請登入 Azure 入口網站,並從 Azure Cloud Shell 執行下列指令碼。 將:

  • <ManagedInstanceName> 取代為您的受控執行個體簡短名稱。
  • <AGName> 取代為 SQL Server 上建立的可用性群組名稱。
  • <DAGName> 取代為 SQL Server 上建立的分散式可用性群組名稱。
  • <DatabaseName> 取代為 SQL Server 可用性群組中複寫的資料庫。
  • <SQLServerIP> 取代為您 SQL Server 的 IP 位址。 提供的 IP 位址必須可由受控執行個體存取。
#  Run in Azure Cloud Shell (select PowerShell console)
# =============================================================================
# POWERSHELL SCRIPT TO CREATE MANAGED INSTANCE LINK
# Instructs Managed Instance to join distributed availability group on SQL Server
# ===== Enter user variables here ====

# Enter your managed instance name – for example, "sqlmi1"
$ManagedInstanceName = "<ManagedInstanceName>"

# Enter the availability group name that was created on SQL Server
$AGName = "<AGName>"

# Enter the distributed availability group name that was created on SQL Server
$DAGName = "<DAGName>"

# Enter the database name that was placed in the availability group for replication
$DatabaseName = "<DatabaseName>"

# Enter the SQL Server IP
$SQLServerIP = "<SQLServerIP>"

# ==== Do not customize the following cmdlet ====

# Find out the resource group name
$ResourceGroup = (Get-AzSqlInstance -InstanceName $ManagedInstanceName).ResourceGroupName

# Build properly formatted connection endpoint
$SourceIP = "TCP://" + $SQLServerIP + ":5022"

# Create link on managed instance. Join distributed availability group on SQL Server.
New-AzSqlInstanceLink -ResourceGroupName $ResourceGroup -InstanceName $ManagedInstanceName -Name $DAGName |
-PrimaryAvailabilityGroupName $AGName -SecondaryAvailabilityGroupName $ManagedInstanceName |
-TargetDatabase $DatabaseName -SourceEndpoint $SourceIP

此作業的結果會是建立連結要求成功執行的時間戳記。

若要確認 SQL 受控執行個體與 SQL Server 之間的連線,請在 SQL Server 上執行下列查詢。 連線不是即時作業。 DMV 最多可能需要一分鐘的時間才會開始顯示成功的連線。 請持續重新整理 DMV,直到 SQL 受控執行個體複本的連線顯示為 CONNECTED 為止。

-- Run on SQL Server
SELECT
    r.replica_server_name AS [Replica],
    r.endpoint_url AS [Endpoint],
    rs.connected_state_desc AS [Connected state],
    rs.last_connect_error_description AS [Last connection error],
    rs.last_connect_error_number AS [Last connection error No],
    rs.last_connect_error_timestamp AS [Last error timestamp]
FROM
    sys.dm_hadr_availability_replica_states rs
    JOIN sys.availability_replicas r
    ON rs.replica_id = r.replica_id

建立連線之後,在初始植入階段移動和還原資料庫的完整備份時,SSMS 中的 [物件總管] 可能一開始會在處於 [還原中] 狀態的次要複本上顯示複寫的資料庫。 還原資料庫之後,複寫必須更新以讓兩個資料庫處於同步狀態。 初始植入完成之後,資料庫將不再處於 [還原中] 狀態。 植入小型資料庫的速度,可能會快到讓您無法在 SSMS 中看到初始 [還原中] 狀態。

重要

  • 除非 SQL Server 與 SQL 受控執行個體之間存在網路連線,否則連結將無法運作。 若要針對網路連線進行疑難排解,請執行測試網路連線中的步驟。
  • 在 SQL Server 上定期備份記錄檔。 如果使用的記錄空間達到 100%,在降低使用的空間之前,會停止複寫到 SQL 受控執行個體。 強烈建議您藉由設定每日作業來自動執行記錄備份。 如需詳細資料,請參閱備份 SQL Server 上的記錄檔

停止工作負載

要將資料庫容錯移轉至次要複本,請先在維護期間停止主要複本的任何應用程式工作負載。 這可讓資料庫複寫趕上次要複寫,以便您可移轉或容錯移轉至 Azure,而不會遺失資料。 雖然主要資料庫是 Always On 可用性群組的一部分,但您無法將其設定為唯讀模式。 容錯移轉之前,您必須確保應用程式不會將交易認可至主要複本。

切換複寫模式

SQL Server 與 SQL 受控執行個體之間的複寫預設為非同步。 將資料庫容錯移轉到次要複本之前,請將連結切換至同步模式。 跨大型網路距離的同步複寫可能會讓主要複本上的交易變慢。

從非同步模式切換至同步模式,需要同時在 SQL 受控執行個體和 SQL Server 上變更複寫模式。

切換複寫模式 (SQL 受控執行個體)

使用 Azure PowerShell 或 Azure CLI 在 SQL 受控執行個體上切換複寫模式。

首先,請確定您已登入 Azure,並已使用 Select-AzSubscription PowerShell 或 az account set Azure CLI 命令選取裝載受控執行個體的訂用帳戶。 如果您的帳戶有多個 Azure 訂用帳戶,選取正確的訂用帳戶特別重要。

在下列 PowerShell 範例中,將 <SubscriptionID> 取代為您的 Azure 訂用帳戶 ID。

# Run in Azure Cloud Shell (select PowerShell console)

# Enter your Azure subscription ID
$SubscriptionID = "<SubscriptionID>"

# Login to Azure and select subscription ID
if ((Get-AzContext ) -eq $null)
{
    echo "Logging to Azure subscription"
    Login-AzAccount
}
Select-AzSubscription -SubscriptionName $SubscriptionID

請確定您知道要容錯移轉的連結名稱。 您可以使用 Get-AzSqlInstanceLink PowerShell 或 az sql mi link list Azure CLI 命令。

使用下列 PowerShell 指令碼來列出 SQL 受控執行個體上的所有使用中連結。 將 <ManagedInstanceName> 取代為您的受控執行個體簡短名稱。

# Run in Azure Cloud Shell (select PowerShell console)
# =============================================================================
# POWERSHELL SCRIPT TO LIST ALL LINKS ON MANAGED INSTANCE
# ===== Enter user variables here ====

# Enter your managed instance name – for example, "sqlmi1"
$ManagedInstanceName = "<ManagedInstanceName>"

# ==== Do not customize the following cmdlet ====

# Find out the resource group name
$ResourceGroup = (Get-AzSqlInstance -InstanceName $ManagedInstanceName).ResourceGroupName

# List all links on the specified managed instance
Get-AzSqlInstanceLink -ResourceGroupName $ResourceGroup -InstanceName $ManagedInstanceName 

從之前指令碼的輸出中,記錄您想要容錯移轉之連結的 Name 屬性。

然後,使用 Update-AzSqlInstanceLink PowerShell 或 az sql mi link update Azure CLI 命令,將複寫模式從非同步切換為同步,以同步處理已識別連結的 SQL 受控執行個體。

在下列 PowerShell 範例中:

  • <ManagedInstanceName> 取代為您的受控執行個體簡短名稱。
  • <DAGName> 取代為您在上一個步驟中找到的連結名稱 (上一個步驟中的 Name 屬性)。
# Run in Azure Cloud Shell (select PowerShell console)
# =============================================================================
# POWERSHELL SCRIPT TO SWITCH LINK REPLICATION MODE (ASYNC\SYNC)
# ===== Enter user variables here ====

# Enter the link name 
$LinkName = "<DAGName>"  

# Enter your managed instance name – for example, "sqlmi1" 
$ManagedInstanceName = "<ManagedInstanceName>" 

# ==== Do not customize the following cmdlet ====

# Find out the resource group name
$ResourceGroup = (Get-AzSqlInstance -InstanceName $ManagedInstanceName).ResourceGroupName

# Update replication mode of the specified link
Update-AzSqlInstanceLink -ResourceGroupName $ResourceGroup -InstanceName $ManagedInstanceName |
-Name $LinkName -ReplicationMode "Sync"

執行上述命令後,會顯示作業的摘要來指出成功,而 ReplicationMode屬性會顯示為 Sync

若您需要還原此作業,請執行上述指令碼以切換複寫模式,但請將 -ReplicationMode 中的 Sync 字串取代為 Async

切換複寫模式 (SQL Server)

在 SQL Server 上使用下列 T-SQL 指令碼,將 SQL Server 上分散式可用性群組的複寫模式從非同步變更為同步。進行下列取代:

  • <DAGName> 使用分散式可用性群組 (用來建立連結的群組) 的名稱。
  • <AGName> 使用在 SQL Server 上建立的可用性群組 (用來建立連結的群組) 的名稱。
  • <ManagedInstanceName> 取代為您的受控執行個體名稱。
-- Run on SQL Server
-- Sets the distributed availability group to a synchronous commit.
-- ManagedInstanceName example: 'sqlmi1'
USE master
GO
ALTER AVAILABILITY GROUP [<DAGName>] 
MODIFY 
AVAILABILITY GROUP ON
    '<AGName>' WITH
    (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT),
    '<ManagedInstanceName>' WITH
    (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT);

若要確認您已成功變更連結的複寫模式,請使用下列動態管理檢視。 結果表示 SYNCHRONOUS_COMIT 狀態。

-- Run on SQL Server
-- Verifies the state of the distributed availability group
SELECT
    ag.name, ag.is_distributed, ar.replica_server_name,
    ar.availability_mode_desc, ars.connected_state_desc, ars.role_desc,
    ars.operational_state_desc, ars.synchronization_health_desc
FROM
    sys.availability_groups ag
    join sys.availability_replicas ar
    on ag.group_id=ar.group_id
    left join sys.dm_hadr_availability_replica_states ars
    on ars.replica_id=ar.replica_id
WHERE
    ag.is_distributed=1

現在您已將 SQL 受控執行個體和 SQL Server 切換為同步模式,這兩個執行個體之間的複寫會是同步的。 如果您需要反轉此狀態,請遵循相同的步驟,並為 SQL Server 和 SQL 受控執行個體設定 async 狀態。

檢查 SQL Server 和 SQL 受控執行個體上的 LSN 值

若要完成容錯移轉或移轉,請確認複寫已完成。 為此,請確保 SQL Server 與 SQL 受控執行個體的記錄檔記錄中的記錄序號 (LSN) 相同。

一開始,預期主要複本上的 LSN 會高於次要複本上的 LSN。 網路延遲可能會導致複寫稍微落後於主要複本。 因為工作負載已在主要複本上停止,所以 LSN 預期應該會在一段時間後符合並停止改變。

在 SQL Server 上使用下列 T-SQL 查詢,讀取上次記錄的交易記錄 LSN。 將:

  • <DatabaseName> 使用您的資料庫名稱,並尋找最後一次強行寫入的 LSN 號碼。
-- Run on SQL Server
-- Obtain the last hardened LSN for the database on SQL Server.
SELECT
    ag.name AS [Replication group],
    db.name AS [Database name], 
    drs.database_id AS [Database ID], 
    drs.group_id, 
    drs.replica_id, 
    drs.synchronization_state_desc AS [Sync state], 
    drs.end_of_log_lsn AS [End of log LSN],
    drs.last_hardened_lsn AS [Last hardened LSN] 
FROM
    sys.dm_hadr_database_replica_states drs
    inner join sys.databases db on db.database_id = drs.database_id
    inner join sys.availability_groups ag on drs.group_id = ag.group_id
WHERE
    ag.is_distributed = 1 and db.name = '<DatabaseName>'

在 SQL 受控執行個體上使用下列 T-SQL 查詢,讀取您資料庫中最後一次強行寫入的 LSN。 將 <DatabaseName> 取代為您的資料庫名稱。

此查詢適用於一般用途 SQL 受控執行個體。 針對業務關鍵 SQL 受控執行個體,取消註解指令碼結尾的 and drs.is_primary_replica = 1。 在業務關鍵服務層級上,此篩選可確保只會讀取主要複本詳細資料。

-- Run on SQL managed instance
-- Obtain the LSN for the database on SQL Managed Instance.
SELECT
    db.name AS [Database name],
    drs.database_id AS [Database ID], 
    drs.group_id, 
    drs.replica_id, 
    drs.synchronization_state_desc AS [Sync state],
    drs.end_of_log_lsn AS [End of log LSN],
    drs.last_hardened_lsn AS [Last hardened LSN]
FROM
    sys.dm_hadr_database_replica_states drs
    inner join sys.databases db on db.database_id = drs.database_id
WHERE
    db.name = '<DatabaseName>'
    -- for Business Critical, add the following as well
    -- AND drs.is_primary_replica = 1

或者,您也可以使用 Get-AzSqlInstanceLink PowerShell 或 az sql mi link show Azure CLI 命令來擷取 SQL 受控執行個體上連結的 LastHardenedLsn 屬性,此屬性提供與上述 T-SQL 查詢相同的資訊。

重要

再次確認您的工作負載已在主要複本上停止。 確認 SQL Server 和 SQL 受控執行個體上的 LSN 相符,而且在一段時間內保持一致。 這兩個執行個體上的穩定 LSN 表示結尾記錄已複寫到次要複本,而且工作負載實際上已停止。

容錯移轉資料庫

如果您想要使用 PowerShell 在 SQL Server 2022 與 SQL 受控執行個體 之間容錯移轉資料庫,同時仍維持連結,或針對任何版本的 SQL Server 執行有資料遺失的容錯移轉,請使用 SSMS 中的 SQL Server 與受控執行個體之間的容錯移轉精靈來產生適合您環境的指令碼。 您可從主要或次要複本執行計劃性容錯移轉。 若要執行強制容錯移轉,請連線次要複本。

若要在容錯移轉或移轉資料庫時中斷連結並停止複寫,不論 SQL Server 版本為何,請使用 Remove-AzSqlInstanceLink PowerShell 或 az sql mi link delete Azure CLI 命令。

警告

  • 在容錯移轉之前,請停止來源資料庫的工作負載,以便複寫資料庫可完全趕上並進行容錯移轉,而不會遺失資料。 如果執行強制容錯移轉,或在 LSN 相符之前中斷連結,您可能會遺失資料。
  • 在 SQL Server 2019 與舊版容錯移轉資料庫會發生中斷並移除兩個複本之間的連結。 您無法容錯回復到初始主要複本。
  • 在使用 SQL Server 2022 維護連結時容錯移轉資料庫目前為預覽狀態。

下列範例指令碼會中斷連結並結束複本之間的複寫,在兩個執行個體上進行資料庫讀取/寫入。 將:

  • <ManagedInstanceName> 取代為您的受控執行個體名稱。
  • <DAGName> 取代為容錯移轉之連結的名稱 (稍早所執行命令 Get-AzSqlInstanceLink 輸出中的 Name 屬性)。
# Run in Azure Cloud Shell (select PowerShell console) 
# =============================================================================
# POWERSHELL SCRIPT TO FAIL OVER OR MIGRATE DATABASE TO AZURE
# ===== Enter user variables here ====

# Enter your managed instance name – for example, "sqlmi1"
$ManagedInstanceName = "<ManagedInstanceName>"
$LinkName = "<DAGName>"

# ==== Do not customize the following cmdlet ====

# Find out the resource group name
$ResourceGroup = (Get-AzSqlInstance -InstanceName $ManagedInstanceName).ResourceGroupName

# Failover the specified link
Remove-AzSqlInstanceLink -ResourceGroupName $ResourceGroup |
-InstanceName $ManagedInstanceName -Name $LinkName -Force

容錯移轉成功時,連結會卸除且不再存在。 SQL Server 資料庫和 SQL 受控執行個體資料庫都可以執行讀取/寫入工作負載。 它們完全獨立。 將應用程式連線字串重新指向您想要主動使用的資料庫。

重要

在成功容錯移轉至 SQL 受控執行個體之後,請手動將應用程式連接字串重新指向 SQL 受控執行個體 FQDN,才能完成移轉或容錯移轉流程並繼續在 Azure 執行。

清除可用性群組

由於使用 SQL Server 2022 進行容錯移轉並不會中斷連結,因此您可以選擇就地保留連結和可用性群組。

如果您決定中斷連結,或如果您想在 SQL Server 2019 與舊版之間進行容錯移轉,則必須卸除分散式可用性群組,以從 SQL 伺服器移除連結中繼資料。 不過,您可以選擇將可用性群組保留在 SQL Server 上。

若要清理可用性群組資源,請取代下列值,然後執行範例程式碼:在下列程式碼中,取代:

  • <DAGName> 使用 SQL Server 上的分散式可用性群組 (用來建立連結的群組) 的名稱。
  • <AGName> 使用 SQL Server 上的可用性群組 (用來建立連結的群組) 的名稱。
-- Run on SQL Server
USE MASTER
GO
DROP AVAILABILITY GROUP <DAGName> --mandatory
GO
-- DROP AVAILABILITY GROUP <AGName> --optional
-- GO

疑難排解

本節提供指引,解決設定及使用連結問題。

錯誤

如果您在建立連結或容錯移轉資料庫時遇到錯誤訊息,則請檢閱查詢輸出視窗中的錯誤訊息以取得詳細資訊。

如果您在使用連結時發生錯誤,查詢會在失敗的步驟停止執行。 解決錯誤狀況之後,重新執行命令以繼續進行您的動作。

在強制容錯移轉之後狀態不一致

使用強制容錯移轉可能造成主要與次要複本之間狀態不一致,導致兩個複本都處於相同角色的大腦分裂案例。 在此狀態資料複寫會失敗,直到使用者手動將一個複本指定為主要複本,將另一複本指定為次要複本並解決此問題為止。

如需連結功能的詳細資訊,請參閱下列資源: