在 Linux 上設定具有多寫入端磁碟的 SQL Server 容錯移轉叢集執行個體

如要在 Compute Engine 的兩個不同可用區中,為 SQL Server 實現高可用性,您可以部署使用多寫入端磁碟的 Linux 版 SQL Server 容錯移轉叢集執行個體 (FCI)。與傳統的無共用架構不同,這種設定可讓您同時將不同可用區的節點連結至同一部磁碟。本指南說明如何使用 Google Cloud Hyperdisk 的低延遲同步複製功能,在 Compute Engine 的 Linux 上部署高可用性 SQL Server FCI。

這種設計可確保 SQL Server 即使在不太可能發生的區域中斷事件中,仍能保持可用性。結合 Pacemaker 叢集協調功能和 Compute Engine 的跨可用區復原能力,可為需要共用儲存空間的任務關鍵資料庫工作負載,提供強大的高效能解決方案。

使用多重寫入器磁碟實作高可用性的好處

在 Linux 上使用含多寫入端磁碟的 SQL Server FCI,而非 Always On 可用性群組 (AG),可免除管理多個資料副本的複雜性,以及 AG 設定造成的同步處理負擔。

與在每個節點上使用完整資料副本的 AG 架構相比,共用磁碟區架構的儲存空間效率也更高。在鏡像案例中,共用磁碟區也能降低磁碟成本。

這項架構的主要亮點

  • 可用區備援:在節點故障或可用區服務中斷的罕見情況下,提供資料保護。
  • 簡化管理作業:與 Always On 可用性群組相比,管理多個資料副本的複雜度較低。
  • 儲存空間效率:使用單一共用磁碟區儲存資料和記錄,並透過多重寫入功能進行最佳化。
  • Linux 原生自動化調度管理:使用業界標準的高可用性擴充功能 (HAE),實現無縫容錯移轉。

在內部部署環境中,如果發生容錯移轉,您可以讓 WSFC 執行 ARP 公告通知網路設備 IP 位址變更。Google Cloud,但會忽略 ARP 公告。因此,您必須實作內部負載平衡器 (請參閱「執行 Windows Server 容錯移轉叢集」)

架構

本文假設您已具備 SQL Server、Active Directory 和 Compute Engine 的基本知識。

目標

本教學課程說明如何完成下列工作,以達成目標:

  • 在 Linux 上建立 SQL Server 部署作業。
  • 建立、附加及設定可多重寫入的磁碟。
  • 設定 Pacemaker 叢集。
  • 設定負載平衡器。
  • 執行容錯移轉測試。

費用

本教學課程使用 Google Cloud的計費元件,包括:

使用 Pricing Calculator,根據您的預測使用量來產生預估費用。

事前準備

  1. 本教學課程需要 Google Cloud 專案。您可以建立新專案,或選取已建立的專案:

    1. 在 Google Cloud 控制台的專案選擇器頁面中,選取或建立 Google Cloud 專案。

      選取或建立專案所需的角色

      • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您在專案中獲派角色,即可選取該專案。
      • 建立專案:如要建立專案,您需要「專案建立者」角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色

      前往專案選取器

    2. 確認專案已啟用計費功能 Google Cloud

    3. 在 Google Cloud 控制台中啟用 Cloud Shell。

      啟用 Cloud Shell

準備專案和網路

如要準備 Google Cloud 專案和虛擬私有雲,以便部署 SQL Server FCI,請完成下列步驟:

  1. 在 Google Cloud 控制台中,按一下「啟用 Cloud Shell」啟動 Cloud Shell。按鈕,開啟 Cloud Shell

    前往 Google Cloud 控制台

  2. 設定預設的專案 ID

    gcloud config set project PROJECT_ID
    

    PROJECT_ID 替換為 Google Cloud 專案 ID。

  3. 設定預設區域:

    gcloud config set compute/region REGION
    

    REGION 替換為要部署的區域 ID。

建立叢集節點

