如何在Ubuntu 20.04上配置MySQL集群複製

介紹

MySQL 複製可靠地將數據和操作從一個數據庫鏡像到另一個。 傳統複製 包括配置為接受數據庫寫操作的主服務器,以及將來自主服務器日誌的操作複製並應用到自己的數據集的次要服務器。 這些次要服務器可以用於讀取,但通常無法執行數據寫入。

群組複製是實現更靈活、容錯的複製機制的一種方式。 這個過程涉及建立一個池,其中每個服務器都參與確保數據被正確複製。 如果主服務器遇到問題,成員選舉可以從組中選擇新的主。 這允許剩餘的節點在面對問題時繼續運行。 通過實現 Paxos 共識算法 提供成員資格協商、失敗檢測和消息傳遞。

在本教程中,您將使用一組三台 Ubuntu 20.04 服務器設置 MySQL 群組複製。 請注意,您在 MySQL 中部署群組複製所需的最小 MySQL 實例數是三個,而最大數是九個。 在完成本教程時,您將可以將群組設置為單主或多主複製群組。

注意:数据库服务器在复制设置中可以担任两种角色之一:它们可以是主实例(也称为实例),用户可以向其写入数据;或者是副本(或次要实例),它存储源上所有数据的副本。从历史上看,这些角色曾被称为主实例从实例。在2020年7月发布的博文中,MySQL团队承认了这种术语的负面含义,并宣布他们正在努力更新数据库程序及其文档,以使用更具包容性的语言。

然而,这是一个持续的过程。虽然MySQL的文档和程序版本8中的许多命令已经更新为将复制拓扑中的服务器称为主服务器及其次级服务器(或副本),但仍有一些地方出现了负面术语。本指南将尽可能使用更具包容性的术语,但在一些情况下,旧术语不可避免地会出现。

先决条件

要完成本指南,您需要:

  • 三台运行 Ubuntu 20.04 的服务器。每台都应该有一个具有 sudo 权限的非 root 管理用户,并配置了 UFW 防火墙。请按照我们的 Ubuntu 20.04 初始服务器设置指南 来设置每台服务器。
  • 每台服务器上都安装了 MySQL。本指南假定您正在使用默认 Ubuntu 资源库中可用的最新版本的 MySQL,截至本文撰写时为版本 8.0.28。要在所有服务器上安装此版本,请按照我们的指南 在 Ubuntu 20.04 上安装 MySQL 来操作。

为了保持清晰,本指南将把这三台服务器分别称为 member1member2member3。在本指南的示例中,这些成员将具有以下 IP 地址:

Member IP address
member1 203.0.113.1
member2 203.0.113.2
member3 203.0.113.3

在本指南中,任何必须在 member1 上运行的命令都将有蓝色背景,如下所示:

同样,任何必须在 member2 上运行的命令都将有红色背景:

而任何必须在 member3 上运行的命令都将有绿色背景:

最后,任何必须在 三台服务器中的每台 上运行的命令都将具有标准背景:

步驟 1 — 生成 UUID 以識別 MySQL 群組

在打開 MySQL 配置文件以配置群組複製設置之前,您需要生成一個 UUID,以便用於識別您將要創建的 MySQL 群組。

member1 上,使用 uuidgen 命令來生成一個有效的 UUID 用於該群組:

  1. uuidgen
Output
168dcb64-7cce-473a-b338-6501f305e561

複製您收到的值,因為一會兒在配置服務器池的群組名稱時需要參考此值。

步驟 2 — 在 MySQL 配置文件中設置群組複製

現在您可以修改 MySQL 的配置文件了。使用您偏好的文本編輯器打開每個 MySQL 伺服器上的主 MySQL 配置文件。在這裡,我們將使用 nano

  1. sudo nano /etc/mysql/my.cnf

在Ubuntu上,MySQL預先安裝了多個不同的文件,您可以使用這些文件來定義各種配置更改。默認情況下,my.cnf文件僅用於從子目錄引用其他文件。您需要在!includedir行下面添加自己的配置。這將允許您覆蓋來自已包含文件的任何設置。

