背景: 一个公司从初创到公司业务壮大,在数据库的使用都会面临类似的过程。
表迁移的主要场景有两种:
针对两种方案,有非常多的迁移手段,而迁移之前数据是否持续同步,或者迁移过程dump+load等类似方式,会决定了业务的影响时间。
相信大多数情况下,我们都需要业务影响时间尽量短,所以数据库之间的持续同步成为了首选,我们有一种手段:Master-Slave +Replication Filter
数据库如果是集群下,数据迁移就演变成了不同集群之间的数据迁移。但MySQL随着5.7的稳定以及8.0的到来,HA主流方案已经不止限于传统的额Master-Slave,PXC和MGR的使用方越来越多。
所以我们今天就主要来聊聊MGR +Replication Filter和PXC +Replication Filter的数据迁移方案。
--------------------------------华丽的分割线--------------------------
Cluster A 希望从node3节点,将T1表同步Cluster B集群的备节点上.因为考虑B集群有业务使用,因为不希望影响主要的写节点和读节点。并且MGR集群之间的节点是相互同步的,前提是通过修改调整参数group_replication_single_primary_mode=0来实现每个节点都可以提供对外的写能力。
而Replication Filter,需要通过设置Replicate_DB_Table='DB1.T1'来进行过滤。
这样就可以实现t1表从Cluster A到 Cluster B的准实时同步了。
但“坑”就在这里悄然无息的挖出来给你了 - Cluster B如果是MGR或者PXC,那么这个集群的节点之间会出现数据不一致。
数据库版本:PXC 5.7.25
Replicate_Do_Table: DB1.T1
现象:
从而发生了节点之间数据不一致的情况,此时,如果业务应用的写入口由于故障或者某种原因,切换到了PXC作为SLAVE的节点上,对不一致的数据进行了操作,从而会导致其余全部非SLAVE的PXC节点,由于数据错误,全部自动关闭数据库实例,进而只剩下一个充当SLAVE的节点,由于多数节点都关闭了,顾集群整体故障。
数据库版本:MySQL 5.7.25
Replicate_Do_Table: DB1.T1
现象:
从而发生了节点之间数据不一致的情况,此时,如果业务应用的写入口由于故障或者某种原因,切换到了MGR作为SLAVE的节点上,对不一致的数据进行了操作,从而会导致其余全部非SLAVE的MGR节点,由于数据错误,全部自动关闭了集群(并没有关闭实例),进而只剩下一个充当SLAVE的MGR节点,由于多数节点都退出了集群,顾集群整体故障。
如果在group_replication_single_primary_mode=1的情况下,5.7版本MGR的非Primary节点是无法设置Replication Filter的。
但是!!! MySQL 8.0解决了此问题!!!
数据库版本:MySQL 8.0.13
Replicate_Do_Table: DB1.T1
原因:
MySQL 8.0 在以上情况,数据一致了,这是为什么呢?首先我们需要先了解下MGR具备了两个Channel
既然是channel,那么就和MySQL的多源复制非常像了,而Replication_Filter作为全局的筛选规则,作用在了每个channel中,顾集群节点同步过来的消息,会被本地的group_replication_applier和group_replication_recovery两个channel的replicate_db_table过滤掉了。导致了数据不一致。但这个现象是5.7以及之前的版本。
而MySQL 8.0 提供了Global级别Replication Filter和 Channel级别的Replication Filter:
在8.0下,默认设置Replication Filter会进入Global级别,不影响每个Channel的Replication Filter。特别指定了Channel会进入Channel级别。
MGR的两个Channel无法设置Channel级别的Replication Filter。
所以,既然无法为MGR设置Replication Filter,数据自然在MGR节点之间的流动就正常了。
PXC虽然没有类似的channel,但内部应用binlog event 也基于了sql_thread的机制。
个人的建议:
MGR对于每个MySQL的使用者,都或多或少的听过,或多或少的用过了,未知的Bug绝对超乎你的想象。所以,MGR使用时,在你无法掌控未知Bug导致的各种异常下,使用一定要谨慎。数据一致性校验,数据延迟校验一定一定要有的。