MySQL Shell 8.4  /  ...  /  設定 InnoDB Cluster 和 MySQL Router

6.8.3 設定 InnoDB Cluster 和 MySQL Router

在以下範例中,我們將使用 AdminAPI 的沙箱部署來完成以下工作,以部署具有 MySQL Router 的 InnoDB Cluster。

部署和使用 MySQL 的本機沙箱執行個體,讓您可以在部署到生產伺服器之前,先在本機測試功能。AdminAPI 具有內建功能,可建立預先設定的沙箱執行個體,以便在本機部署的情境中與 InnoDB Cluster、InnoDB ClusterSet 和 InnoDB ReplicaSet 搭配使用。

此範例包含以下章節

警告

沙箱執行個體僅適用於在您的本機電腦上部署和執行以進行測試。

安裝

安裝下列元件

建立 InnoDB Cluster 沙箱設定

為了提供一個容錯能力,請建立具有三個執行個體的 InnoDB Cluster。在此範例中,我們將使用在同一部電腦上執行的三個沙箱執行個體。在實際的設定中,這三個執行個體會在網路上的不同主機上執行。

  1. 若要啟動 MySQL Shell,請發出

    > mysqlsh
  2. 若要建立和啟動 MySQL 沙箱執行個體,請使用 X AdminAPI 的一部分 dba.deploySandboxInstance() 函式。在 MySQL Shell 中發出以下三個語句,並為每個執行個體輸入 root 密碼

    mysql-js> dba.deploySandboxInstance(3310)
    mysql-js> dba.deploySandboxInstance(3320)
    mysql-js> dba.deploySandboxInstance(3330)
    注意

    對所有執行個體使用相同的 root 密碼。

建立 InnoDB Cluster