首先,通過包含[mysqld]標頭來開始一個新的部分,然後按照以下示例中突出顯示的步驟添加您需要啟用組複製所需的設置。請注意,這些設置是從官方MySQL文檔中概述的組複製所需的最小設置進行修改的。loose-前綴允許MySQL優雅地處理它不認識的選項,而不會導致失敗。您需要立即填寫和自定義其中一些設置:

/etc/mysql/my.cnf
. . .
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

[mysqld]

# General replication settings
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
log_bin = binlog
binlog_format = ROW
transaction_write_set_extraction = XXHASH64
loose-group_replication_bootstrap_group = OFF
loose-group_replication_start_on_boot = OFF
loose-group_replication_ssl_mode = REQUIRED
loose-group_replication_recovery_use_ssl = 1

# Shared replication group configuration
loose-group_replication_group_name = ""
loose-group_replication_ip_whitelist = ""
loose-group_replication_group_seeds = ""

# Single or Multi-primary mode? Uncomment these two lines
# for multi-primary mode, where any host can accept writes
#loose-group_replication_single_primary_mode = OFF
#loose-group_replication_enforce_update_everywhere_checks = ON

# Host specific replication configuration
server_id = 
bind-address = ""
report_host = ""
loose-group_replication_local_address = ""

為了更清楚地解釋所有這些配置選項,它們已被分成以下小節。請仔細閱讀它們,因為有些部分向您提出了有關如何部署您的複製組或需要輸入特定於您自己配置的詳細信息的選擇。

樣板組複製設置

第一部分包含了群组复制所需的一般设置,无需修改:

/etc/mysql/my.cnf
. . .
# 一般复制设置
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
log_bin = binlog
binlog_format = ROW
transaction_write_set_extraction = XXHASH64
loose-group_replication_bootstrap_group = OFF
loose-group_replication_start_on_boot = OFF
loose-group_replication_ssl_mode = REQUIRED
loose-group_replication_recovery_use_ssl = 1
. . .

MySQL中群组复制的一个特定要求是数据必须存储在InnoDB存储引擎中。MySQL文档建议明确禁用其他可能导致错误的存储引擎的使用,方法类似于此部分中的第一行未注释的行。

其余的设置打开了全局事务ID,配置了群组复制所需的二进制日志记录,并为群组配置了SSL。此配置还设置了一些其他有助于恢复和引导的项目。您无需修改此部分中的任何内容,它在您的三个服务器上应该完全相同,因此在添加后您可以继续进行。

共享群组复制设置

第二部分设置了群组的共享设置。您需要自定义一次,然后在每个节点上使用相同的设置。具体来说,您必须添加群组的UUID(您在上一步中创建的),授权组成员的列表以及联系种子成员以获取加入群组时的初始数据。

loose-group_replication_group_name設置為之前使用uuidgen命令生成的UUID值。請確保將UUID放置在空的雙引號之間。

接下來,將loose-group_replication_ip_whitelist設置為所有MySQL服務器IP地址的列表,用逗號分隔。 loose-group_replication_group_seeds設置應該幾乎與白名單相同,但應將指定的組復制端口附加到每個成員的末尾。出於本指南的目的,使用建議的組復制端口33061:

/etc/mysql/my.cnf
. . .
#共享復制組配置
loose-group_replication_group_name = "168dcb64-7cce-473a-b338-6501f305e561"
loose-group_replication_ip_whitelist = "203.0.113.1,203.0.113.2,203.0.113.3"
loose-group_replication_group_seeds = ""203.0.113.1:33061,203.0.113.2:33061,203.0.113.3:33061"
. . .

該部分在每個MySQL服務器上應該相同,請確保在每個服務器上仔細複製它。

選擇單一主要還是多主要

接下來,您需要決定是配置單一主要還是多主要群。在單一主要配置中,MySQL指定單個主要服務器(幾乎始終是第一個組成員)來處理寫操作。多主要群允許群中的任何成員執行寫操作。

