全部產品
Search
文件中心

Elastic Compute Service:MySQL InnoDB Cluster高可用實踐

更新時間:Apr 16, 2025

單台MySQL資料庫服務存在效能限制和單點故障風險,可能導致業務系統不可用。您可以通過多台ECS執行個體搭建MySQL InnoDB Cluster高可用資料庫叢集,並利用代理服務實現靈活調度和讀寫分離,提升資料庫的可用性和容錯能力。

架構說明

在搭建服務叢集時使用多個可用性區域ECS伺服器,可以降低單可用性區域內機器發生故障時的業務停機風險,增強業務系統的穩定性。

  • 代理節點:負責處理用戶端請求,並將其轉寄到合適的資料庫節點。這些代理節點同樣可以部署在多個可用性區域內,進一步提升高可用性。

  • 主節點:作為叢集中的核心資料處理節點,處理所有的寫入操作並將資料同步給其他節點。

  • 從節點:通過複製主節點的資料保持一致性,僅支援唯讀操作。一旦主節點出現故障,從節點將自動進行新主節點的選舉,保證叢集的持續運行。

環境準備

  1. 建立4台ECS執行個體,本文樣本作業系統為Alibaba Cloud Linux 3。

    說明

    執行個體

    公網訪問

    VPC

    虛擬交換器(vSwitch)

    IP地址

    代理節點

    ECS A

    需要開通公網訪問。

    安裝完成後,可關閉公網訪問以提升安全性。

    192.168.0.0/16

    192.168.0.0/24

    192.168.0.1

    主節點(讀寫)

    ECS B

    192.168.1.0/24

    192.168.1.1

    從節點(唯讀)

    ECS C

    192.168.2.0/24

    192.168.2.1

    從節點(唯讀)

    ECS D

    192.168.2.2

  2. ECS B、ECS C、ECS D安裝 MySQL 服務,確保所有執行個體的MySQL版本一致,本文樣本使用的是MySQL 8.4。如果您不瞭解如何安裝,請參考手動部署MySQL資料庫(Linux)

操作步驟

步驟一:設定叢集節點

  1. 遠端連線ECS B、ECS C、ECS D執行個體。具體操作,請參見使用Workbench工具以SSH協議登入Linux執行個體

  2. ECS B、ECS C、ECS D建立一個用於叢集通訊的MySQL使用者,使用者名稱和密碼需保持一致。

    重要
    • 請將代碼中的<username>替換為建立MySQL使用者的使用者名稱。

    • 請將代碼中的<password>替換為建立MySQL使用者時所用的密碼。需遵循以下密碼原則:密碼必須包含至少一個大寫字母、一個小寫字母、一個數字和一個特殊字元,且總長度不少於8個字元。

    #執行後需要輸入root使用者密碼
    sudo mysql -uroot -p \
    -e "CREATE USER '<username>'@'%' IDENTIFIED BY '<password>';" \
    -e "GRANT ALL PRIVILEGES ON *.* TO '<username>'@'%' WITH GRANT OPTION;" \
    -e "FLUSH PRIVILEGES;"
  3. ECS B、ECS C和ECS D的MySQL設定檔/etc/my.cnf中添加以下內容。

    #設定主機名稱為節點的IP地址
    report_host=192.168.x.x
    #開啟GTID強一致性
    enforce_gtid_consistency=ON
    gtid_mode=ON
    #設定節點服務ID,此值需要每個節點唯一正整數
    server_id=1
    #設定每個節點最大串連數,需要確保每個節點值統一
    max_connections=1024
    #禁用InnoDB以外的儲存引擎
    disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
  4. 重啟ECS B、ECS C和ECS D的MySQL服務,使配置修改生效。

    sudo systemctl restart mysqld

