InnoDB Cluster詳解

  • 2019 年 10 月 4 日
  • 筆記

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/wzy0623/article/details/100779450

目錄

一、InnoDB Cluster簡介

1. 整體架構

2. MySQL Shell

3. MySQL Router

4. MySQL伺服器集群

二、創建InnoDB Cluster

1. 檢查實例配置

2. 配置實例

3. 創建集群

4. 向集群添加實例

5. 查看集群狀態

6. 基於已有組複製的集群創建

7. 配置MySQL Router

8. 客戶端連接測試

三、使用MySQL Shell管理InnoDB Cluster

1. 配置實例的自動重新加入

2. 從InnoDB Cluster中刪除實例

3. 重啟群集

4. 解散InnoDB Cluster

5. 配置新主選舉權重

6. 配置故障轉移一致性

7. 更改組複製拓撲

8. 設置InnoDB Cluster的選項


MySQL作為當今最流行的關係資料庫系統,在其高可用特性上也在不斷進行著嘗試和改進。最初的MySQL版本只提供一種簡單的主從非同步複製,滿足最基本的數據同步。為了提高複製性能,從單執行緒到組提交再到多執行緒複製,基本解決了複製延遲問題。為了解決從庫與主庫的一致性讀問題,新增了半同步複製,而為了提供自動故障轉移功能,又提供了組複製功能。要做到真正的高可用,失敗切換必須對應用透明,於是在組複製的基礎上,又發展出了InnoDB Cluster。本文說明InnoDB Cluster的相關概念、安裝部署及管理維護。需要指出的一點是,在InnoDB Cluster出現前,實現MySQL資料庫的高可用性,除了原生的複製功能,通常還需要藉助第三方中間件,如Keepalived、MHA等等。

一、InnoDB Cluster簡介

1. 整體架構

InnoDB Cluster主要由MySQL Shell、MySQL Router和MySQL伺服器集群組成,三者協同工作,共同為MySQL提供完整的高可用性解決方案。圖1所示為InnoDB Cluster的整體架構。

圖1 InnoDB Cluster架構

InnoDB Cluster以組複製為基礎,集群中的每個MySQL伺服器實例都是組複製的成員,提供了在InnoDB Cluster內複製數據的機制,並且具有內置的故障轉移功能。MySQL Shell在InnoDB Cluster中充當控制台角色,使用它包含的AdminAPI,可以使安裝、配置、管理、維護多個MySQL組複製實例的工作更加輕鬆。通過AdminAPI的幾條交互指令就可自動完成組複製配置。MySQL Router可以根據集群部署資訊自動生成配置,將客戶端應用程式透明地連接到MySQL伺服器實例。如果伺服器實例意外故障,群集將自動重新配置。在默認的單主模式下,InnoDB Cluster 具有單個讀寫主伺服器實例。多個輔助伺服器實例是主伺服器實例的副本。如果主伺服器出現故障,則輔助伺服器將自動升級為主伺服器。MySQL Router可以檢測到這種情況並將客戶端應用程式自動轉發到新的主伺服器。

2. MySQL Shell

MySQL Shell是MySQL Server的高級客戶端和程式碼編輯器。除了和mysql命令行客戶端程式一樣,使用常規的SQL功能外,MySQL Shell還提供了JavaScript和Python的腳本功能,並包含多個API,其中的AdminAPI用於操作InnoDB Cluster。

(1)主要功能 MySQL Shell中提供了以下主要功能:

  • MySQL Shell支援JavaScript、Python和SQL三種語言,預設為JavaScript,用js、py、sql進行語言切換。根據當前活動的語言,任何輸入的程式碼都將作為其中一種語言進行處理。
  • 提供互動式程式碼執行模式。
  • 除了程式碼的互動式執行之外,MySQL Shell還可以從不同的源獲取程式碼並對其進行處理,例如用mysqlsh執行一個名為code.js的文件: mysqlsh –file code.js
  • MySQL Shell包含以下用JavaScript和Python實現的API,可以使用它們來開發與MySQL交互的程式碼。例如,當MySQL Shell使用X協議連接到MySQL伺服器時,X DevAPI可以將MySQL用作文檔資料庫,提供與MongoDB類似的功能;使用AdminAPI能夠管理InnoDB Cluster。
  • 可以使用JavaScript或Python創建對象,對MySQL Shell基本功能進行擴展。
  • MySQL Shell可以以表格、Tab分割、垂直或JSON格式輸出返回結果。
  • MySQL Shell包含許多以JavaScript和Python模式存在的內置全局對象:cluster代表InnoDB Cluster;dba使用AdminAPI提供對InnoDB Cluster管理功能的訪問;session表示全局會話;db代表預設資料庫;shell提供對MySQL Shell函數的訪問;util提供MySQL ShellMySQL Shell實用程式。

(2)安裝 MySQL Shell可謂是「開箱即用」,只要根據作業系統平台選擇下載安裝包,然後將安裝包解壓即可直接使用,不需要任何其它額外安裝過程。例如,要在Linux 64位平台上運行MySQL Shell,可從https://dev.mysql.com/downloads/shell/下載mysql-shell-8.0.17-linux-glibc2.12-x86-64bit.tar.gz文件,然後執行下面的命令:

tar -zxvf mysql-shell-8.0.17-linux-glibc2.12-x86-64bit.tar.gz

生成的mysql-shell-8.0.17-linux-glibc2.12-x86-64bit目錄下有bin、lib、share三個子目錄,分別存儲可執行文件、庫文件和文檔。只要執行bin目錄下的mysqlsh文件即可運行MySQL Shell:

[mysql@hdp1~]$~/mysql-shell-8.0.17-linux-glibc2.12-x86-64bit/bin/mysqlsh  MySQL Shell 8.0.17    Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.  Oracle is a registered trademark of Oracle Corporation and/or its affiliates.  Other names may be trademarks of their respective owners.    Type 'help' or '?' for help; 'quit' to exit.   MySQL  JS > 

MySQL Shell包含的AdminAPI,可通過dba全局變數及其相關方法訪問。dba變數的方法能夠部署、配置和管理InnoDB Cluster。執行? dba指令或dba.help()函數可以查看dba相關的所有方法:

 MySQL  JS > ? dba  NAME        dba - Global variable for InnoDB cluster management.    DESCRIPTION        The global variable dba is used to access the AdminAPI functionality and        perform DBA operations. It is used for managing MySQL InnoDB clusters.    PROPERTIES        verbose              Enables verbose mode on the dba operations.    FUNCTIONS        checkInstanceConfiguration(instance[, options])              Validates an instance for MySQL InnoDB Cluster usage.          ...          For more help on a specific function use: dba.help('<functionName>')          e.g. dba.help('deploySandboxInstance')   MySQL  JS >