如果您希望配置多主组,请取消注释loose-group_replication_single_primary_modeloose-group_replication_enforce_update_everywhere_checks指令。这将设置一个多主组。对于单主组,请保持这两行注释:

/etc/mysql/my.cnf
. . .
# 单主或多主模式?取消对这两行的注释
# 以使用多主模式,在此模式下任何主机都可以接受写入
#loose-group_replication_single_primary_mode = OFF
#loose-group_replication_enforce_update_everywhere_checks = ON
. . .

这些设置必须在每个 MySQL 服务器上相同。

您可以稍后更改此设置,但在这样做后,您必须重新启动 MySQL 组中的每个成员。要切换到新配置,您将需要停止组中的每个 MySQL 实例,使用新设置启动每个成员,然后重新引导组复制。这不会影响任何数据,但需要短暂的停机窗口。

特定主机配置设置

第四部分包含在每个服务器上不同的设置,包括:

  • 服务器 ID
  • 要绑定到的地址
  • 要向其他成员报告的地址
  • 本地复制地址和监听端口

server_id 指令必须设置为唯一的数字。对于第一个成员,将其设置为1,并在每个额外的主机上递增该数字。将bind-addressreport_host设置为各自服务器的IP地址,以便MySQL实例将会监听外部连接并将其地址正确报告给其他主机。loose-group_replication_local_address也应设置为当前服务器的IP地址,后跟群组复制端口(33061)附加到IP地址上。作为示例,这是配置部分的内容

对于member1使用其示例IP地址:

/etc/mysql/my.cnf
. . .
# 主机特定的复制配置
server_id = 1
bind-address = "203.0.113.1"
report_host = "203.0.113.1"
loose-group_replication_local_address = "203.0.113.1:33061"

在每个MySQL服务器上完成此过程。这是member2的配置:

/etc/mysql/my.cnf
. . .
# 主机特定的复制配置
server_id = 2
bind-address = "203.0.113.2"
report_host = "203.0.113.2"
loose-group_replication_local_address = "203.0.113.2:33061"

这是member3的配置:

/etc/mysql/my.cnf
. . .
# 主机特定的复制配置
server_id = 3
bind-address = "203.0.113.3"
report_host = "203.0.113.3"
loose-group_replication_local_address = "203.0.113.3:33061"

确保更新每个突出显示的IP地址为正在编辑其配置的服务器的IP地址。

完成后,请仔细检查每个主机上的共享复制设置是否相同,并且主机特定的设置是否为每个主机自定义。完成后在每个主机上保存并关闭文件。如果您使用nano编辑文件,可以按CTRL + XY,然后ENTER

您的每台服务器的MySQL配置文件现在包含了引导MySQL组复制所需的指令。要将新的设置应用到MySQL实例,请使用以下命令重新启动每台服务器上的服务:

  1. sudo systemctl restart mysql

有了这个,您可以继续通过更新每台服务器的防火墙规则来启用远程访问。

第3步 — 更新每台服务器的UFW规则

假设您遵循了先决条件初始服务器设置指南,您将在安装了MySQL并启用了OpenSSH UFW配置文件的每台服务器上设置了防火墙。这是一个重要的安全措施,因为这些防火墙目前会阻止连接到服务器上的任何端口,除了ssh连接外,这些连接需要与每台服务器各自的authorized_keys文件中的密钥相匹配。

在MySQL配置文件中,您配置了服务在默认端口3306上监听外部连接。您还定义了33061作为成员用于复制协调的端口。

在您的每个成员服务器上,您需要为该组中的其他成员打开对这两个端口的访问权限,以便它们之间可以相互通信。要在成员1上为成员2打开对这些端口的访问权限,请在成员1上运行以下ufw命令:

  1. sudo ufw allow from member2_server_ip to any port 3306
  2. sudo ufw allow from member2_server_ip to any port 33061

