目录
- 1. 什么是主从复制?
- 2. mysql主从复制原理
- 3. mysql支持的复制类型
- 4. mysql主从复制优点
- 5. 主从复制案例分析
- 1. master的写操作,slaves被动的进行一样的操作,保持数据一致性,那么slave是否可以主动的进行写操作?
- 2. 主从复制中,可以有N个slave,可是这些slave又不能进行写操作,要他们干嘛?
- 3. 主从复制中有master,slave1,slave2,...等等这么多MYSQL数据库,那比如一个JAVA WEB应用到底应该连接哪个数据库?
- 4. 如果mysql proxy , direct , master他们中的某些挂了怎么办?
- 5. 当master的二进制日志每产生一个事件,都需要发往slave,如果我们有N个slave,那是发N次,还是只发一次?
- 6. 当一个select发往mysql proxy,可能这次由slave-2响应,下次由slave-3响应,这样的话,就无法利用查询缓存了。
- 7. 随着应用的日益增长,读操作很多,我们可以扩展slave,但是如果master满足不了写操作了,怎么办呢?
- 6. 主从形式
- 7. shell实现MYSQL主从校验
- 搭建MYSQL互为主从
- 1. 使用yum安装部署mysql两台
- 2. 关闭防火墙和selinux
- 3. 查看mysql的版本信息
- 4. 启动mysql服务,查看系统中是否存在mysql进程,并查看mysql的端口号
- 5. 修改配置两台mysql的主配置文件
- 6. 在mysql中新建数据库名
- 7. 在mysql中新建用户名并授权
- 8. 最后查看两台服务器从的状态
- 9. 检验mysql主从状态
1. 什么是主从复制?
主从复制的原理:
- 简而言之,MySQL-A在进行写操作时,都会更新数据库A的二进制sql日志,通过网络传输将二进制sql日志传递给数据库B,B再将二进制sql日志写入B数据库,完成主从复制。
2. mysql主从复制原理
从库生成两个线程,一个I/O线程,一个SQL线程;
- i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中;
- 主库会生成一个 log dump 线程,用来给从库 i/o线程传binlog;
- SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致;
3. mysql支持的复制类型
- 基于语句的复制: 在主服务器上执行的SQL语句(写入bin log中),在从服务器上执行同样的语句。
基于语句;比如create database wg;
MariaDB [(none)]> create database wg;
Query OK, 1 row affected (0.00 sec)
- 基于行的复制:把改变的内容(写入bin log中)复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持。
基于行;比如wg库
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| wg |
+--------------------+
5 rows in set (0.00 sec)
- 混合类型的复制:
MySQL默认采用混合类型的复制,效率比较高。
混合类型(两者结合)
MariaDB [(none)]> create database wg;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| wg |
+--------------------+
5 rows in set (0.00 sec)
4. mysql主从复制优点
- 健壮性: 主服务器出现故障时,可以切到从服务器作为备份
- 速度快: 更新操作在主服务器端,查询操作在从服务器端,可以加快用户的响应时间
- 备份: 避免影响业务
5. 主从复制案例分析
1. master的写操作,slaves被动的进行一样的操作,保持数据一致性,那么slave是否可以主动的进行写操作?
假设slave可以主动的进行写操作,slave又无法通知master,这样就导致了master和slave数据不一致了。因此slave不应该进行写操作,至少是slave上涉及到复制的数据库不可以写。实际上,这里已经揭示了读写分离的概念。
2. 主从复制中,可以有N个slave,可是这些slave又不能进行写操作,要他们干嘛?
可以实现数据备份。
类似于高可用的功能,一旦master挂了,可以让slave顶上去,同时slave提升为master。
异地容灾,比如master在北京,地震挂了,那么在上海的slave还可以继续。
主要用于实现scale out,分担负载,可以将读的任务分散到slaves上。
【很可能的情况是,一个系统的读操作远远多于写操作,因此写操作发向master,读操作发向slaves进行操作】
3. 主从复制中有master,slave1,slave2,…等等这么多MYSQL数据库,那比如一个JAVA WEB应用到底应该连接哪个数据库?
当 然,我们在应用程序中可以这样,insert/delete/update这些更新数据库的操作,用connection(for master)进行操作,select用connection(for slaves)进行操作。那我们的应用程序还要完成怎么从slaves选择一个来执行select,例如简单的轮循算法。
这样的话,相当于应用程序完成了SQL语句的路由,而且与MYSQL的主从复制架构非常关联,一旦master挂了,某些slave挂了,那么应用程序就要修改了。能不能让应用程序与MYSQL的主从复制架构没有什么太多关系呢?可以看下面的图:
找一个组件,application program只需要与它打交道,用它来完成MYSQL的代理,实现SQL语句的路由。
mysql proxy并不负责,怎么从众多的slaves挑一个?可以交给另一个组件(比如haproxy)来完成。
这就是所谓的MYSQL READ WRITE SPLITE,MYSQL的读写分离。
4. 如果mysql proxy , direct , master他们中的某些挂了怎么办?
总统一般都会弄个副总统,以防不测。同样的,可以给这些关键的节点来个备份。
5. 当master的二进制日志每产生一个事件,都需要发往slave,如果我们有N个slave,那是发N次,还是只发一次?
如果只发一次,发给了slave-1,那slave-2,slave-3,…它们怎么办?
显 然,应该发N次。实际上,在MYSQL master内部,维护N个线程,每一个线程负责将二进制日志文件发往对应的slave。master既要负责写操作,还的维护N个线程,负担会很重。可 以这样,slave-1是master的从,slave-1又是slave-2,slave-3,…的主,同时slave-1不再负责select。 slave-1将master的复制线程的负担,转移到自己的身上。这就是所谓的多级复制的概念。
6. 当一个select发往mysql proxy,可能这次由slave-2响应,下次由slave-3响应,这样的话,就无法利用查询缓存了。
应该找一个共享式的缓存,比如memcache来解决。将slave-2,slave-3,…这些查询的结果都缓存至mamcache中。
7. 随着应用的日益增长,读操作很多,我们可以扩展slave,但是如果master满足不了写操作了,怎么办呢?
scale on ?更好的服务器? 没有最好的,只有更好的,太贵了。。。
scale out ? 主从复制架构已经满足不了。
可以分库【垂直拆分】,分表【水平拆分】。
6. 主从形式
mysql主从复制 灵活
- 一主一从
- 主主复制
- 一主多从—扩展系统读取的性能,因为读是在从库读取的;
- 多主一从—5.7开始支持
- 联级复制—
7. shell实现MYSQL主从校验
搭建MYSQL互为主从
1. 使用yum安装部署mysql两台
服务器A
yum -y install mysql mysql-server -----安装mysql服务
服务器B
yum -y install mysql mysql-server -----安装mysql服务
2. 关闭防火墙和selinux
服务器A
service iptables stop -----关闭防火墙
setenforce 0 -----关闭selinux
服务器B
service iptables stop -----关闭防火墙
setenforce 0 -----关闭selinux
3. 查看mysql的版本信息
mysql --version -----查看mysql版本信息
4. 启动mysql服务,查看系统中是否存在mysql进程,并查看mysql的端口号
service mysqld start -----启动mysql服务
ps -ef | grep mysql -----查看mysql进程
netstat -nltp | grep mysql -----查看mysql端口
5. 修改配置两台mysql的主配置文件
服务器A
vim /etc/my.cnf -----mysql修改配置文件
[MYSQL]
server-id=1
log-bin=mysql-bin -----二进制日志
relay-log=mysql-relay -----中继日志
服务器B
vim /etc/my.cnf -----mysql修改配置文件
[MYSQL]
server-id=2
log-bin=mysql-bin -----二进制日志
relay-log=mysql-relay -----中继日志
6. 在mysql中新建数据库名
服务器A
mysql -----登录mysql
create database wg; -----创建数据库wg
服务器B
mysql -----登录mysql
create database wg; -----创建数据库wg
7. 在mysql中新建用户名并授权
服务器A
grant all on *.* to tom@'%' identified by '123'; -----新建用户并授权
show master status; -----查看服务器A主的状态
服务器B
grant all on *.* to tom@'%' identified by '123'; -----新建用户并授权
stop slave; -----关闭从服务器复制功能
change master to master_host='192.168.179.128',master_user='tom',master_password='123',master_log_file='mysql-bin.000003',master_log_pos=307; ------做主同步的操作
slave start; -----开启从服务器复制功能
show master status -----查看服务器B主的状态
服务器A
grant all on *.* to tom@'%' identified by '123'; -----新建用户并授权
stop slave; -----关闭从服务器复制功能
change master to master_host='192.168.179.129',master_user='tom',master_password='123',master_log_file='mysql-bin.000003',master_log_pos=386; ------做主同步的操作
slave start; -----开启从服务器复制功能
8. 最后查看两台服务器从的状态
服务器A
show slave status \G; ------查看从的状态
服务器B
show slave status \G; ------查看从的状态
最后出现双YSE表示MYSQL互为主从成功!!!
9. 检验mysql主从状态