使用常規格式object.help('methodname')可以獲得特定方法的聯機幫助,例如:

 MySQL  JS > dba.help('getCluster')  NAME        getCluster - Retrieves a cluster from the Metadata Store.    SYNTAX        dba.getCluster([name][, options])    WHERE        name: Parameter to specify the name of the cluster to be returned.        options: Dictionary with additional options.    RETURNS         The cluster object identified by the given name or the default cluster.    DESCRIPTION        If name is not specified or is null, the default cluster will be        returned.          If name is specified, and no cluster with the indicated name is found, an        error will be raised.          The options dictionary accepts the connectToPrimary option, which        defaults to true and indicates the shell to automatically connect to the        primary member of the cluster.    EXCEPTIONS        MetadataError in the following scenarios:          - If the Metadata is inaccessible.        - If the Metadata update operation failed.          ArgumentError in the following scenarios:          - If the Cluster name is empty.        - If the Cluster name is invalid.        - If the Cluster does not exist.          RuntimeError in the following scenarios:          - If the current connection cannot be used for Group Replication.   MySQL  JS >

3. MySQL Router

在InnoDB Cluster架構中,MySQL Router起到對應用程式透明路由的作用。當用–bootstrap選項引導路由時,會根據InnoDB Cluster元數據自動生成或更新配置文件。這項功能專為結合InnoDB Cluster而設計,簡化了對MySQL Router配置的維護工作。關於MySQL Router的功能、安裝、配置、啟動等說明,參見「MySQL Router 8 詳解」。

4. MySQL伺服器集群

這部分指組複製中的多個MySQL實例,是InnoDB Cluster得以實現的核心。關於組複製的概念原理、安裝配置,參見以下系列文章:

二、創建InnoDB Cluster

使用四台虛擬機搭建InnoDB Cluster,部署如圖2所示:

圖2 InnoDB Cluster部署

主機資訊如下表所示。

主機名

IP:埠

角色或組件

hdp1

172.16.1.124

MySQL Shell、MySQL Router

hdp2

172.16.1.125:3306

組複製成員PRIMARY

hdp3

172.16.1.126:3306

組複製成員SECONDARY

hdp4

172.16.1.127:3306

組複製成員SECONDARY

硬體配置為,每台主機CPU4核、記憶體8G、硬碟100G。軟體版本如下:

  • 作業系統:CentOS Linux release 7.2.1511 (Core) 64位
  • MySQL Server:8.0.16(mysql-8.0.16-linux-glibc2.12-x86_64.tar.xz)
  • MySQL Shell:8.0.17(mysql-shell-8.0.17-linux-glibc2.12-x86-64bit.tar.gz)
  • MySQL Router:8.0.17(mysql-router-8.0.17-linux-glibc2.12-x86_64.tar.xz)

MySQL Server、MySQL Shell、MySQL Router都已經安裝好。MySQL Server和MySQL Router的安裝分別參見「https://wxy0327.blog.csdn.net/article/details/90081518#%E4%B8%89%E3%80%81%E5%AE%89%E8%A3%85mysql-8.0.16」和「https://wxy0327.blog.csdn.net/article/details/100518636#1.%20%E5%AE%89%E8%A3%85」。

下面使用MySQL Shell創建InnoDB Cluster,並配置MySQL Router為應用客戶端提供對InnoDB Cluster實例的透明連接。在創建InnoDB Cluster之前,要確保使用的伺服器實例滿足以下要求:

  • InnoDB Cluster使用組複製,因此伺服器實例必須滿足組複製的要求。
  • 組複製僅支援InnoDB存儲引擎。其它如MyISAM表不能由組複製寫入。
  • 必須在InnoDB Cluster中的所有實例上啟用性能模式(Performance Schema )。
  • MySQL Shell用於配置InnoDB Cluster腳本需要訪問Python 2.7版。在Linux上,必須將Python作為shell環境的一部分。下面的作業系統命令檢查是否正確配置了Python: $ /usr/bin/env python
  • 如果Python解釋器啟動,則無需進一步操作。否則可能需要在/usr/bin/python和Python二進位文件之間創建一個軟鏈接。
  • 所有實例必須具有唯一的server_id。

1. 檢查實例配置

AdminAPI提供dba.checkInstanceConfiguration()方法以驗證實例是否滿足組複製要求,該方法不會更改實例上的任何配置,也不會檢查實例上的任何數據。下面是檢查172.16.1.125:3306的命令和輸出:

[mysql@hdp1~]$mysqlsh  MySQL Shell 8.0.17    Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.  Oracle is a registered trademark of Oracle Corporation and/or its affiliates.  Other names may be trademarks of their respective owners.    Type 'help' or '?' for help; 'quit' to exit.   MySQL  JS > dba.checkInstanceConfiguration('[email protected]:3306')  Please provide the password for '[email protected]:3306': ******  Save password for '[email protected]:3306'? [Y]es/[N]o/Ne[v]er (default No):  Validating MySQL instance at 172.16.1.125:3306 for use in an InnoDB cluster...    This instance reports its own address as hdp2:3306  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.    Checking whether existing tables comply with Group Replication requirements...  No incompatible tables detected    Checking instance configuration...    NOTE: Some configuration options need to be fixed:  +--------------------------+---------------+----------------+--------------------------------------------------+  | Variable                 | Current Value | Required Value | Note                                             |  +--------------------------+---------------+----------------+--------------------------------------------------+  | binlog_checksum          | CRC32         | NONE           | Update the server variable                       |  | enforce_gtid_consistency | OFF           | ON             | Update read-only variable and restart the server |  | gtid_mode                | OFF           | ON             | Update read-only variable and restart the server |  | server_id                | 1             | <unique ID>    | Update read-only variable and restart the server |  +--------------------------+---------------+----------------+--------------------------------------------------+    Some variables need to be changed, but cannot be done dynamically on the server.  NOTE: Please use the dba.configureInstance() command to repair these issues.    {      "config_errors": [          {              "action": "server_update",              "current": "CRC32",              "option": "binlog_checksum",              "required": "NONE"          },          {              "action": "server_update+restart",              "current": "OFF",              "option": "enforce_gtid_consistency",              "required": "ON"          },          {              "action": "server_update+restart",              "current": "OFF",              "option": "gtid_mode",              "required": "ON"          },          {              "action": "server_update+restart",              "current": "1",              "option": "server_id",              "required": "<unique ID>"          }      ],      "status": "error"  }   MySQL  JS >

在表格中列出了四個檢查項:binlog_checksum、enforce_gtid_consistency、gtid_mode、server_id的當前值和所需值,及其修改它們要採取的措施。同時指出,使用dba.configureInstance()來修復這些問題。

對集群中的每個伺服器實例重複此過程:

dba.checkInstanceConfiguration('[email protected]:3306')  dba.checkInstanceConfiguration('[email protected]:3306')

運行dba.checkInstanceConfiguration()之後生成的報告提供了有關所需的任何配置更改的資訊,要正確配置這些屬性後,才能繼續創建集群。

2. 配置實例