部署兩個 VM 做為叢集節點,第三個 VM 則做為專屬用戶端,用於驗證連線和容錯移轉效能。

  1. 初始化其餘指令會用到的下列變數。

    BOOT_DISK_SIZE=50
    BOOT_IOPS=10000
    BOOT_THROUGHPUT=400
    DATA_IOPS=10000
    DATA_THROUGHPUT=400
    DATA_DISK_SIZE=200
    REGION=$(gcloud config get-value compute/region)
    ZONE1=$REGION-a
    ZONE2=$REGION-b
    SUBNET=SUBNET_NAME
    MACHINE_TYPE=c3-standard-8
    VPC_NAME=VPC_NAME
    
  2. 建立兩個地區磁碟,一個用於資料,另一個用於記錄檔。如要允許兩個執行個體存取磁碟,請使用 --access-mode=READ_WRITE_MANY 旗標,為兩個磁碟啟用多重寫入模式。

    gcloud compute disks create sqlfci-mw-data-disk \
    --size=$DATA_DISK_SIZE \
    --type=hyperdisk-balanced-high-availability \
    --region=$REGION \
    --replica-zones=$ZONE1,$ZONE2 \
    --provisioned-iops=$DATA_IOPS \
    --provisioned-throughput=$DATA_THROUGHPUT \
    --access-mode=READ_WRITE_MANY
    
    gcloud compute disks create sqlfci-mw-log-disk \
    --size=$DATA_DISK_SIZE \
    --type=hyperdisk-balanced-high-availability \
    --region=$REGION \
    --replica-zones=$ZONE1,$ZONE2 \
    --provisioned-iops=$DATA_IOPS \
    --provisioned-throughput=$DATA_THROUGHPUT \
    --access-mode=READ_WRITE_MANY
    
  3. 建立 Linux VM,並連結您建立的多重寫入磁碟。

    gcloud compute instances create node-1 \
    --boot-disk-size=$BOOT_DISK_SIZE \
    --boot-disk-type=hyperdisk-balanced \
    --boot-disk-provisioned-iops=$BOOT_IOPS \
    --boot-disk-provisioned-throughput=$BOOT_THROUGHPUT \
    --zone $ZONE1 \
    --machine-type $MACHINE_TYPE \
    --subnet $SUBNET \
    --image-family ubuntu-2204-lts \
    --image-project ubuntu-os-cloud \
    --disk="name=sqlfci-mw-data-disk,scope=regional,mode=rw" \
    --disk="name=sqlfci-mw-log-disk,scope=regional,mode=rw" \
    --scopes=compute-rw,trace,service-control,service-management,pubsub,monitoring-write,logging-write,storage-rw \
    --tags=sqlfci
    
    gcloud compute instances create node-2 \
    --boot-disk-size=$BOOT_DISK_SIZE \
    --boot-disk-type=hyperdisk-balanced \
    --boot-disk-provisioned-iops=$BOOT_IOPS \
    --boot-disk-provisioned-throughput=$BOOT_THROUGHPUT \
    --zone $ZONE2 \
    --machine-type $MACHINE_TYPE \
    --subnet $SUBNET \
    --image-family ubuntu-2204-lts \
    --image-project ubuntu-os-cloud \
    --disk="name=sqlfci-mw-data-disk,scope=regional,mode=rw" \
    --disk="name=sqlfci-mw-log-disk,scope=regional,mode=rw" \
    --scopes=compute-rw,trace,service-control,service-management,pubsub,monitoring-write,logging-write,storage-rw \
    --tags=sqlfci
    
  4. 建立 Windows 用戶端 VM (cl-node),用於測試連線。

    gcloud compute instances create cl-node \
    --boot-disk-size=100 \
    --boot-disk-type=hyperdisk-balanced \
    --machine-type $MACHINE_TYPE \
    --image-family windows-2025 \
    --image-project windows-cloud \
    --zone $ZONE1 \
    --subnet $SUBNET \
    --scopes=compute-rw,trace,service-control,service-management,pubsub,monitoring-write,logging-write,storage-rw
    

建立內部負載平衡器

  1. 為叢集和負載平衡器保留 IP 位址。

    gcloud compute addresses create sqlfci-lb-ipaddress \
    --region=$REGION \
    --subnet=$SUBNET \
    --purpose="SHARED_LOADBALANCER_VIP"
    CLUSTER_ADDRESS=$(gcloud compute addresses describe sqlfci-lb-ipaddress \
    --region $REGION \
    --format=value\(address\)) && \
    echo "Cluster IP address: $CLUSTER_ADDRESS"
    
  2. 為叢集建立健康狀態檢查。

    gcloud compute health-checks create tcp sqlfci-healthcheck \
    --port="60008" \
    --region=$REGION \
    --check-interval=3 \
    --timeout=2 \
    --unhealthy-threshold=2 \
    --healthy-threshold=5
    
  3. 如要允許連線至健康狀態檢查通訊埠,請建立防火牆規則。

    gcloud compute firewall-rules create "allow-sqlfci-healthcheck-60008" \
    --allow "tcp:60008" \
    --target-tags sqlfci \
    --network $VPC_NAME \
    --source-ranges="35.191.0.0/16,130.211.0.0/22" \
    --priority="1000"
    

    詳情請參閱「健康狀態檢查的防火牆規則」。

  4. 為叢集節點建立執行個體群組。

    gcloud compute instance-groups unmanaged create sqlfci-1-uig \
    --zone=$ZONE1
    gcloud compute instance-groups unmanaged add-instances sqlfci-1-uig \
    --zone=$ZONE1 \
    --instances=node-1
    
    gcloud compute instance-groups unmanaged create sqlfci-2-uig \
    --zone=$ZONE2
    gcloud compute instance-groups unmanaged add-instances sqlfci-2-uig \
    --zone=$ZONE2 \
    --instances=node-2
    
  5. 建立負載平衡器後端服務。

    gcloud compute backend-services create sqlfci-backend-services \
    --region=$REGION \
    --load-balancing-scheme="INTERNAL" \
    --protocol="TCP" \
    --health-checks=sqlfci-healthcheck \
    --health-checks-region=$REGION
    
    gcloud compute backend-services add-backend sqlfci-backend-services \
    --region=$REGION \
    --instance-group=sqlfci-1-uig \
    --instance-group-zone=$ZONE1
    
    gcloud compute backend-services add-backend sqlfci-backend-services \
    --region=$REGION \
    --instance-group=sqlfci-2-uig \
    --instance-group-zone=$ZONE2
    
  6. 建立負載平衡器轉送規則。

    gcloud compute forwarding-rules create "sqlfci-forwarding-rule" \
    --load-balancing-scheme=INTERNAL \
    --network=$VPC_NAME \
    --subnet=$SUBNET \
    --region=$REGION \
    --address=$CLUSTER_ADDRESS \
    --ip-protocol="TCP" \
    --ports="ALL" \
    --backend-service=sqlfci-backend-services \
    --backend-service-region=$REGION
    
  7. 建立 Cloud Storage bucket,將檔案從主要叢集節點轉移至次要叢集節點。

    gcloud storage buckets create gs://BUCKET_NAME \
    --location=$REGION \
    --public-access-prevention
    

    BUCKET_NAME 替換為要建立的值區名稱。

    詳情請參閱「建立值區」。

