在上一篇文章《深入理解MySQL多源复制(一)》中,介绍了MySQL多源复制的相关内容,本文将继续讲解MySQL多源复制,主要内容是过滤复制以及在已有复制过滤配置中新增复制对象;
首先,来看一下MySQL 复制中复制过滤器CHANGE REPLICATION FILTER 的语法,从语法上看, 5.7 和 8.0版本基本一样,但是细心的读者可能会发现,其实在语法上一个非常不同的差异,8.0的语法支持[FOR CHANNEL channel]通道语法,而5.7版本其实是不支持的;详细的语法如下所示:
5.7版本:
CHANGE REPLICATION FILTER filter[, filter][, ...] filter: { REPLICATE_DO_DB = (db_list) | REPLICATE_IGNORE_DB = (db_list) | REPLICATE_DO_TABLE = (tbl_list) | REPLICATE_IGNORE_TABLE = (tbl_list) | REPLICATE_WILD_DO_TABLE = (wild_tbl_list) | REPLICATE_WILD_IGNORE_TABLE = (wild_tbl_list) | REPLICATE_REWRITE_DB = (db_pair_list) } db_list: db_name[, db_name][, ...] tbl_list: db_name.table_name[, db_table_name][, ...] wild_tbl_list: 'db_pattern.table_pattern'[, 'db_pattern.table_pattern'][, ...] db_pair_list: (db_pair)[, (db_pair)][, ...] db_pair: from_db, to_db
8.0版本:
CHANGE REPLICATION FILTER filter[, filter] [, ...] [FOR CHANNEL channel] filter: { REPLICATE_DO_DB = (db_list) | REPLICATE_IGNORE_DB = (db_list) | REPLICATE_DO_TABLE = (tbl_list) | REPLICATE_IGNORE_TABLE = (tbl_list) | REPLICATE_WILD_DO_TABLE = (wild_tbl_list) | REPLICATE_WILD_IGNORE_TABLE = (wild_tbl_list) | REPLICATE_REWRITE_DB = (db_pair_list) } db_list: db_name[, db_name][, ...] tbl_list: db_name.table_name[, db_name.table_name][, ...] wild_tbl_list: 'db_pattern.table_pattern'[, 'db_pattern.table_pattern'][, ...] db_pair_list: (db_pair)[, (db_pair)][, ...] db_pair: from_db, to_db
下面来看一下具体的实现
##指定数据库db1,db2
CHANGE REPLICATION FILTER REPLICATE_DO_DB=(db1, db2)
##指定表db1.t7 ,忽略表db2.t7
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = (‘db1.t7’), REPLICATE_WILD_IGNORE_TABLE = (‘db2.t7’);
##忽略表t1,t2开头的表
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = (‘db2.t1%’,’db2.t2%’);
##下面的语句重写发生在主数据库db1上的语句到从数据库db2上
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((db1, db2));
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((dbA, dbB), (dbC, dbD));
###清空
CHANGE REPLICATION FILTER REPLICATE_DO_DB=();
CHANGE REPLICATION FILTER REPLICATE_DO_TABLE=();
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE=();
CHANGE REPLICATION FILTER Replicate_Ignore_DB=();
CHANGE REPLICATION FILTER Replicate_Wild_Ignore_Table=();
5.7和8.0的区别就在于,8.0支持FOR CHANNEL channel语法,而5.7不支持,下面的语法在8.0的实例上可以成功执行,而在5.7的实例上支持,会包语法的错误;
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('wjqtest.src_bill','wjqtest.src_bug_list','wjqtest.src_group') for channel 'wjqtest_10.30.124.186_4306';
那么,你可能会问“FOR CHANNEL channel”和5.7有什么区别呢?区别就在于,在多源复制的情况,可以为单独的复制通道配置复制过滤,而在8.0之前的版本是无法做到的
如果是在5.7环境中执行下面的语法
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('wjqtest.src_bill','wjqtest.src_bug_list','wjqtest.src_group');
会将所有的复制通道全部都设置成上述的过滤器配置,如果是多个数据源的话,就需要在把多个源需要过滤的库表进行进行配置;这样是不是就不如8.0支持FOR CHANNEL channel更方便一些了呢;
上面说完了多源复制中的复制过滤的相关内容,那么在实际的生产中有如下的需求:
如果是对其中一个或多个实例进行过滤复制,并且运行一段时间后,想在这个源上再增加一个或多个库或表复制,该怎么实现呢?可以思考一下
.
.
.
.
.
实际需求:
主1:10.30.124.186 4306 db1 db2
主2:10.30.124.186 4307 db3
从: 10.30.124.187 4306
假如之前实现的是过滤复制,复制的是主1的db1 和 主2的db3,已经运行一段时间了。现在想增加主1上的db2,该如何实现?
具体实现方法如下:
1. 使用mysqldump 导出 db2(记录pos1),并导入多源从库。
2. 停止多源从库的sql线程(STOP SLAVE SQL_THREAD ),并记录此刻同步到主1的位置pos2。
3. 使用mysqlbinlog 将pos1 到 pos2 的变更应用到从库。(mysqlbinlog –start-position=pos1 –stop-position=pos2 -d db2 mysqlbin.001769 | mysql -u -p -h -P )
4. 在线修改多源从库的过滤条件(CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = (‘db1.%’,’db2.%’,’db3.%’);)
5.启动sql_thread线程,检查主从复制状态
相关文章
参考链接:
https://dev.mysql.com/doc/refman/8.0/en/change-replication-filter.html