MySQL Shell 8.4  /  MySQL InnoDB ClusterSet  /  升級 InnoDB ClusterSet

8.10 升級 InnoDB ClusterSet

若要升級 InnoDB ClusterSet 中的伺服器執行個體,請完成下列步驟

檢查已安裝二進位檔的版本

  • mysqlrouter --version:檢查已安裝的 MySQL Router 版本。

  • mysqlsh --version:檢查已安裝的 MySQL Shell 版本。

  • mysqld --version:檢查已安裝的 MySQL Server 版本。

升級 MySQL Router。

若要升級 MySQL Router,請完成下列步驟

  1. 停止 MySQL Router。

    在 Unix 系統上,如果您使用了選用的 --directory 引導選項,則會建立一個獨立的安裝,所有產生的目錄和檔案都會位於您在 引導路由器時所選取的位置。這些檔案包含 stop.sh。導覽至此目錄並發出此命令

    ./stop.sh

    在 Microsoft Windows 上,如果您使用了選用的 --directory 引導選項,則會建立一個獨立的安裝,所有產生的目錄和檔案都會位於您在 引導路由器時所選取的位置。這些檔案包含 stop.ps1。導覽至此目錄並發出此命令

    .\stop.ps1

    或是在使用 systemd 的 Linux 系統上,藉由發出下列命令來停止 MySQL Router 服務

    systemctl stop mysqlrouter.service

    否則,請終止相關 mysqlrouter 處理程序的處理程序 ID (PID)

  2. 取得並安裝最新版本的 MySQL Router。

  3. 啟動 MySQL Router。

    在 Unix 系統上,如果您使用了選用的 --directory 引導選項,則會建立一個獨立的安裝,所有產生的目錄和檔案都會位於您所選取的位置。這些檔案包含 start.sh。導覽至此目錄並發出此命令

    ./start.sh

    如果新路由器的路徑已變更,您必須更新 start.sh Shell 指令碼以反映路徑。

    #!/bin/bash
    basedir=/tmp/myrouter
    ROUTER_PID=$basedir/mysqlrouter.pid /usr/bin/mysqlrouter -c $basedir/mysqlrouter.conf &
    disown %-

    如果您手動升級 MySQL Router,而非使用套件管理,則可以更新 basedir=。再次引導路由器也會重新產生 start.sh Shell 指令碼。

    或是在使用 systemd 的 Linux 系統上,藉由發出下列命令來啟動 MySQL Router 服務

    systemctl start mysqlrouter.service

    在 Microsoft Windows 上,如果您使用了選用的 --directory 引導選項,則會建立一個獨立的安裝,所有產生的目錄和檔案都會位於您所選取的位置。這些檔案包含 start.ps1。導覽至此目錄並發出此命令

    .\start.ps1

    使用新的路由器二進位檔啟動 MySQL Router 時,路由器的版本會升級

    mysqlrouter --version

升級 MySQL Shell

藉由安裝新的二進位檔,並停止和啟動 MySQL Shell 來升級 MySQL Shell

  1. 取得並安裝最新版本的 MySQL Shell。

  2. 藉由發出下列命令來停止並退出 MySQL Shell

    \q
  3. 藉由發出下列命令,從命令列重新啟動 MySQL Shell

    mysqlsh
  4. 升級 InnoDB ClusterSet 中繼資料

    • 若要升級 ClusterSet,請將 MySQL Shell 的全域工作階段連線至您的 ClusterSet,並使用 dba.upgradeMetadata() 作業,將 ClusterSet 的中繼資料升級至新的中繼資料。

      如果 ClusterSet 的中繼資料結構描述需要升級,則升級程序本身應在 ClusterSet 的主要叢集中執行。

      中繼資料升級

      如果 InnoDB ClusterSet 已使用最新版本,則中繼資料升級可能不會執行任何動作。

升級 MySQL Server

藉由先升級所有複本叢集的執行個體,然後升級主要叢集的執行個體來升級 MySQL Server。

升級每個叢集 (主要或複本叢集) 時,請在升級主要執行個體之前,升級所有次要執行個體。