若要建立 InnoDB Cluster,請完成下列步驟

  1. 發出以下命令,連線至您要作為 InnoDB Cluster 中主要執行個體的 MySQL 執行個體

    mysql-js> shell.connect('root@localhost:3310')
  2. 發出 dba.createCluster() 命令以建立叢集,並使用指定的變數 cluster 來保存輸出值

    mysql-js> cluster = dba.createCluster('devCluster')

    此命令會輸出

    A new InnoDB cluster will be created on instance 'localhost:3310'.
    
    Validating instance configuration at localhost:3310...
    NOTE: Instance detected as a sandbox.
    Please note that sandbox instances are only suitable for deploying test clusters for use within the same host.
    
    This instance reports its own address as 127.0.0.1:3310
    
    Instance configuration is suitable.
    NOTE: Group Replication will communicate with other members using '127.0.0.1:33101'. 
          Use the localAddress option to override.
    
    Creating InnoDB cluster 'devCluster' on '127.0.0.1:3310'...
    
    Adding Seed Instance...
    Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
    At least 3 instances are needed for the cluster to be able to withstand up to
    one server failure.
    
    <Cluster:devCluster>
  3. 使用已指定變數 clustercluster.status() 函式,驗證建立是否成功

    mysql-js> cluster.status()

    輸出以下狀態

     {
    “clusterName”: “devCluster”,
    “defaultReplicaSet”: {
            "name": "default",
    "primary": "127.0.0.1:3310",
    "ssl": "REQUIRED",
    "status": "OK_NO_TOLERANCE",
    "statusText": "Cluster is NOT tolerant to any failures.",
    "topology": {
       "127.0.0.1:3310": {
           "address": "127.0.0.1:3310",
           "memberRole": "PRIMARY",
           "mode": "R/W",
           "readReplicas": {},
           "replicationLag": null,
           "role": "HA",
           "status": "ONLINE",
           "version": "8.0.28"
       }
    },
    "topologyMode": "Single-Primary"
    }, “groupInformationSourceMember”:
    “127.0.0.1:3310” }
  4. 叢集已啟動並執行,但尚未容忍失敗。使用 <Cluster>.addInstance() 函式,將另一個 MySQL 伺服器執行個體新增至叢集

    {
    mysql-js> cluster.addInstance('root@localhost:3320')
    NOTE: The target instance '127.0.0.1:3320' has not been pre-provisioned (GTID set is empty). 
          The Shell is unable to decide whether incremental state recovery can correctly provision it.
    The safest and most convenient way to provision a new instance is through automatic clone provisioning, 
    which will completely overwrite the state of '127.0.0.1:3320' with a physical snapshot from an existing 
    cluster member. To use this method by default, set the 'recoveryMethod' option to 'clone'.
    
    The incremental state recovery may be safely used if you are sure all updates ever executed in the 
    cluster were done with GTIDs enabled, there are no purged transactions and the new instance contains 
    the same GTID set as the cluster or a subset of it. To use this method by default, set the 
    'recoveryMethod' option to 'incremental'.
    
    Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone):
    mysql-js> cluster.addInstance('root@localhost:3330')
    }
  5. 從提示中選取恢復方法。選項如下

    • 複製:將您新增至主要叢集的執行個體複製,並刪除執行個體包含的任何交易。會自動安裝 MySQL 複製外掛程式。假設您要新增的是空的執行個體 (尚未處理任何交易),或包含您不想保留的交易的執行個體,請選取「複製」選項。

    • 增量復原:使用非同步複製將叢集處理的所有交易復原至加入的執行個體。如果您確定叢集處理的所有更新都已完成,並且已啟用全域交易 ID (GTID),則增量復原很適合。沒有已清除的交易,且新的執行個體包含與叢集相同的 GTID 集,或是其子集。

    在此範例中,請選取 C 代表複製

         Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone): C
    Validating instance configuration at localhost:3320...
    NOTE: Instance detected as a sandbox.
    Please note that sandbox instances are only suitable for deploying test clusters for 
    use within the same host.
    
    This instance reports its own address as 127.0.0.1:3320
    
    Instance configuration is suitable.
    NOTE: Group Replication will communicate with other members using '127.0.0.1:33201'. 
          Use the localAddress option to override.
    
    A new instance will be added to the InnoDB cluster. Depending on the amount of
    data on the cluster this might take from a few seconds to several hours.
    
    Adding instance to the cluster...
    
    Monitoring recovery process of the new cluster member. Press ^C to stop monitoring 
    and let it continue in background.
    Clone based state recovery is now in progress.
    
    NOTE: A server restart is expected to happen as part of the clone process. If the
    server does not support the RESTART command or does not come back after a
    while, you may need to manually start it back.
    
    * Waiting for clone to finish...
    NOTE: 127.0.0.1:3320 is being cloned from 127.0.0.1:3310
    ** Stage DROP DATA: Completed
    ** Clone Transfer
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed
    
    NOTE: 127.0.0.1:3320 is shutting down...
    
    * Waiting for server restart... ready
    * 127.0.0.1:3320 has restarted, waiting for clone to finish...
    ** Stage RESTART: Completed
    * Clone process has finished: 72.61 MB transferred in about 1 second (~72.61 MB/s)
    
    State recovery already finished for '127.0.0.1:3320'
    
    The instance '127.0.0.1:3320' was successfully added to the cluster.
  6. 新增第三個建立的執行個體,並再次選取 C 作為「複製」復原方法

    mysql-js> cluster.addInstance('root@localhost:3330')
  7. 發出以下命令,檢查叢集的狀態

    mysql-js> cluster.status()

    輸出以下內容

    {
    "clusterName": "devCluster",
    "defaultReplicaSet": {
       "name": "default",
       "primary": "127.0.0.1:3310",
       "ssl": "REQUIRED",
       "status": "OK",
       "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
           "topology": {
               "127.0.0.1:3310": {
                   "address": "127.0.0.1:3310",
                   "memberRole": "PRIMARY",
                   "mode": "R/W",
                   "readReplicas": {},
                   "replicationLag": null,
                   "role": "HA",
                   "status": "ONLINE",
                   "version": "8.0.28"
               },
               "127.0.0.1:3320": {
                   "address": "127.0.0.1:3320",
                   "memberRole": "SECONDARY",
                   "mode": "R/O",
                   "readReplicas": {},
                   "replicationLag": null,
                   "role": "HA",
                   "status": "ONLINE",
                   "version": "8.0.28"
               },
               "127.0.0.1:3330": {
                   "address": "127.0.0.1:3330",
                   "memberRole": "SECONDARY",
                   "mode": "R/O",
                   "readReplicas": {},
                   "replicationLag": null,
                   "role": "HA",
                   "status": "ONLINE",
                   "version": "8.0.28"
               }
           },
           "topologyMode": "Single-Primary"
       },
       "groupInformationSourceMember": "127.0.0.1:3310"
    }
    The setup of the InnoDB Cluster was successful!
  8. 現在叢集最多可容忍一次失敗。發出以下命令來結束 MySQL Shell:\q