安裝必要軟體

在將參與容錯移轉叢集的兩個 Linux VM (node-1node-2) 上,下載、安裝及設定 SQL Server 引擎和叢集管理。

  1. 使用 SSH 連線至每個 VM。詳情請參閱「連線至 Linux VM」和「控管 SSH 網路存取權的最佳做法」。

  2. 更新 node-1node-2 上的 hosts file

    1. 開啟 hosts file 進行編輯。

      sudo vi /etc/hosts
      
    2. 找出每個 Linux VM 的內部 IP 位址,然後將主機項目附加到檔案底部。

      前往 Compute Engine

      NODE1_INTERNAL_IP node-1
      NODE2_INTERNAL_IP node-2
      

      NODE1_INTERNAL_IPNODE2_INTERNAL_IP 替換為各個 Linux VM 的內部 IP 位址。

  3. 檢查 VM 之間的通訊。參與 Always On 可用性群組的所有 VM 必須能夠與其他 VM 通訊:返回每個 Linux VM,從每個 VM 執行指令,並確認所有 VM 都能彼此通訊。

    ping -c 4 node-1
    ping -c 4 node-2
    

    輸出內容會與以下所示內容類似:

    PING node-1 (10.128.0.37) 56(84) bytes of data.
    64 bytes from node-1 (10.128.0.37): icmp_seq=1 ttl=128 time=1.91 ms
    64 bytes from node-1 (10.128.0.37): icmp_seq=2 ttl=128 time=0.234 ms
    64 bytes from node-1 (10.128.0.37): icmp_seq=3 ttl=128 time=0.249 ms
    64 bytes from node-1 (10.128.0.37): icmp_seq=4 ttl=128 time=0.263 ms
    
  4. 安裝 SQL Server 2025。

    1. 將 SQL Server 存放區新增至系統。

      curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
      curl -fsSL https://packages.microsoft.com/config/ubuntu/22.04/mssql-server-2025.list | sudo tee /etc/apt/sources.list.d/mssql-server-2025.list
      sudo apt-get update
      
    2. 安裝 SQL Server。

      sudo apt-get install -y mssql-server
      
    3. 安裝 SQL Server 開發人員工具。 在將加入容錯移轉叢集的兩個 Linux VM 上,下載並安裝 SQL Server 工具。

      curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
      sudo apt-get update
      
      sudo ACCEPT_EULA=Y apt-get install -y mssql-tools18 unixodbc-dev
      
  5. 安裝 Pacemaker。 Pacemaker 是開放原始碼的高可用性資源管理員軟體,可與 Corosync 叢集引擎搭配使用。在本節中,您將在兩個叢集 VM 上安裝 Pacemaker。

    1. node-1node-2 上安裝 Pacemaker。

      sudo apt-get install -y pacemaker pcs fence-agents resource-agents pacemaker-cli-utils crmsh
      
    2. 安裝 Pacemaker 的 SQL Server 資源代理程式。

      sudo apt-get install -y mssql-server-ha
      
  6. 如果 VM 已啟用防火牆,請為 SQL Server 開啟防火牆。

    1. 執行下列指令,檢查 Uncomplicated Firewall 是否已安裝並啟用。

      sudo ufw status
      
    2. 如果狀態為「active」,請執行下列指令開啟通訊埠。 如果防火牆服務未執行,可以忽略這個步驟。

      sudo ufw allow 1433
      sudo ufw allow 5022
      sudo ufw reload
      

設定主要資料庫節點

在本節中,您將初始化兩個多重寫入器磁碟,並為每個磁碟設定磁碟區群組和邏輯群組。

設定 LVM。