升級 MySQL Server 是選用的

升級 MySQL Server 是選用的。伺服器升級的影響可能比升級 MySQL Shell 和 MySQL Router 來得大。此外,您應該始終保持 MySQL Shell 和 MySQL Router 在最新版本,即使伺服器不是也一樣;這對於 InnoDB 叢集和 ReplicaSet 也是如此。

如需使用群組複製進行升級的詳細資訊,請參閱升級群組複製成員

  1. 藉由發出下列其中一個命令來停止 MySQL Server

    • 如果 MySQL Server 使用 systemd,請發出

      systemctl stop mysqld
    • 如果 MySQL Server 使用 init.d,請發出

      /etc/init.d/mysql stop
    • 如果 MySQL Server 使用 service,請發出

      service mysql stop
    • 如果您在 Microsoft Windows 上部署 MySQL Server,請發出

      mysqladmin -u root -p shutdown
  2. 取得並安裝最新版本的 MySQL Server。

  3. 藉由發出下列其中一個命令來啟動 MySQL Server

    • 如果 MySQL Server 使用 systemd,請發出

      systemctl start mysqld
    • 如果 MySQL Server 使用 init.d,請發出

      /etc/init.d/mysql start
    • 如果 MySQL Server 使用 service,請發出

      service mysql start
    • 如果您在 Microsoft Windows 上部署 MySQL Server,請發出

      mysqld
  4. 當所有次要執行個體都升級後,升級主要執行個體以完成升級程序。

升級後狀態檢查

在升級 MySQL Router、MySQL Shell 和 MySQL Server 之後

  1. 藉由發出 <ClusterSet>.status()檢查 ClusterSet 的狀態。如需有關 <ClusterSet>.status() 的詳細資訊,請參閱第 8.6 節,「InnoDB ClusterSet 狀態與拓撲」

  2. 解決 <ClusterSet>.status() 作業傳回的任何 clusterErrorsstatusText

  3. 藉由發出 <Cluster>.status()檢查 ClusterSet 中的每個叢集並解決任何問題。如需有關 <Cluster>.status() 的詳細資訊,請參閱使用 Cluster.status() 檢查叢集的狀態

  4. 藉由發出 <ClusterSet>.listRouters()檢查所有已註冊 MySQL Router 執行個體的詳細資料。如需詳細資訊,請參閱整合 MySQL Router 與 InnoDB ClusterSet

這些命令可讓您檢查升級是否成功,或是否需要完成任何其他步驟。

注意