啟動 MySQL Router

在設定 MySQL InnoDB Cluster 之後,測試叢集的高可用性。為此,請使用 MySQL Router。如果一個執行個體失敗,MySQL Router 會自動更新其路由設定,並確保將新的連線路由到其餘的執行個體。

在 MySQL Router 可以執行路由操作之前,請讓它知道新的 InnoDB Cluster。若要執行此操作,請使用 –bootstrap 選項,並將 MySQL Router 指向叢集的目前 R/W MySQL 伺服器執行個體 (主要執行個體)。使用 -d 選項,將 Router 的設定儲存在名為 mysql-router 的資料夾中。

  1. 在您的主目錄中開啟終端機

    • 在 Linux 系統上,發出

      [demo-user@losthost]$> mysqlrouter --bootstrap root@localhost:3310 -d mysqlrouter
    • 在 Windows 系統上,發出

      C:\Users\demo-user> mysqlrouter --bootstrap root@localhost:3310 -d mysql-router

      然後,MySQL Router 會列印其將用於路由連線的 TCP/IP 連接埠。如需詳細資訊,請參閱部署 MySQL Router

  2. 在 MySQL Router 設定成功後,在背景執行緒中啟動它

    • 在 Windows 系統上,使用 start /B 命令,並將 Router 指向使用 –bootstrap 選項產生的設定檔

      C:\> start /B mysqlrouter -c %HOMEPATH%\mysql-router\mysqlrouter.conf
    • 或呼叫先前建立的 mysqlrouter 資料夾中的 Windows PowerShell 指令碼

      \mysqlrouter\start.ps1
    • 在使用 systemd 的 Linux 系統上,發出

      sudo systemctl start mysqlrouter.service
    • 或在 Linux 系統上,呼叫先前建立的 mysqlrouter 資料夾中的 Shell 指令碼

      /mysqlrouter/start.sh

測試 MySQL Router 設定

現在,InnoDB Cluster 和 MySQL Router 正在執行,請測試叢集設定。