AdminAPI提供了dba.configureInstance()函數,用於檢查實例是否針對InnoDB Cluster 進行了適當配置,並在發現任何與InnoDB Cluster不兼容的設置時配置實例。如果實例不需要更改配置,dba.configureInstance()命令輸出確認實例已準備好使用InnoDB Cluster。根據MySQL Shell連接到實例的方式以及在實例上運行的MySQL版本,能夠通過將這些更改自動保存到遠程實例的配置文件(預設為MySQL實例數據目錄下的mysqld-auto.cnf文件)來持久化更改,或者手動更改實例的配置文件。無論進行配置更改的方式如何,必須重新啟動實例以確保伺服器檢測到配置更改。下面是配置172.16.1.125:3306的命令和輸出:

 MySQL  JS > dba.configureInstance('[email protected]:3306')  Please provide the password for '[email protected]:3306': ******  Save password for '[email protected]:3306'? [Y]es/[N]o/Ne[v]er (default No):  Configuring MySQL instance at 172.16.1.125:3306 for use in an InnoDB cluster...    This instance reports its own address as hdp2:3306  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.    NOTE: Some configuration options need to be fixed:  +--------------------------+---------------+----------------+--------------------------------------------------+  | Variable                 | Current Value | Required Value | Note                                             |  +--------------------------+---------------+----------------+--------------------------------------------------+  | binlog_checksum          | CRC32         | NONE           | Update the server variable                       |  | enforce_gtid_consistency | OFF           | ON             | Update read-only variable and restart the server |  | gtid_mode                | OFF           | ON             | Update read-only variable and restart the server |  | server_id                | 1             | <unique ID>    | Update read-only variable and restart the server |  +--------------------------+---------------+----------------+--------------------------------------------------+    Some variables need to be changed, but cannot be done dynamically on the server.  Do you want to perform the required configuration changes? [y/n]: y  Do you want to restart the instance after configuring it? [y/n]: y  Configuring instance...  The instance '172.16.1.125:3306' was configured for InnoDB cluster usage.  Restarting MySQL...  NOTE: MySQL server at 172.16.1.125:3306 was restarted.   MySQL  JS >

一旦針對實例發出dba.configureInstance(),該命令首先檢查實例的當前設置是否適合InnoDB Cluster使用,並將在一個報告中顯示InnoDB Cluster所需的設置。這步與dba.checkInstanceConfiguration的作用類似。

當針對MySQL Shell當前運行的本地MySQL實例發出dba.configureInstance()時,它會嘗試自動配置實例。對遠程實例發出dba.configureInstance()時,如果實例支援自動保持配置更改,則可以選擇執行此操作。滿足以下要求的實例會自動支援持久配置更改:

  • 該實例正在運行MySQL 8.0.11或更高版本。
  • persisted_globals_load設置為ON(預設值)。

如果遠程實例不支援持久化更改以配置InnoDB群集使用,則必須在本地配置實例。

對於動態伺服器變數,在dba.configureInstance()後不需要重新啟動實例,但對只讀伺服器變數,需要重啟實例。此資訊顯示在發出dba.configureInstance()之後生成的報告中。如果實例支援RESTART語句,則MySQL Shell可以關閉然後啟動實例。這可確保mysqld檢測到對實例配置文件所做的更改。

執行dba.configureInstance()後再次檢查實例配置的輸出如下:

 MySQL  JS > dba.checkInstanceConfiguration('[email protected]:3306')  Please provide the password for '[email protected]:3306': ******  Save password for '[email protected]:3306'? [Y]es/[N]o/Ne[v]er (default No):  Validating MySQL instance at 172.16.1.125:3306 for use in an InnoDB cluster...    This instance reports its own address as hdp2:3306  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.    Checking whether existing tables comply with Group Replication requirements...  No incompatible tables detected    Checking instance configuration...  Instance configuration is compatible with InnoDB cluster    The instance '172.16.1.125:3306' is valid for InnoDB cluster usage.    {      "status": "ok"  }   MySQL  JS >

對集群中的每個伺服器實例重複配置過程:

dba.configureInstance('[email protected]:3306')  dba.configureInstance('[email protected]:3306')

3. 創建集群

準備好實例後,使用dba.createCluster()函數創建集群,參數為自定義的集群名稱。在創建集群之前,MySQL Shell必須連接到一個實例,並將該實例用作群集的種子實例。種子實例將被複制到添加到群集的其它實例,從而使它們成為種子實例的副本。當發出dba.createCluster(name)時,MySQL Shell會創建與連接到的伺服器實例的會話。下面是以172.16.1.125:3306作為種子實例創建名為testCluster集群的命令及輸出:

 MySQL  JS > connect [email protected]:3306  Creating a session to '[email protected]:3306'  Please provide the password for '[email protected]:3306': ******  Save password for '[email protected]:3306'? [Y]es/[N]o/Ne[v]er (default No):  Fetching schema names for autocompletion... Press ^C to stop.  Your MySQL connection id is 616  Server version: 8.0.16 MySQL Community Server - GPL  No default schema selected; type use <schema> to set one.   MySQL  172.16.1.125:3306 ssl  JS > dba.createCluster('testCluster')  A new InnoDB cluster will be created on instance '172.16.1.125:3306'.    Validating instance at 172.16.1.125:3306...    This instance reports its own address as hdp2:3306    Instance configuration is suitable.  Creating InnoDB cluster 'testCluster' on '172.16.1.125:3306'...    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:testCluster>   MySQL  172.16.1.125:3306 ssl  JS >

dba.createCluster函數返回一個Cluster對象。千萬注意,一旦伺服器實例屬於一個集群,只使用MySQL Shell和AdminAPI來管理它們。嘗試在實例添加到群集後手動更改組複製的配置不受支援。同樣,不支援修改對InnoDB Cluster至關重要的伺服器變數,例如在使用AdminAPI配置實例後的server_uuid。

要能夠容忍一個實例的失敗,集群至少包含三個MySQL實例,添加更多實例會增加對實例失敗的容忍度。下面添加另外兩個實例。

4. 向集群添加實例

使用Cluster.addInstance(instance)函數向集群添加更多實例,其中instance是已配置實例的連接資訊。下面是將172.16.1.126:3306實例添加到集群的命令及輸出:

 MySQL  172.16.1.125:3306 ssl  JS > var cluster = dba.getCluster()   MySQL  172.16.1.125:3306 ssl  JS > cluster.addInstance('[email protected]:3306')  Please provide the password for '[email protected]:3306': ******  Save password for '[email protected]:3306'? [Y]es/[N]o/Ne[v]er (default No):    NOTE: The target instance '172.16.1.126:3306' has not been pre-provisioned (GTID set  is empty). The Shell is unable to decide whether incremental distributed 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  '172.16.1.126:3306' with a physical snapshot from an existing cluster member.  To use this method by default, set the 'recoveryMethod' option to 'clone'.    The incremental distributed 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 [I]ncremental recovery/[A]bort (default Incremental recovery):  Validating instance at 172.16.1.126:3306...    This instance reports its own address as hdp3:3306    Instance configuration is suitable.  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.  Incremental distributed state recovery is now in progress.    * Waiting for distributed recovery to finish...  NOTE: '172.16.1.126:3306' is being recovered from 'hdp2:3306'  * Distributed recovery has finished    The instance '172.16.1.126:3306' was successfully added to the cluster.     MySQL  172.16.1.125:3306 ssl  JS >