設定 LVM。

  1. 備份現有設定。

    sudo cp /etc/lvm/lvm.conf /etc/lvm/lvm.conf.bak
    
  2. 更新系統 ID 來源:

    sudo sed -i 's/^\(\s*system_id_source\s*=\s*\)"none"/\1"uname"/' /etc/lvm/lvm.conf
    
  3. 確認變更已成功。

    grep 'system_id_source *= *"uname"' /etc/lvm/lvm.conf
    
  4. 設定 LVM 磁碟區群組和邏輯磁碟區。

    sudo pvcreate /dev/nvme0n2 /dev/nvme0n3
    sudo pvs
    sudo vgcreate vgdata /dev/nvme0n2
    sudo lvcreate -l 100%FREE -n lvdata vgdata
    sudo vgcreate vglogtmp /dev/nvme0n3
    sudo lvcreate -l 70%FREE  -n lvlog vglogtmp
    sudo lvcreate -l 100%FREE -n lvtmp vglogtmp
    sudo vgs -o+systemid
    
  5. 以 64 KB 區塊大小將磁碟區格式化為 xfs 檔案系統。

    sudo mkfs.xfs -d su=64k,sw=1 -L data /dev/vgdata/lvdata -f
    sudo mkfs.xfs -d su=64k,sw=1 -L dblog /dev/vglogtmp/lvlog -f
    sudo mkfs.xfs -d su=64k,sw=1 -L tmp /dev/vglogtmp/lvtmp -f
    
  6. 確認磁碟區已建立。

    sudo lvs
    

掛接及格式化磁碟

為共用磁碟設定掛接點,並授予 mssql 使用者存取權。

  1. 為新磁碟區建立掛接點。

    sudo mkdir /mssql
    sudo mkdir -p /mssql/db_data
    sudo mkdir -p /mssql/db_log
    sudo mkdir -p /mssql/db_temp
    
  2. 將 LVM 磁碟區掛接至掛接點。

    sudo mount /dev/vgdata/lvdata /mssql/db_data
    sudo mount /dev/vglogtmp/lvlog /mssql/db_log
    sudo mount /dev/vglogtmp/lvtmp /mssql/db_temp
    
  3. mssql使用者設為掛接點的擁有者。

    sudo chown mssql:mssql /mssql/db_data
    sudo chown mssql:mssql /mssql/db_log
    sudo chown mssql:mssql /mssql/db_temp
    
  4. 設定 SQL Server:

    1. 設定變數,將主資料庫重新定位至共用儲存空間,然後執行 mssql-conf 工具。

      sudo MSSQL_MASTER_DATA_FILE="/mssql/db_data/master.mdf" MSSQL_MASTER_LOG_FILE="/mssql/db_data/mastlog.ldf" /opt/mssql/bin/mssql-conf setup
      
    2. 選擇 開發人員版 的 SQL Server 版本,並接受授權協議。

      開發人員版包含所有企業版功能,但只能用於非正式環境。如要進一步瞭解 SQL Server 版本和 Microsoft 授權,請參閱這篇文章這篇文章

    3. 指定 SA 帳戶的密碼。

    4. 確認 mssql-server 服務正在執行。

      systemctl status mssql-server --no-pager
      

設定 SQL Server 和 Pacemaker

  1. 為 Pacemaker 建立 SQL Server 使用者。 將 SA_PASSWORD 替換為 SQL Server 上 SA 帳戶的密碼,並將 PA_PASSWORD 替換為 pacemaker 帳戶使用的密碼。

    QUERY="
    CREATE LOGIN [pacemaker] with PASSWORD= N'PA_PASSWORD';
    ALTER SERVER ROLE [sysadmin] ADD MEMBER [pacemaker];
    GO"
    
    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  2. 將 Pacemaker 登入名稱和密碼新增至 SQL Server 密碼資料夾。

    {
      echo 'pacemaker'
      echo PA_PASSWORD'
    } | sudo tee /var/opt/mssql/secrets/passwd > /dev/null
    sudo chown root:root /var/opt/mssql/secrets/passwd
    sudo chmod 400 /var/opt/mssql/secrets/passwd
    
  3. 更新 SQL Server 設定,使用新的資料、記錄和暫時位置。您也會設定 SQL Server 建議設定。

    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdatadir /mssql/db_data
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultlogdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdumpdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf traceflag 9944 3979 on
    sudo /opt/mssql/bin/mssql-conf set control.alternatewritethrough 0
    sudo /opt/mssql/bin/mssql-conf set control.writethrough 1
    