不要直接連線到其中一個 MySQL 伺服器執行個體,而是透過 MySQL Router 連線。

  1. 發出以下連線命令

    > mysqlsh root@localhost:6446
  2. 提供 root 密碼以連線到 InnoDB Cluster。

  3. 藉由建立變數 cluster,並使用 dba.getCluster() 操作的值來指派變數,以檢查 InnoDB Cluster 的狀態

    mysql-js> cluster = dba.getCluster()
    mysql-js> cluster.status()
  4. 切換至 SQL 模式

    mysql-js> \sql
  5. 發出以下命令,查詢執行個體正在執行的連接埠

    mysql-sql> SELECT @@port;
            
            +--------+
            | @@port |
            +--------+
            |   3310 |
            +--------+
    1 row in set (0.0007 sec)
  6. 切換回 JavaScript 模式

    mysql-js> \js
  7. 使用 dba.killSandboxInstance() 函式來停止 MySQL 伺服器執行個體

                dba.killSandboxInstance(3310)
                
    Killing MySQL instance...
    
    Instance localhost:3310 successfully killed.
  8. 執行 SELECT @@port 命令,針對剛停止的執行個體執行,並檢查結果,以確認 MySQL Router 是否正確路由流量

    • 切換至 SQL 模式

      mysql-js> \sql
    • 檢查 MySQL 的連接埠

      mysql-sql> SELECT @@port;
  9. 傳回錯誤;ERROR: 2013 (HY000): Lost connection to MySQL server during query。此錯誤表示在連接埠 3310 上執行的執行個體已不再執行。

  10. 再次檢查連接埠

    mysql-sql> SELECT @@port;
    +--------+
    | @@port |
    +--------+
    |   3320 |
    +--------+
  11. 此輸出顯示在連接埠 3320 上執行的執行個體已升級為新的 讀/寫主要執行個體。

  12. 返回 JavaScript 模式,並檢查叢集的狀態

    mysql-js> cluster.status()
    {
       "clusterName": "devCluster",
       "defaultReplicaSet": {
           "name": "default",
           "primary": "127.0.0.1:3320",
           "ssl": "REQUIRED",
           "status": "OK_NO_TOLERANCE",
           "statusText": "Cluster is NOT tolerant to any failures. 1 member is not active.",
           "topology": {
               "127.0.0.1:3310": {
                   "address": "127.0.0.1:3310",
                   "memberRole": "SECONDARY",
                   "mode": "n/a",
                   "readReplicas": {},
                   "role": "HA",
                   "shellConnectError": "MySQL Error 2003: Could not open connection to '127.0.0.1:3310': 
                                         Can't connect to MySQL server on '127.0.0.1:3310' (10061)",
                   "status": "(MISSING)"
               },
               "127.0.0.1:3320": {
                   "address": "127.0.0.1:3320",
                   "memberRole": "PRIMARY",
                   "mode": "R/W",
                   "readReplicas": {},
                   "replicationLag": null,
                   "role": "HA",
                   "status": "ONLINE",
                   "version": "8.0.28"
               },
               "127.0.0.1:3330": {
                   "address": "127.0.0.1:3330",
                   "memberRole": "SECONDARY",
                   "mode": "R/O",
                   "readReplicas": {},
                   "replicationLag": null,
                   "role": "HA",
                   "status": "ONLINE",
                   "version": "8.0.28"
               }
           },
           "topologyMode": "Single-Primary"
       },
       "groupInformationSourceMember": "127.0.0.1:3320"
    }
  13. 正式在連接埠 3310 上執行的 MySQL 伺服器執行個體為 MISSING

  14. 發出帶有連接埠號碼的 dba.startSandboxInstance() 操作,重新啟動此執行個體

    mysql-js> dba.startSandboxInstance(3310)
  15. 檢查叢集的狀態會顯示該執行個體已在叢集中還原為作用中,但身為 次要成員

    mysql-js > cluster.status()
    {
      "clusterName": "devCluster",
      "defaultReplicaSet": {
          "name": "default",
          "primary": "127.0.0.1:3320",
          "ssl": "REQUIRED",
          "status": "OK",
          "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
          "topology": {
              "127.0.0.1:3310": {
                  "address": "127.0.0.1:3310",
                  "memberRole": "SECONDARY",
                  "mode": "R/O",
                  "readReplicas": {},
                  "replicationLag": null,
                  "role": "HA",
                  "status": "ONLINE",
                  "version": "8.0.28"
              },
              "127.0.0.1:3320": {
                  "address": "127.0.0.1:3320",
                  "memberRole": "PRIMARY",
                  "mode": "R/W",
                  "readReplicas": {},
                  "replicationLag": null,
                  "role": "HA",
                  "status": "ONLINE",
                  "version": "8.0.28"
              },
              "127.0.0.1:3330": {
                  "address": "127.0.0.1:3330",
                  "memberRole": "SECONDARY",
                  "mode": "R/O",
                  "readReplicas": {},
                  "replicationLag": null,
                  "role": "HA",
                  "status": "ONLINE",
                  "version": "8.0.28"
              }
          },
          "topologyMode": "Single-Primary"
      },
      "groupInformationSourceMember": "127.0.0.1:3320"
    }
  16. 所有執行個體都已恢復線上,且叢集可以再次容忍一次失敗。