Mysql Group Replication(MGR) 组复制

MySQL Group Replication正是基于这些技术和概念,实现了一种多主全更新的复制协议。

简而言之,一个Replication-group就是一组节点,每个节点都可以独立执行事务,而读写事务则会在于group内的其他节点进行协调之后再commit。因此,当一个事务准备提交时,会自动在group内进行原子性的广播,告知其他节点变更了什么内容/执行了什么事务。这种原子广播的方式,使得这个事务在每一个节点上都保持着同样顺序。这意味着每一个节点都以同样的顺序,接收到了同样的事务日志,所以每一个节点以同样的顺序重演了这些事务日志,最终整个group保持了完全一致的状态。

组复制可以在两种模式下运行。

1.在单主模式下,组复制具有自动选主功能,每次只有一个 server成员接受更新。

2.在多主模式下,所有的 server 成员都可以同时接受更新。

MGR的限制

仅支持InnoDB表,并且每张表一定要有一个主键;

必须打开GTID特性,二进制日志格式必须设置为ROW;

二进制日志不支持binlog event checksum

目前一个MGR集群最多支持9个节点

事务写集合(Transaction write set extraction)必须打开。(这个目前与savepoint冲突,这也是导致mysqldump无法备份GR实例的原因

SERIALIZABLE 隔离级别不支持

并行执行DDL可能导致数据一致性等方面的错误,目前不支持在多节点同时执行同一对象的DDL

外键的级联约束操作目前的实现并不完全支持

三 主从复制限制

  1.存储引擎必须为innodb

  2.每个表必须提供主键

  3.只支持ipv4,网络需求较高

  4.一个group最多只能有9台服务器

  5.不支持Replication event checksums,

  6.不支持Savepoints

  7.multi-primary mode部署方式不支持SERIALIZABLE事务隔离级别

  8.multi-primary mode部署方式不能完全支持级联外键约束

  9.multi-primary mode部署方式不支持在不同节点上对同一个数据库对象并发执行DDL

尽管数据库服务可用,但当有一个 server 崩溃时,连接到它的客户端必须定向或故障转移到不同的 server。这不是组复制要解决的问题。连接器,负载均衡器,路由器或其他形式的中间件更适合处理这个问题。

准备阶段:

此操作是多主模式

1、开放33061端口

#  --permanent永久生效,没有此参数重启后失效

firewall-cmd --zone=public --add-port=33061/tcp --permanent

重新载入防火墙

firewall-cmd --reload

firewalld常用命令

# 启动         systemctl start firewalld

# 关闭          systemctl stop firewalld

# 查看状态  systemctl status firewalld

# 开机禁用  systemctl disable firewalld

# 开机启用  systemctl enable firewalld

# 查看所有打开的端口        firewall-cmd --zone=public --list-ports

2、三台服务器设置免密

ssh-keygen -t rsa

ssh-copy-id mgr1

ssh-copy-id mgr2

ssh-copy-id mgr3

3、三台服务器设置hosts

特别要注意一个关键点: 必须保证各个mysql节点的主机名不一致,并且能通过主机名找到各成员!

则必须要在每个节点的/etc/hosts里面做主机名绑定,否则后续将节点加入group组会失败!报错RECOVERING!

vim /etc/hosts

192.168.59.138 mgr1

192.168.59.140 mgr2

192.168.59.139 mgr3

4、关闭selinux

临时关闭:输入命令setenforce 0,重启系统后还会开启。

永久关闭:输入命令vi /etc/selinux/config,将SELINUX=enforcing改为SELINUX=disabled

一、修改配置参数(三台都修改)

mgr1

[mysqld]

user=mysql

basedir=/usr/local/mysql

datadir=/data/mysql

socket=/tmp/mysql.sock

log-error=/data/mysql/mysql.err

pid-file=/data/mysql/mysql.pid

character-set-server=utf8

innodb_rollback_on_timeout = ON

collation-server=utf8_general_ci

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

lower_case_table_names=1

max_connections=10000

sync_binlog=1

binlog_format=row

########basic settings########

server-id =138

character_set_server=utf8

max_allowed_packet = 16M

lower_case_table_names=1

slow_query_log=1

slow_query_log_file=/data/mysql/slow.log

########replication settings########

#####replication 复制配置###############

log-bin = /data/mysql/mysql-bin

max_binlog_size=500M

binlog_format = row

sync_binlog=1

expire_logs_days=15

###group replication###########

gtid_mode=on

enforce_gtid_consistency= ON

master_info_repository = TABLE

relay_log_info_repository = TABLE

binlog_checksum = NONE

log_slave_updates = ON

#log_slave_updates是将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中。

transaction_write_set_extraction = XXHASH64

##server必须为每个事物收集写集合,使用XXHASH64哈希算法将其编码为散列

loose-group_replication_group_name ='51837954-2d8a-11ed-bc2d-000c29f511b3'

#组的名字可以随便起,但不能用主机的GTID

loose-group_replication_start_on_boot = off  # #插件在server启动时不自动启动组复制

loose-group_replication_bootstrap_group = off #同上

loose-group_replication_ip_whitelist="192.168.59.138,192.168.59.140,192.168.59.139"

report_host=192.168.59.138

report_port=3306

loose-group_replication_local_address = '192.168.59.138:33061'

loose-group_replication_group_seeds ='192.168.59.138:33061,192.168.59.140:33061,192.168.59.139:33061'

loose-group_replication_single_primary_mode = FALSE #关闭单主模式的参数

loose-group_replication_enforce_update_everywhere_checks = TRUE #开启多主模式的参数

########innodb settings########

innodb_flush_log_at_trx_commit = 1 #改为1 是为了更安全, 值为2是性能

innodb_buffer_pool_size=128M

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

secure_file_priv="/tmp"

[mysql]

socket=/tmp/mysql.sock

default-character-set=utf8

[client]

mgr2

[mysqld]

user=mysql

basedir=/usr/local/mysql

datadir=/data/mysql

socket=/tmp/mysql.sock

log-error=/data/mysql/mysql.err

pid-file=/data/mysql/mysql.pid

character-set-server=utf8

innodb_rollback_on_timeout = ON

collation-server=utf8_general_ci

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

lower_case_table_names=1

max_connections=10000

binlog_format=row

########basic settings########

server-id =140

character_set_server=utf8

max_allowed_packet = 16M

lower_case_table_names=1

slow_query_log=1

slow_query_log_file=/data/mysql/slow.log

########replication settings########

#####replication 复制配置###############

log-bin = /data/mysql/mysql-bin

max_binlog_size=500M

binlog_format = row

sync_binlog=1

expire_logs_days=15

###group replication###########

gtid_mode=on

enforce_gtid_consistency= ON

master_info_repository = TABLE

relay_log_info_repository = TABLE

binlog_checksum = NONE

log_slave_updates = ON

#log_slave_updates是将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中。

transaction_write_set_extraction = XXHASH64

##server必须为每个事物收集写集合,使用XXHASH64哈希算法将其编码为散列

loose-group_replication_group_name ='51837954-2d8a-11ed-bc2d-000c29f511b3'

#组的名字可以随便起,但不能用主机的GTID

loose-group_replication_start_on_boot = off  # #插件在server启动时不自动启动组复制

loose-group_replication_bootstrap_group = off #同上

loose-group_replication_ip_whitelist="192.168.59.138,192.168.59.140,192.168.59.139"

report_host=192.168.59.140

report_port=3306

loose-group_replication_local_address = '192.168.59.140:33061'

loose-group_replication_group_seeds ='192.168.59.140:33061,192.168.59.138:33061,192.168.59.139:33061'

loose-group_replication_single_primary_mode = FALSE #关闭单主模式的参数

loose-group_replication_enforce_update_everywhere_checks = TRUE #开启多主模式的参数

########innodb settings########

innodb_flush_log_at_trx_commit = 1 #改为1 是为了更安全, 值为2是性能

innodb_buffer_pool_size=128M

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

secure_file_priv="/tmp"

[mysql]

socket=/tmp/mysql.sock

default-character-set=utf8

[client]

mgr3

[mysqld]

user=mysql

basedir=/usr/local/mysql

datadir=/data/mysql

socket=/tmp/mysql.sock

log-error=/data/mysql/mysql.err

pid-file=/data/mysql/mysql.pid

character-set-server=utf8

innodb_rollback_on_timeout = ON

collation-server=utf8_general_ci

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

lower_case_table_names=1

max_connections=10000

sync_binlog=1

binlog_format=row

########basic settings########

server-id =139

character_set_server=utf8

max_allowed_packet = 16M

lower_case_table_names=1

slow_query_log=1

slow_query_log_file=/data/mysql/slow.log

########replication settings########

#####replication 复制配置###############

log-bin = /data/mysql/mysql-bin

max_binlog_size=500M

binlog_format = row

sync_binlog=1

expire_logs_days=15

###group replication###########

gtid_mode=on

enforce_gtid_consistency= ON

master_info_repository = TABLE

relay_log_info_repository = TABLE

binlog_checksum = NONE

log_slave_updates = ON

#log_slave_updates是将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中。

transaction_write_set_extraction = XXHASH64

##server必须为每个事物收集写集合,使用XXHASH64哈希算法将其编码为散列

loose-group_replication_group_name ='51837954-2d8a-11ed-bc2d-000c29f511b3'

#组的名字可以随便起,但不能用主机的GTID

loose-group_replication_start_on_boot = off  # #插件在server启动时不自动启动组复制

loose-group_replication_bootstrap_group = off #同上

loose-group_replication_ip_whitelist="192.168.59.138,192.168.59.140,192.168.59.139"

report_host=192.168.59.139

report_port=3306

loose-group_replication_local_address = '192.168.59.139:33061'

loose-group_replication_group_seeds ='192.168.59.138:33061,192.168.59.140:33061,192.168.59.139:33061'

loose-group_replication_single_primary_mode = FALSE #关闭单主模式的参数

loose-group_replication_enforce_update_everywhere_checks = TRUE #开启多主模式的参数

########innodb settings########

innodb_flush_log_at_trx_commit = 1 #改为1 是为了更安全, 值为2是性能

innodb_buffer_pool_size=128M

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

secure_file_priv="/tmp"

[mysql]

socket=/tmp/mysql.sock

default-character-set=utf8

[client]

二、在node0和node1和node2 创建复制账号

set sql_log_bin=0;

create user rpl_user@'%';

grant replication slave on *.* to rpl_user@'%' identified by 'rpl_pass';

flush privileges;

set sql_log_bin=1;

修改账号密码,也要set sql_log_bin=0

/usr/local/mysql/bin/mysql -uroot  -p123@abc

change master to master_user='rpl_user',master_password='rpl_pass' for channel 'group_replication_recovery';

组内每台主机,都需要先安装组复制插件.否则会导致启动失败.

mysql>INSTALL PLUGIN group_replication SONAME 'group_replication.so';

克隆的机器需要修改uuid,因为复制的机器uuid相同

配置完,重启mysql服务

node0节点上执行 启动组复制

set  global group_replication_bootstrap_group=ON;

set global group_replication_ip_whitelist="192.168.59.0/24";

START GROUP_REPLICATION;   

SELECT * FROM performance_schema.replication_group_members;

SET GLOBAL group_replication_bootstrap_group=OFF;

node1

set global group_replication_allow_local_disjoint_gtids_join=ON;

set global group_replication_ip_whitelist="192.168.59.0/24";

START GROUP_REPLICATION;                                               

SELECT * FROM performance_schema.replication_group_members;

node2

set global group_replication_allow_local_disjoint_gtids_join=ON;

set global group_replication_ip_whitelist="192.168.59.0/24";

START GROUP_REPLICATION;                                               

SELECT * FROM performance_schema.replication_group_members;

select * from performance_schema.replication_group_members; 

查看集群状态,都为ONLINE就表示OK:

测试:

node0上创建测试库

create database mgr1;

use mgr1;

create table mgr1.t1(id int primary key, cn varchar(30));

insert into t1 values(1,'a');

node1上查看

use mgr1;

select * from t1;

node1上插入  insert into t1 values(2,'Tom');

node2上查看

node2上插入  insert into t1 values(3,'li');

模拟节点宕机

node1上,service mysql stop

node2上,继续插入数据

启动node1节点

service mysql start

mysql>

set global group_replication_allow_local_disjoint_gtids_join = on;

START GROUP_REPLICATION;

再次查看组成员,发现已重新加入组

mysql> SELECT * FROM performance_schema.replication_group_members;

注意:前面的用户密码修改和创建用户操作必须设置binlog不记录,执行后再打开,否则会引起START GROUP_REPLICATION执行报错:

报错信息如下:

ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error log

根据提示打开group_replication_allow_local_disjoint_gtids_join选项,mysql命令行执行:

mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;

再次启动组复制

mysql> START GROUP_REPLICATION;

2、连不上master,报错信息如下:

2017-04-17T16:18:14.756191+08:00 25 [Warning] Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.

2017-04-17T16:18:14.814193+08:00 25 [ERROR] Slave I/O for channel 'group_replication_recovery': error connecting to master'repl_user@host-192-168-99-156:3306' - retry-time: 60  retries: 1, Error_code: 2005

2017-04-17T16:18:14.814219+08:00 25 [Note] Slave I/O thread for channel 'group_replication_recovery' killed while connecting to master

2017-04-17T16:18:14.814227+08:00 25 [Note] Slave I/O thread exiting for channel 'group_replication_recovery', read up to log 'FIRST', position 4

2017-04-17T16:18:14.814342+08:00 19 [ERROR] Plugin group_replication reported: 'There was an error when connecting to the donor server. Check group replication recovery's connection credentials.'

解决方案:

添加映射

vim /etc/hosts

重启下组复制

mysql> stop group_replication;

Query OK, 0 rows affected (8.76 sec)

mysql> start group_replication;

Query OK, 0 rows affected (2.51 sec)

日常维护步骤:

1、如果从库某一节点关闭

    stop group_replication;

2、如果所有的库都关闭后,第一个库作为主库首先执行

    set global group_replication_bootstrap_group=ON;

    start group_replication;

剩下的库直接执行即可!

    set global group_replication_allow_local_disjoint_gtids_join=ON;

    start group_replication;

3、如果主库故障,会自动从两个从库选出一个主库,主库启动后再次执行如下命令后会变成从库

    start group_replication;

至此MGR搭建并验证完成

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容