將 TempDB 移至共用磁碟

  1. 取得暫存資料庫檔案清單,並用來建立 Alter 查詢。這個查詢會在下一個步驟中用於設定 TempDB 檔案的新位置。

    QUERY="
    SET NOCOUNT ON;
    SELECT 'ALTER DATABASE tempdb MODIFY FILE (NAME = [' + f.name + '],' + ' FILENAME = ''/mssql/db_temp/' + f.name + CASE WHEN f.type = 1 THEN '.ldf' ELSE '.mdf' END + ''');' FROM sys.master_files f WHERE f.database_id = DB_ID(N'tempdb');"
    
    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  2. 擷取上一個指令的輸出內容。 您將使用輸出內容組成下一個要執行的指令。

    QUERY="QUERY_OUTPUT"
    

    使用輸出內容的查詢範例:

    QUERY="
    ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev], FILENAME = '/mssql/db_temp/tempdev.mdf');
    ALTER DATABASE tempdb MODIFY FILE (NAME = [templog], FILENAME = '/mssql/db_temp/templog.ldf');
    ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev2], FILENAME = '/mssql/db_temp/tempdev2.mdf');
    ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev3], FILENAME = '/mssql/db_temp/tempdev3.mdf');"
    

  3. 執行產生的 SQL 指令,移動 TempDB 檔案。

    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  4. 重新啟動 SQL Server 服務,變更就會生效。

    sudo systemctl restart mssql-server.service
    
  5. 確認已建立 TempDB 檔案。

    ls -l /mssql/db_temp/
    
  6. 確認 SQL Server 服務正在執行。

    systemctl status mssql-server --no-pager
    

設定 HAProxy

  1. hacluster 設定新密碼。

    sudo passwd hacluster
    
  2. 如要完成設定並測試網路負載平衡器是否設定正確,請在兩個叢集節點上安裝及設定 HAProxy tcp listener

    1. 安裝 HAProxy。

      sudo apt-get install haproxy
      
    2. 輸入 Y 即可完成安裝。

    3. 編輯 haproxy.cfg 檔案。

      sudo vi /etc/haproxy/haproxy.cfg
      
    4. haproxy.cfg filedefaults 區段中,將模式變更為 tcp

    5. haproxy.cfg 檔案結尾處附加下列部分。

      #---------------------------------------------------------------
      # Set up health check listener for SQL Server Availability Group
      #---------------------------------------------------------------
      listen healthcheck
      bind *:60008
      
  3. 啟動 HAProxy 服務。

    sudo systemctl start haproxy.service
    sudo systemctl status haproxy.service
    
  4. 停止並停用 HAProxy 服務。

    sudo systemctl stop haproxy.service
    sudo systemctl disable haproxy.service
    
  5. 使用下列指令,將機器金鑰檔案上傳至 Cloud Storage。

    sudo gcloud storage cp /var/opt/mssql/secrets/machine-key gs://BUCKET_NAME/
    

    請將 BUCKET_NAME 替換為建立的值區名稱。

  6. 停止並停用 SQL Server 服務。從這個時間點開始,服務將由叢集控管。

    sudo systemctl stop mssql-server.service
    sudo systemctl disable mssql-server.service
    
  7. 卸載共用儲存空間。

    sudo umount /mssql/db_data
    sudo umount /mssql/db_log
    sudo umount /mssql/db_temp
    
  8. 清理現有的預設叢集設定。

    sudo pcs cluster destroy
    

設定次要節點

  1. 為 LVM 磁碟區建立掛接點。由於這個磁碟已與「node-1」共用,因此不必格式化。設定 node-1 時,您已格式化磁碟並設定 LVM 磁碟區。

    sudo mkdir /mssql
    sudo mkdir -p /mssql/db_data
    sudo mkdir -p /mssql/db_log
    sudo mkdir -p /mssql/db_temp
    
    sudo chown mssql:mssql /mssql/db_data
    sudo chown mssql:mssql /mssql/db_log
    sudo chown mssql:mssql /mssql/db_temp
    
  2. 設定 SQL Server。

    1. 如要將主資料庫遷移至共用資料磁碟,請設定下列變數,然後執行 mssql-conf 工具來套用變更。

      sudo MSSQL_MASTER_DATA_FILE="/mssql/db_data/master.mdf" MSSQL_MASTER_LOG_FILE="/mssql/db_data/mastlog.ldf" /opt/mssql/bin/mssql-conf setup
      
    2. 選擇 開發人員版 的 SQL Server 版本,並接受授權協議。

      開發人員版包含所有企業版功能,但只能用於非正式環境。如要進一步瞭解 SQL Server 版本和 Microsoft 授權,請參閱這篇文章這篇文章

    3. 指定 SA 帳戶的密碼。

    4. 確認 mssql-server 服務正在執行。

      systemctl status mssql-server --no-pager
      
  3. 為 Pacemaker 叢集建立 SQL Server 使用者。 將 SA_PASSWORD 替換為 SQL Server 上 SA 帳戶的密碼,並將 PA_PASSWORD 替換為 pacemaker 帳戶使用的密碼。

    QUERY="
    CREATE LOGIN [pacemaker] with PASSWORD= N'PA_PASSWORD';
    ALTER SERVER ROLE [sysadmin] ADD MEMBER [pacemaker];
    GO"
    
    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  4. 將 Pacemaker 登入名稱和密碼新增至 SQL Server 密碼資料夾。

    {
      echo 'pacemaker'
      echo 'PA_PASSWORD'
    } | sudo tee /var/opt/mssql/secrets/passwd > /dev/null
    sudo chown root:root /var/opt/mssql/secrets/passwd
    sudo chmod 400 /var/opt/mssql/secrets/passwd
    
  5. 更新 SQL Server 設定,使用新的資料、記錄和暫時位置。您也會設定 SQL Server 建議設定。

    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdatadir /mssql/db_data
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultlogdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdumpdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf traceflag 9944 3979 on
    sudo /opt/mssql/bin/mssql-conf set control.alternatewritethrough 0
    sudo /opt/mssql/bin/mssql-conf set control.writethrough 1
    
  6. 將 TempDB 移至共用資料磁碟。

    1. 取得暫存資料庫檔案清單,並用來建立 Alter 查詢。

      QUERY="
      SET NOCOUNT ON;
      SELECT 'ALTER DATABASE tempdb MODIFY FILE (NAME = [' + f.name + '],' + ' FILENAME = ''/mssql/db_temp/' + f.name + CASE WHEN f.type = 1 THEN '.ldf' ELSE '.mdf' END + ''');' FROM sys.master_files f WHERE f.database_id = DB_ID(N'tempdb');"
      
      /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
      
    2. 擷取上一個指令的輸出內容。您將使用輸出內容組成下一個要執行的指令。

      QUERY="QUERY_OUTPUT"
      

      使用輸出內容的查詢範例:

      QUERY="
      ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev], FILENAME = '/mssql/db_temp/tempdev.mdf');
      ALTER DATABASE tempdb MODIFY FILE (NAME = [templog], FILENAME = '/mssql/db_temp/templog.ldf');
      ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev2], FILENAME = '/mssql/db_temp/tempdev2.mdf');
      ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev3], FILENAME = '/mssql/db_temp/tempdev3.mdf');"
      
    3. 如要移動 TempDB 檔案,請執行產生的 SQL 指令。

      /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
      
    4. 如要讓變更生效,請重新啟動 SQL Server 服務。

      sudo systemctl restart mssql-server.service
      
    5. 確認 SQL Server 服務正在執行。

      sudo systemctl status mssql-server --no-pager
      
    6. 確認已建立 TempDB 檔案。

      ls -l /mssql/db_temp/
      
  7. 停止並暫時停用 SQL Server 服務。

    sudo systemctl stop mssql-server.service
    sudo systemctl disable mssql-server.service
    
  8. 為確保兩個節點都使用相同的 SQL Server 金鑰,請從 node-1 下載電腦金鑰檔案。

    sudo rm /var/opt/mssql/secrets/machine-key
    sudo gcloud storage cp gs://BUCKET_NAME/machine-key /var/opt/mssql/secrets/machine-key
    sudo chown mssql:mssql /var/opt/mssql/secrets/machine-key
    sudo chmod 0600  /var/opt/mssql/secrets/machine-key
    
  9. 設定 LVM。

    1. 備份現有設定。

      sudo cp /etc/lvm/lvm.conf /etc/lvm/lvm.conf.bak
      
    2. 更新系統 ID 來源。

      sudo sed -i 's/^\(\s*system_id_source\s*=\s*\)"none"/\1"uname"/' /etc/lvm/lvm.conf
      

      執行下列指令,確認變更:

      cat /etc/lvm/lvm.conf | grep uname
      

      輸出內容會與以下所示內容類似:

      #     Set the system ID from the hostname (uname) of the system.
      system_id_source = "uname"
      
    3. 確認變更已成功。

      grep 'system_id_source *= *"uname"' /etc/lvm/lvm.conf
      
  10. hacluster 設定新密碼。

    sudo passwd hacluster
    
  11. 如要完成設定並測試網路負載平衡器是否設定正確,請在兩個叢集節點上安裝及設定 HAProxy tcp listener

    1. 安裝 HAProxy。

      sudo apt-get install haproxy
      

    2. 選擇 Y 完成安裝。

    3. 編輯 haproxy.cfg 檔案。

      sudo vi /etc/haproxy/haproxy.cfg
      
    4. haproxy.cfg file 的預設值部分中,將模式變更為 tcp

    5. haproxy.cfg 檔案結尾處附加下列部分。

      #---------------------------------------------------------------
      # Set up health check listener for SQL Server Availability Group
      #---------------------------------------------------------------
      listen healthcheck
      bind *:60008
      
    6. 啟動 HAProxy 服務。

      sudo systemctl start haproxy.service
      sudo systemctl status haproxy.service
      
  12. 停止並停用 HAProxy 服務。

    sudo systemctl stop haproxy.service
    sudo systemctl disable haproxy.service
    
  13. 清除現有的預設叢集設定。

    sudo pcs cluster destroy
    