确保将member2_server_ip更改为反映您的成员2服务器的实际IP地址。然后,为成员3打开相同端口的访问权限,请运行以下命令:

  1. sudo ufw allow from member3_server_ip to any port 3306
  2. sudo ufw allow from member3_server_ip to any port 33061

接下来,更新其他两台服务器的防火墙规则。在成员2上运行以下命令,确保将IP地址分别更改为成员1成员3的IP地址:

  1. sudo ufw allow from member1_server_ip to any port 3306
  2. sudo ufw allow from member1_server_ip to any port 33061
  3. sudo ufw allow from member3_server_ip to any port 3306
  4. sudo ufw allow from member3_server_ip to any port 33061

最后,在成员3上运行以下两个命令。再次确保您为每台服务器输入了正确的IP地址:

  1. sudo ufw allow from member1_server_ip to any port 3306
  2. sudo ufw allow from member1_server_ip to any port 33061
  3. sudo ufw allow from member2_server_ip to any port 3306
  4. sudo ufw allow from member2_server_ip to any port 33061

添加这些UFW规则后,您的三个MySQL实例将被允许访问其他两台服务器上MySQL使用的端口。

有了对MySQL端口的访问权限,您现在可以创建一个复制用户并启用组复制插件。

步骤4 — 配置复制用户并启用组复制插件

為了與複製群組中的其他伺服器建立連接,每個 MySQL 實例都必須擁有專用的複製使用者。

每個 MySQL 伺服器上,使用管理使用者登錄到您的 MySQL 實例以開始交互式會話:

  1. sudo mysql

注意: 請確保在本節中運行每個命令在每個您的 MySQL 實例上

因為每個伺服器將有自己的複製使用者,您需要在創建過程中關閉二進位日誌記錄。否則,一旦開始複製,群組將嘗試將複製使用者從主要傳播到其他伺服器,從而與已存在的複製使用者發生衝突。從 MySQL 提示符在您的每個伺服器上運行以下命令:

  1. SET SQL_LOG_BIN=0;

現在您可以運行一個 CREATE USER 語句來創建您的複製使用者。運行以下命令,創建一個名為 repl 的使用者。此命令指定複製使用者必須使用 SSL 連接。此外,在創建此複製使用者時,請確保使用安全密碼取代密碼

  1. CREATE USER 'repl'@'%' IDENTIFIED BY 'password' REQUIRE SSL;

接下來,將新使用者授予伺服器上的複製權限:

  1. GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

然後刷新權限以實施更改:

  1. FLUSH PRIVILEGES;

隨後,重新啟用二進位日誌記錄以恢復正常操作:

  1. SET SQL_LOG_BIN=1;

接下來,設置 group_replication_recovery 通道以使用您的新複製使用者及其相關密碼。然後,每個伺服器將使用這些憑據對群組進行身份驗證:

  1. CHANGE REPLICATION SOURCE TO SOURCE_USER='repl', SOURCE_PASSWORD='password' FOR CHANNEL 'group_replication_recovery';

注意:如果您使用的是早于 8.0.23 版本的 MySQL,则需要使用 MySQL 的传统语法来设置这个:

  1. CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery';

安装了复制用户之后,您可以启用 group_replication 插件以准备初始化组:

  1. INSTALL PLUGIN group_replication SONAME 'group_replication.so';

通过运行以下命令验证插件是否已激活:

  1. SHOW PLUGINS;

由于 group_replication 插件是最近添加的插件,因此它将出现在列表底部:

Output
+----------------------------+----------+--------------------+----------------------+---------+ | Name | Status | Type | Library | License | +----------------------------+----------+--------------------+----------------------+---------+ | | | | | | | . . . | . . . | . . . | . . . | . . . | | | | | | | | group_replication | ACTIVE | GROUP REPLICATION | group_replication.so | GPL | +----------------------------+----------+--------------------+----------------------+---------+ 45 rows in set (0.00 sec)

此输出确认了插件已加载并且当前处于活动状态。在继续下一步之前,请确保您已在每个 MySQL 实例上运行了本节中的每个命令。

步骤 5 — 启动组复制

