1.內網服務器有倆套主從複製環境,一套是基於傳統複製的5.6.26版本,另一套是基於GTID的5.7.19版本的複製。如今開發的需求是須要將基於傳統複製的上面的倆個表同步到基於基於GTID複製上面去,而且要求同步的倆個表中有一個表的一列的值必須是源的10倍。node
root@mysqldb 15:51: [remix_test]> show create table sbtest1 \G *************************** 1. row *************************** Table: sbtest1 Create Table: CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL, `k` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
表結構如上所示,在原來的基礎上column k必須乘以10,即new_k = old_k*10mysql
1.如何將倆個表的數據同步過來。在這裏咱們採用了使用主從同步的方案,可是主從同步的方案又帶來了如下幾個問題:sql
2.如何將同步過來的數據作修改。在這裏咱們採起的方案是使用觸發器,可是觸發器自己會消耗資源;由於觸發器是基於row行的,因此假如咱們一次性修改500條數據花費1s中,觸發器觸發修改會觸發500次,加入每行數據修改花費1s,那麼觸發器就會花費500s。shell
Last_SQL_Error: Error 'Can't update table 'sbtest1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.' on query. Default database: 'remix_test'. Query: 'insert into sbtest1(id,k) values(39039,1),(39040,10)'
1.數據同步:服務器
mysql> set global gtid_mode='ON_PERMISSIVE';
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Cannot replicate anonymous transaction when AUTO_POSITION = 1, at file /home/mysql/data_3307/mysql-bin.000005, position 234.; the first event '' at 4, the last event read from '/home/mysql/data_3307/mysql-bin.000005' at 299, the last byte read from '/home/mysql/data_3307/mysql-bin.000005' at 299.'
mysql> Change replication filter REPLICATE_DO_DB=(remix_test),REPLICATE_DO_TABLE = (remix_test.sbtest1,remix_test.sbtest2);
mysql> delimiter || ; mysql> create trigger tr1 after insert on sbtest1 -> for each row -> begin -> update sbtest1 set k=new.k*10 where id=new.id; -> end|| mysql> delimiter ;
shell> mysqldump --set-gtid-purged=OFF --single-transaction --dump-slave=2 -uroot -p -t remix_test sbtest1 > sbtest1_20180402.sql shell> mysqldump --set-gtid-purged=OFF --single-transaction --dump-slave=2 -uroot -p -t remix_test sbtest2 > sbtest2_20180402.sql
shell> mysql -S /var/lib/mysql/mysql_3306.sock -uroot -p remix_test< sbtest1_20180402.sql shell> mysql -S /var/lib/mysql/mysql_3306.sock -uroot -p remix_test<sbtest2_20180402.sql
mysql> grant replication slave on 'slave'@'ip_address' identified by 'new_password'; mysql> flush privileges;
mysql> set global gtid_mode='ON_PERMISSIVE';
mysql> change master ......
mysql> change replication filter replicate_do_db=(remix_test),replicate_do_table=(remix_test.sbtest1,remix_test.sbtest2);
mysql> create table sbtest1_bak like sbtest1; mysql> insert into sbtest1_bak select id,k*10 from sbtest1;
9.基於GTID複製的MASTER上面建立觸發器ide
root@mysqldb 15:39: [remix_test]> delimiter || root@mysqldb 15:41: [remix_test]> create trigger tr2 after update on sbtest1 -> for each row -> begin -> update sbtest1_bak set k=new.k*10 where id=new.id; -> end|| root@mysqldb 15:48: [remix_test]> delimiter || root@mysqldb 15:48: [remix_test]> create trigger tr3 after delete on sbtest1 -> for each row -> begin -> delete from sbtest1_bak where id=old.id; -> end|| Query OK, 0 rows affected (0.11 sec) root@mysqldb 15:49: [remix_test]> delimiter ; root@mysqldb 15:06: [remix_test]> create trigger tr1 after insert on sbtest1 -> for each row -> begin -> insert into sbtest1_bak(id,k) select id,k*10 from sbtest1 where id=new.id; -> end|| Query OK, 0 rows affected (0.11 sec) root@mysqldb 15:08: [remix_test]> delimiter ;
MySQL5.7已經開始支持多源複製了,主要語法是:測試
mysql> change master to ........ for channel 'channel_name';
可是咱們線上在開啓多源複製的時候還須要針對單個channel作過濾,這時候咱們發現MySQL5.7的版本並不支持針對單個channel作過濾,須要升級到MySQL8.0以上,過濾規則是對全部的channel都會起做用。this
在偶然的一次有作複製過濾的MySQL實例作了重啓,在啓動的slave的時候忽然發現報錯,show slave status的時候看到以前replication filter的規則所有丟失了。因此須要注意一下。日誌