步驟二:建立叢集

  1. 遠端連線ECS A執行個體。具體操作,請參見使用Workbench工具以SSH協議登入Linux執行個體

  2. ECS A安裝mysql-shell、mysql-router。

    #添加MySQL官方源
    sudo rpm -Uvh https://repo.mysql.com/mysql84-community-release-el8-1.noarch.rpm
    #安裝mysql-shell、mysql-router
    sudo dnf install -y mysql-shell mysql-router mysql-community-client
  3. 通過MySQL Shell串連到主節點,請將<username>替換為MySQL的使用者名稱,<IP>替換為主節點IP地址,執行後需要輸入密碼,並且詢問您是否儲存密碼,儲存密碼後再次串連無需輸入密碼。

    mysqlsh --js <username>@<IP>:3306

    image

  4. 建立叢集,您需要修改<cluster_name>為叢集名稱。

    var cluster = dba.createCluster('<cluster_name>');
  5. 為叢集添加從節點,請將<username>替換為MySQL的使用者名稱,<IP>替換為從節點IP地址。您需要為每個從節點都執行添加動作。

    說明

    例如,若要添加節點地址為192.168.2.1,使用者為cluster_user,則命令為:cluster.addInstance('cluster_user@192.168.2.1:3306');

    cluster.addInstance('<username>@<IP>:3306');

    輸出如下資訊,表示從節點添加成功。image

  6. 查看叢集狀態。

    cluster.status();

    輸出如下資訊,表示叢集建立完成。image

步驟三:設定代理節點

  1. 遠端連線ECS A執行個體。具體操作,請參見使用Workbench工具以SSH協議登入Linux執行個體

  2. 執行命令初始化代理設定,請將<username>替換為MySQL的使用者名稱,<IP>替換為主節點IP地址,執行後您需要輸入MySQL使用者的密碼。

    說明

    命令預設將初始設定檔案儲存到目錄/mnt/mysqlrouter下。

    sudo mysqlrouter --bootstrap <username>@<IP>:3306 --directory /mnt/mysqlrouter \
    --conf-bind-address 0.0.0.0 --user=mysqlrouter
  3. 編輯mysqlrouter服務檔案。

    說明

    命令預設使用目錄/mnt/mysqlrouter,如果您修改了目錄,需要修改ExecStart與ExecStop路徑。

    sudo tee /usr/lib/systemd/system/mysqlrouter.service <<-'EOF'
    [Unit]
    Description=MySQL Router Service
    After=network.target
    
    [Service]
    User=mysqlrouter
    Group=mysqlrouter
    Type=forking
    ExecStart=/mnt/mysqlrouter/start.sh
    ExecStop=/mnt/mysqlrouter/stop.sh
    Restart=on-failure
    StandardOutput=journal
    
    [Install]
    WantedBy=multi-user.target
    EOF
  4. 執行命令啟動服務。

    #重新整理服務檔案
    sudo systemctl daemon-reload
    #啟動mysqlrouter
    sudo systemctl start mysqlrouter.service
    #設定mysqlrouter開機自啟
    sudo systemctl enable mysqlrouter.service
    #查看服務狀態
    sudo systemctl status mysqlrouter.service

驗證叢集

通過停止主節點(ECS B)類比故障,驗證叢集能否自動切換節點並繼續提供服務。

  1. 遠端連線ECS A執行個體。具體操作,請參見使用Workbench工具以SSH協議登入Linux執行個體

  2. 使用MySQL用戶端串連到代理節點(ECS A),請將<username>替換為MySQL的使用者名稱。

    mysql -h127.0.0.1 -P6450 -u<username> -p
  3. 執行SQL語句查看叢集狀態,結果顯示三個節點線上,其中一個節點擔任主節點。

    SELECT * FROM performance_schema.replication_group_members;

    image

  4. 執行SQL語句添加測試庫與測試表。

    -- 1. 建立資料庫
    CREATE DATABASE test_db;
    
    -- 2. 使用資料庫
    USE test_db;
    
    -- 3. 建立表:test_table
    CREATE TABLE test_table (
        id INT AUTO_INCREMENT PRIMARY KEY, -- 自增主鍵
        name VARCHAR(100) NOT NULL,        -- 名稱
        value DECIMAL(10, 2) NOT NULL
    );
    
    -- 4. 添加記錄到 test_table
    INSERT INTO test_table (name, value) VALUES
    ('Item A', 100.50),
    ('Item B', 200.75);
  5. 停止主節點(ECS B)執行個體類比宕機事件。

  6. 等待主節點停止後,再次執行SQL語句查看叢集狀態,發現兩個節點線上,且從節點已自動切換為主節點。

    SELECT * FROM performance_schema.replication_group_members;

    image

  7. 執行SQL語句查詢資料查看是否有遺失資料。

    SELECT * FROM test_table;
  8. 啟動主節點(ECS B)執行個體類比宕機恢複。

  9. 執行SQL語句查看叢集狀態,結果顯示三個節點線上,其中ECS B自動加入叢集。

    SELECT * FROM performance_schema.replication_group_members;

    image