现在,每个 MySQL 服务器都配置了一个复制用户并启用了组复制插件,您可以开始启动您的组。

引导第一个节点

要启动组,请在 组的单个成员 上完成以下步骤。为了演示目的,本指南将在 member1 上完成这些步骤。

小组成员依赖现有成员在最初加入小组时发送复制数据、最新成员名单和其他信息。因此,您需要使用稍微不同的程序启动初始组成员,以便它知道不要期望从其种子列表中的其他成员接收此信息。

如果设置了group_replication_bootstrap_group变量,则告诉成员不应该期望从对等方接收信息,而应该建立一个新组并选择自己为主要成员。您可以使用以下命令打开此变量:

  1. SET GLOBAL group_replication_bootstrap_group=ON;

然后,您可以为初始组成员启动复制:

  1. START GROUP_REPLICATION;

之后,您可以将group_replication_bootstrap_group变量设置回OFF,因为唯一适用此情况的情况是没有现有的组成员:

  1. SET GLOBAL group_replication_bootstrap_group=OFF;

该组将以此服务器作为唯一成员启动。通过检查performance_schema数据库中replication_group_members表中的条目来验证此内容:

  1. SELECT * FROM performance_schema.replication_group_members;

此查询将返回表示当前主机的单个行:

Output
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+ | group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1 | 3306 | ONLINE | PRIMARY | 8.0.28 | XCom | +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+ 1 row in set (0.00 sec)

对于MEMBER_STATEONLINE值表示该节点在组内完全可操作。

接下来,创建一个带有一些示例数据的测试数据库和表。一旦向该组添加了更多成员,这些数据将自动复制到它们。

首先创建一个名为playground的示例数据库:

  1. CREATE DATABASE playground;

接下來,使用以下命令在playground數據庫中創建一個名為equipment的示例表:

  1. CREATE TABLE playground.equipment (
  2. id INT NOT NULL AUTO_INCREMENT,
  3. type VARCHAR(50),
  4. quant INT,
  5. color VARCHAR(25),
  6. PRIMARY KEY(id)
  7. );

此表包含以下四列:

  • id:此列將包含自動遞增的整數值,這意味著在將表加載到樣本數據時,您不需要為此列指定值
  • type:此列將包含描述該行表示的遊樂場設備類型的字符串值
  • quant:此列將包含整數值,表示給定類型的遊樂場設備的數量
  • color:此列將保存指定設備的顏色的字符串值

同時,請注意id列被指定為此表的主鍵。在MySQL中,每個複製到組的表都必須有一列指定為表的主鍵。

最後,運行以下命令將一行數據插入到表中:

  1. INSERT INTO playground.equipment (type, quant, color) VALUES ("slide", 2, "blue");

查詢表以確保數據已正確輸入:

  1. SELECT * FROM playground.equipment;
Output
+----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ 1 row in set (0.00 sec)

在驗證此服務器是組的成員並且具有寫入功能後,其他服務器可以加入該組。

啟動其餘節點

接下來,在成員2上啟動群組複製。由於您已經有一個活動成員,因此無需引導引導群組,此成員可以直接加入:

  1. START GROUP_REPLICATION;

成員3上,以相同的方式啟動群組複製:

  1. START GROUP_REPLICATION;

再次檢查任何三個伺服器的成員清單。這次,輸出中將列出三個伺服器:

  1. SELECT * FROM performance_schema.replication_group_members;
Output
+---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+ | group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1 | 3306 | ONLINE | PRIMARY | 8.0.28 | XCom | | group_replication_applier | 1ae4b211-1b01-11e7-9d89-ceb93e1d5494 | 203.0.113.2 | 3306 | ONLINE | SECONDARY | 8.0.28 | XCom | | group_replication_applier | 157b597a-1b01-11e7-9d83-566a6de6dfef | 203.0.113.3 | 3306 | ONLINE | SECONDARY | 8.0.28 | XCom | +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+----------------------------+ 3 rows in set (0.00 sec)