首先調用dba.getCluster()函數獲取集群對象,並賦予一個變數。如果未指定群集名稱,則返回默認群集。預設情況下使用dba.getCluster()時,MySQL Shell會嘗試連接到群集的主實例。設置connectToPrimary選項以配置此行為。如果connectToPrimary為true且活動的全局MySQL Shell會話不是主實例,則會查詢主節點的集群,並且集群對象將連接到該集群。如果connectToPrimary為false,則集群對象使用活動會話,就是與MySQL Shell當前全局會話相同的實例。

要在獲取群集時強制連接到輔助節點,請建立與群集的輔助成員的連接,並通過發出以下命令來使用connectToPrimary選項:

mysql-js> shell.connect(secondary_member)  mysql-js> var cluster1 = dba.getCluster(testCluster, {connectToPrimary:false})

注意輔助實例的super_read_only = ON,因此無法對其進行更改。

如果使用的是MySQL 8.0.17或更高版本,可以選擇實例如何恢復與群集同步所需的事務,可選方式有克隆和增量兩種,預設為增量。只有當加入實例恢復了先前由集群處理的所有事務時,它才能作為在線實例加入並開始處理事務。同樣在8.0.17及更高版本中,可以使用waitRecovery選項控制Cluster.addInstance()的行為方式,讓恢復操作在後台進行或監視MySQL Shell中的不同級別的進度。

如果要在一個已經包含大量數據(幾十G會數百G)的集群中添加實例,推薦的方法是使用xtrabackup複製一個主節點副本,然後添加該副本實例時使用增量恢復。這樣做有兩個明顯的優點,一是可以在對主節點影響最小的情況下聯機執行,二是減少實例恢復所需時間。如何使用xtrabackup進行聯機複製可以參考「https://wxy0327.blog.csdn.net/article/details/95619837#5.%20%E5%90%91%E7%BB%84%E4%B8%AD%E6%B7%BB%E5%8A%A0%E5%AE%9E%E4%BE%8B」。

以同樣的方法添加第三個實例:

cluster.addInstance('[email protected]:3306')

5. 查看集群狀態

集群對象提供status()方法,可以檢查集群狀態。在檢查InnoDB Cluster的狀態之前,需要通過連接到集群中的任何實例來獲取對InnoDB Cluster對象的引用。但如果要更改群集的配置,則必須連接到可讀寫實例。status()從所連接的伺服器實例的集群視圖檢索集群的狀態,並輸出狀態報告。所連接實例的狀態直接影響狀態報告中提供的資訊,因此應確保連接實例的狀態為ONLINE。下面是連接172.16.1.125:3306獲取集群狀態及輸出:

 MySQL  172.16.1.125:3306 ssl  JS > cluster.status()  {      "clusterName": "testCluster",      "defaultReplicaSet": {          "name": "default",          "primary": "hdp2:3306",          "ssl": "REQUIRED",          "status": "OK",          "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",          "topology": {              "hdp2:3306": {                  "address": "hdp2:3306",                  "mode": "R/W",                  "readReplicas": {},                  "role": "HA",                  "status": "ONLINE",                  "version": "8.0.16"              },              "hdp3:3306": {                  "address": "hdp3:3306",                  "mode": "R/O",                  "readReplicas": {},                  "role": "HA",                  "status": "ONLINE",                  "version": "8.0.16"              },              "hdp4:3306": {                  "address": "hdp4:3306",                  "mode": "R/O",                  "readReplicas": {},                  "role": "HA",                  "status": "ONLINE",                  "version": "8.0.16"              }          },          "topologyMode": "Single-Primary"      },      "groupInformationSourceMember": "hdp2:3306"  }   MySQL  172.16.1.125:3306 ssl  JS >

Cluster.status()的輸出提供以下資訊:

  • clusterName:在dba.createCluster期間分配給此集群的名稱。
  • defaultReplicaSet:屬於InnoDB Cluster並包含數據集的伺服器實例。
  • primary:僅在群集以單主模式運行時顯示。顯示當前主實例的地址。如果未顯示此欄位,則群集將以多主模式運行。
  • ssl:群集是否使用安全連接。顯示REQUIRED或DISABLED的值,預設為REQUIRED,具體取決於在createCluster()或addInstance()期間如何配置memberSslMode選項。此參數返回的值對應於實例上的group_replication_ssl_mode伺服器變數的值。
  • status:集群狀態,反映了此群集可提供的高可用性。實例狀態為以下之一:ONLINE,實例在線並參與群集;OFFLINE,實例已失去與其它實例的連接;RECOVERING,實例嘗試通過在成為ONLINE成員之前檢索所需的事務來嘗試與集群同步;UNREACHABLE,實例已丟失與群集的通訊;ERROR,實例在恢復階段或應用事務時遇到錯誤。實例進入ERROR狀態後,super_read_only選項設置為ON,要退出ERROR狀態,必須手動設置super_read_only = OFF。MISSING,實例的狀態,它是已配置群集的一部分,但當前不可用。MISSING狀態特定於InnoDB Cluster,它不是Group Replication生成的狀態。MySQL Shell使用此狀態來指示在元數據中註冊但在實時群集視圖中找不到的實例。
  • topology:已添加到集群的實例。
  • 實例的主機名。
  • role:此實例在集群中提供的功能,目前只有HA。
  • mode:伺服器是讀寫(「R/W」)還是只讀(「R/O」)。從版本8.0.17開始,從實例中super_read_only變數的當前狀態以及群集是否具有仲裁派生的。在之前版本中,mode的值來自實例是作為主實例還是輔助實例。通常,如果實例是主要的,則模式為「R/W」,如果為輔助實例,則模式為「R/O」。無論super_read_only變數的狀態如何,群集中沒有可見仲裁的任何實例都標記為「R/O」。
  • groupInformationSourceMember:用於獲取有關集群的資訊的內部連接,顯示為類似URI的連接字元串,通常為最初用於創建集群的連接。

要顯示有關群集的更多資訊,可使用擴展選項。如Cluster.status({'extended':value})提供附加資訊,value值控制輸出資訊:

  • 0:默認值,禁用附加資訊。
  • 1:包括有關組複製報告的組複製協議版本,組名稱,集群成員UUID,集群成員角色和狀態以及受防護系統變數列表的資訊。
  • 2:包括有關連接和應用程式處理的事務的資訊。

6. 基於已有組複製的集群創建

如果在已經配置好的組複製上創建InnoDB Cluster,並且希望使用它來創建集群,可將adoptFromGR選項傳遞給dba.createCluster()函數。創建的InnoDB Cluster會匹配複製組是以單主資料庫還是多主資料庫運行。 要採用現有的組複製組,使用MySQL Shell連接到組成員。以下示例採用單主組複製,172.16.1.125:3306為主實例,172.16.1.126:3306和172.16.1.127:3306為兩個輔助實例。這裡連接到172.16.1.125:3306創建集群。

mysqlsh --uri [email protected]:3306   MySQL  172.16.1.125:3306 ssl  JS > var cluster = dba.createCluster('testCluster', {adoptFromGR: true});  A new InnoDB cluster will be created based on the existing replication group on instance '172.16.1.125:3306'.    Creating InnoDB cluster 'testCluster' on '172.16.1.125:3306'...    Adding Seed Instance...  Adding Instance 'hdp3:3306'...  Adding Instance 'hdp4:3306'...  Adding Instance 'hdp2:3306'...  Resetting distributed recovery credentials across the cluster...  Cluster successfully created based on existing replication group.   MySQL  172.16.1.125:3306 ssl  JS >

