本文主要是介绍MySQL数据库复制技术 Part 7 : 组复制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1 MySQL数据库 Group Replication
MySQL Group Replication(下简称:MGR)是MySQL官方推出的一种基于Paxos协议的状态机复制。在MGR出现之前,用户常见的MySQL高可用方式,无论怎么变化架构,本质就是Master-Slave架构。MySQL 5.7版本开始支持无损半同步复制(lossless semi-sync replication),从而进一步提示数据复制的强一致性
组复制是一种可用于实现容错系统的技术。复制组是一个通过消息传递相互交互的Server集群。复制组由多个Server成员组成,如下图的Master1、Master2、Master3,所有成员独立完成各自的事务。
当客户端发起一个更新事务时,该事务先在本地执行,执行完成之后就要发起对事务的提交操作。在还没有真正提交之前,需要将产生的复制写集广播出去,复制到其它成员。如果冲突检测成功,组内决定该事务可以提交,其它成员可以应用,否则就回滚。
最终,所有组内成员以相同的顺序接收同一组事务。因此组内成员以相同的顺序应用相同的修改,保证组内数据强一致性。
2 MySQL Group Replication 要求
要用于组复制的服务器实例必须满足以下要求。
2.1 基础架构
2.1.1 InnoDB存储引擎
数据必须存储在 InnoDB
事务存储引擎中。事务以乐观方式执行,然后在提交时检查冲突。如果存在冲突,为了保持整个组的一致性,将回滚一些事务。这意味着需要事务存储引擎。此外, InnoDB
还提供了一些附加功能,可以在与Group Replication一起操作时更好地管理和处理冲突。使用其他存储引擎,包括临时存储引擎 MEMORY
存储引擎,可能会导致组复制错误。您可以通过disabled_storage_engines
在组成员上设置系统变量来阻止使用其他存储引擎 ,例如:
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
2.1.2 主键
要由组复制的每个表必须具有已定义的主键或等效的主键,其中等效项是非null唯一键。这些密钥作为表中每一行的唯一标识符是必需的,使系统能够通过准确识别每个事务已修改的行来确定哪些事务冲突。
2.1.3 外键
不建议使用级联外键,如果旧库本身有外键,业务上无法去除并且使用的是多主模式,那么,请配置 group_replication_enforce_update_everywhere_check ,强制检查每个组成员的级联检查,避免多主模式下执行级联操作造成的检测不到的冲突。
2.1.4 隔离级别
官网建议使用READ COMMITTED级别,除非应用程序依赖于REPLEATABLE READ,RC模式下没有GAP LOCK,比较好支持Innodb本身的冲突检测机制何组复制的内部分布式检测机制一起协同工作。不支持SERIALIZABLE隔离级别。
2.1.5 ID自增&步长
这里需要注意到,搭建group的时候,每个实例中的auto_increment_increment跟auto_increment_offset的配置情况。
- auto_increment_increment,在GROUP中范围在1-9(因为一个GROUP最多只能有9个组成员),GROUP中安装的时候,默认为7;
- auto_increment_offset,增长步长,GROUP安装过程,是等于@@server_id的,但是注意有个规则是,当 auto_increment_offset > auto_increment_increment的时候,则是忽略 auto_increment_offset的设置,第一个insert的从1开始,组内其他成员的初始值按照插入顺序 1+n*组员个数,若GROUP有3个成员,A,B,C,serverid分别为2243310,2243320,3423340,A先insert,C再insert,B最后insert,则初始值 A是1,B是9,C是6
2.1.6 IPv4 协议
MySQL Group Replication使用的组通信引擎仅支持IPv4。因此,组复制需要IPv4网络基础结构。
2.2 数据库实例
2.2.1 Binary Log Active
MySQL Group Replication复制二进制日志内容,因此二进制日志需要打开才能运行。默认情况下启用此选项。
--- 配置my.cnflog_bin = /app/mysql5.7/logs/ocean-bin
2.2.2 Slave Updates Logged
服务器需要记录通过复制应用程序应用的二进制日志。组中的服务器需要记录他们收到的所有事务并从组中应用。这是必需的,因为恢复是通过依赖组中的参与者的二进制日志来进行的。因此,每个事务的副本都需要存在于每个服务器上,即使对于那些未在服务器本身上启动的事务也是如此。
--- 配置my.cnflog_slave_updates = 1
2.2.3 Binary Log Row Format
组复制依赖于基于行的复制格式,以在组中的服务器之间一致地传播更改。它依赖于基于行的基础结构来提取必要的信息,以检测在组中的不同服务器中并发执行的事务之间的冲突。
--- 配置my.cnfbinlog_format = 'ROW'
2.2.4 Binary Log Checksums Off
由于复制事件校验和的设计限制,组复制无法使用它们,因此必须禁用它们。
--- 配置my.cnfbinlog_checksum = NONE
2.2.5 Global Transaction Identifiers On
组复制使用全局事务标识符来准确跟踪在每个服务器实例上已提交的事务,从而能够推断哪些服务器执行的事务可能与其他地方已提交的事务冲突。换句话说,显式事务标识符是框架的基本部分,以便能够确定哪些事务可能发生冲突。
--- 配置my.cnfgtid_mode = ON
2.2.6 Replication Information Repositories
复制应用程序需要将主信息和中继日志元数据写入 系统表mysql.slave_master_info
和 mysql.slave_relay_log_info
系统表。这可确保组复制插件具有一致的可复制性和复制元数据的事务管理。
--- 配置my.cnfmaster_info_repository=TABLE
relay_log_info_repository=TABLE
2.2.7 Transaction Write Set Extraction
收集行以将其记录到二进制日志时,服务器也会收集写入集。写集基于每行的主键,是标记的简化紧凑视图,唯一标识已更改的行。然后,此标记用于检测冲突。
--- 配置my.cnftransaction_write_set_extraction=XXHASH64
2.2.8 Multithreaded Appliers
组复制成员可以配置为多线程应用程序,从而可以并行应用事务。
--- 配置my.cnfslave_parallel_workers = 3
slave_preserve_commit_order = 1
slave_parallel_type = [ LOGICAL_CLOCK | DATABASE ]
配置 --slave-parallel-workers=N
启用成员上的多线程应用程序。组复制依赖于围绕保证所有参与成员以相同顺序接收和应用已提交事务的一致性机制,因此您还必须设置 --slave-preserve-commit-order=1
确保并行事务的最终提交与原始事务的顺序相同。最后,为了确定哪些事务可以并行执行,中继日志必须包含生成的事务父信息 --slave-parallel-type=LOGICAL_CLOCK
。尝试在--slave-parallel-workers
不设置其他两个选项的情况下添加set大于0 的成员会 生成错误,并且会阻止实例加入。
3 MySQL Group Replication 配置
3.1 基础环境
实例名 | 主机名 | IP地址 | 实例ID | 实例端口 | 通讯端口 | 软件版本 | my.cnf |
node1 | node1 | 10.11.12.1 | 1 | 3306 | 20001 | 5.7.24 | Y |
node2 | node2 | 10.11.12.2 | 2 | 3306 | 20002 | 5.7.24 | Y |
node3 | node3 | 10.11.12.3 | 3 | 3306 | 20003 | 5.7.24 | Y |
3.2 单主模式
组中的每个服务器实例都可以在独立的物理机器上运行,也可以在同一台机器上运行。本节介绍如何在一台物理计算机上创建具有三个MySQL Server实例的复制组。这意味着需要三个数据目录,每个服务器实例一个,并且您需要独立配置每个实例。
3.2.1 部署MySQL实例
单实例部署请参考《MySQL数据库安装实践 Part 1:单实例部署》。Group Replication是MySQL Server 5.7.17及更高版本提供的内置MySQL插件。
3.2.2 MySQL组复制配置(at all of nodes)
--- 配置my.cnf#InnoDB enginesdisabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"#Replication infrastructureserver_id = 1
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 = /app/mysql5.7/logs/ocean-bin
binlog_format = ROW#Group Replication parametertransaction_write_set_extraction = XXHASH64
loose-group_replication_group_name = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group_replication_start_on_boot = OFF
loose-group_replication_local_address = "10.11.12.1:20001"
loose-group_replication_group_seeds = "10.11.12.1:20001,10.11.12.2:20002,10.11.12.3:20003"
loose-group_replication_bootstrap_group = OFF
loose-binlog_gtid_simple_recovery = ON
loose-group_replication_enforce_update_everywhere_checks = OFF
关于MGR相关参数说明
- transaction_write_set_extraction --- 记录事务的算法
- group_replication_start_on_boot --- 是否随服务器启动而自动启动组复制
- group_replication_bootstrap_group --- 引导组成员的组,这个用于第一次搭建MGR跟重新搭建MGR的时候使用
- group_replication_group_name --- 此GROUP的名字,必须是一个有效的UUID,以此来区分整个内网里边的各个不的GROUP
- group_replication_local_address --- 本地的IP地址字符串,host:port
- group_replication_group_seeds --- 需要接受本实例的信息服务器IP地址字符串
- group_replication_single_primary_mode --- 是否启动单主模式,如果启动,则本实例是主库,提供读写,其他实例仅提供读
- group_replication_enforce_update_everywhere_checks --- 多主模式下,强制检查每一个实例是否允许该操作
3.2.3 创建数据同步账号(at all of nodes)
--- 禁止binlogSET SQL_LOG_BIN=0;--- 创建用户CREATE USER rep@'10.11.12.%' IDENTIFIED BY 'root1234';
GRANT REPLICATION SLAVE ON *.* TO rep@'10.11.12.%';
FLUSH PRIVILEGES;--- 开启binlogSET SQL_LOG_BIN=1;
3.2.4 安装Group Replication插件(at all of nodes)
--- 安装Group Replication插件INSTALL PLUGIN group_replication SONAME 'group_replication.so';--- 查看插件状态SHOW PLUGINS;
3.2.5 开启Group Replication(at the node1)
--- 查看当前的group replication相关参数show global variables like 'group%';--- 启动 group_replication_bootstrap_groupSET GLOBAL group_replication_bootstrap_group=ON;--- 配置MGRCHANGE MASTER TO MASTER_USER='rep', MASTER_PASSWORD='root1234' FOR CHANNEL 'group_replication_recovery';--- 启动MGRstart group_replication;--- 查看Error logtail -50f /app/mysql5.7/logs/node1.err--- 关闭 group_replication_bootstrap_groupSET GLOBAL group_replication_bootstrap_group=OFF;--- 查看数据文件ls -rtlh /app/mysql5.7/data | grep relay-- *_apaplier.* 系列文件 提供 SQL_Thread 使用,存储同个组内其他SERVER的binnary log,这个文件在第一个组成员加入组的时候,可以在Error Log看到其安装信息。
-- *_recovery.* 系列文件 是做什么使用的呢,在第一个成员启动MGR的时候,并没有看到其相关信息,稍后解疑!
3.2.6 添加node2
--- 查看当前的group replication相关参数show global variables like 'group%';--- 配置MGRCHANGE MASTER TO MASTER_USER='rep', MASTER_PASSWORD='root1234' FOR CHANNEL 'group_replication_recovery';--- 启动MGRstart group_replication;--- 查看Error logtail -50f /app/mysql5.7/logs/node2.err--- 查看组复制成员SELECT * FROM performance_schema.replication_group_members;--- 查看组复制成员SELECT * FROM performance_schema.replication_group_member_stats\G;
通过errrlog,可以详细看到启动过程的所有步骤信息,由于新增数据,导致node2需要使用到 group_replication_recovery 通道来恢复数据。
3.2.7 添加node3
--- 查看当前的group replication相关参数show global variables like 'group%';--- 配置MGRCHANGE MASTER TO MASTER_USER='rep', MASTER_PASSWORD='root1234' FOR CHANNEL 'group_replication_recovery';--- 启动MGRstart group_replication;--- 查看Error logtail -50f /app/mysql5.7/logs/node3.err--- 查看组复制成员SELECT * FROM performance_schema.replication_group_members;--- 查看组复制成员SELECT * FROM performance_schema.replication_group_member_stats\G;
通过errrlog,可以详细看到启动过程的所有步骤信息,由于新增数据,导致node3需要使用到 group_replication_recovery 通道来恢复数据,这跟node2是一模一样的过程,但是,由于前期node1造了大量的数据,所以在整个recovery的过程中,可以查看到 *_recovery.* 系列文件 的变化情况。
通过error log大小的变化,是通过group_replication_recovery 通道来恢复数据,需要恢复的binary log是存放在 *_recovery.* 系列文件 ,通过本次recovery 文件查看,发现,在recovery过程中,通道内的IO_THREAD拉去日志存储在 *_recovery.* 系列文件 中,当通道内的 SQL_Thread 完成日志应用后,则会删除掉 *_recovery.* 系列文件 文件,新建空文件,代表已经没有数据需要恢复。
至此,单主模式已搭建结束,node1可提供读写,但是node2和node3仅提供读服务。
通道说明
- group_replication_applier 通道 提供组内成员向 MASTER 实时同步binlog日志使用,这个通道内IO_thread拉取到的日志存放在 *_apaplier.* 系列文件中,再通过SQL_Thread应用到组内的各个SERVER上。
- group_replication_recovery 通道 提供 首次加入GROUP或者重新加入GROUP时恢复数据使用,这个通道内 IO_thread拉取到的日志存放在 *_recovery.* 系列文件中,再通过SQL_Thread应用到组内的各个SERVER上,应用结束后,删除所有 *_recovery.* 系列文件 ,重新建立新的 *_recovery.* 系列文件。
3.3 多主模式
3.3.1 多主模式参数配置
my.cnf的配置参数中,把 group_replication_single_primary_mode 参数设置成‘OFF’状态即可。
--- 动态修复方式set global group_replication_single_primary_mode=OFF;--- 配置文件修改方式loose-group_replication_single_primary_mode = OFF
注:单主模式运行时,动态修改此参数会报错
需先停止组复制, 操作流程:
- 业务端连接IP处理
- 组内成员依次主动退出
- 关闭 group_replication_single_primary_mode参数
- 依次启动组内的实例
3.3.2 组内成员依次退出
node1实例退组
--- node1实例退组stop group_replication;--- 查看node2、node3的errorlogtail -50f /app/mysql5.7/log/node2.errtail -50f /app/mysql5.7/log/node3.err
errorlog如下
node1停止gr
node2实例被选举为 new primary member
node3实例被选举为 secondary member
这个时候,node1可读写,但是不在group中,其binlog内容不会在组内同步;node3自动升级为主库,可读写,binlog会同步到node2上。这里的主库升级,是看MEMBER_ID的升序排序情况,最小的升级为主库。
node2上通过查看 replication_group_members、global_status,可以查看现在的组成员以及主库信息。
--- 查看组内成员信息SELECT * FROM performance_schema.replication_group_members;--- 查看global组信息SELECT * FROM performance_schema.global_status WHERE variable_name LIKE '%group%';
node2实例退组
--- node2实例退组stop group_replication;--- 查看node2的errorlogtail -50f /app/mysql5.7/logs/node3.err
node1,node2均可以读写,但是不在组中,业务目前在node1上运行,node3也可以读写,目前是主库。
node3实例退组
--- node3实例退组stop group_replication;
组内的所有成员都依次退出了GROUP。
3.3.3 配置group_replication_single_primary_mode参数(at all of nodes)
--- 动态修复方式set global group_replication_single_primary_mode=OFF;--- 配置文件修改方式loose-group_replication_single_primary_mode = OFF
3.3.4 依次启动组内的实例
首先启动实例A,然后启动实例B,紧接着启动实例C。实例A启动的时候,可以看到成了一个新的GROUP,B加入到时候,需要通过 group_replication_recovery 通道恢复数据,C加入到时候,也需要通过 group_replication_recovery 通道恢复数据,这部分的内容跟 3.2.5 配置Group 中的errorlog内容。
--- node1实例启动---- 需要启动 group_replication_bootstrap_group 引导组,启动后需要关闭,防止脑裂set global group_replication_bootstrap_group=ON;CHANGE MASTER TO MASTER_USER='rep', MASTER_PASSWORD='root1234' FOR CHANNEL 'group_replication_recovery';START GROUP_REPLICATION;set global group_replication_bootstrap_group=OFF;--- node2实例启动CHANGE MASTER TO MASTER_USER='rep', MASTER_PASSWORD='root1234' FOR CHANNEL 'group_replication_recovery';start group_replication;--- node3实例启动CHANGE MASTER TO MASTER_USER='rep', MASTER_PASSWORD='root1234' FOR CHANNEL 'group_replication_recovery';start group_replication;
3.3.5 监控GR状态
目前GROUP中的各个成员都关闭了super_read_only选项,提供了读写服务,由于三个都为主库,属于多主情况,所以 global_status中无法查看到主库信息,因为这个GROUP中,每个SERVER都是MASTER。
--- 查看组成员select * from performance_schema.replication_group_members;--- 查看组内master信息select * from performance_schema.global_status where variable_name like '%group%';--- 查看单主模式参数show global variables like 'group_replication_single_primary_mode';--- 查看只读show global variables like 'super%';
至此,多主模式已搭建结束,实例node1、node2、node3均可提供读写。
4 日常运维
4.1 运维用到的表
table_schema | table_name | type | description |
performance_schema | replication_group_members | 重要 常用 | 查看组成员 |
performance_schema | replication_group_member_stats | 重要 常用 | 当前实例在组中的同步情况, 查看applier通道的同步情况。 |
performance_schema | replication_connection_stats | 重要 常用 | 当前实例中各个通道的使用情况, applier通道是一定有显示, recovery通道看是否使用过, 如果有则显示,没有则不显示。 |
performance_schema | replication_applier_stats | 重要 常用 | 当前server中各个通道是否启用。 |
performance_schema | global_status | 重要 常用 | 单主模式下,查看当前主库信息。 |
performance_schema | replication_applier_configuration | 了解 不常用 | |
performance_schema | replication_applier_status_by_coordinator | 了解 不常用 | |
performance_schema | replication_applier_status_by_worker | 了解 不常用 | |
performance_schema | replication_connection_configuration | 了解 不常用 | |
mysql | slave_master_info | 重要 不常用 | 设置了master_info_repository=TABLE,所以master的相关信息会存储在这个表格。 如果使用GROUP中的SERVER备份数据库,恢复时,注意要清理这个表格。 |
mysql | slave_relay_log_info | 重要 不常用 | 设置了relay_log_info_repository=TABLE,所以master的相关信息会存储在这个表格。 如果使用GROUP中的SERVER备份数据库,恢复时,注意要清理这个表格。 |
4.2 运维用到的查询语句
--- 查询组成员信息SELECT * FROM performance_schema.replication_group_members;--- 单主模式,查询master。(UUID一致的即为master)SELECT * FROM performance_schema.replication_group_members;SELECT * FROM performance_schema.global_status;--- 实例是否读写show global variables like 'super%';SELECT * FROM performance_schema.replication_group_members;---- 如果super_read_only是启动的,那么该成员仅提供读服务;
---- 如果super_read_only是关闭的,并且 replication_group_members 中正常的成员n 满足 2n+1 > 整个GROUP成员个数,并且该成员的 member state是online,则该成员可提供读写服务。--- 检查组复制状态SELECT * FROM performance_schema.replication_group_members;SELECT * FROM performance_schema.replication_group_member_stats;SELECT * FROM performance_schema.replication_connection_stats;SELECT * FROM performance_schema.replication_applier_stats;tail -50f /app/mysql5.7/logs/node1.errtail -50f /app/mysql5.7/logs/node2.errtail -50f /app/mysql5.7/logs/node3.err
附件
单主模式my.cnf参数对比 | ||
node1 | node2 | node3 |
[mysqld]
disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
#Replication infrastructure
server_id = 1 log_bin_index = /app/mysql5.7/logs/node1-bin.index enforce_gtid_consistency = ON expire_logs_days = 7
#Group Replication parameter
transaction_write_set_extraction = XXHASH64 loose-group_replication_single_primary_mode = ON | [mysqld]
disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
#Replication infrastructure
server_id = 2 log_bin_index = /app/mysql5.7/logs/node2-bin.index enforce_gtid_consistency = ON expire_logs_days = 7
#Group Replication parameter
transaction_write_set_extraction = XXHASH64 | [mysqld]
disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
#Replication infrastructure
server_id = 3 log_bin_index = /app/mysql5.7/logs/node3-bin.index enforce_gtid_consistency = ON expire_logs_days = 7
#Group Replication parameter
transaction_write_set_extraction = XXHASH64 |
单主模式 & 多主模式,my.cnf参数对比 | |
单主模式 | 多主模式 |
[mysqld]
disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
#Replication infrastructure
server_id = 1 log_bin_index = /app/mysql5.7/logs/node1-bin.index enforce_gtid_consistency = ON expire_logs_days = 7
#Group Replication parameter
transaction_write_set_extraction = XXHASH64 loose-group_replication_single_primary_mode = ON | [mysqld]
disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
#Replication infrastructure
server_id = 1 log_bin_index = /app/mysql5.7/logs/node1-bin.index enforce_gtid_consistency = ON expire_logs_days = 7
#Group Replication parameter
transaction_write_set_extraction = XXHASH64 loose-group_replication_single_primary_mode = OFF |
参考
MySQL 5.7 Reference Manual - Chapter 17 Group Replication
相关链接
MySQL数据库复制技术 Part 1 : 复制技术介绍
MySQL数据库复制技术 Part 2 : 主从复制
MySQL数据库复制技术 Part 3 : 级联复制
MySQL数据库复制技术 Part 4 : 双主复制
MySQL数据库复制技术 Part 5 : 半同步复制
MySQL数据库复制技术 Part 6 : GTID复制
这篇关于MySQL数据库复制技术 Part 7 : 组复制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!