1.介绍
MGR(MySQL Group Replication)是一个MySQL Server插件,可用于创建弹性,高可用MySQL集群方案。有一个内置的组成员服务,在任何给定的时间点,保持组的视图一致并可供所有服务器使用。服务器可以离开并加入组,视图也会相应更新。当成员离开组,故障检测机制会检测到此情况并通知组视图已更改
2.前期规划
mysql5.7.28安装请看这里 传送门
3.环境准备
关掉所有防火墙
1 2 3 4 |
# 关闭防火墙 systemctl stop firewalld # 临时关闭selinux setenforce 0 |
配置主机名,按照先前规划,填写/etc/hosts文件(每台主机都要配置)
1 2 3 4 |
#(这个名字你随意,你本机主机名是什么就配置什么,你也可以修改你的主机名) 192.168.6.121 test1 192.168.6.122 test2 192.168.6.123 test3 |
在MGR_NODE1节点上生成一个UUID,作为MGR组名
1 |
mysql -uroot -p -e "SELECT UUID()" |
1 |
UUID:1128dcb5-27b0-11ea-b0b4-0050568b6568 |
再次修改数据库配置文件/etc/my.cnf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
symbolic-links=0 #如果你原先有配置这行那么久不用,如果没有就加上 server_id=121 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=/data/mysql/log/binlog binlog_format=row transaction_write_set_extraction=XXHASH64 loose-group_replication_group_name="1128dcb5-27b0-11ea-b0b4-0050568b6568" loose-group_replication_start_on_boot=off loose-group_replication_local_address= "192.168.6.121:13306" loose-group_replication_group_seeds= "192.168.6.121:13306,192.168.6.122:13306,192.168.6.123.13306" loose-group_replication_bootstrap_group=off loose-group_replication_single_primary_mode=off #单主模式这里请开启为ON loose-group_replication_enforce_update_everywhere_checks=on #多主模式这里请开启为on,启用严格数据同步检查 loose-group_replication_member_weight=100 #当主成员在发生故障转移时被选为主要成员的可能性的权重weight百分比,和server_uuid 配合进行选举,这个值越大,主宕机后通过和这个值选举余下机器中权重最高的作为下一个主 report_host=192.168.6.121 report_port=3306 |
我的node1(192.168.6.121)完整配置文件(当前配置文件为多主配置,单主请自行修改上面2个参数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
[client] port = 3306 socket = /tmp/mysql.sock [mysqld] port = 3306 socket = /tmp/mysql.sock user = mysql basedir = /usr/local/mysql datadir = /data/mysql/data pid-file = /data/mysql/mysql.pid symbolic-links=0 server_id=1123 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=mysql-bin binlog_format=ROW transaction_write_set_extraction=XXHASH64 loose-group_replication_group_name="c399ac69-27d0-11ea-9bdc-0050568b6568" loose-group_replication_start_on_boot=off loose-group_replication_local_address= "192.168.6.123:24903" loose-group_replication_group_seeds= "192.168.6.121:24901,192.168.6.122:24902,192.168.6.123:24903" loose-group_replication_bootstrap_group=off loose-group_replication_single_primary_mode=off loose-group_replication_enforce_update_everywhere_checks=on loose-group_replication_member_weight=100 report_host=192.168.6.121 report_port=3306 #auto_increment_increment=3 #auto_increment_offset=1 log_error = /data/mysql/mysql-error.log slow_query_log = 1 long_query_time = 1 slow_query_log_file = /data/mysql/mysql-slow.log skip-external-locking key_buffer_size = 32M max_allowed_packet = 1024M table_open_cache = 128 sort_buffer_size = 768K net_buffer_length = 8K read_buffer_size = 768K read_rnd_buffer_size = 512K myisam_sort_buffer_size = 8M thread_cache_size = 16 query_cache_size = 16M tmp_table_size = 32M performance_schema_max_table_instances = 1000 explicit_defaults_for_timestamp = true #skip-networking max_connections = 500 max_connect_errors = 100 open_fil1s_limit = 65525 binlog_format=mixed expire_logs_days = 10 early-plugin-load = "" default_storage_engine = InnoDB innodb_file_per_table = 1 innodb_buffer_pool_size = 128M innodb_log_file_size = 32M innodb_log_buffer_size = 8M innodb_flush_log_at_trx_commit = 1 innodb_lock_wait_timeout = 50 [mysqldump] quick max_allowed_packet = 16M [mysql] no-auto-rehash [myisamchk] key_buffer_size = 32M sort_buffer_size = 768K read_buffer = 2M write_buffer = 2M |
以上标准版文件需要更改的点有:
server_id:不能与其他MySQL实例重复
loose-group_replication_group_name:通过SELECT UUID()生成一个UUID作为组名
loose-group_replication_local_address:当前节点用于内部通讯的ip:port
loose-group_replication_group_seeds:组内成员通讯的ip:port
参数讲解:
1 2 3 4 5 6 7 |
user:启动进程的user port:数据库使用的端口 datadir:数据库的数据目录位置 log-error:数据库的错误日志位置 pid-file:数据库的pid文件位置 socket:数据库的sock文件位置 symbolic-links:禁用符号链接以防止出现各种安全风险 |
MGR要求的相关参数
1 2 3 4 5 6 7 8 9 |
server_id:不同实例必须保证此server_id不同,如果启用了二进制日志记录,则必须指定该选项,否则不允许服务器启动 gtid_mode:使用全局事务标识符(GTID)来标识事务。将此选项设置为–gtid-mode=ON 要求 enforce-gtid-consistency设置为ON enforce_gtid_consistency:ON:不允许任何事务违反GTID一致性 OFF:允许事务违反GTID一致性。WARN:允许所有事务违反GTID一致性,但在这种情况下会生成警告 master_info_repository:设置从站将主状态和连接信息记录到 FILE(master.info)还是TABLE (mysql.slave_master_info)中 relay_log_info_repository:设置从站在中继日志中的位置是写入FILE (relay-log.info)还是 写入TABLE (mysql.slave_relay_log_info)中 binlog_checksum:启用后,此变量会使主服务器为二进制日志中的每个事件写入校验和,当binlog_checksum禁用(值 NONE)时,服务器通过编写和检查每个事件的事件长度(而不是校验和)来验证它是否只将完整事件写入二进制日志 log_slave_updates:设置从主服务器接受的更新是否写入二进制日志中 log_bin:设置二进制日志的位置 binlog_format:二进制日志格式,有行模式,语句模式,混合模式,使用MGR必须使用行模式 |
组复制相关参数
1 2 3 4 5 6 7 8 9 |
transaction_write_set_extraction:定义用于生成标识与事务关联的写入的哈希的算法,哈希值将用于分布式冲突检测和处理 loose-group_replication_group_name:通知插件它正在加入或创建的组,需要使用SELECT UUID()生成一个UUID loose-group_replication_start_on_boot:重启服务后自动是否自动加入组,默认off loose-group_replication_local_address:告诉插件使用哪个ip:port与组中的其他成员进行内部通信。这里的ip与端口不能与MySQL默认的ip:port 相同,如果使用相同ip则port必须不相同 loose-group_replication_group_seeds:设置组成员的主机名和端口 loose-group_replication_bootstrap_group:插件是否引导组,此选项只能在任何时候在一个服务器实例上使用,通常是第一次引导组时(或者在整个组关闭并重新备份的情况下)。如果多次引导组,例如当多个服务器实例设置了此选项时,则可以创建一个人工分裂脑情景,其中存在两个具有相同名称的不同组。 loose-group_replication_single_primary_mode:单主模式设置为ON,多主模式设置为OFF loose-group_replication_enforce_update_everywhere_checks:在所有节点启用多主数据更新的严格一致性检查 |
配置以上后重启数据库
启动首个MGR节点,启动后登入数据库
1 |
mysql -uroot -p |
以下命令是在(121)数据库中执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 创建MGR内部消息互通的用户 SET SQL_LOG_BIN=0; #创建用户,要注意不能记录到binlog文件中 CREATE USER rpl_user@'192.168.6.121' IDENTIFIED BY '123456'; CREATE USER rpl_user@'192.168.6.122' IDENTIFIED BY '123456'; CREATE USER rpl_user@'192.168.6.123' IDENTIFIED BY '123456'; GRANT REPLICATION SLAVE ON *.* TO 'rpl_user'@'192.168.6.121' IDENTIFIED BY '123456'; GRANT REPLICATION SLAVE ON *.* TO 'rpl_user'@'192.168.6.122' IDENTIFIED BY '123456'; GRANT REPLICATION SLAVE ON *.* TO 'rpl_user'@'192.168.6.123' IDENTIFIED BY '123456'; FLUSH PRIVILEGES; SET SQL_LOG_BIN=1; # 安装MGR插件 INSTALL PLUGIN group_replication SONAME 'group_replication.so'; # 检查是否成功安装 SHOW PLUGINS; #如果配置文件里的binlog_format不生效,那么这里你要全局设置下,否则启动不了,目前我也不知道为啥配置文件里的不生效,很蛋疼,你也可以通过show variables like 'binlog_format';这条命令查看你的配置是不是ROW(这里可以算个大坑了) SET SESSION binlog_format = 'ROW'; SET GLOBAL binlog_format = 'ROW'; SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF; ##注意这里启动后一定要关闭,之所以要先开启group_replication_bootstrap_group,然后关闭group_replication_bootstrap_group,是因为start group_replication前需要重新引导组复制,引导并开启组复制之后,将group_replication_bootstrap_group关闭是为了避免实例重启后又重新引导了一个组复制,导致复制异常。 |
查看是否成功
1 |
SELECT * FROM performance_schema.replication_group_members; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#完整查看所有信息(包括他的主节点信息) SELECT MEMBER_ID, MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, IF(global_status.VARIABLE_NAME IS NOT NULL, 'PRIMARY', 'SECONDARY') AS MEMBER_ROLE FROM performance_schema.replication_group_members LEFT JOIN performance_schema.global_status ON global_status.VARIABLE_NAME = 'group_replication_primary_member' AND global_status.VARIABLE_VALUE = replication_group_members.MEMBER_ID; |
!—关于重启组这里有个坑
1 |
set global group_replication_bootstrap_group=on; #primary(或者说第一台节点)重新启动要先开下这个东西,因为我们默认这个参数是关闭的 所以你启动不了group |
然后将primary机器的my.cnf文件分别复制一份到另外两台机器,注意配置文件里一些目录未创建的就创建一下
1 2 3 4 |
#其他2台机器配置点修改如下只修改以下2点即可 server_id 修改为前期部署规划的值 loose-group_replication_local_address 修改为该节点用于内部通讯的ip地址 |
其他2台机器(122和123)执行如下(多主模式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
SET SQL_LOG_BIN=0; CREATE USER rpl_user@'%' IDENTIFIED BY '123456'; GRANT REPLICATION SLAVE ON *.* TO 'rpl_user'@'%' IDENTIFIED BY '123456'; FLUSH PRIVILEGES; SET SQL_LOG_BIN=1; 安装插件 INSTALL PLUGIN group_replication SONAME 'group_replication.so'; #设置使用复制组用户,加入组复制 CHANGE MASTER TO MASTER_USER='rpl_user',MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery'; #ip加入白名单,这个看自己需求(可加可不加,因为我有防火墙所以我要加) set global group_replication_ip_whitelist="192.168.6.121,192.168.6.122,192.168.6.123"; set global group_replication_allow_local_disjoint_gtids_join=ON;#除了第一个节点,其他节点都需要执行这个命令,意思大概是组复制允许本地不相交 SET SESSION binlog_format = 'ROW'; SET GLOBAL binlog_format = 'ROW'; START GROUP_REPLICATION; |
查看是否成功
1 2 3 |
SELECT * FROM performance_schema.replication_group_members\G #MEMBER_STATE显示为ONLINE表示成功 |
多主模式切换为单主模式
MGR切换模式需要重新启动组复制,因些需要在所有节点上先关闭组复制,设置 group_replication_single_primary_mode=OFF 等参数,再启动组复制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#停止组复制(所有节点都执行) stop group_replication; set global group_replication_enforce_update_everywhere_checks=OFF; set global group_replication_single_primary_mode=ON; #随便选一台为主节点,执行 SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF; # 从节点(主机2、主机3)执行 START GROUP_REPLICATION; #查看组信息 SELECT MEMBER_ID, MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, IF(global_status.VARIABLE_NAME IS NOT NULL, 'PRIMARY', 'SECONDARY') AS MEMBER_ROLE FROM performance_schema.replication_group_members LEFT JOIN performance_schema.global_status ON global_status.VARIABLE_NAME = 'group_replication_primary_member' AND global_status.VARIABLE_VALUE = replication_group_members.MEMBER_ID; |
单主模式切换为多主模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# 停止组复制(所有节点执行): stop group_replication; set global group_replication_single_primary_mode=OFF; set global group_replication_enforce_update_everywhere_checks=ON; # 随便选择某个节点执行 SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF; # 其他节点执行 START GROUP_REPLICATION; # 查看组信息,所有节点的 MEMBER_ROLE 都为 PRIMARY SELECT MEMBER_ID, MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, IF(global_status.VARIABLE_NAME IS NOT NULL, 'PRIMARY', 'SECONDARY') AS MEMBER_ROLE FROM performance_schema.replication_group_members LEFT JOIN performance_schema.global_status ON global_status.VARIABLE_NAME = 'group_replication_primary_member' AND global_status.VARIABLE_VALUE = replication_group_members.MEMBER_ID; |
等待测试
错误:
1 |
如果遇到此种加入组超时的错误,请查看一下,你的所有机器UUID是否一致,或者你重新生成一组新的UUID,然后所有机器都配置下这个uuid再按顺序启动,一定要按顺序。 |
关于清除binlog日志文件初始化:
1 2 |
功能说明:删除所有的binglog日志文件,并将日志索引文件清空,重新开始所有新的日志文件。用于第一次进行搭建主从库时,进行主库binlog初始化工作; 测试如下: |
1 2 3 4 |
清除代码 reset master; show master status\G |
1 |
显示所有的binlog已经被删除掉,且binlog从000001 开始记录 |
测试(多主模式)
在某个节点的数据库内执行(我当前是在122执行的)
1 2 3 4 |
CREATE DATABASE shooter; USE shooter; CREATE TABLE book (c1 INT PRIMARY KEY, c2 TEXT NOT NULL); INSERT INTO book VALUES (1, 'Luis'); |
在其他节点执行查询代码 查看是否有刚才的新建的数据
1 |
SELECT * FROM book; |
查看121节点
查看123节点
到此MGR多主模式集群成功
测试(单主模式) (单主模式只有primary可写,其他节点只读)
1.主节点插入数据查看另外2个节点是否同步
1 2 3 |
use shooter; select * from book; insert into book(c1,c2) value (8,'family'); |
2.查看另外两台机器
续言:MGR监控
组成员信息查看
1 |
SELECT * FROM performance_schema.replication_group_members; |
组成员状态信息
1 |
select * from performance_schema.replication_group_member_stats\G |
显示有关组复制的信息,例:已经从组接收并在应用程序队列中排队的事务(中继日志)
1 |
SELECT * FROM performance_schema.replication_connection_status\G |
显示与组复制相关的通道和线程的状态如果有许多不同的工作线程应用事务,那么工作表也可用于监视每个工作线程正在执行的操作
1 |
SELECT * FROM performance_schema.replication_applier_status; |
存放从库relay log 信息
1 |
select * from mysql.slave_relay_log_info\G |
显示存放master相关信息
1 |
select * from mysql.slave_master_info\G |
组复制要求与限制
- 必须是InnoDB存储引擎。数据必须存储在 InnoDB事务存储引擎中。事务以乐观方式执行,然后在提交时检查冲突。如果存在冲突,为了保持整个组的一致性,将回滚一些事务。这意味着需要事务存储引擎。此外, InnoDB还提供了一些附加功能,可以在与Group Replication一起操作时更好地管理和处理冲突
- 主键。必须使用拥有主键或者等效主键,也就是唯一且非空键
- IPv4网络。 MySQL Group Replication使用的组通信引擎仅支持IPv4。
- 网络性能。 MySQL Group Replication旨在部署在服务器实例彼此非常接近的集群环境中。网络延迟和网络带宽都会影响组的性能和稳定性。所有小组成员之间必须始终保持双向通信。如果阻止服务器实例的入站或出站通信(例如,通过防火墙或连接问题),则该成员无法在该组中运行,并且组成员(包括有问题的成员)可能无法报告受影响的服务器实例的正确成员状态
1 2 |
修改表引擎方法 alter table table_name engine=innodb; |
一些限制
- 启动二进制日志。 设置 –log-bin[=log_file_name]。MySQL Group Replication会复制二进制日志内容,因此二进制日志需要打开才能运行。
- 二进制日志行格式。 设置–binlog-format=row,查看行格式的二进制日志可以用mysqlbinlog –base64-output=’DECODE-ROWS’ /data/log/binlog.000002或者在数据库内执行
- 从主库获取的日志提交之后记录到本地binlog日志中,设置–log-slave-updates
- 启用GTID,设置–gtid-mode=ON
- 设置–master-info-repository=TABLE 和 –relay-log-info-repository=TABLE。复制应用程序需要将master信息和中继日志元数据写入系统表mysql.slave_master_info和 mysql.slave_relay_log_info系统表。这可确保组复制插件具有一致的可复制性和复制元数据的事务管理
- 设置 –transaction-write-set-extraction=XXHASH64此标记用于检测冲突。
多线程并行执行事务,相关参数如下
单双主优缺点,参考大佬讲解
1 |
https://www.cnblogs.com/gaogao67/p/10931313.html |
- 本文固定链接: https://www.yoyoask.com/?p=1146
- 转载请注明: shooter 于 SHOOTER 发表