完成叢集設定

返回 node-1 繼續設定叢集。

  1. hacluster 使用者身分進行驗證。

    sudo pcs host auth node-1 node-2 -u hacluster -p "HA_PASSWORD"
    
  2. 建立名為 ubuntu_fci 的叢集。

    sudo pcs cluster setup ubuntu_fci node-1 addr="NODE1_INTERNAL_IP" node-2 addr="NODE2_INTERNAL_IP" --start --enable
    
  3. 為雙節點叢集設定無仲裁政策。

    sudo pcs property set no-quorum-policy="ignore"
    
  4. 建立虛擬 IP 位址叢集資源。

    sudo pcs resource create pcs-cluster-vip ocf:heartbeat:IPaddr2 ip="CLUSTER_ADDRESS" cidr_netmask=32 nic=ens3 op monitor interval=30s
    

    CLUSTER_ADDRESS 替換為先前保留的 IP 位址。

  5. 為所有共用磁碟區建立叢集資源物件。

    sudo pcs resource create vgdata ocf:heartbeat:LVM-activate vgname=vgdata vg_access_mode=system_id activation_mode=exclusive
    sudo pcs resource create vglogtmp ocf:heartbeat:LVM-activate vgname=vglogtmp vg_access_mode=system_id activation_mode=exclusive
    sudo pcs resource create data_dir ocf:heartbeat:Filesystem device="/dev/mapper/vgdata-lvdata" directory="/mssql/db_data" fstype="xfs"
    sudo pcs resource create log_dir ocf:heartbeat:Filesystem device="/dev/mapper/vglogtmp-lvlog" directory="/mssql/db_log" fstype="xfs"
    sudo pcs resource create tmp_dir ocf:heartbeat:Filesystem device="/dev/mapper/vglogtmp-lvtmp" directory="/mssql/db_temp" fstype="xfs"
    
  6. 建立資源群組,並將所有建立的物件新增至新群組。

    sudo pcs resource group add sql_group pcs-cluster-vip vgdata vglogtmp data_dir log_dir tmp_dir
    
  7. 為 Microsoft SQL Server 服務建立叢集資源,並新增至現有資源群組。

    sudo pcs resource create sql_fci ocf:mssql:fci  op stop timeout=60s --group sql_group
    
  8. 為 HAProxy 建立叢集資源,並加入同一個群組。

    sudo pcs resource create pcs-healthcheck systemd:haproxy.service op monitor interval=20s timeout=30s --group sql_group
    
  9. 建立叢集限制,控管資源的啟動順序。

    sudo pcs constraint order set  pcs-cluster-vip vgdata vglogtmp data_dir log_dir tmp_dir sql_fci pcs-healthcheck
    