叢集添加節點

在MySQL InnoDB Cluster中,當需要擴充叢集或應對節點宕機時,可通過MySQL Shell串連叢集並使用addInstance命令添加新節點,新節點會自動同步資料。

重要
  • 當叢集的節點宕機數量超過半數,會導致叢集不可用,建議節點數量為單數以確保可用性。

  • 在節點加入叢集前,您需要完成安裝MySQL並按照步驟一:設定叢集節點中的第2、3、4步設定叢集節點。

  1. 遠端連線ECS A執行個體。具體操作,請參見使用Workbench工具以SSH協議登入Linux執行個體

  2. 通過MySQL Shell串連到叢集中任意節點,請將<username>替換為MySQL的使用者名稱,<IP>替換為節點IP地址,執行後需要輸入密碼,並且詢問您是否儲存密碼,儲存密碼後再次串連無需輸入密碼。

    mysqlsh --js <username>@<IP>:3306
  3. 擷取叢集。

    var cluster = dba.getCluster();
  4. 為叢集添加節點,請將<username>替換為MySQL的使用者名稱,<IP>替換為節點IP地址。

    說明

    例如,若要添加節點地址為192.168.2.1,使用者為cluster_user,則命令為:cluster.addInstance('cluster_user@192.168.2.1:3306');

    cluster.addInstance('<username>@<IP>:3306');

    輸出如下資訊,表示節點添加成功。image

指定叢集主節點

在MySQL InnoDB Cluster中,如果主節點宕機,系統會自動從剩餘節點中選舉出新的主節點。若需要手動指定主節點,可通過MySQL Shell串連叢集,並使用setPrimaryInstance命令來設定目標主節點。

  1. 遠端連線ECS A執行個體。具體操作,請參見使用Workbench工具以SSH協議登入Linux執行個體

  2. 通過MySQL Shell串連到叢集中任意節點,請將<username>替換為MySQL的使用者名稱,<IP>替換為節點IP地址,執行後需要輸入密碼,並且詢問您是否儲存密碼,儲存密碼後再次串連無需輸入密碼。

    mysqlsh --js <username>@<IP>:3306
  3. 擷取叢集。

    var cluster = dba.getCluster();
  4. 為叢集設定目標主節點,請將<username>替換為MySQL的使用者名稱,<IP>替換為節點IP地址。

    說明

    例如,若要設定節點地址為192.168.2.1,使用者為cluster_user,則命令為:cluster.setPrimaryInstance('cluster_user@192.168.2.1:3306');

    cluster.setPrimaryInstance('<username>@<IP>:3306');

    輸出如下資訊,表示節點設定成功。image

相關文檔

  • 有關MySQL InnoDB Cluster更多資訊,請參見MySQL官方文檔

  • 推薦使用ApsaraDB RDS服務,簡化部署和管理複雜性,更多資訊,請參見什麼是RDS MySQL

  • 對叢集服務進行即時監控,包括CPU、記憶體、磁碟I/O、網路流量等指標,及時發現並處理異常,更多資訊,請參見什麼是CloudMonitor