新群集與組複製的模式匹配。如果組複製以單主模式運行,則會創建單主群集。如果組複製以多主模式運行,則會創建多主集群。

7. 配置MySQL Router

MySQL Router可以使用–bootstrap選項基於InnoDB Cluster的元數據進行自我配置。這會自動配置MySQL Router以將連接路由到群集的伺服器實例。客戶端應用程式連接到MySQL Router提供的埠,無需了解InnoDB Cluster拓撲。如果發生意外故障,InnoDB Cluster會自動調整,MySQL Router會檢測到更改。這消除了客戶端應用程式處理故障轉移的需求。MySQL不建議手動配置MySQL Router以重定向到InnoDB Cluster的埠,而是建議始終使用–bootstrap選項,因為這可確保MySQL Router從InnoDB Cluster的元數據中獲取其配置。使用生產部署時,建議將MySQL Router部署於客戶端應用程式所在的每台電腦上。

MySQL Router使用包含的元數據快取插件來檢索InnoDB Cluster的元數據,該元數據由構成InnoDB Cluster的伺服器實例地址列表及其在集群中的角色組成。MySQL Router從它所連接的實例中檢索InnoDB Cluster元數據,例如172.16.1.125:3306:

[mysql@hdp1~]$mysqlrouter --bootstrap [email protected]:3306  Please enter MySQL password for wxy:  # Reconfiguring system MySQL Router instance...    WARNING: router_id 1 not found in metadata  - Checking for old Router accounts    - No prior Router accounts found  - Creating mysql account mysql_router1_c13bmjjayuwr@'%' for cluster management  - Storing account in keyring  - Adjusting permissions of generated files  - Creating configuration /home/mysql/mysql-router-8.0.17-linux-glibc2.12-x86_64/mysqlrouter.conf    # MySQL Router configured for the InnoDB cluster 'testCluster'    After this MySQL Router has been started with the generated configuration        $ /etc/init.d/mysqlrouter restart  or      $ systemctl start mysqlrouter  or      $ mysqlrouter -c /home/mysql/mysql-router-8.0.17-linux-glibc2.12-x86_64/mysqlrouter.conf    the cluster 'testCluster' can be reached by connecting to:    ## MySQL Classic protocol    - Read/Write Connections: localhost:6446  - Read/Only Connections:  localhost:6447    ## MySQL X protocol    - Read/Write Connections: localhost:64460  - Read/Only Connections:  localhost:64470      Existing configuration backed up to '/home/mysql/mysql-router-8.0.17-linux-glibc2.12-x86_64/mysqlrouter.conf.bak'    Existing dynamic state backed up to '/home/mysql/mysql-router-8.0.17-linux-glibc2.12-x86_64/var/lib/mysqlrouter/state.json.bak'  [mysql@hdp1~]$

基於檢索到的InnoDB Cluster元數據,MySQL Router自動配置mysqlrouter.conf文件,包括帶有bootstrap_server_addresses的metadata_cache部分,其中包含集群中所有伺服器實例的地址。下面是引導時自動生成的/home/mysql/mysql-router-8.0.17-linux-glibc2.12-x86_64/mysqlrouter.conf文件的內容:

# File automatically generated during MySQL Router bootstrap  [DEFAULT]  name=system  keyring_path=/home/mysql/mysql-router-8.0.17-linux-glibc2.12-x86_64/var/lib/mysqlrouter/keyring  master_key_path=/home/mysql/mysql-router-8.0.17-linux-glibc2.12-x86_64/mysqlrouter.key  connect_timeout=15  read_timeout=30  dynamic_state=/home/mysql/mysql-router-8.0.17-linux-glibc2.12-x86_64/var/lib/mysqlrouter/state.json    [logger]  level = INFO    [metadata_cache:testCluster]  router_id=1  user=mysql_router1_c13bmjjayuwr  metadata_cluster=testCluster  ttl=0.5  use_gr_notifications=0    [routing:testCluster_default_rw]  bind_address=0.0.0.0  bind_port=6446  destinations=metadata-cache://testCluster/default?role=PRIMARY  routing_strategy=first-available  protocol=classic    [routing:testCluster_default_ro]  bind_address=0.0.0.0  bind_port=6447  destinations=metadata-cache://testCluster/default?role=SECONDARY  routing_strategy=round-robin-with-fallback  protocol=classic    [routing:testCluster_default_x_rw]  bind_address=0.0.0.0  bind_port=64460  destinations=metadata-cache://testCluster/default?role=PRIMARY  routing_strategy=first-available  protocol=x    [routing:testCluster_default_x_ro]  bind_address=0.0.0.0  bind_port=64470  destinations=metadata-cache://testCluster/default?role=SECONDARY  routing_strategy=round-robin-with-fallback  protocol=x

通過在引導MySQL Router之後添加另一個伺服器實例來更改群集的拓撲時,需要根據更新的元數據更新bootstrap_server_addresses。可以使用–bootstrap選項重新引導MySQL Router並重啟MySQL Router達到此目的。

生成的MySQL Router配置會創建用於連接到群集的TCP埠,包括使用經典MySQL協議和X協議與群集通訊的埠,預設值如下:

  • 6446:用於經典MySQL協議讀寫會話,MySQL Router將傳入連接重定向到主伺服器實例。
  • 6447:對於經典MySQL協議只讀會話,MySQL Router將傳入連接重定向到其中一個輔助伺服器實例。
  • 64460:用於X協議讀寫會話,MySQL Router將傳入連接重定向到主伺服器實例。
  • 64470:用於X協議只讀會話,MySQL Router將傳入連接重定向到其中一個輔助伺服器實例。

傳入連接的重定向方式取決於所使用的群集類型。使用單主群集時,默認情況下,MySQL Router會發布X協議和經典協議埠,客戶端連接到這些埠(如6446或64460)以進行讀寫會話,並重定向到群集的單個主節點。使用多主群集時,讀寫會話將以循環方式重定向到其中一個主實例。例如,到埠6446的第一個連接將被重定向到主實例1,到埠6446的第二個連接將被重定向到主實例2,依此類推。對於傳入的只讀連接,MySQL Router以循環方式將連接重定向到其中一個輔助實例。路由策略由routing_strategy選項控制,參見「https://wxy0327.blog.csdn.net/article/details/100518636#2.%20%E5%90%AF%E5%8A%A8」。

使用–bootstrap選項進行引導後,執行下面的命令後台啟動MySQL Router:

[mysql@hdp1~]$mysqlrouter &

8. 客戶端連接測試

現在,可以將MySQL客戶端(如mysql或MySQL Shell)連接到其中一個傳入的MySQL Router埠,並查看客戶端如何透明地連接到其中一個InnoDB Cluster實例。測試腳本文件router_connect_test.sh的內容如下:

mysql -uwxy -123456 -P6446 --protocol=TCP -N -r -B -e"select @@hostname"  mysql -uwxy -123456 -P6446 --protocol=TCP -N -r -B -e"select @@hostname"  mysql -uwxy -123456 -P6447 --protocol=TCP -N -r -B -e"select @@hostname"  mysql -uwxy -123456 -P6447 --protocol=TCP -N -r -B -e"select @@hostname"  mysql -uwxy -123456 -P6447 --protocol=TCP -N -r -B -e"select @@hostname"  mysqlsh --sql -uwxy -123456 -P64460 -e"select @@hostname"  mysqlsh --sql -uwxy -123456 -P64460 -e"select @@hostname"  mysqlsh --sql -uwxy -123456 -P64470 -e"select @@hostname"  mysqlsh --sql -uwxy -123456 -P64470 -e"select @@hostname"  mysqlsh --sql -uwxy -123456 -P64470 -e"select @@hostname"

執行測試腳本並將結果輸出導文件:

[mysql@hdp1~]$./router_connect_test.sh > result.txt

查看測試結果:

[mysql@hdp1~]$cat result.txt  hdp2  hdp2  hdp3  hdp4  hdp3  @@hostname  hdp2  @@hostname  hdp2  @@hostname  hdp4  @@hostname  hdp3  @@hostname  hdp4  [mysql@hdp1~]$

9. 測試高可用性 要測試高可用性是否有效,可以通過終止實例來模擬意外停止。群集檢測到實例離開群集並重新配置自身,重新配置的確切方式取決於使用的是單主群集還是多主群集,以及實例在群集中的角色。在單主模式下:

  • 如果當前主節點離開集群,則其中一個輔助實例被選為新主節點,其中實例由最低server_uuid區分優先順序。MySQL Router將讀寫連接重定向到新選擇的主節點。
  • 如果當前輔助節點離開群集,MySQL Router將停止將只讀連接重定向到該實例。

(1)停止172.16.1.125:3306實例,測試客戶端連接

# 在hdp2上執行  mysqladmin -uroot -p123456 shutdown    # 在hdp1上執行  router_connect_test.sh > result.txt  cat result.txt

測試結果如下:

hdp3  hdp3  hdp4  hdp4  hdp4  @@hostname  hdp3  @@hostname  hdp3  @@hostname  hdp4  @@hostname  hdp4  @@hostname  hdp4

停止hdp2後,選舉的新主節點為hdp3,集群變為了一主一從,客戶端訪問正常。

(2)重新啟動172.16.1.125:3306實例,測試客戶端連接

# 在hdp2上執行  mysqld_safe &    # 在hdp1上執行  router_connect_test.sh > result.txt  cat result.txt

測試結果如下:

hdp3  hdp3  hdp2  hdp4  hdp2  @@hostname  hdp3  @@hostname  hdp3  @@hostname  hdp2  @@hostname  hdp4  @@hostname  hdp2

啟動hdp2後,它自動變為輔助節點,集群又成了一主兩從,客戶端訪問正常。

(3)停止172.16.1.127:3306實例,測試客戶端連接

# 在hdp4上執行  mysqladmin -uroot -p123456 shutdown    # 在hdp1上執行  router_connect_test.sh > result.txt  cat result.txt

測試結果如下:

hdp3  hdp3  hdp2  hdp2  hdp2  @@hostname  hdp3  @@hostname  hdp3  @@hostname  hdp2  @@hostname  hdp2  @@hostname  hdp2

停止hdp4後,集群變為了一主一從,客戶端訪問正常。

(4)重新啟動172.16.1.127:3306實例,測試客戶端連接

# 在hdp4上執行  mysqld_safe &    # 在hdp1上執行  router_connect_test.sh > result.txt  cat result.txt

測試結果如下:

hdp3  hdp3  hdp2  hdp4  hdp2  @@hostname  hdp3  @@hostname  hdp3  @@hostname  hdp2  @@hostname  hdp4  @@hostname  hdp2

啟動hdp4後,集群又成為了一主兩從,客戶端訪問正常。

三、使用MySQL Shell管理InnoDB Cluster

本節介紹如何使用MySQL Shell處理常見的InnoDB Cluster管理任務,大部分配置本質上是使用MySQL Shell提供的方法和選項配置組複製相關的系統變數。

1. 配置實例的自動重新加入

運行MySQL 8.0.16及更高版本的實例支援組複製自動重新加入功能,可以將實例配置為在被驅逐後自動重新加入群集。 AdminAPI提供了autoRejoinTries選項,用於配置在驅逐後重新加入群集的嘗試次數。默認情況下,實例不會自動重新加入群集。可以使用以下命令在集群級別或單個實例上配置autoRejoinTries選項:

  • dba.createCluster()
  • Cluster.addInstance()
  • Cluster.setOption()
  • Cluster.setInstanceOption()

autoRejoinTries選項對應group_replication_autorejoin_tries系統變數,例如將重連嘗試次數由預設的0改為10:

[mysql@hdp1~]$mysql -uwxy -p123456 -P6446 --protocol=TCP -N -r -B -e"select @@group_replication_autorejoin_tries"  Warning: Using a password on the command line interface can be insecure.  0  [mysql@hdp1~]$mysqlsh --uri [email protected]:3306 -p123456 -e "var cluster = dba.getCluster(); cluster.setOption('autoRejoinTries',10)"  WARNING: Using a password on the command line interface can be insecure.  WARNING: Each cluster member will only proceed according to its exitStateAction if auto-rejoin fails (i.e. all retry attempts are exhausted).    Setting the value of 'autoRejoinTries' to '10' in all ReplicaSet members ...    Successfully set the value of 'autoRejoinTries' to '10' in the 'default' ReplicaSet.  [mysql@hdp1~]$mysql -uwxy -p123456 -P6446 --protocol=TCP -N -r -B -e"select @@group_replication_autorejoin_tries"  Warning: Using a password on the command line interface can be insecure.  10  [mysql@hdp1~]$

autoRejoinTries選項接受介於0和2016之間的正整數值,默認值為0,即不嘗試自動重新加入。自動重連適用於網路不穩定的場景。

運行MySQL 8.0.12及更高版本的實例具有group_replication_exit_state_action變數,可以使用AdminAPI exitStateAction選項配置該變數。這可以控制在意外離開集群時實例執行的操作。默認情況下,exitStateAction選項為READ_ONLY,這意味著離開集群的實例意外地變為只讀。如果exiStateAction是ABORT_SERVER,那麼在意外離開集群的情況下,實例會關閉MySQL,並且必須先重新啟動它才能重新加入集群。

[mysql@hdp1~]$mysql -uwxy -p123456 -P6446 --protocol=TCP -N -r -B -e"select @@group_replication_exit_state_action"  Warning: Using a password on the command line interface can be insecure.  READ_ONLY  [mysql@hdp1~]$mysqlsh --uri [email protected]:3306 -p123456 -e "var cluster = dba.getCluster(); cluster.setOption('exitStateAction','ABORT_SERVER')"  WARNING: Using a password on the command line interface can be insecure.  Setting the value of 'exitStateAction' to 'ABORT_SERVER' in all ReplicaSet members ...    Successfully set the value of 'exitStateAction' to 'ABORT_SERVER' in the 'default' ReplicaSet.  [mysql@hdp1~]$mysql -uwxy -p123456 -P6446 --protocol=TCP -N -r -B -e"select @@group_replication_exit_state_action"  Warning: Using a password on the command line interface can be insecure.  ABORT_SERVER  [mysql@hdp1~]$

