GDC 氣隙隔離環境中的 MySQL 資料庫參考實作

本指南提供詳盡的逐步教學課程,說明如何在 Google Distributed Cloud (GDC) 氣隙隔離環境中,跨三個可用區部署高可用性 MySQL 8.4 InnoDB 叢集。這項架構採用 Group Replication 進行 Paxos 型共識、MySQL Router 進行智慧型連線路由,以及 MySQL Shell 進行叢集協調。

這項實作方式嚴格採用虛擬機器 (VM),可略過 GDC 實體隔離方案限制,避免跨可用區 Kubernetes 延展叢集發生問題,確保完整的多可用區韌性,不會有資料損失的風險。

架構圖如下:

執行服務共置堆疊的三個 VM 架構。

事前準備

部署 VM

按照「建立及啟動 VM 執行個體」一文的說明,在三個可用區中建立三個 VM。

設定本機環境,透過金鑰配對與 VM 建立 SSH 連線: 連線至 VM

您需要此套件才能使用安全複製 (SCP) 傳輸套件: 傳輸檔案

我們使用 Ubuntu 22.04 作業系統和 n3-standard-2-gdc 機型進行驗證。 如果是正式環境,請使用資源較多的機型。

使用下列方式取得 VM 的 IP:

VM_NAME=$1

if [[ -z "$VM_NAME" ]]; then
  echo "Error: VM_NAME must be provided."
  echo "Usage: $0 <VM_NAME>"
  exit 1
fi

# 1. Get External IP from 'instances list'
EXT_IP=$(gdcloud compute instances list | awk -v vm="${VM_NAME}" '$1 == vm {print $5}')

if [[ -z "$EXT_IP" ]]; then
  echo "Error: Could not find VM '${VM_NAME}' in the instance list."
  exit 1
fi

INTERNAL_IP=$(gdcloud compute instances describe "${VM_NAME}" | awk '/^status:/ {in_status=1} in_status && /- [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $2; exit}' | cut -d'/' -f1)

if [[ -z "$INTERNAL_IP" ]]; then
  INTERNAL_IP="<Not assigned or not found>"
fi

echo "${VM_NAME}"
echo "External IP: ${EXT_IP}"
echo "Internal IP: ${INTERNAL_IP}"

設定環境變數

在本機工作站的殼層工作階段中設定下列變數:

export PROJECT_ID="your-project-id"
export VM1_NAME="mysql-node-1"
export VM2_NAME="mysql-node-2"
export VM3_NAME="mysql-node-3"
export VM1_IP="10.0.1.245" # Zone 1
export VM2_IP="10.0.1.241" # Zone 2
export VM3_IP="10.0.1.242" # Zone 3
export CLUSTER_NAME="mysql-ha-cluster"

網路設定

如需從專案或機構外部連線至資料庫,請務必相應設定 PNP (專案網路政策)。

根據用途,按照「PNP 總覽」一節操作。

準備氣隙隔離軟體

使用 Docker 下載套件

從連線的工作站執行下列指令,擷取 MySQL 8.4 和 Shell 元件:

mkdir -p ./mysql-packages
docker run --rm -v "$(pwd)/mysql-packages:/packages" ubuntu:22.04 bash -c "
  apt-get update && apt-get install -y curl gnupg apt-rdepends wget lsb-release
  curl -LsS https://dev.mysql.com/get/mysql-apt-config_0.8.39-1_all.deb -o config.deb
  # Configure for MySQL 8.4 LTS
  DEBIAN_FRONTEND=noninteractive dpkg -i config.deb 
  apt-get update
  cd /packages
  PACKAGES='mysql-server mysql-shell mysql-router'
  apt-get download \$(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends \${PACKAGES} | grep '^\w')
"

轉移及安裝

.deb 檔案上傳至所有三部 VM 的 /tmp/packages/,然後安裝:

# From workstation: scp ./mysql-packages/*.deb ${VM_IP}:/tmp/packages/
# On each VM:
sudo dpkg -i /tmp/packages/*.deb

確認 dpkg 未傳回任何錯誤。如果有的話,請檢查記錄檔,看看可能缺少哪些 .deb 檔案包,並將這些檔案包納入下載內容。

系統提示設定根密碼時,請將欄位留白。我們稍後會設定密碼。

MySQL 節點設定

設定 MySQL 以供叢集使用

編輯所有節點上的 /etc/mysql/mysql.conf.d/mysqld.cnf,啟用 GTID 和二進位記錄:

[mysqld]
bind-address = 0.0.0.0
server-id = 1 # Use 2 and 3 for other VMs
gtid-mode = ON
enforce-gtid-consistency = ON
binlog-format = ROW
log-bin = mysql-bin
report_host = 10.0.1.245 # Use the VM's specific IP

重新啟動服務:

sudo systemctl restart mysql

然後連線至資料庫:

sudo mysql

並設定根密碼:

CREATE USER 'root'@'%' IDENTIFIED WITH 'caching_sha2_password' BY 'your_new_secure_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

初始化及驗證 InnoDB 叢集

使用 MySQL Shell 建立叢集

僅在 VM 1 上,使用 MySQL Shell 初始化叢集:

mysqlsh --uri root@localhost
# Inside MySQL Shell:
\js
dba.configureInstance('root@VM1_IP')
var cluster = dba.createCluster('mysql-ha-cluster')
cluster.addInstance('root@VM2_IP')
cluster.addInstance('root@VM3_IP')
cluster.status()

啟動 MySQL Router

在所有三部 VM 上,啟動路由器以偵測新叢集:

sudo mysqlrouter --bootstrap root@VM1_IP --user=mysqlrouter
sudo systemctl restart mysqlrouter
sudo systemctl enable mysqlrouter

驗證負載平衡和連線

從任何節點執行這些指令,確保路由器正確分配流量。

  1. 驗證寫入路由 (Active Primary):查詢通訊埠 6446 (傳統 RW)。這項函式應嚴格傳回目前主要伺服器的名稱。

    mysql -u root -pyour_new_secure_password -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  2. 驗證讀取平衡 (循環式):多次查詢通訊埠 6447 (傳統 RO)。並在叢集中的所有可用節點主機名稱之間循環。

    for i in {1..4}; do mysql -u root -pyour_new_secure_password -h 127.0.0.1 -P 6447 -e "SELECT @@hostname;"; done
    
  3. 檢查連線拓撲:使用 MySQL Shell 確認所有成員都已正確平衡。ONLINE

    mysqlsh --uri root@localhost --cluster
    
    # inside the shell
    > cluster.status()
    

設定全域負載平衡器

使用 GDC 全域 L4 負載平衡器,為應用程式提供單一穩定的虛擬 IP (VIP)。請按照「設定內部全域負載平衡器」一文的說明,設定內部全域 L4 負載平衡器,並將 VM 設為負載平衡器的目標:將 VM 設為負載平衡器目標

自動容錯移轉驗證

這項測試會確認叢集選出新的領導者,且路由器會重新導向流量,不需手動介入。

模擬主要執行個體故障

找出目前的主要節點 (例如節點 1),然後停止 MySQL 服務:

sudo systemctl stop mysql

驗證選舉和路徑轉移

等待 10 到 20 秒,共識通訊協定就會選出新的領導者。

  1. 檢查叢集狀態:從 VM 2 或 3 驗證是否已選出新的主要節點。

    mysqlsh --uri root@localhost --cluster
    
    # inside the shell
    > cluster.status()
    

    確認其中一個剩餘節點標示為 PRIMARY,而失敗的節點標示為 UNREACHABLEMISSING

  2. 驗證寫入路徑:再次測試 RW 連接埠 (6446)。現在應會傳回新主機的主機名稱。

    mysql -u root -p -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  3. 測試全域 VIP 連線:從應用程式伺服器查詢全域 VIP。

    mysql -u root -p -h ${LB_IP} -P 3306 -e "SELECT @@hostname;"
    

復原並驗證重新加入

在失敗的節點上啟動 MySQL 服務,並確認該節點重新加入為次要副本。

sudo systemctl start mysql
mysqlsh --uri root@localhost --cluster -e "cluster.status()"

確認所有三個節點都傳回 ONLINE 狀態。