MySQL主从复制

简介

master数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到slave数据库上,然后将这些日志重新执行(重做);从而使得slave数据库的数据与master数据库保持一致。

MySQL数据库自身提供的主从复制功能可以方便的实现数据的多处自动备份,实现数据库的拓展。多个数据备份不仅可以加强数据的安全性,通过实现读写分离还能进一步提升数据库的负载性能。

目录

一、主从原理

1.1 主从复制基本原理

1.2 主从复制原理运行流程

二、主从用途

2.1 主从复制的形式选择

2.2 主从复制的作用

三、主从配置

3.1 主从复制环境准备,安装数据库

3.2 一主多从配置文件

3.3 验证一主多从同步

四、常见问题

4.1 Slave_IO_Running: NO

4.2 Slave_SQL_Running: NO

4.3 mysql主从复制存在的问题


一、主从原理

Mysql之一主多从复制_主从同步

Binary log:主数据库的二进制日志

Relay log:从服务器的中继日志

1.1 主从复制基本原理:

从库生成两个线程,一个I/O线程,一个SQL线程;i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中;主库会生成一个 log dump 线程,用来给从库 i/o线程传binlog;SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致;

1.2 主从复制原理运行流程:

    1> master在每个事务更新数据完成之前,将该操作记录串行地写入到binlog文件中;

    2> slave开启一个I/O Thread,该线程在master打开一个普通连接,主要工作是binlog dump process。如果读取的进度已经跟上了master,就进入睡眠状态并等待master产生新的事件。I/O线程最终的目的是将这些事件写入到中继日志中;

    3> SQL Thread会读取中继日志,并顺序执行该日志中的SQL事件,从而与主数据库中的数据保持一致;


二、主从形式与用途

2.1 主从形式

Mysql主从复制比较灵活,形式多种

v一主一从

v主主复制(互为主从)

v一主多从(常用于扩展系统读取性能,因为读是在从库读取的)

v多主一从(5.7开始支持)

v联级复制

联级复制就是master服务器,只给一台slave服务器同步数据,然后slave服务器在向后端的所有slave服务器同步数据,降低master服务器的写压力,和复制数据的网络IO。

Mysql之一主多从复制_主从复制_02

2.2 主从用途

    v实时灾备,用于故障切换,主数据库出现问题,可以切换到从数据库

    v读写分离,提供查询服务

    v数据备份,避免影响业务

三、主从配置

3.1 环境准备

OS:centos7.2

Mysql:5.6

防火墙、selinux:关闭

Mysql安装方式:Yum


部署环境 ---> 一主多从

Master:192.168.174.164

Slave1:192.168.174.132

Slave2:192.168.174.133


3.1.1 安装Mysql

主从安装方式一致

3.1.2 安装一些常用linux工具

yum -y install wget vim net-tools

3.1.3 下载Mysql5.6的yum源

wget http://dev.mysql.com/get/mysql-community-release-el7-5noarch.rpm

rpm -ivh mysql-community-release-el7-5.noarch.rpm


3.1.4 yum安装Mysql服务并启动

yum -y install mysql-community-server

service mysqld start

netstat -anptl|grep 3306
tcp6  0  0 :::3306       :::*    LISTEN      1248/mysqld


3.1.5 更改数据库密码,验证是否能正常登陆

mysql -uroot -e "set password for 'root'@'localhost'=password('123456');"

mysql -uroot -p123456


3.2 一主多从复制

3.2.1 数据库配置文件

Master:

# vim /etc/my.cnf

log-bin=mysql-bin 
binlog-format = mixed
server-id = 1
relay-log =relay-bin
relay-log-index = slave-relay-bin.index

Mysql之一主多从复制_mysql_03

Slave1:

# vim /etc/my.cnf
 
log-bin=mysql-bin  
binlog-format = mixed
server-id = 2
relay-log =relay-bin
relay-log-index = slave-relay-bin.index

Mysql之一主多从复制_mysql_04

Slave2:

# vim /etc/my.cnf
 
log-bin=mysql-bin
binlog-format = mixed
server-id = 3
relay-log =relay-bin
relay-log-index = slave-relay-bin.index

Mysql之一主多从复制_主从复制_05

备注:修改完配置文件后重启服务:systemctl restart mysqld

Mysql配置文件详情请参考以下地址:

http://blog.51cto.com/13266497/2150082


3.2.2 数据库一主多从操作

Master:

1> 授权用户相应权限

mysql> grant replication slave on *.* to 'lxq'@'192.168.174.%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)


 

2> 查看master状态值,用于slave库上同步

mysql> show master status\G;
*************************** 1. row ***************************
              File: mysql-bin.000001
       Position: 329
     Binlog_Do_DB:
     Binlog_Ignore_DB:
     Executed_Gtid_Set:
1 row in set (0.00 sec)


 

 