設定 STONITH 柵欄

STONITH 是一種防護策略,可維護高可用性叢集中節點的完整性。STONITH 服務會在節點層級運作,保護叢集免於無回應或狀態不明的節點影響。建議使用專為 Compute Engine 打造的fence_gce防護裝置 Google Cloud。

設定圍欄裝置

  1. 檢查 fence_gce - Compute Engine 的 Fence 代理程式是否已安裝在 node-1 上。

    sudo pcs stonith list | grep fence_gce
    

    如需詳細資訊,請參閱:

  2. 設定叢集防護資源。

    sudo pcs stonith create node-1-fence fence_gce \
    plug=node-1 \
    zone=ZONE1 \
    project=PROJECT_ID \
    pcmk_reboot_timeout=300 pcmk_monitor_retries=4 pcmk_delay_max=30 \
    op monitor interval="300s" timeout="120s" \
    op start interval="0" timeout="60s"
    
    sudo pcs stonith create node-2-fence fence_gce \
    plug=node-2 \
    zone=ZONE2 \
    project=PROJECT_ID \
    pcmk_reboot_timeout=300 pcmk_monitor_retries=4 pcmk_delay_max=30 \
    op monitor interval="300s" timeout="120s" \
    op start interval="0" timeout="60s"
    

    ZONE1ZONE2 替換為部署 Linux VM 的區域,並將 PROJECT_ID 替換為專案 ID。

  3. 您可以執行 status 指令,測試隔離代理程式的狀態。

    sudo fence_gce -o status -n node-1 --zone=ZONE1
    sudo fence_gce -o status -n node-2 --zone=ZONE2
    

    輸出內容會與以下所示內容類似:

    Status: ON
    

ZONE1ZONE2 替換為部署 Linux VM 的區域。

  1. 為防護裝置建立位置限制,確保裝置只在預期執行個體上運作。

    sudo pcs constraint location node-1-fence avoids node-1
    sudo pcs constraint location node-2-fence avoids node-2
    
  2. 在 Pacemaker 叢集中啟用防護機制,並設定叢集防護機制逾時。

    sudo pcs -f stonith_cfg property set stonith-enabled=true
    sudo pcs property set stonith-timeout="300s"
    
  3. 清除叢集啟動程序。

    sudo pcs resource cleanup
    
  4. 檢查叢集的狀態。

    sudo crm status
    

    輸出內容會與以下所示內容類似:

      Cluster Summary:
        * Stack: corosync
        * Current DC: node-1 (version 2.1.2-ada5c3b36e2) - partition with quorum
        * Last updated: Tue Jun  2 21:36:47 2026
        * Last change:  Mon Apr 27 12:31:58 2026 by root via crm_resource on node-1
        * 2 nodes configured
        * 10 resource instances configured
    
      Node List:
        * Online: [ node-1 node-2 ]
    
      Full List of Resources:
        * Resource Group: sql_group:
          * pcs-cluster-vip   (ocf:heartbeat:IPaddr2):         Started node-2
          * vgdata    (ocf:heartbeat:LVM-activate):    Started node-2
          * vglogtmp  (ocf:heartbeat:LVM-activate):    Started node-2
          * data_dir  (ocf:heartbeat:Filesystem):      Started node-2
          * log_dir   (ocf:heartbeat:Filesystem):      Started node-2
          * tmp_dir   (ocf:heartbeat:Filesystem):      Started node-2
          * sql_fci   (ocf:mssql:fci):                 Started node-2
          * pcs-healthcheck   (systemd:haproxy.service):       Started node-2
        * node-1-fence       (stonith:fence_gce):     Started node-2
        * node2-fence        (stonith:fence_gce):     Started node-1
    

測試圍欄裝置

