八.双主复制模型架构构建
1.双主复制模型架构简介
主-主复制(也叫双主复制或双向复制)包含两台服务器,每一个都配配置为对方的主库和备库,换句话说,它们是一对主库。
架构如图:
2.双主模型架构的配置过程:
(1).各自使用不同的server-id;
(2).都启用二进制日志和中继日志;
(3).定义自动增长的id字段的增长方式
(4).都授权有复制权限的用户帐号;
(5).各自把对方指定为主服务器;
3.考虑一个问题:
如果A服务器上自动增长的列编号有一个35,此时还没有同步到B服务器上,在B服务器上插入一条数据,编号也是35。当同步A的35到B服务器上来的话,必然产生数据丢失。
解决方法:
我们只要保证两台服务器上插入的自增长数据不同就可以了
如:A插入奇数ID,B插入偶数ID,当然如果服务器多的话,你可以定义算法,只要不同就可以了。
4.双主复制的数据库主配置文件配置
node3节点的配置:
1 2 3 4 5 6 7 8 9 10 11 |
[root@node3 ~]# vim /etc/my.cnf [mysqld] #在此配置段中增加如下内容; log-bin=mysql-bin binlog_format=mixed server-id = 1 relay-log=relay-bin #第一个变量名 auto_increment_offset 指自增字段的起始值。 auto_increment_offset=1 #第二个变量名 auto_increment_increment 就是指字段一次递增多少; auto_increment_increment=2 log_slave_updates = 1 |
node4节点的配置:
1 2 3 4 5 6 7 8 9 10 11 |
[root@node4 ~]# vim /etc/my.cnf [mysqld] log-bin=mysql-bin binlog_format=mixed server-id = 10 relay-log = relay-bin log_slave_updates = 1 #第一个变量名 auto_increment_offset 指自增字段的起始值。 auto_increment_offset=2 #第二个变量名 auto_increment_increment 就是指字段一次递增多少; auto_increment_increment=2 |
其它配置不变,由于我先前实验做了基于SSL的安全复制,我们需要将ssl配置段删除;
略。
配置完成后重启mysqld服务即可;
5.设置复制帐号;
两个节点都需要设置帐号,为了方便我们就全部设置一致:
1 2 |
MariaDB [(none)]> grant replication slave,replication client on *.* to repluser@'172.16.%.%' identified by 'replpass'; MariaDB [(none)]> flush privileges; |
上述命令两个节点都执行一遍;
6.查看两个节点的时间点;
node3节点的时间点;
1 2 3 4 5 6 7 |
MariaDB [(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000009 | 653 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) |
node4节点的时间点:
1 2 3 4 5 6 7 |
MariaDB [(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000009 | 653 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) |
两个节点的时间点都是一致的;那就方便设置了;
7.双主复制模型开启设置
node3节点启动:
1 2 3 4 5 6 |
#开启复制; MariaDB [(none)]> change master to master_host='172.16.31.21',master_user='repluser',master_password='replpass',master_log_file='mysql-bin.000009',master_log_pos=653; Query OK, 0 rows affected (0.08 sec) #开启复制进程; MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec) |
node4节点启动:
1 2 3 4 |
MariaDB [(none)]> change master to master_host='172.16.31.20',master_user='repluser',master_password='replpass',master_log_file='mysql-bin.000009',master_log_pos=653; Query OK, 0 rows affected (0.02 sec) MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec) |
8.查看节点的复制状态信息;
node3的节点的主从复制状态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
MariaDB [(none)]> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.31.21 Master_User: repluser Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000009 Read_Master_Log_Pos: 653 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 535 Relay_Master_Log_File: mysql-bin.000009 Slave_IO_Running: Yes Slave_SQL_Running: Yes 信息略; Seconds_Behind_Master: 0 1 row in set (0.00 sec) |
node4节点的主从复制状态信息;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
MariaDB [(none)]> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.31.20 Master_User: repluser Master_Port: 3306 Connect_Retry: 5 Master_Log_File: mysql-bin.000009 Read_Master_Log_Pos: 653 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 535 Relay_Master_Log_File: mysql-bin.000009 Slave_IO_Running: Yes Slave_SQL_Running: Yes 信息略; Seconds_Behind_Master: 0 1 row in set (0.00 sec) |
9.双主复制架构测试:
在node3节点插入2行数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#创建数据库mydb; MariaDB [(none)]> create database mydb; Query OK, 1 row affected (0.00 sec) #切换到数据库mydb; MariaDB [(none)]> use mydb; Database changed #创建表tb1; MariaDB [mydb]> create table tb1 (id int unsigned not null auto_increment primary key, name char(30)); Query OK, 0 rows affected (0.08 sec) #插入数据tom; MariaDB [mydb]> insert into tb1 (name) values ('tom'); Query OK, 1 row affected (0.01 sec) #插入数据jerry; MariaDB [mydb]> insert into tb1 (name) values ('jerry'); Query OK, 1 row affected (0.01 sec) #查看ID,可发现node3增长是按奇数增长的; MariaDB [mydb]> select * from tb1; +----+-------+ | id | name | +----+-------+ | 1 | tom | | 3 | jerry | +----+-------+ 2 rows in set (0.00 sec) |
node4节点也插入2条数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#查看数据库; MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | binlog | | hellodb | | information_schema | | mydb | | mysql | | performance_schema | | relaylog | | test | +--------------------+ 8 rows in set (0.00 sec) MariaDB [(none)]> use mydb; Database changed MariaDB [mydb]> insert into tb1 (name) values ('andy'); Query OK, 1 row affected (0.04 sec) MariaDB [mydb]> insert into tb1 (name) values ('allen'); Query OK, 1 row affected (0.01 sec) MariaDB [mydb]> select * from tb1; +----+-------+ | id | name | +----+-------+ | 1 | tom | | 3 | jerry | | 4 | andy | | 6 | allen | +----+-------+ 4 rows in set (0.00 sec) |
让在node3节点上插入的行的自动增长都为奇数,让node4节点服务器上的自动增长都为偶数。
至此,MariaDB/MySQL的主从复制、半同步复制、基于SSL加密的复制以及MariaDB/MySQL的双主模型架构就全部完成。
九.数据库复制过滤器功能
1.复制过滤器功能的简介
主服务器只能过滤到库级别,从服务器可以过滤到表级别;
要想使设置永久生效,就写入配置文件
让slave仅复制有限的几个数据库,而非所有;
有两种实现思路:
(1) 主服务器仅向二进制日志中记录有特定数据库相关的写操作;
问题:即时点还原将无法全面实现;
binlog_do_db= # 数据库白名单
binlog_ignore_db= # 数据库黑名单
(2)从服务器的SQL_THREAD仅在中断日志中读取特定数据相关的语句并应用在本地;
问题:会造成网络带宽和磁盘IO的浪费;
replicate_do_db= (数据库白名单,多个用列表)
replicate_ignore_db= (黑名单)
不建议同时使用,
如果同时启用则以白名单为准,
如果同时出现在白黑名单中,则拒绝复制
replicate_do_table= db_name.table_name (表的白名单)
replicate_ignore_table=(表的黑名单)
replicate_wild_do_table=
replicate_wild_ignore_table=
以上两项支持通配符,进行过滤;
2.复制过滤器功能的实现;
(1).基于库的白名单的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#我们在node4节点实现只允许同步testdb这个数据库; #先停止slave进程; MariaDB [(none)]> stop slave; Query OK, 0 rows affected (0.01 sec) #设置过滤器的白名单,允许同步的数据库; MariaDB [(none)]> set global replicate_do_db='testdb'; Query OK, 0 rows affected (0.00 sec) #启动slave进程; MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec) #查看关于过滤器的选项参数; MariaDB [(none)]> show global variables like '%replicat%'; +----------------------------------+-----------+ | Variable_name | Value | +----------------------------------+-----------+ | innodb_replication_delay | 0 | | replicate_annotate_row_events | OFF | | replicate_do_db | testdb | | replicate_do_table | | | replicate_events_marked_for_skip | replicate | | replicate_ignore_db | | | replicate_ignore_table | | | replicate_wild_do_table | | | replicate_wild_ignore_table | | +----------------------------------+-----------+ 9 rows in set (0.00 sec) |
我们到node3节点创建数据库testdb;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | binlog | | information_schema | | mysql | | performance_schema | | relaylog | | test | +--------------------+ 6 rows in set (0.00 sec) MariaDB [(none)]> create database testdb; Query OK, 1 row affected (0.00 sec) |
我们在node4节点上查看数据库,发现testdb被同步过来:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | binlog | | information_schema | | mysql | | performance_schema | | relaylog | | test | | testdb | +--------------------+ 7 rows in set (0.00 sec) |
我们在node3节点新建数据库mydb;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
MariaDB [(none)]> create database mydb; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | binlog | | information_schema | | mydb | | mysql | | performance_schema | | relaylog | | test | | testdb | +--------------------+ 8 rows in set (0.00 sec) |
到node4节点查看数据库,发现mydb没有被同步过来,白名单只允许testdb同步过来:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | binlog | | information_schema | | mysql | | performance_schema | | relaylog | | test | | testdb | +--------------------+ 7 rows in set (0.00 sec) |
(2).基于表做过滤实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#在从服务器节点node4上做hellodb库的students表过滤 MariaDB [(none)]> stop slave; Query OK, 0 rows affected (0.04 sec) MariaDB [(none)]> set global replicate_ignore_table='hellodb.students'; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> show global variables like '%replicat%'; +----------------------------------+------------------+ | Variable_name | Value | +----------------------------------+------------------+ | innodb_replication_delay | 0 | | replicate_annotate_row_events | OFF | | replicate_do_db | testdb | | replicate_do_table | | | replicate_events_marked_for_skip | replicate | | replicate_ignore_db | | | replicate_ignore_table | hellodb.students | | replicate_wild_do_table | | | replicate_wild_ignore_table | | +----------------------------------+------------------+ 9 rows in set (0.00 sec) MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec) #在从服务器查看从服务器中的hellodb库中的students表中的信息 MariaDB [(none)]> use hellodb; Database changed MariaDB [hellodb]> select * from students; +-------+---------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+---------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | | 6 | Shi Qing | 46 | M | 5 | NULL | | 7 | Xi Ren | 19 | F | 3 | NULL | | 8 | Lin Daiyu | 17 | F | 7 | NULL | | 9 | Ren Yingying | 20 | F | 6 | NULL | | 10 | Yue Lingshan | 19 | F | 3 | NULL | | 11 | Yuan Chengzhi | 23 | M | 6 | NULL | | 12 | Wen Qingqing | 19 | F | 1 | NULL | | 13 | Tian Boguang | 33 | M | 2 | NULL | | 14 | Lu Wushuang | 17 | F | 3 | NULL | | 15 | Duan Yu | 19 | M | 4 | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 17 | Lin Chong | 25 | M | 4 | NULL | | 18 | Hua Rong | 23 | M | 7 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | | 20 | Diao Chan | 19 | F | 7 | NULL | | 21 | Huang Yueying | 22 | F | 6 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 23 | Ma Chao | 23 | M | 4 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | Sun Dasheng | 100 | M | NULL | NULL | +-------+---------------+-----+--------+---------+-----------+ 25 rows in set (0.01 sec) |
主服务器节点node3也是有hellodb数据库的,我们在这个库中的students表中插入一个数据:
1 2 3 4 |
MariaDB [(none)]> use hellodb; Database changed MariaDB [hellodb]> insert into students(stuid,name,age,gender,classid) values (26,'Qiao Feng',35,'M',5); Query OK, 1 row affected (0.02 sec) |
我们到从节点上查看hellodb库的students表,发现在主节点node3插入的数据未同步过来,实现了表过滤操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
MariaDB [hellodb]> select * from students; +-------+---------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+---------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | | 6 | Shi Qing | 46 | M | 5 | NULL | | 7 | Xi Ren | 19 | F | 3 | NULL | | 8 | Lin Daiyu | 17 | F | 7 | NULL | | 9 | Ren Yingying | 20 | F | 6 | NULL | | 10 | Yue Lingshan | 19 | F | 3 | NULL | | 11 | Yuan Chengzhi | 23 | M | 6 | NULL | | 12 | Wen Qingqing | 19 | F | 1 | NULL | | 13 | Tian Boguang | 33 | M | 2 | NULL | | 14 | Lu Wushuang | 17 | F | 3 | NULL | | 15 | Duan Yu | 19 | M | 4 | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 17 | Lin Chong | 25 | M | 4 | NULL | | 18 | Hua Rong | 23 | M | 7 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | | 20 | Diao Chan | 19 | F | 7 | NULL | | 21 | Huang Yueying | 22 | F | 6 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 23 | Ma Chao | 23 | M | 4 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | Sun Dasheng | 100 | M | NULL | NULL | +-------+---------------+-----+--------+---------+-----------+ 25 rows in set (0.00 sec) |
我们在主节点上创建一张表tb1:
1 2 |
MariaDB [hellodb]> create table tb1 like students; Query OK, 0 rows affected (0.11 sec) |
我们到从服务器节点查看表是否同步过来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
MariaDB [hellodb]> show tables; +-------------------+ | Tables_in_hellodb | +-------------------+ | classes | | coc | | courses | | scores | | students | | tb1 | | teachers | | toc | +-------------------+ 8 rows in set (0.00 sec) |
至此,数据库的复制过滤器功能就介绍完毕了。