Slave1:

1> 使用change master语句,确定master库的ip、用户、密码等信息

mysql> change master to
    -> master_host='192.168.174.164',
    -> master_user='lxq',
    -> master_password='123456',
    -> master_log_file='mysql-bin.000001', 
    -> master_log_pos=329;
Query OK, 0 rows affected, 2 warnings (0.00 sec)

以下两项是从master status中获取的File和Position与下列相对应

master_log_file='mysql-bin.000001'

master_log_pos=329

 

 

2> 开启同步

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)


 

3> 验证Slave_IO_Running、Slave_SQL_Running是否是YES,两个都是YES表示mysql主从复制配置成功了。

mysql> show slave status\G;
*************************** 1. row ***************************
      Slave_IO_State: Waiting for master to send event
        Master_Host: 192.168.174.164
        Master_User: lxq
        Master_Port: 3306
       Connect_Retry: 60
      Master_Log_File: mysql-bin.000001
    Read_Master_Log_Pos: 329
       Relay_Log_File: relay-bin.000002
       Relay_Log_Pos: 283
   Relay_Master_Log_File: mysql-bin.000001
      Slave_IO_Running: Yes
     Slave_SQL_Running: Yes

Slave_IO_Running: Yes(负责从库去主库读取二进制日志,并写入到从库的中继日志)

Slave_SQL_Running: Yes(负责将中继日志准换成SQL语句后执行)

备注:Slave2库重复一下Slave1的操作即可完成一主多从

 

3.3 验证能否成功同步

测试主从是否同步(master数据库上执行Sql、Slave上面去验证)

Master:

mysql> create database lxqdb;

mysql> create table lxqdb.lxq(id int,name varchar(50),sex varchar(10));

mysql> insert into lxqdb.lxq(id,name,sex) values (1,'lxq','male');


Slave:

mysql> show databases;
+--------------------+
| Database     |
+--------------------+
| information_schema|
| lxqdb       |
| mysql       |
| performance_schema|
+--------------------+
4 rows in set (0.01 sec)


mysql> select * from lxqdb.lxq;
+------+------+------+
| id | name| sex |
+------+------+------+
| 1  | lxq | male|
+------+------+------+
1 row in set (0.00 sec)


一、常见问题

4.1 Slave_IO_Running: NO

一般的原因是:

    1> master服务器的网络不通,或者master服务器的防火墙拒绝了外部连接3306端口,selinux模式选择都可能会影响结果。

    2> 在配置slave服务器时,使用chage master语句时输错了ip地址和密码等信息。

    3> master主服务器授权了错误的IP地址,权限。

解决方法:

   关闭防火墙或开通3306的访问权限,selinux设置为disabled;

   slave的服务器上使用master授权用户登陆一下master数据库确保授权和slave地址能够访问,最后slave库检查一下change master语句是否有误;

4.2 Slave_SQL_Running: No

mysql同步故障原因:

    1> 程序可能在slave上进行了写操作

    2> 也可能是slave机器重起后,事务回滚造成的.

一般是事务回滚造成

解决方法1:

mysql> stop slave;

mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;

mysql> start start;

备注:不一定会生效,操作两次不生效后,选择第二种方法


解决方法2:

mysql> stop slave;  

mysql> show master status;

master服务器上查看主机状态,记录File和Position对应的值,然后到slave服务器上执行手动同步(change master语句),参考同步时使用的语句。

备注:强制从某一个点同步,这种方法会停掉master写操作,会丢失部分没有同步的数据,不影响使用。

 

4.3 mysql主从复制存在的问题

    1> 主库宕机后,数据可能丢失

    2> 从库只有一个sql Thread,主库写压力大,复制很可能延时

解决方法:

    半同步复制---解决数据丢失的问题

    异行复制----解决从库复制延迟的问题

v全同步复制

全同步复制,当主库提交事务之后,所有的从库节点必须收到、APPLY并且提交这些事务,然后主库线程才能继续做后续操作。但缺点是,主库完成一个事务的时间会被拉长,性能降低。

v异步复制

异步复制,主库将事务 Binlog 事件写入到 Binlog 文件中,此时主库只会通知一下 Dump 线程发送这些新的 Binlog,然后主库就会继续处理提交操作,而此时不会保证这些 Binlog 传到任何一个从库节点上。

v半步复制

半同步复制的原理是,一个事务在主服务器上执行完成后,必须至少确保至少在一台从服务器上执行完成后,事务才算提交成功。

主库写入一个事务commit提交并执行完之后,并不直接将请求反馈给前端应用用户,而是等待从库也接收到binlog日志并成功写入中继日志后,主库才返回commit操作成功给客户端。半同步复制保障了事物执行后,至少有两份日志记录,一份在主库的binlog上 ,另一份至少在从库的中继日志Relay log上,这样就极大的保证了数据的一致性。