其他步驟取決於您略過多少個版本、您正在升級的版本,以及您來自哪個版本。

  1. 藉由檢查 InnoDB ClusterSet 的狀態開始您的升級後檢查。此檢查使用 <ClusterSet>.status({extended:1}) 作業

    在此範例中,我們發出 <ClusterSet>.status({extended:1})

      mysql-js><ClusterSet>.status({extended:1})
    {
        "clusters": {
            "cluster1": {
                "clusterRole": "PRIMARY",
                "globalStatus": "OK",
                "primary": "127.0.0.1:3310",
                "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",
                        "status": "ONLINE",
                        "version": "8.0.28"
                    }
                },
                "transactionSet": "c0361cad-9093-11ec-94ce-0a0027000010:1-90,c0362acf-9093-11ec-94ce-0a0027000010:1"
            },
            "replicacluster1": {
                "clusterErrors": [
                    "ERROR: Cluster members are reachable but they're all OFFLINE.",
                    "WARNING: Replication from the Primary Cluster not in expected state"
                ],
                "clusterRole": "REPLICA",
                "clusterSetReplication": {
                    "applierStatus": "OFF",
                    "applierThreadState": "",
                    "applierWorkerThreads": 4,
                    "receiver": "127.0.0.1:3320",
                    "receiverStatus": "OFF",
                    "receiverThreadState": "",
                    "source": "127.0.0.1:3310"
                },
                "clusterSetReplicationStatus": "STOPPED",
                "globalStatus": "NOT_OK",
                "status": "OFFLINE",
                "statusText": "All members of the group are OFFLINE",
                "topology": {
                    "127.0.0.1:3320": {
                        "address": "127.0.0.1:3320",
                        "instanceErrors": [
                            "NOTE: group_replication is stopped."
                        ],
                        "memberRole": "SECONDARY",
                        "memberState": "OFFLINE",
                        "mode": "R/O",
                        "status": "(MISSING)",
                        "version": "8.0.28"
                    }
                },
                "transactionSet": "1ec95a0b-9094-11ec-9bc5-0a0027000010:1,c0361cad-9093-11ec-94ce
                                   -0a0027000010:1-90,c0362acf-9093-11ec-94ce-0a0027000010:1",
                "transactionSetConsistencyStatus": "OK",
                "transactionSetErrantGtidSet": "",
                "transactionSetMissingGtidSet": ""
            },
            "replicacluster2": {
                "clusterRole": "REPLICA",
                "clusterSetReplication": {
                    "applierStatus": "APPLIED_ALL",
                    "applierThreadState": "Waiting for an event from Coordinator",
                    "applierWorkerThreads": 4,
                    "receiver": "127.0.0.1:3330",
                    "receiverStatus": "ON",
                    "receiverThreadState": "Waiting for source to send event",
                    "source": "127.0.0.1:3310"
                },
                "clusterSetReplicationStatus": "OK",
                "globalStatus": "OK",
                "status": "OK_NO_TOLERANCE",
                "statusText": "Cluster is NOT tolerant to any failures.",
                "topology": {
                    "127.0.0.1:3330": {
                        "address": "127.0.0.1:3330",
                        "memberRole": "PRIMARY",
                        "mode": "R/O",
                        "replicationLagFromImmediateSource": "",
                        "replicationLagFromOriginalSource": "",
                        "status": "ONLINE",
                        "version": "8.0.28"
                    }
                },
                "transactionSet": "329dc243-9094-11ec-b9dd-0a0027000010:1,c0361cad-9093-11ec
                                   -94ce-0a0027000010:1-90,c0362acf-9093-11ec-94ce-0a0027000010:1",
                "transactionSetConsistencyStatus": "OK",
                "transactionSetErrantGtidSet": "",
                "transactionSetMissingGtidSet": ""
            }
        },
        "domainName": "clusterset1",
        "globalPrimaryInstance": "127.0.0.1:3310",
        "metadataServer": "127.0.0.1:3310",
        "primaryCluster": "cluster1",
        "status": "AVAILABLE",
        "statusText": "Primary Cluster available, there are issues with a Replica cluster."
    }

    如需有關 <ClusterSet>.status() 作業的詳細資訊,請參閱 ClusterSet.status()

  2. 解決 <ClusterSet>.status({extended:1}) 作業傳回的任何錯誤。

    在此範例中,我們在 clusterErrors 中傳回了一個錯誤,通知我們 <ClusterSet>.status({extended:1}) 作業無法連線至任何線上成員,且 statusText 指出主要叢集可用,但 InnoDB ClusterSet 中的複本叢集有問題。

      ...
      "replicacluster1": {
        "clusterErrors": [
                      "ERROR: Could not connect to any ONLINE members but there are unreachable instances 
                              that could still be ONLINE."
                  ],
      ...        
       "statusText": "Primary Cluster available, there are issues with a Replica cluster."
    }

    在此範例中,我們需要檢查 InnoDB 叢集 replicacluster1 的狀態,並確保將其恢復上線。

  3. 解決 <ClusterSet>.status({extended:1}) 作業傳回的問題後,我們會檢查 ClusterSet 中每個 InnoDB 叢集的狀態。

    藉由發出 <Cluster>.status() 來檢查每個 InnoDB 叢集的狀態。

    在下列範例中,<Cluster>.status({extended: true}) (用來提供有關 InnoDB 叢集狀態的更詳細資訊) 會傳回兩個問題

        mysqlsh> cluster.status({extended: true});   
        {
            "clusterName": "MyCluster",
            "defaultReplicaSet": {
                "GRProtocolVersion": "8.0.16",
                "groupName": "459ec434-8926-11ec-b8c3-02001707f44a",
                "groupViewChangeUuid": "AUTOMATIC",
                "groupViewId": "16443558036060755:13",
                "name": "default",
                "ssl": "REQUIRED",
                "status": "OK",
                "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
                "topology": {
                    "example-el7-1644251369:33311": {
                        "address": "example-el7-1644251369:33311",
                        "applierWorkerThreads": 4,
                        "fenceSysVars": [],
                        "instanceErrors": [
                            "NOTE: instance server_id is not registered in the metadata. 
                                   Use cluster.rescan() to update the metadata.",
                            "NOTE: The required parallel-appliers settings are not enabled on the instance. 
                                   Use dba.configureInstance() to fix it."
                        ],
                        "memberId": "247131ab-8926-11ec-850b-02001707f44a",
                        "memberRole": "PRIMARY",
                        "memberState": "ONLINE",
                        "mode": "R/W",
                        "readReplicas": {},
                        "replicationLag": null,
                        "role": "HA",
                        "status": "ONLINE",
                        "version": "8.0.28"
                    },
                    "example-el7-1644251369:33314": {
                        "address": "example-el7-1644251369:33314",
                        "applierWorkerThreads": 4,
                        "fenceSysVars": [],
                        "instanceErrors": [
                            "NOTE: instance server_id is not registered in the metadata. 
                                   Use cluster.rescan() to update the metadata.",
                            "NOTE: The required parallel-appliers settings are not enabled on the instance. 
                                   Use dba.configureInstance() to fix it."
                        ],
                        "memberId": "303dcfa7-8926-11ec-a6e5-02001707f44a",
                        "memberRole": "PRIMARY",
                        "memberState": "ONLINE",
                        "mode": "R/W",
                        "readReplicas": {},
                        "replicationLag": null,
                        "role": "HA",
                        "status": "ONLINE",
                        "version": "8.0.28"
                    },
                    "example-el7-1644251369:33317": {
                        "address": "example-el7-1644251369:33317",
                        "applierWorkerThreads": 4,
                        "fenceSysVars": [],
                        "instanceErrors": [
                            "NOTE: instance server_id is not registered in the metadata. 
                                   Use cluster.rescan() to update the metadata.",
                            "NOTE: The required parallel-appliers settings are not enabled on the instance. 
                                   Use dba.configureInstance() to fix it."
                        ],
                        "memberId": "3bb2592e-8926-11ec-8b6f-02001707f44a",
                        "memberRole": "PRIMARY",
                        "memberState": "ONLINE",
                        "mode": "R/W",
                        "readReplicas": {},
                        "replicationLag": null,
                        "role": "HA",
                        "status": "ONLINE",
                        "version": "8.0.28"
                    }
                },
                "topologyMode": "Multi-Primary"
            },
            "groupInformationSourceMember": "example-el7-1644251369:33311",
            "metadataVersion": "2.1.0"
        }

    <Cluster>.status({extended: true}) 會顯示有關叢集的更詳細資訊。在此範例中,我們使用布林值 true,這相當於 <Cluster>.status({'extended':1})。如需詳細資訊,請參閱使用 Cluster.status() 檢查叢集的狀態

    instanceErrors 表示在此升級中,我們應在 InnoDB 叢集中的每個成員上發出 <Cluster>.rescan()dba.configureInstance()

    ...
    "NOTE: instance server_id is not registered in the
    metadata. Use cluster.rescan() to update the metadata.",
    "NOTE: The required parallel-appliers settings are not
    enabled on the instance. Use dba.configureInstance() to fix it."
    ...

    <Cluster>.rescan() 操作讓您可以重新掃描 InnoDB Cluster,以尋找新的和過時的 Group Replication 實例,以及已使用拓樸模式的變更。如需更多資訊,請參閱重新掃描叢集

    mysqlsh> cluster1.rescan();
    Rescanning the cluster...
    
    Result of the rescanning operation for the 'MyCluster1' cluster:
    {
        "name": "MyCluster1",
        "newTopologyMode": null,
        "newlyDiscoveredInstances": [],
        "unavailableInstances": [],
        "updatedInstances": []
    }
    注意

    您只能在 ClusterSet 的個別叢集上執行 <Cluster>.rescan(),而不能在整個 ClusterSet 上執行。

    dba.configureInstance() 函式會檢查所有必要的設定,以啟用實例用於 InnoDB Cluster 的使用。如需更多資訊,請參閱為 InnoDB Cluster 使用設定生產實例

    在此範例中,我們在叢集中的每個成員上執行 dba.configureInstance(),以確保實例上已啟用所需的平行套用程式設定

      mysqlsh> dba.configureInstance('cladmin:cladminpw@localhost:33311')
        The instance 'example-el7-1644251369:33311' belongs to an InnoDB Cluster.
        Configuring local MySQL instance listening at port 33311 for use in an InnoDB cluster...
    
        This instance reports its own address as ^[[1mexample-el7-1644251369:33311^[[0m
        Clients and other cluster members will communicate with it through this address by default. 
        If this is not correct, the report_host MySQL system variable should be changed.
    
        applierWorkerThreads will be set to the default value of 4.
    
        ^[[36mNOTE: ^[[0mSome configuration options need to be fixed:
        +----------------------------------------+---------------+----------------+----------------------------+
        | Variable                               | Current Value | Required Value | Note                       |
        +----------------------------------------+---------------+----------------+----------------------------+
        | binlog_transaction_dependency_tracking | COMMIT_ORDER  | WRITESET       | Update the server variable |
        +----------------------------------------+---------------+----------------+----------------------------+
    
        Configuring instance...
        The instance 'example-el7-1644251369:33311' was configured to be used in an InnoDB cluster.
  4. 一旦您解決了 <ClusterSet>.status({extended:1})<Cluster>.status({extended:1}) 操作所傳回的問題後,您必須執行 <ClusterSet>.listRouters()

    <ClusterSet>.listRouters() 會傳回所有已註冊的 MySQL Router 實例的詳細資訊。這些詳細資訊提供每個已註冊的 MySQL Router 實例的相關資訊,例如其在中繼資料中的名稱、主機名稱、連接埠等等。如需更多資訊,請參閱將 MySQL Router 與 InnoDB ClusterSet 整合

    例如,在我們的範例 ClusterSet 上,我們執行

    mysqlsh> <ClusterSet>.listRouters();
    
    WARNING: The following Routers were bootstrapped before the ClusterSet was created: [EXAMPLE::R1]. 
             Please re-bootstrap the Routers to ensure the optimal configurations are set.
    
    {
        "domainName": "MyClusterSet",
        "routers": {
            "EXAMPLE::R1": {
                "hostname": "EXAMPLE",
                "lastCheckIn": "2022-02-23 07:14:50",
                "roPort": 6447,
                "roXPort": 6449,
                "routerErrors": [
                    "WARNING: Router needs to be re-bootstraped."
                ],
                "rwPort": 6446,
                "rwXPort": 6448,
                "targetCluster": null,
                "version": "8.0.28"
            }
        }
    }

    傳回的資訊顯示

    • MySQL Router 實例的名稱。

    • 上次簽入時間戳記,它是由儲存在中繼資料中的 MySQL Router 定期 ping 所產生。

    • 執行 MySQL Router 實例的主機名稱。

    • MySQL Router 為傳統 MySQL 通訊協定連線發佈的唯讀和讀寫連接埠。

    • MySQL Router 為 X 通訊協定連線發佈的唯讀和讀寫連接埠。

    • 目標叢集的名稱。在此範例中,MySQL Router 將來自用戶端應用程式的流量導向至 InnoDB ClusterSet 部署中目前是主要叢集的叢集。

    • 此 MySQL Router 實例的版本。

    在此範例中,也有關於傳回的 routerErrors 的資訊。

    routerErrors 通知我們 MySQL Router 需要重新引導。此錯誤的原因是,如果您根據獨立叢集建立 ClusterSet,則必須再次引導 MySQL Router,以通知 Router 它正在 ClusterSet 上運作。

    解決這些警告以完成升級後檢查。如果您沒有收到任何警告,則表示您的升級後檢查已完成。