InnoDB Cluster詳解

目錄

一、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 >

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章