Mysql的主从架构模式,是很多企业广泛使用,并且大家所广为熟知的一种架构模式,这是DBA所应该熟练掌握的技能。
• 1.mysql主从复制主要用途
○ a.用于备份,避免影响业务
○ b.实时灾备,用于故障切换
○ c.读写分离,提供查询服务
• 2.mysql主从复制存在的问题
○ a.主库宕机后, 数据可能丢失
○ b.主库写压力大, 复制可能会延时
• 3.mysql主从复制解决方法
○ a.半同步复制、或者全同步复制. 要求: Mysql5.7版本
○ b.并行复制, 解决从库复制延迟的问题. 建议: 5.7版
• 4.mysql主从复制原理
1.在主库上把将更改DDL DML DCL记录到二进制日志Binary Log中。
2.备库I/O线程将主库上的二进制日志复制到自己的中继日志Relay Log中
3.备库SQL线程读取中继日志中的事件,将其重放到备库数据库之上。
1.MySQL数据库传统复制
数据库传统主从复制如下, 如需实现多从, 将以下实验从案例在配置一次即可
操作系统
/etc/hosts文件解析
192.168.70.160 master1
192.168.70.161 Slave1
Master配置
//1.配置文件/etc/my.cnf
log-bin
server-id=160
//2.重启mysql服务生效
[root@Master ~]# systemctl restart mysqld
//3.模拟线上数据库
mysql> create database linuxdb;
mysql> use linuxdb;
mysql> create table t1(id int, name varchar(20));
mysql> insert into t1 values (1,'tt');
mysql> insert into t1 values (2,'ttt');
mysql> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | tt |
| 2 | ttt |
+------+------+
//4.授权, 允许能够远程连接的主机(replicaiton)
mysql> grant replication slave, replication client on *.*
to 'rep'@'192.168.70.%' identified by 'Rep123.com';
//5.导出当前数据
[root@Master ~]# mysqldump -uroot -pBgx123.com \
--all-databases \
--single-transaction \
--master-data=1 \
--flush-logs > /root/db-$(date +%F)-all.sql
//6.将备份文件传送至Slave
[root@Master ~]# scp /root/db-2018-05-10-all.sql root@slave1:/root
Slave配置
//1.检查是否能使用远程账户登录
[root@slave ~]# mysql -hmaster -urep -pRep123.com
//2.修改配置文件/etc/my.cnf, 从需开启binlog
server-id=161
//3.重启mysql数据库服务
[root@slave ~]# systemctl restart mysqld
//4.导入数据,追master的bin_log
[root@Slave ~]# mysql -uroot -p'Bgx123.com' -e "source /root/db-2018-05-10-all.sql"
//5.指向Master,无需指定binlogfile和pos
mysql> change master to
master_host='master1',
master_user='rep',
master_password='Rep123.com';
//6.启动slave角色
mysql> start slave;
//7.查看角色是否同步
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: master1
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: Master1-bin.000003
Read_Master_Log_Pos: 589
Relay_Log_File: Slave1-relay-bin.000004
Relay_Log_Pos: 613
Relay_Master_Log_File: Master1-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
2.MySQL数据库Gtid复制
数据库Gtid主从复制如下, 如需实现多从, 将以下实验从案例在配置一次即可
/etc/hosts文件解析
192.168.70.160 master1
192.168.70.161 Slave1
注意:如果实验过传统主从复制, 请重置Slave数据库,文章后续会介绍
Master配置
//1.配置文件/etc/my.cnf
log-bin
server-id=160
gtid_mode = ON
enforce_gtid_consistency=1
//2.重启mysql服务生效
[root@Master ~]# systemctl restart mysqld
//3.模拟线上数据库
mysql> create database linuxdb;
mysql> use linuxdb;
mysql> create table t1(id int, name varchar(20));
mysql> insert into t1 values (1,'tt');
mysql> insert into t1 values (2,'ttt');
mysql> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | tt |
| 2 | ttt |
+------+------+
//4.授权, 允许能够远程连接的主机(replicaiton)
mysql> grant replication slave, replication client on *.*
to 'rep'@'192.168.70.%' identified by 'Rep123.com';
//5.导出当前数据
[root@Master ~]# mysqldump -uroot -pBgx123.com \
--all-databases \
--single-transaction \
--master-data=1 \
--flush-logs > /root/db-$(date +%F)-all.sql
//6.将备份文件传送至Slave
[root@Master ~]# scp /root/db-2018-05-10-all.sql root@slave1:/root
Slave配置
//1.重新初始化环境
[root@Slave1 ~]# systemctl stop mysqld
[root@Slave1 ~]# rm -rf /var/lib/mysql/*
[root@Slave1 ~]# chown -R mysql.mysql /var/lib/mysql
[root@Slave1 ~]# systemctl start mysqld
//2.检查是否能使用远程账户登录
[root@slave ~]# mysql -hmaster -urep -pRep123.com
//3.修改配置文件/etc/my.cnf
server-id=161
gtid_mode = ON
enforce_gtid_consistency=1
[可选,保存连接信息至表中]
#log-info-repository=TABLE
#relay-log-intp-repository=TABLE
//4.重启mysql数据库服务
[root@slave ~]# systemctl restart mysqld
//5.导入数据,追master的bin_log
[root@Slave ~]# mysql -uroot -p'Bgx123.com' -e "source /root/db-2018-05-10-all.sql"
//6.指向Master,gtid自动协商同步
mysql> change master to
master_host='master1',
master_user='rep',
master_password='Rep123.com',
master_auto_position=1;
//7.启动slave角色
mysql> start slave;
//8.查看角色是否同步
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: master1
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: Master1-bin.000003
Read_Master_Log_Pos: 589
Relay_Log_File: Slave1-relay-bin.000004
Relay_Log_Pos: 613
Relay_Master_Log_File: Master1-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
MySQL数据库双主复制
注意: 数据库双主M-M架构, 需要基于gtid的主从架构演变
Gtid M-M复制, 基于主从模式,演变为双主
//Master1
1.修改配置
log -bin
server-id=1
gtid_mode = ON
enforce_gtid_consistency=1
2.重启mysql数据库
systemctl restart mysqld
3.授权
4.导出数据库
//Master2
1.修改配置
log -bin
server-id=2
gtid_mode = ON
enforce_gtid_consistency=1
2.重启mysql数据库
systemctl restart mysqld
3.授权
给master1授权,由于之前授权针对网段
4.恢复Master1数据, 保持主从同步
master1和master2数据必须保持一致
在master1上执行 change to master --> mater2
在master2上执行 change to master -->master1
3.MySQL数据库多源复制
数据库M-M-S-S
[root@Master1 ~]# cat /etc/hosts
192.168.70.160 master1
192.168.70.161 master2
192.168.70.162 slave2
192.168.70.163 slave3
Master1
1.修改配置
log -bin
server_id=160
gtid_mode = ON
enforce_gtid_consistency=1
2.重启mysql服务器
systemctl restart mysqld
3.授权(建议网段)
mysql> grant replication slave,replication client on *.* to rep@'192.168.70.%' identified by 'Rep123.com';
mysql> flush privileges;
4.导出对应的数据
mysqldump -uroot -p'Bgx123.com' \
--all-databases \
--master-data=1 \
--single-transaction \
--flush-logs > /root/$(date +%F)-mysql-all.sql
5.分发对应的数据
scp --> master2
scp --> slave1
scp --> slave2
Master2
1.修改配置
server_id=161
log_bin
gtid_mode = ON
enforce_gtid_consistency = 1
2.重启
3.导入数据
[root@Master2 ~]# mysql -uroot -pBgx123.com -e "reset master;"
[root@Master2 ~]# mysql -uroot -pBgx123.com < /root/2018-05-10-mysql-test.sql
4.验证远程账户是否可用
1.防火墙
2.账户密码
5.登陆数据库,清理从库的二进制日志
mysql> reset master;
6.指定master
mysql> change master to
master_host='master1',
master_user='rep',
master_password='Rep123.com',
master_auto_position=1;
7.启动 slave 角色
mysql > start slave;
8.查看角色状态
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: master1
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: Master1-bin.000003
Read_Master_Log_Pos: 154
Relay_Log_File: Master2-relay-bin.000002
Relay_Log_Pos: 371
Relay_Master_Log_File: Master1-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Master1
mysql> flush privileges;
mysql>change master to
master_host='master2',
master_user='rep',
master_password='Rep123.com',
master_auto_position=1;
2.启动slave角色
mysql > start slave; #
3.查看slave状态
mysql > show slave status\G
双主OK
Slave1和Slave2一致
1. 修改配置
server_id=162
gtid_mode = ON
enforce_gtid_consistency = 1
master-info-repository=TABLE
relay-log-info-repository=TABLE
2.重启数据库
[root@slave2 ~]# systemctl restart mysqld
3. 初始化数据库 导入数据
[root@slave2 ~]# mysql -uroot -p'Bgx123.com' -e "reset master;"
[root@slave2 ~]# mysql -uroot -p'Bgx123.com' < /root/2018-05-10-mysql-test.sql
4.清理二进制日志文件
reset master;
//指向Master1
mysql> change master to
master_host='master1',
master_user='rep',
master_password='Rep123.com',
master_auto_position=1 for channel 'master1-channel';
//指向Master2
mysql> change master to
master_host='master2',
master_user='rep',
master_password='Rep123.com',
master_auto_position=1 for channel 'master2-channel';
5.mysql > start slave;
6.mysql > show slave status\G
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: master1
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: Master1-bin.000001
Read_Master_Log_Pos: 154
Relay_Log_File: slave2-relay-bin-master1@002dchannel.000002
Relay_Log_Pos: 371
Relay_Master_Log_File: Master1-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
mysql> show slave status\G
*************************** 2. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: master1
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: Master1-bin.000001
Read_Master_Log_Pos: 154
Relay_Log_File: slave2-relay-bin-master1@002dchannel.000002
Relay_Log_Pos: 371
Relay_Master_Log_File: Master1-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
4.MysQL数据库读写分离
1.部署MyCat
//Mycat依赖于Java环境
[root@Mycat ~]# yum install -y java
[root@Mycat ~]# java -version
openjdk version "1.8.0_161"
OpenJDK Runtime Environment (build 1.8.0_161-b14)
OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)
//下载MyCat
[root@Mycat ~]# mkdir /soft/
[root@Mycat ~]# tar xf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /soft/
[root@Mycat ~]# wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
2.配置应用程序连接MyCat账户密码
[root@Mycat ~]# vim /soft/mycat/conf/server.xml
#注意:底下有user用户需注释
<!-- 应用连接mycat账户-->
<user name="blog">
<!-- 应用连接mycat密码-->
<property name="password">123456</property>
<!-- 针对哪个库进行授权 -->
<property name="schemas">blog</property>
</user>
<user name="www">
<property name="password">123456</property>
<property name="schemas">www</property>
</user>
3.配置Mycat连接后端数据库
balance负载均衡类型
1.balance="0"不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
2.balance="1", 所有的主机都参与select语句的负载均衡, 但写语句还是由writeHost
3.balance="2"所有读操作都随机的在writeHost、readhost上分发。
[root@Mycat ~]# cat /soft/mycat/conf/schema.xml
[root@Mycat conf]# cat schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!--链接mycat后的显示名称 -->
<schema name="blog" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> </schema>
<schema name="www" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn2"> </schema>
<!--dateNode数据节点 dataHost相当于主机池-->
<dataNode name="dn1" dataHost="dn1pool" database="blog" />
<dataNode name="dn2" dataHost="dn2pool" database="www" />
<!--定义blog资源池限制-->
<dataHost name="dn1pool" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<!--健康检查-->
<heartbeat>select user()</heartbeat>
<writeHost host="Master" url="192.168.70.160:3306" user="blog" password="Bgx123.com">
<readHost host="Slave1" url="192.168.70.161:3306" user="blog" password="Bgx123.com" />
<readHost host="Slave2" url="192.168.70.162:3306" user="blog" password="Bgx123.com" />
</writeHost>
</dataHost>
<!--定义www资源池限制-->
<dataHost name="dn2pool" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<!--健康检查-->
<heartbeat>select user()</heartbeat>
<!--定义www库读写主机,可以定义多个-->
<writeHost host="Master" url="192.168.70.160:3306" user="www" password="Bgx123.com">
<readHost host="Slave1" url="192.168.70.161:3306" user="www" password="Bgx123.com" />
<readHost host="Slave2" url="192.168.70.162:3306" user="www" password="Bgx123.com" />
</writeHost>
</dataHost>
</mycat:schema>
4.配置MySQL相关信息, 均在MySQL-Master上操作
mysql> create databse blog;
mysql> create databse www;
mysql> create table blog.b(id int);
mysql> create table www.w(id int);
mysql> grant all on www.* to www@'192.168.70.%' identified by 'Bgx123.com';
mysql> grant all on blog.* to blog@'192.168.70.%' identified by 'Bgx123.com';
5.启动MyCat中间件
[root@Mycat ~]# /soft/mycat/bin/mycat start
Starting Mycat-server...
[root@Mycat conf]# lsof -i :8066
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 5352 root 76u IPv6 52537 0t0 TCP *:8066 (LISTEN)
[root@Mycat conf]# lsof -i :9066
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 5352 root 72u IPv6 52535 0t0 TCP *:9066 (LISTEN)
6.测试Mycat中间件
//需要开启日志为deblog可查看详细分离情况
[root@Mycat ~]# vim /soft/mycat/conf/log4j2.xml
<asyncRoot level="debug" includeLocation="true">
[root@Mycat ~]# tail -f /soft/mycat/log/mycat.log |grep "222222"
//连接Mycat使用不规则语句插入与查询, 便于查看策略
mysql> insert into blog.b valuse (222222);
mysql> select * from blog.b where id = '222222';
5.MySQL数据库架构演变
文档更新时间: 2019-02-06 17:05 作者:李延召