目录
关于GreatSQL及MGR的FAQ,持续更新中。
GreatSQL是由万里数据库维护的MySQL分支,开源、免费。GreatSQL基于Percona Server,在其基础上进一步提升MGR(MySQL Group Replication)的性能及可靠性。此外,GreatSQL合并了华为鲲鹏计算团队贡献的Patch,实现了InnoDB并行查询特性,以及对InnoDB事务锁的优化。
GreatSQL可以作为MySQL或Percona Server的可选替代方案,用于线上生产环境。
GreatSQL完全免费并兼容MySQL或Percona Server。
相对于MySQL官方社区版,GreatSQL有以下几个优势:
InnoDB性能更好
MGR更可靠、稳定,性能也更好。
无论是更可靠的MGR还是性能更好的InnoDB,都值得将当前的MySQL或Percona Server升级到GreatSQL。
关于GreatSQL的优势可阅读下面几篇文章:
二进制包下载地址:https://gitee.com/GreatSQL/GreatSQL/releases。
目前提供CentOS 7、CentOS 8两种操作系统,以及X86和ARM两种不同架构下的二进制包、RPM包。
带 minimal 关键字的安装包是对二进制文件进行strip后,所以文件尺寸较小,功能上没本质区别,仅是不支持gdb debug功能,可以放心使用。
可以直接用git clone的方式下载GreatSQL源码,例如:
# 可从gitee下载
$ git clone https://gitee.com/GreatSQL/GreatSQL.git
# 或从github下载
$ git clone https://github.com/GreatSQL/GreatSQL.git
GreatSQL提供Ansible一键安装包,可在gitee或github下载:
GreatSQL提供Docker镜像,可直接从docker hub拉取:
# 直接下载最新版本
$ docker pull docker.io/greatsql/greatsql
# 或自行指定版本
$ docker pull docker.io/greatsql/greatsql:8.0.25
# 或指定ARM版本
$ docker pull docker.io/greatsql/greatsql:8.0.25-aarch64
使用GreatSQL过程中如果遇到问题,可将问题细节整理清楚后,联系GreatSQL社区寻求帮助。
微信搜索添加 wanlidbc
添加GreatSQL社区助手
或申请加入GreatSQL社区QQ群(533341697
)
此外,我们已经在B站发布MGR相关系列视频,可以前往学习,视频链接:https://space.bilibili.com/1363850082 。
GreatSQL不计划每个小版本都跟随,暂定奇数版本跟随方式,即 8.0.25、8.0.27、8.0.29 … 以此类推。
未来若有版本计划变更我们再更新。
可以利用MySQL Router来实现读写分离。
是可以的,最好采用相同版本号的MySQL Shell即可。
下面是关于MGR使用的一些限制:
upgrade=AUTO
。gap lock
,因此建议把所有节点的事务隔离级别都改成 READ COMMITTED
。基于相同的原因,MGR集群中也不要使用 table lock
及 name lock
(即 GET_LOCK()
函数 )。multi-primary
)模式下不支持串行(SERIALIZABLE
)隔离级别。multi-primary
)模式下不支持多层级联外键表。另外,为了避免因为使用外键造成MGR报错,建议设置 group_replication_enforce_update_everywhere_checks=ON
。multi-primary
)模式下,如果多个节点都执行 SELECT ... FOR UPDATE
后提交事务会造成死锁。看起来限制有点多,但绝大多数时候并不影响正常的业务使用。
此外,想要启用MGR还有几个要求:
log_slave_updates=1
。binlog_format=ROW
。server_id
及 server_uuid
不能相同。binlog_checksum=NONE
,但是从8.0.20后,可以设置 binlog_checksum=CRC32
。gtid_mode=ON
。master_info_repository=TABLE
及 relay_log_info_repository=TABLE
,不过从MySQL 8.0.23开始,这两个选项已经默认设置TABLE,因此无需再单独设置。lower_case_table_names
设置要求一致。slave_parallel_type = LOGICAL_CLOCK
slave_parallel_workers = N
,N>0,可以设置为逻辑CPU数的2倍binlog_transaction_dependency_tracking = WRITESET
slave_preserve_commit_order = 1
slave_checkpoint_period = 2
MGR最多可支持9个节点,无论是单主还是多主模式。
设置参数 group_replication_bootstrap_group=ON
即可。但是当MGR第一个节点初始化启动时,或者整个MGR集群都关闭再重启时,第一个节点都必须先采用引导模式 group_replication_bootstrap_group=ON
。
支持的。可以在MGR集群的前端挂载MySQL Router,即可实现读负载均衡。
不支持。由于MGR采用shared nothing模式,每个节点都存储全量数据,因此所有写入每个节点都要再应用一次。
一定程度上来说,是的。因为MGR需要在多个节点间进行事务冲突检测,不过这方面的开销有限,总体来说也还好。
当启用MGR服务后,MySQL会监听33061端口,该端口用于MGR节点间的通信。因此当服务器间有防火墙策略时,记得针对该端口开放。
当然了,可自行定义该端口,例如 group_replication_local_address=192.168.0.1:33062
。
这个不是必须的。
之所以要在每个节点上都加上各节点的hostname对照表,是因为在MGR节点间通信过程中,可能收到的主机名和本地实际配置的不一致。
这种情况下,也可以在每个节点上自行设置 report_host
及 report_port
来解决这个问题。
可以的,但非常不推荐。
此外,由于MGR默认的allowlist不包含公网地址,因此需要将公网地址加进去,例如:
group_replication_ip_allowlist='192.0.2.0/24, 114.114.114.0/24'
顺便提醒下,MGR默认的allowlist范围(group_replication_ip_allowlist=AUTOMATIC
)是以下几个
IPv4 (as defined in RFC 1918)
10/8 prefix (10.0.0.0 - 10.255.255.255) - Class A
172.16/12 prefix (172.16.0.0 - 172.31.255.255) - Class B
192.168/16 prefix (192.168.0.0 - 192.168.255.255) - Class C
IPv6 (as defined in RFC 4193 and RFC 5156)
fc00:/7 prefix - unique-local addresses
fe80::/10 prefix - link-local unicast addresses
127.0.0.1 - localhost for IPv4
::1 - localhost for IPv6
有时候docker容器的IP地址不在上述范围中,也会导致MGR服务无法启动。
执行下面的命令:
[root@GreatSQL]> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+-----------...-+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID ... | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+-----------...-+-------------+--------------+-------------+----------------+
| group_replication_applier | 4ebd3504-1... | 3306 | ONLINE | SECONDARY | 8.0.25 |
| group_replication_applier | 549b92bf-1... | 3307 | ONLINE | SECONDARY | 8.0.25 |
| group_replication_applier | 5596116c-1... | 3308 | ONLINE | SECONDARY | 8.0.25 |
| group_replication_applier | ed5fe7ba-3... | 3309 | ONLINE | PRIMARY | 8.0.25 |
+---------------------------+-----------...-+-------------+--------------+-------------+----------------+
如果只看到一个节点的 MEMBER_ROLE
值为 PRIMARY,则表示这是单主模式。如果看到所有节点上该状态值均为 PRIMARY,则表示这是多主模式。
另外,也可以通过查询MySQL选项值来确认:
[root@GreatSQL]# mysqladmin var|grep -i group_replication_single_primary_mode
| group_replication_single_primary_mode | ON
值为 ON,这表示采用单主模式。如果该值为 OFF,则表示采用多主模式。
在MySQL Shell中也可以查看状态来确认:
MySQL GreatSQL:3306 ssl JS > var c=dba.getCluster()
MySQL GreatSQL:3306 ssl JS > c.describe() /* 或者 c.status() */
...
"topologyMode": "Single-Primary"
...
P.S,强烈建议采用单主模式,遇到bug或其他问题的概率更低,运行MGR更稳定可靠。
在MySQL客户端命令行模式下,执行下面的命令即可:
-- 从单主切换为多主
[root@GreatSQL]> SELECT group_replication_switch_to_multi_primary_mode();
+--------------------------------------------------+
| group_replication_switch_to_multi_primary_mode() |
+--------------------------------------------------+
| Mode switched to multi-primary successfully. |
+--------------------------------------------------+
-- 从多主切换为单主
[root@GreatSQL]> SELECT group_replication_switch_to_single_primary_mode();
+---------------------------------------------------+
| group_replication_switch_to_single_primary_mode() |
+---------------------------------------------------+
| Mode switched to single-primary successfully. |
+---------------------------------------------------+
注意: 切换时会重新选主,新的主节点有可能不是切换之前的那个,这时可以运行下面的命令来重新指定:
[root@GreatSQL]> SELECT group_replication_set_as_primary('ed5fe7ba-37c2-11ec-8e12-70b5e873a570');
+--------------------------------------------------------------------------+
| group_replication_set_as_primary('ed5fe7ba-37c2-11ec-8e12-70b5e873a570') |
+--------------------------------------------------------------------------+
| Primary server switched to: ed5fe7ba-37c2-11ec-8e12-70b5e873a570 |
+--------------------------------------------------------------------------+
也可以通过MySQL Shell来操作:
MySQL GreatSQL:3306 ssl JS > var c=dba.getCluster()
> c.switchToMultiPrimaryMode() /*切换为多主模式*/
Switching cluster 'MGR27' to Multi-Primary mode...
Instance 'GreatSQL:3306' was switched from SECONDARY to PRIMARY.
Instance 'GreatSQL:3307' was switched from SECONDARY to PRIMARY.
Instance 'GreatSQL:3308' was switched from SECONDARY to PRIMARY.
Instance 'GreatSQL:3309' remains PRIMARY.
The cluster successfully switched to Multi-Primary mode.
> c.switchToSinglePrimaryMode() /*切换为单主模式*/
Switching cluster 'MGR27' to Single-Primary mode...
Instance 'GreatSQL:3306' remains PRIMARY.
Instance 'GreatSQL:3307' was switched from PRIMARY to SECONDARY.
Instance 'GreatSQL:3308' was switched from PRIMARY to SECONDARY.
Instance 'GreatSQL:3309' was switched from PRIMARY to SECONDARY.
WARNING: The cluster internal session is not the primary member anymore. For cluster management operations please obtain a fresh cluster handle using dba.getCluster().
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.
> c.setPrimaryInstance('GreatSQL:3309'); /*重新设置主节点*/
Setting instance 'GreatSQL:3309' as the primary instance of cluster 'MGR27'...
Instance 'GreatSQL:3306' was switched from PRIMARY to SECONDARY.
Instance 'GreatSQL:3307' remains SECONDARY.
Instance 'GreatSQL:3308' remains SECONDARY.
Instance 'GreatSQL:3309' was switched from SECONDARY to PRIMARY.
The instance 'GreatSQL:3309' was successfully elected as primary.
P.S,强烈建议采用单主模式,遇到bug或其他问题的概率更低,运行MGR更稳定可靠。
首先,可以执行下面的命令查看当前除了 PRIMARY 节点外,其他节点的 trx_tobe_certified
或 relaylog_tobe_applied
值是否较大:
[root@GreatSQL]> SELECT MEMBER_ID AS id, COUNT_TRANSACTIONS_IN_QUEUE AS trx_tobe_certified, COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE AS relaylog_tobe_applied, COUNT_TRANSACTIONS_CHECKED AS trx_chkd, COUNT_TRANSACTIONS_REMOTE_APPLIED AS trx_done, COUNT_TRANSACTIONS_LOCAL_PROPOSED AS proposed FROM performance_schema.replication_group_member_stats;
+--------------------------------------+-------------------+---------------------+----------+----------+----------+
| id |trx_tobe_certified |relaylog_tobe_applied| trx_chkd | trx_done | proposed |
+--------------------------------------+-------------------+---------------------+----------+----------+----------+
| 4ebd3504-11d9-11ec-8f92-70b5e873a570 | 0 | 0 | 422248 | 6 | 422248 |
| 549b92bf-11d9-11ec-88e1-70b5e873a570 | 0 | 238391 | 422079 | 183692 | 0 |
| 5596116c-11d9-11ec-8624-70b5e873a570 | 2936 | 238519 | 422115 | 183598 | 0 |
| ed5fe7ba-37c2-11ec-8e12-70b5e873a570 | 2976 | 238123 | 422167 | 184044 | 0 |
+--------------------------------------+-------------------+---------------------+----------+----------+----------+
其中,relaylog_tobe_applied
的值表示远程事务写到relay log后,等待回放的事务队列,trx_tobe_certified
表示等待被认证的事务队列大小,这二者任何一个值大于0,都表示当前有一定程度的延迟。
另外,也可以查看接收到的事务和已执行完的事务之间的差距来判断:
[root@GreatSQL]> SELECT RECEIVED_TRANSACTION_SET FROM performance_schema.replication_connection_status WHERE channel_name = 'group_replication_applier' UNION ALL SELECT variable_value FROM performance_schema.global_variables WHERE variable_name = 'gtid_executed'\G
*************************** 1. row ***************************
RECEIVED_TRANSACTION_SET: 6cfb873b-573f-11ec-814a-d08e7908bcb1:1-3124520
*************************** 2. row ***************************
RECEIVED_TRANSACTION_SET: 6cfb873b-573f-11ec-814a-d08e7908bcb1:1-3078139
可以看到,接收到的事务 GTID 已经到了 3124520,而本地只执行到 3078139,二者的差距是 46381。可以顺便持续关注这个差值的变化情况,估算出本地节点是否能追平延迟,还是会加大延迟。
是的,支持。
在MySQL Router初始化部署时,添加 --name
、--directory
及端口号等参数即可,例如:
-- 部署第一个实例
root@GreatSQL# mysqlrouter --bootstrap mymgr@192.168.1.1:3306 --name=MGR1 --directory=/etc/mysqlrouter/MGR1 --user=mysqlrouter --conf-base-port=6446 --https-port=8443
-- 部署第二个实例
root@GreatSQL# mysqlrouter --bootstrap mymgr@192.168.1.1:4306 --name=MGR2 --directory=/etc/mysqlrouter/MGR2 --user=mysqlrouter --conf-base-port=7446 --https-port=9443
然后每个实例用各自目录下的 start.sh
和 stop.sh
脚本启停即可。
关于MySQL Router多实例部署的方法,可以参考这篇参考文档:《叶问》38期,MGR整个集群挂掉后,如何才能自动选主,不用手动干预。
首先,答案是肯定的,可以的。
其次,为了保障MGR的数据安全性,对不同角色节点的要求是这样的:
group_replication_start_on_boot=ON
和 skip_slave_start=ON
予以保证在这两个MGR集群间的主从复制可以采用异步复制,也可以采用半同步复制,主要取决于两个集群间的网络延迟情况及架构设计方案。这时候,整体架构方案类似下面这样:
在这个架构下,两个MGR集群间是相互独立的,如果前端挂载MySQL Router的话,需要单独创建对应的连接。
如果担心MGR节点因为发生切换,只要原来指向的Master没有退出MGR集群,则这个主从复制关系还是存在的,不受影响。如果担心原来的Master节点退出MGR集群而导致复制中断,则可以采用MySQL 8.0.22后推出的新特性 Async Replication Auto failover 来解决,把各节点都加到复制源中,可以参考下面的资料:
要看具体是哪种情况。
如果两个节点是正常关闭的话,则会向MGR集群发送退出信号,这种情况下,这两个节点属于正常退出,最后仅剩的节点会被提升为Primary角色,还可以正常工作,允许对其进行读写,只是此时没有可用性冗余了。当其他节点再次启动并加入集群后,又能恢复正常服务。
如果是因为网络故障,或者mysqld进程发生oom、或被误杀、或其他原因退出了,则这些节点会被标识为 UNREACHABLE 状态,等待直到 group_replication_member_expel_timeout
时长(单位:秒)后这个节点才会正式退出集群。在这种情况下,一旦超过多数派节点处于 UNREACHABLE 状态时,则整个集群不可用,无法提供读写服务。这种情况下,需要把剩下的节点重启MGR服务才能恢复。
正常情况下,不要把 group_replication_member_expel_timeout
值调整太大,并且MGR的事务一致性级别尽量不要选择 AFTER 模式,以防出现整个集群服务不可用的问题,详细参见这篇文章:为什么MGR一致性模式不推荐AFTER。
MGR在初始化启动时,是可以只启动两个节点,甚至只有一个节点,但是这样就失去MGR的意义了。因为只要少于三个节点,就没办法进行多数派投票,当发生网络故障等情况时,无法投票确认哪些节点该被踢出集群。
是可以的,并且会复制到所有MGR节点,但是仅能创建空表,业务上不能写入数据。
往无主键的InnoDB表中写入数据时,会报告类似下面的错误:
[root@GreatSQL] [test]> insert into t3 select 1;
ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin.
同理,也可以创建MyISAM表,但写入时会提示失败。
此外,当欲加入MGR集群的新实例中有无主键的InnoDB表时,如果要通过 MySQL Shell 添加该节点,会发出类似下面的报错,无法加入:
Validating instance configuration at mgr03:3306...
This instance reports its own address as mgr03:3306
ERROR: The following tables do not have a Primary Key or equivalent column:
test.t3
Group Replication requires tables to use InnoDB and have a PRIMARY KEY or PRIMARY KEY Equivalent (non-null unique key). Tables that do not follow these requirements will be readable but not updateable when used with Group Replication. If your applications make updates (INSERT, UPDATE or DELETE) to these tables, ensure they use the InnoDB storage engine and have a PRIMARY KEY or PRIMARY KEY Equivalent.
If you can't change the tables structure to include an extra visible key to be used as PRIMARY KEY, you can make use of the INVISIBLE COLUMN feature available since 8.0.23: https://dev.mysql.com/doc/refman/8.0/en/invisible-columns.html
ERROR: Instance must be configured and validated with dba.checkInstanceConfiguration() and dba.configureInstance() before it can be used in an InnoDB cluster.
Cluster.addInstance: Instance check failed (RuntimeError)
这个报错在MySQL 8.0.25依然存在,据说在MySQL 8.0.27得到解决。
如果改成手动加入新节点,或者直接删除无主键表,则可以成功。
从上面的错误提示也能看出来,如果创建一个和主键等价的唯一索引(且要求不允许为NULL),该唯一索引可用做InnoDB表的聚集索引,就不会再报错了,业务也能正常写入数据。
MySQL Router通过两个端口来区分读写服务请求,默认是 6446端口提供读写服务,6447端口提供只读服务。
在单主模式下,读写服务只会连接到Primary节点。对于读写服务端口,可选的策略有以下两种:
只读服务默认是对所有Secondary节点轮询。对于只读服务端口,可选的策略有以下X种:
现在我们知道了,MySQL Router只有在所有Secondary节点都不可用时,才会去连接Primary节点读数据,无法做到在发起只读请求时,同时连接主从节点。
更多关于 MySQL Router 可用的策略请参见文档 routing_strategy参数/选项。
简单整理了下,大概有以下原因可能导致MGR服务无法启动:
group_replication_bootstrap_group=ON
)。group_replication_group_name
值要一致才可以。group_replication_group_name
,常见于新手。要为MGR服务专门新开一个服务端口,常用33061端口,但新手可能会照样写成3306端口。report-host
,主动上报hostname即可解决。答案是肯定的。
不过由于MySQL 5.7里没有MGR管理的几个UDF,因此在MySQL Shell里调用 setPrimaryInstance()
、switchToMultiPrimaryMode()
等函数时会报错,是不支持的。
所以说,还是尽量升级到MySQL 8.0吧。
可以利用GreatSQL安装包中提供的mysqldump工具执行逻辑备份。
也可以利用相同版本号的Percona Xtrabackup执行物理备份,例如利用Percona XtraBackup 8.0.25-17备份GreatSQL 8.0.25-15、GreatSQL 8.0.25-16版本,利用Percona XtraBackup 2.4备份GreatSQL 5.7.36-39版本。
Enjoy GreatSQL
面向金融级应用的GreatSQL正式开源
https://mp.weixin.qq.com/s/cI_wPKQJuXItVWpOx_yNTg
Changes in GreatSQL 8.0.25 (2021-8-18)
https://mp.weixin.qq.com/s/qcn0lmsMoLtaGO9hbpnhVg
MGR及GreatSQL资源汇总
https://mp.weixin.qq.com/s/qXMct_pOVN5FGoLsXSD0MA
GreatSQL MGR FAQ
https://mp.weixin.qq.com/s/J6wkUpGXw3YkyEUJXiZ9xA
在Linux下源码编译安装GreatSQL/MySQL
https://mp.weixin.qq.com/s/WZZOWKqSaGSy-mpD2GdNcA
GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。
Gitee:
https://gitee.com/GreatSQL/GreatSQL
GitHub:
https://github.com/GreatSQL/GreatSQL
Bilibili:
https://space.bilibili.com/1363850082/video
微信&QQ群:
可搜索添加GreatSQL社区助手微信好友,发送验证信息“加群”加入GreatSQL/MGR交流微信群
QQ群:533341697
微信小助手:wanlidbc
本文由博客一文多发平台 OpenWrite 发布!
手机扫一扫
移动阅读更方便
你可能感兴趣的文章