需要注意的是,在使用自動重新加入功能時,exitStateAction選項配置的操作僅在所有嘗試重新加入群集失敗的情況下發生。

2. 從InnoDB Cluster中刪除實例

可以使用Cluster.removeInstance(instance)方法隨時從群集中刪除實例:

 MySQL  172.16.1.126:3306 ssl  JS > var cluster = dba.getCluster();   MySQL  172.16.1.126:3306 ssl  JS > cluster.removeInstance('[email protected]:3306');  The instance will be removed from the InnoDB cluster. Depending on the instance  being the Seed or not, the Metadata session might become invalid. If so, please  start a new session to the Metadata Storage R/W instance.    Instance '172.16.1.126:3306' is attempting to leave the cluster...    The instance '172.16.1.126:3306' was successfully removed from the cluster.     MySQL  172.16.1.126:3306 ssl  JS >

cluster.removeInstance()操作可確保從ONLINE的所有集群成員和實例本身的元數據中刪除實例。

當要刪除的實例具有仍需要應用的事務時,AdminAPI會等待MySQL Shell dba.gtidWaitTimeout選項為要應用的事務(GTID)配置的秒數。 MySQL Shell dba.gtidWaitTimeout選項的默認值為60秒:

 MySQL  172.16.1.126:3306 ssl  JS > option dba.gtidWaitTimeout  60   MySQL  172.16.1.126:3306 ssl  JS >

更改默認值的資訊:

 MySQL  172.16.1.126:3306 ssl  JS > shell.options['dba.gtidWaitTimeout']=120  120   MySQL  172.16.1.126:3306 ssl  JS > option dba.gtidWaitTimeout  120   MySQL  172.16.1.126:3306 ssl  JS >

如果在等待應用事務並且force選項為false(預設)時達到dba.gtidWaitTimeout定義的超時值,則會發出錯誤並中止刪除操作。如果在等待應用事務並且force選項設置為true時達到dba.gtidWaitTimeout定義的超時值,則操作將繼續而不會出現錯誤,並從群集中刪除該實例。從群集中刪除實例時忽略錯誤可能導致實例與群集不同步,從而阻止其稍後重新加入群集。只有當不再使用實例時在開啟強制選項,在所有其它情況下,應該始終嘗試恢復實例,並僅狀態為ONLINE時將其刪除。

3. 重啟群集

可以使用dba.rebootClusterFromCompleteOutage()重啟整個集群。此操作採用MySQL Shell當前連接的實例並使用其元數據來恢復群集。如果群集的實例已完全停止,則必須啟動實例,然後才能啟動群集。 在生產部署的情況下,必須在MySQL Shell之外啟動實例。實例啟動後,需要連接到中斷之前應用了最多事務的實例。如果不確定是哪個實例,可連接到任何實例並按照dba.rebootClusterFromCompleteOutage()中的交互消息進行操作,該消息檢測連接的實例是否應用了最多事務。

 MySQL  JS > dba.rebootClusterFromCompleteOutage();  Dba.rebootClusterFromCompleteOutage: An open session is required to perform this operation. (RuntimeError)   MySQL  JS > connect [email protected]:3306  Creating a session to '[email protected]:3306'  Please provide the password for '[email protected]:3306': ******  Save password for '[email protected]:3306'? [Y]es/[N]o/Ne[v]er (default No):  Fetching schema names for autocompletion... Press ^C to stop.  Your MySQL connection id is 165  Server version: 8.0.16 MySQL Community Server - GPL  No default schema selected; type use <schema> to set one.   MySQL  172.16.1.125:3306 ssl  JS > dba.rebootClusterFromCompleteOutage();  Reconfiguring the default cluster from complete outage...    The instance 'hdp4:3306' was part of the cluster configuration.  Would you like to rejoin it to the cluster? [y/N]: y    The instance 'hdp3:3306' was part of the cluster configuration.  Would you like to rejoin it to the cluster? [y/N]: y    The safest and most convenient way to provision a new instance is through  automatic clone provisioning, which will completely overwrite the state of  '172.16.1.125:3306' with a physical snapshot from an existing cluster member.  To use this method by default, set the 'recoveryMethod' option to 'clone'.    The incremental distributed 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'.    Incremental distributed state recovery was selected because it seems to be safely usable.    The cluster was successfully rebooted.    <Cluster:testCluster>   MySQL  172.16.1.125:3306 ssl  JS >

dba.rebootClusterFromCompleteOutage()操作遵循以下步驟以確保正確重新配置集群:

  • 檢查在MySQL Shell當前連接的實例上找到的InnoDB Cluster元數據,以查看它是否包含最多事務。如果不是則操作中止。在這種情況下,將MySQL Shell連接到錯誤消息中建議的實例,並從該實例發出dba.rebootClusterFromCompleteOutage()。
  • 如果實例包含包含最多事務,則會根據實例的元數據恢復群集。
  • 交互模式下會運行一個嚮導,檢查當前可以訪問哪個群集實例,並詢問是否要將任何已發現的實例重新加入重新引導的群集。
  • 交互模式下嚮導還會檢測當前無法訪問的實例,並詢問是否要從重新引導的群集中刪除此類實例。

要手動檢測哪個實例具有最多事務,請檢查每個實例上的gtid_executed變數:

show variables like 'gtid_executed';

如果此過程失敗,並且群集元數據已嚴重損壞,則可能需要刪除元數據並從頭開始再次創建群集。可以使用dba.dropMetadataSchema()刪除集群元數據。dba.dropMetadataSchema方法應僅用作無法還原群集時的最後手段,並且刪除的元數據是不可恢復的。

4. 解散InnoDB Cluster