設定圍籬裝置後,建議您按照下列步驟進行測試。

  1. node-2 停止圍籬。

    1. 連線至 node-1,然後執行下列指令,從叢集測試與 node-2 相關聯的柵欄裝置。

      fence_gce -o off -n node-2 --zone=ZONE2
      

      輸出內容會與以下所示內容類似:

      Success: Powered OFF
      
    2. 檢查叢集的狀態。

      sudo crm status
      

      輸出內容會與以下所示內容類似:

        Cluster Summary:
          * Stack: corosync
          * Current DC: node-1 (version 2.1.2-ada5c3b36e2) - partition with quorum
          * Last updated: Tue Jun  2 21:52:00 2026
          * Last change:  Mon Apr 27 12:31:58 2026 by root via crm_resource on node-1
          * 2 nodes configured
          * 10 resource instances configured
    
        Node List:
          * Online: [ node-1 ]
          * OFFLINE: [ node-2 ]
    
        Full List of Resources:
          * Resource Group: sql_group:
            * pcs-cluster-vip   (ocf:heartbeat:IPaddr2): Started node-1
            * vgdata    (ocf:heartbeat:LVM-activate):    Started node-1
            * vglogtmp  (ocf:heartbeat:LVM-activate):    Started node-1
            * data_dir  (ocf:heartbeat:Filesystem):      Started node-1
            * log_dir   (ocf:heartbeat:Filesystem):      Started node-1
            * tmp_dir   (ocf:heartbeat:Filesystem):      Started node-1
            * sql_fci   (ocf:mssql:fci):                 Started node-1
            * pcs-healthcheck   (systemd:haproxy.service):       Started node-1
          * node-1-fence       (stonith:fence_gce):     Stopped
          * node-2-fence        (stonith:fence_gce):     Started node-1
    
    1. 您也會看到 Compute Engine 中的 node-2 已關閉。

      前往 Compute Engine

  2. node-2 上重新啟動圍欄。

    1. 返回 node-1,然後執行下列指令,再次重新啟動執行個體。

      fence_gce -o on -n node-2 --zone=ZONE2
      

      輸出內容會與以下所示內容類似:

      Success: Powered ON
      
    2. 在 Pacemaker 和 Compute Engine 中檢查叢集狀態。稍待片刻,node-2就會恢復連線。

       $ sudo crm status
      

測試容錯移轉

現在可以測試容錯移轉是否如預期運作。

  1. 為 VM 執行個體建立使用者名稱和密碼
  2. 使用遠端桌面連線至 VM,並使用上一步建立的使用者名稱和密碼登入。
  3. 透過遠端桌面連線至 cl-node 上的 Windows VM。
  4. 開啟 PowerShell 工作階段。
  5. 執行下列指令碼,連線至伺服器。每隔五秒,指令碼就會使用可用性群組接聽程式連線至 SQL Server,並查詢伺服器名稱。

    while ($True){
      try {
        $Conn = New-Object System.Data.SqlClient.SqlConnection
        $Conn.ConnectionString = "Server=CLUSTER_ADDRESS;User ID=sa;Password=SA_PASSWORD;Initial Catalog=master"
        $Conn.Open()
    
        $Cmd =  $Conn.CreateCommand()
        $Cmd.CommandText = "SELECT SERVERPROPERTY('ComputerNamePhysicalNetBIOS')"
    
        $Result = $Cmd.ExecuteReader()
        if ($Result.Read()) {
          $currentNode = $Result.GetString(0)
          Write-Host "Current Node: $currentNode at $(Get-Date)"
        }
    
        $Conn.Close()
        Start-Sleep -Seconds 5
      }
      catch {
          Write-Host "SQL Connection Failed at $(Get-Date). Retrying..."
          Start-Sleep -Seconds 15 # Wait before retrying
      }
    }
    

    CLUSTER_ADDRESS 替換為接聽程式 IP 位址,並將 SA_PASSWORD 替換為 SQL Server 上 SA 帳戶的密碼。

    輸出內容會與以下所示內容類似:

      Current Node: node-1 at 06/09/2026 20:24:35
      Current Node: node-1 at 06/09/2026 20:24:40
      Current Node: node-1 at 06/09/2026 20:24:45
      Current Node: node-1 at 06/09/2026 20:24:50
      Current Node: node-1 at 06/09/2026 20:24:55
    

    讓指令碼繼續執行。

  6. 觸發容錯移轉至 node-2:從 node-1 返回 SSH 終端機,然後執行下列指令。

    sudo pcs resource move sql_group node-2
    
  7. 返回 cl-node 的 PowerShell 工作階段。

    1. 觀察執行指令碼的輸出內容,並注意伺服器名稱會因容錯移轉而從 node-1 變更為 node-2

    輸出內容會與以下所示內容類似:

      Current Node: node-1 at 06/09/2026 20:28:51
      Current Node: node-1 at 06/09/2026 20:28:56
      SQL Connection Failed at 06/09/2026 20:29:16. Retrying...
      Current Node: node-2 at 06/09/2026 20:29:31
      Current Node: node-2 at 06/09/2026 20:29:36
    
  8. 啟動容錯回復至 node-1。在節點 1 的指令列中,執行下列指令

    sudo pcs resource move sql_group node-1
    
  9. 返回 cl-node 的 Powershell,按下 Ctrl+C 停止指令碼。

清除所用資源

完成教學課程後,您可以清除所建立的資源,這樣資源就不會繼續使用配額,也不會產生費用。下列各節將說明如何刪除或關閉這些資源。

刪除專案

如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。

刪除專案的方法如下:

  1. 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。

    前往「Manage resources」(管理資源)

  2. 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)
  3. 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。

後續步驟