所有成員的MEMBER_STATE值應為ONLINE。對於一個新的群組,如果任何節點的狀態在幾秒鐘以上都是RECOVERING,通常表示發生了錯誤或配置錯誤。檢查/var/log/mysql/error.log中的日誌以獲取有關出錯原因的其他信息。

接下來,檢查測試數據庫信息是否已經在新成員上複製:

  1. SELECT * FROM playground.equipment;
Output
+----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ 1 row in set (0.01 sec)

如果新成員上有數據,這意味著群組複製正常工作。

第6步 — 測試新群組成員的寫入功能

接下來,您可以嘗試從新的複製群組成員寫入數據庫。這是否成功取決於您是否選擇配置單一主要或多主要群組。

在單一主要環境中進行寫入測試

在單一主要群組中,出於一致性原因,您應該期望來自非主要伺服器的任何寫入操作都會被拒絕。您可以隨時通過在複製群組的任何成員上運行以下查詢來查找當前的主要:

  1. SHOW STATUS LIKE '%primary%';
Output
+----------------------------------+--------------------------------------+ | Variable_name | Value | +----------------------------------+--------------------------------------+ | group_replication_primary_member | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | +----------------------------------+--------------------------------------+ 1 row in set (0.01 sec)

查詢的值將是一個 MEMBER_ID,您可以通過像之前那樣查詢群組成員列表來將其匹配到主機:

  1. SELECT * FROM performance_schema.replication_group_members;
Output
+---------------------------+--------------------------------------+--------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+--------------+-------------+--------------+ | group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1 | 3306 | ONLINE | | group_replication_applier | 1ae4b211-1b01-11e7-9d89-ceb93e1d5494 | 203.0.113.2 | 3306 | ONLINE | | group_replication_applier | 157b597a-1b01-11e7-9d83-566a6de6dfef | 203.0.113.3 | 3306 | ONLINE | +---------------------------+--------------------------------------+--------------+-------------+--------------+ 3 rows in set (0.01 sec)

正如此示例輸出所示,位於 203.0.113.1成員1 — 目前是主要伺服器。如果您嘗試從其他成員寫入資料庫,該操作將失敗:

  1. INSERT INTO playground.equipment (type, quant, color) VALUES ("swing", 10, "yellow");
Output
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement

這是預期的,因為該群組當前配置為單一可寫主要。如果主要伺服器出現問題並離開群組,群組將自動選擇一個新成員成為主要並接受寫入。

在多主要環境中進行寫入測試

對於已配置為多主要方向的群組,任何成員都應該能夠提交寫入到資料庫。

您可以再次检查group_replication_primary_member变量的值,以确保您的组正在多主模式下运行:

  1. SHOW STATUS LIKE '%primary%';
Output
+----------------------------------+-------+ | Variable_name | Value | +----------------------------------+-------+ | group_replication_primary_member | | +----------------------------------+-------+ 1 row in set (0.02 sec)

如果该变量为空,则意味着没有指定的主机,并且任何成员都应该能够接受写入。

member2上测试这一点,尝试向equipment表中写入一些数据:

  1. INSERT INTO playground.equipment (type, quant, color) VALUES ("swing", 10, "yellow");
Output
Query OK, 1 row affected (0.00 sec)

member2在没有任何错误的情况下提交了写操作。

member3上运行以下查询,以检查新项目是否已添加:

  1. SELECT * FROM playground.equipment;
Output
+----+-------+-------+--------+ | id | type | quant | color | +----+-------+-------+--------+ | 1 | slide | 2 | blue | | 2 | swing | 10 | yellow | +----+-------+-------+--------+ 2 rows in set (0.00 sec)

这证实了member2的写入已成功复制。

现在,在member3上测试写入功能,通过运行以下INSERT语句:

  1. INSERT INTO playground.equipment (type, quant, color) VALUES ("seesaw", 3, "green");
Output
Query OK, 1 row affected (0.02 sec)

回到member1,确保来自新成员的写入操作都已复制回:

  1. SELECT * FROM playground.equipment;