解散InnoDB Cluster需要連接到狀態為ONLINE的讀寫實例,例如單主集群中的主實例,並使用Cluster.dissolve()命令。這將刪除與群集關聯的所有元數據和配置,並禁用實例上的組複製,但不會刪除在實例之間複製的任何數據。要再次創建集群,使用dba.createCluster()。

 MySQL  JS > connect [email protected]:3306  Creating a session to '[email protected]:3306'  Please provide the password for '[email protected]:3306': ******  Save password for '[email protected]:3306'? [Y]es/[N]o/Ne[v]er (default No):  Fetching schema names for autocompletion... Press ^C to stop.  Your MySQL connection id is 2830  Server version: 8.0.16 MySQL Community Server - GPL  No default schema selected; type use <schema> to set one.   MySQL  172.16.1.125:3306 ssl  JS > var cluster = dba.getCluster()   MySQL  172.16.1.125:3306 ssl  JS > cluster.dissolve()  The cluster still has the following registered ReplicaSets:  {      "clusterName": "testCluster",      "defaultReplicaSet": {          "name": "default",          "topology": [              {                  "address": "hdp2:3306",                  "label": "hdp2:3306",                  "role": "HA",                  "version": "8.0.16"              },              {                  "address": "hdp4:3306",                  "label": "hdp4:3306",                  "role": "HA",                  "version": "8.0.16"              },              {                  "address": "hdp3:3306",                  "label": "hdp3:3306",                  "role": "HA",                  "version": "8.0.16"              }          ],          "topologyMode": "Single-Primary"      }  }  WARNING: You are about to dissolve the whole cluster and lose the high availability features provided by it. This operation cannot be reverted. All members will be removed from their ReplicaSet and replication will be stopped, internal recovery user accounts and the cluster metadata will be dropped. User data will be maintained intact in all instances.    Are you sure you want to dissolve the cluster? [y/N]: y    Instance 'hdp4:3306' is attempting to leave the cluster...  Instance 'hdp3:3306' is attempting to leave the cluster...  Instance 'hdp2:3306' is attempting to leave the cluster...    The cluster was successfully dissolved.  Replication was disabled but user data was left intact.     MySQL  172.16.1.125:3306 ssl  JS >

dba.gtidWaitTimeout選項配置Cluster.dissolve()操作在從群集中刪除目標實例之前等待群集事務的時間,但僅限於目標實例為ONLINE。如果在等待要刪除的任何實例上應用集群事務超時,則會發出錯誤(除非使用force:true)。

5. 配置新主選舉權重

可以通過在dba.createCluster()或Cluster.addInstance()方法中指定memberWeight影響新主節點的選舉結果。memberWeight選項的值域為0到100之間的整數,預設值為50。該值是故障轉移時自動選舉主節點的百分比權重,對應group_replication_member_weight系統變數。具有較高memberWeight值的實例更有可能在單主群集中被選為主節點。如果多個實例具有相同的memberWeight值,則根據伺服器UUID的字典正序,選擇第一個實例作為主節點。

例如將[email protected]:3306配置為故障轉移到的首選實例:

dba.createCluster('testCluster', {memberWeight:35})  var mycluster = dba.getCluster()  mycluster.addInstance('[email protected]:3306', {memberWeight:25})  mycluster.addInstance('[email protected]:3306', {memberWeight:50})

6. 配置故障轉移一致性

dba.createCluster()的consistency選項用於指定單主模式下故障轉移一致性。該選項配置種子實例的group_replication_consistency系統變數:consistency = 0對應EVENTUAL;consistency = 1對應BEFORE_ON_PRIMARY_FAILOVER。該選項僅對單主模式起作用,多主模式下允許使用但選項無效。僅當目標MySQL伺服器版本為8.0.14或更高版本時才支援一致性選項,並且添加集群的實例具有相同的group_replication_consistency值。

關於組複製中數據一致性的概念,參見「https://wxy0327.blog.csdn.net/article/details/96482662#%E4%BA%8C%E3%80%81%E4%BF%9D%E8%AF%81%E6%95%B0%E6%8D%AE%E4%B8%80%E8%87%B4%E6%80%A7」。

7. 更改組複製拓撲

InnoDB Cluster默認以單主模式運行,其中集群具有一個接受讀寫(R/W)的主伺服器,集群中的所有其餘實例僅接受只讀(R/O) 。將群集配置為在多主模式時,群集中的所有實例都是主節點,這意味著它們同時接受讀取和寫入查詢(R/W)。如果群集的所有實例都運行MySQL伺服器版本8.0.15或更高版本,則可以在群集聯機時更改群集的拓撲。 Cluster.setPrimaryInstance()函數指定一個新的主節點:

 MySQL  172.16.1.125:3306 ssl  JS > cluster.setPrimaryInstance('172.16.1.126:3306')  Setting instance '172.16.1.126:3306' as the primary instance of cluster 'testCluster'...    Instance 'hdp2:3306' was switched from PRIMARY to SECONDARY.  Instance 'hdp4:3306' remains SECONDARY.  Instance 'hdp3:3306' was switched from SECONDARY to PRIMARY.    WARNING: The cluster internal session is not the primary member anymore. For cluster management operations please obtain a fresh cluster handle using <Dba>.getCluster().    The instance '172.16.1.126:3306' was successfully elected as primary.   MySQL  172.16.1.125:3306 ssl  JS >

Cluster.switchToMultiPrimaryMode()切換到多主模式:

 MySQL  172.16.1.125:3306 ssl  JS > cluster.switchToMultiPrimaryMode()  Switching cluster 'testCluster' to Multi-Primary mode...    Instance 'hdp2:3306' was switched from SECONDARY to PRIMARY.  Instance 'hdp4:3306' was switched from SECONDARY to PRIMARY.  Instance 'hdp3:3306' remains PRIMARY.    The cluster successfully switched to Multi-Primary mode.   MySQL  172.16.1.125:3306 ssl  JS > 

Cluster.switchToSinglePrimaryMode()切換到單主模式:

 MySQL  172.16.1.125:3306 ssl  JS > cluster.switchToSinglePrimaryMode('172.16.1.125:3306')  Switching cluster 'testCluster' to Single-Primary mode...    Instance 'hdp2:3306' remains PRIMARY.  Instance 'hdp4:3306' was switched from PRIMARY to SECONDARY.  Instance 'hdp3:3306' was switched from PRIMARY to SECONDARY.    WARNING: Existing connections that expected a R/W connection must be disconnected, i.e. instances that became SECONDARY.    The cluster successfully switched to Single-Primary mode.   MySQL  172.16.1.125:3306 ssl  JS >

8. 設置InnoDB Cluster的選項

可以聯機查看或修改集群設置。Cluster.options檢查群集的當前設置:

 MySQL  172.16.1.125:3306 ssl  JS > cluster.options({all:true})  {      "clusterName": "testCluster",      "defaultReplicaSet": {          "globalOptions": [              {                  "option": "groupName",                  "value": "c8e80b07-d532-11e9-a1cc-005056a57a4e",                  "variable": "group_replication_group_name"              },                ...            }      }  }   MySQL  172.16.1.125:3306 ssl  JS >

Cluster.setOption(option, value)用於全局更改所有群集實例的設置或群集全局設置:

 MySQL  172.16.1.125:3306 ssl  JS > cluster.setOption('clusterName','procCluster')  Setting the value of 'clusterName' to 'procCluster' in the Cluster ...    Successfully set the value of 'clusterName' to 'procCluster' in the Cluster: 'testCluster'.   MySQL  172.16.1.125:3306 ssl  JS >

Cluster.setInstanceOption(instance, option, value)用於更改各個集群實例的設置:

 MySQL  172.16.1.125:3306 ssl  JS > cluster.setInstanceOption('172.16.1.125:3306', 'exitStateAction', 'READ_ONLY')  Setting the value of 'exitStateAction' to 'READ_ONLY' in the instance: '172.16.1.125:3306' ...    Successfully set the value of 'exitStateAction' to 'READ_ONLY' in the 'default' ReplicaSet member: '172.16.1.125:3306'.   MySQL  172.16.1.125:3306 ssl  JS >