Output
+----+--------+-------+--------+ | id | type | quant | color | +----+--------+-------+--------+ | 1 | slide | 2 | blue | | 2 | swing | 10 | yellow | | 3 | seesaw | 3 | green | +----+--------+-------+--------+ 3 rows in set (0.01 sec)

这证实了复制工作在每个方向上,并且每个成员都能够执行写操作。

步骤7 —— 将组恢复正常

一旦群組被啟動,個別成員可以加入和離開而不影響可用性,只要有足夠的成員來選舉主要伺服器。但是,如果進行某些配置更改(例如在單一和多主環境之間切換)或者群組的所有成員都離開了,您可能需要重新啟動群組,就像最初一樣。

成員1上,將group_replication_bootstrap_group變數設置為ON

  1. SET GLOBAL GROUP_REPLICATION_BOOTSTRAP_GROUP=ON;

然後初始化群組:

  1. START GROUP_REPLICATION;

之後,您可以將group_replication_bootstrap_group變數設置回OFF

  1. SET GLOBAL GROUP_REPLICATION_BOOTSTRAP_GROUP=OFF;

一旦第一個成員啟動了群組,其他成員就可以加入:

  1. START GROUP_REPLICATION;

按照此流程為任何其他成員加入:

  1. START GROUP_REPLICATION;

群組現在應該是在線的,所有成員都可用:

  1. SELECT * FROM performance_schema.replication_group_members;
Output
+---------------------------+--------------------------------------+--------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+--------------+-------------+--------------+ | group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1 | 3306 | ONLINE | | group_replication_applier | 1ae4b211-1b01-11e7-9d89-ceb93e1d5494 | 203.0.113.2 | 3306 | ONLINE | | group_replication_applier | 157b597a-1b01-11e7-9d83-566a6de6dfef | 203.0.113.3 | 3306 | ONLINE | +---------------------------+--------------------------------------+--------------+-------------+--------------+ 3 rows in set (0.01 sec)

此過程可用於在需要時重新啟動群組。

步驟8 — 在MySQL啟動時自動加入群組

根據當前設置,如果成員伺服器重新啟動,它將不會在啟動時自動重新加入群組。如果您希望成員在啟動時自動重新加入群組,您可以稍微修改配置文件。

在這一步中概述的設置對於希望成員在啟動時自動加入很有幫助。然而,有一些事情你應該注意。首先,這個設置只影響當 MySQL 實例本身啟動時。如果成員因超時問題而從群組中移除,但 MySQL 實例仍然在線上,該成員將不會自動重新加入。

其次,在首次引導群組時啟用這個設置可能是有害的。當沒有現有的群組可加入時,MySQL 進程將花費很長時間啟動,因為它將嘗試聯繫其他不存在的成員來初始化。只有在長時間的超時之後,它才會放棄並正常啟動。之後,您將不得不使用上面概述的程序來引導群組。

在牢記上述注意事項的前提下,如果您希望配置節點在 MySQL 啟動時自動加入群組,請打開主 MySQL 配置文件:

  1. sudo nano /etc/mysql/my.cnf

在文件內找到 loose-group_replication_start_on_boot 變量,並將其設置為 ON

/etc/mysql/my.cnf

[mysqld]
. . .
loose-group_replication_start_on_boot = ON
. . .

完成後保存並關閉文件。下次啟動 MySQL 實例時,該成員應試圖自動加入群組。

結論

通過完成本教程,您學會了如何在三台 Ubuntu 20.04 伺服器之間配置 MySQL 群組複製。對於單主要設置,成員將在必要時自動選擇可寫的主要設備。對於多主要群組,任何成員都可以執行寫入和更新。

群組複製提供了一種靈活的複製拓撲,允許成員隨時加入或離開,同時提供關於數據一致性和消息排序的保證。配置 MySQL 群組複製可能會稍微複雜一些,但它提供了傳統複製中不可能的功能。

Source:
https://www.digitalocean.com/community/tutorials/how-to-configure-mysql-group-replication-on-ubuntu-20-04