运维笔记36 mysql的一主多从模型(原始主从复制,基于GTID主从复制)

概述:

mysql的主从复制是十分经典的一个应用,但是主从之间总会有数据一致性(data consistency )的问题,一般情况从库会落后主库几个小时,而且在传统一主多从(mysql5.6之前)的模型中当master down掉后,我们不只是需要将一个slave提成master就可以,还要将其他slave的同步目的地从以前的master改成现在master,而且bin-log的序号和偏移量也要去查看,这是十分不方便和耗时的,但mysql5.6引入gtid之后解决了这个问题,本次文章我们会讲解传统的数据库主从切换,mysql5.6之后的主从切换。
系统版本:Red Hat Enterprise Linux Server release 7.1 (Maipo)
mysql版本:
mysql集群框图:
这里写图片描述

1.传统主从切换

没有基于GTID的mysql主从复制在我之前的博客中有记录 运维笔记32 (mysql的主从复制)
或者参考官方文档(强力推荐,仔细读过后会发现写的是真心好)配置基于日志位置的主从复制

master服务器配置:

[mysqld]
binlog-do-db=test   
log-bin=mysql-bin
server-id=1

创建复制用户并授权:

mysql> create user repl;
mysql> grant replication slave on *.* to 'repl' @'172.25.3.%' identified by 'redhat';

从服务器1配置

server-id=2

将主服务器设置为master.mo.com

CHANGE MASTER TO MASTER_HOST='172.25.3.102',MASTER_USER='repl',MASTER_PASSWORD='redhat';

从服务器2配置

server-id=3

将主服务器设置为master.mo.com

CHANGE MASTER TO MASTER_HOST='172.25.3.102',MASTER_USER='repl',MASTER_PASSWORD='redhat';

现在开启salve1,slave2的复制。

start slave;

以上只是一个非常简易的主从配置,我们在接下来会一点点丰富,现在创建一个test库,并写入加入一些数据。

    create database test;
    create table test(id not int auto_increment,
    name varcahr(30),
    school varchar(30)
);
start transaction;
insert into user values(NULL,'mo','test');
insert into user values(NULL,'li','test');
commit;

master与slave1,slave2同步成功。
这里写图片描述
通过该图可以看出同步成功。
现在开始模拟主从切换
首先将master的mysql关闭

[root@master ~]# /etc/init.d/mysqld stop
Shutting down MySQL.... SUCCESS!

现在查看slave上的状态

        Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes

IO线程一直在尝试连接主机,我们把master都关掉了,任他怎么连都是连不上的,所以开始将原来的slave1提升成master。
其实将slave1提升成主,并不需要在slave1上做什么,而是要在其他slave上做设置,而且要根据slave1上的日志号和日志偏移来确定新的主从复制。
现在查看下slave1上的日志

mysql> show binlog events\G
Empty set (0.00 sec)

。。。不存在日志,我们看下data目录

slave2-relay-bin.000001
ca.pem           localhost.localdomain.err  private_key.pem     slave2-relay-bin.000002
client-cert.pem  localhost.localdomain.pid  public_key.pem      slave2-relay-bin.index

发现这里只有relay-log,我们查阅官网的文档

Normally, a slave does not write any updates that are received from a master server to its own binary log. This option causes the slave to write the updates performed by its SQL thread to its own binary log. For this option to have any effect, the slave must also be started with the --log-bin option to enable binary logging.

简单翻译:

一般情况,一个从服务器不会向他的二进制日志更新任何从主服务器接收到的数据,log-slave-updates选项让从服务器也更新他本机的二进制日志。为了让这个选项生效,我们还必须指定log-bin参数。

看到这里,我们在看下自己的配置文件,终于发现了问题,我们的从服务器根本什么都没有配置,data目录下的realy-bin并不没有master上数据更新的,而且他也不会把自己更新的数据写入二进制文件(This option causes the slave to write the updates performed by its SQL thread to its own binary log.),所以要让slave成为master必须添加log-bin,和log-slave-updates。
修改后的slave1,slave2上的配置文件
slave1:

log-bin=mysql-bin
log-slave-updates=ON
server-id=2 

slave2:

log-bin=mysql-bin
log-slave-updates=ON
server-id=3 

查看slave1上的日志

mysql> show binlog events\G
*************************** 1. row ***************************
   Log_name: mysql-bin.000001
        Pos: 4
 Event_type: Format_desc
  Server_id: 2
End_log_pos: 123
       Info: Server ver: 5.7.11-log, Binlog ver: 4
*************************** 2. row ***************************
   Log_name: mysql-bin.000001
        Pos: 123
 Event_type: Previous_gtids
  Server_id: 2
End_log_pos: 154
       Info: 
2 rows in set (0.00 sec)

确定当前的复制文件为mysql-bin.000001,当前的文件偏移为154。这两个都要几下,因为要让其他slave以slave1为master去同步,依靠的就是这个日志。
slave2上配置

mysql> CHANGE MASTER TO MASTER_HOST='172.25.3.103', MASTER_USER='repl', MASTER_PASSWORD='redhat'  ,MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;

开启slave,查看slave2状态

       Master_Host: 172.25.3.103
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
...omit
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

在slave1上写入数据,观察slave2的同步
这里写图片描述
从上图可以看出,我们在笔记本[1](slave1)上插入数据后,在笔记本[2](slave2)上可以查看到,说明切换成功。虽然切换成功,但是因为需要去查找新提升的数据库的日志号和偏移id,整个过程非常麻烦,而且容易出错,在mysql5.6版本更新了GTID之后一切都改变了,让我们下面来介绍一下。

2.基于GTID的主从复制

官方文档关于gtid的定义:

A global transaction identifier (GTID) is a unique identifier created and associated with each transaction committed on the server of origin (master). This identifier is unique not only to the server on which it originated, but is unique across all servers in a given replication setup. There is a 1-to-1 mapping between all transactions and all GTIDs.

简要翻译:通用事务标识符是一个与每个在服务器上提交事务相关的标识符,这个表示符不仅在创造它的服务器上是独一无二的,而且他在所有的从服务器上也是独一无二的,这是一个标识符与事务一对一的符号。
(翻译水平有限。。。英文好的同学自动无视)
GTID的格式就像下面这样:

3E11FA47-71CA-11E1-9E33-C80AA9429562:23

用冒号分割开,左半部分是mysql的uuid,右半部份是事务的id。
我们通过下面方式查看我们的master与slave的uuid

[root@master data]# cat auto.cnf 
[auto]
server-uuid=b7f3c1bc-12b5-11e7-a4ba-5254000d5ada

[root@slave1 data]# cat auto.cnf 
[auto]
server-uuid=6447f007-12c2-11e7-91f7-525400d18cb9

现在我们要恢复环境,重新让域名为master的服务器变成mysql主数据库,但是大家要知道,在设置主从复制之前,我们的主数据库与从数据库一定要先是一致的,否则会出现一种情况,我有两台服务器,mster和slave,但现在他们并没有做主从,我准备为master上的test库做一次主从复制,但是,slave上没有这个test库,现在做主从就会出问题,因为,slave去读取master的日志的时候发现要向一个test的库插入数据,可是我都没有这个库,这时主从同步就会卡在这里。
这里写图片描述
如上图,由于我们刚才将master在主从中剔除了,导致后续更新的数据,master中并没有,为了稳妥起见,我们使用1中的根据偏移量来进行主从的同步。
这里写图片描述
从上图可以看出,开始修改时候的二进制日志是’mysql-bin.000001’,偏移是4。所以我们从这里开始同步。
在master上输入如下

mysql> CHANGE MASTER TO MASTER_HOST='172.25.3.103',MASTER_USER='repl',MASTER_PASSWORD='redhat',MAASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=4;

这里写图片描述
现在两边数据同步了。
我们开始带有gtid的主从复制!

master配置:
my.cnf:

[mysqld]
binlog-do-db=test
log-bin=mysql-bin
server-id=1
gtid-mode=ON
enforce-gtid-consistency

slave1配置

[mysqld]
read-only
socket=/usr/local/lnmp/mysql/data/mysql.sock
gtid-mode=ON
enforce-gtid-consistency
log-bin=mysql-bin
log-slave-updates=ON
server-id=2

slave2只是将slave1的配置修改中的server-id修改一下。
现在关闭master,slave2的slave。并重启所有节点。

现在我们将slave1,slave2都将master指向master.mo.com,并且加上
MASTER_AUTO_POSITION = 1。让slave根据gtid自动同步。’

CHANGE MASTER TO MASTER_HOST='172.25.3.102',MASTER_USER='repl',MASTER_PASSWORD='redhat',MASTER_AUTO_POSITION=1;

现在开启slave。
观察一下是否同步成功。

这里写图片描述
根据图片可以看到,slave开启成功。而且是基于GTID的!
现在在主库上插入一些数据,观察从数据库的日志信息。
要查找slave的二进制日志,首先要看下data目录,二进制日志文件都有什么

[root@slave1 data]# ls
auto.cnf         ibtmp1                     mysqld_safe.pid     slave1.mo.com.err
ca-key.pem       localhost.localdomain.err  mysql.sock          slave1.mo.com.pid
ca.pem           localhost.localdomain.pid  mysql.sock.lock     slave1-relay-bin.000001
client-cert.pem  master.info                performance_schema  slave1-relay-bin.000002
client-key.pem   mysql                      private_key.pem     slave1-relay-bin.index
ib_buffer_pool   mysql-bin.000001           public_key.pem      sys
ibdata1          mysql-bin.000002           relay-log.info      test
ib_logfile0      mysql-bin.000003           server-cert.pem
ib_logfile1      mysql-bin.index            server-key.pem

发现最新的二进制是mysql-bin.000003,我们在进到数据库,查看下这个日志。

mysql> show binlog events in 'mysql-bin.000003'\G

OMIT...
*************************** 3. row ***************************
   Log_name: mysql-bin.000003
        Pos: 154
 Event_type: Gtid
  Server_id: 1
End_log_pos: 219
       Info: SET @@SESSION.GTID_NEXT= 'b7f3c1bc-12b5-11e7-a4ba-5254000d5ada:1'
*************************** 4. row ***************************

看到日志中有一行是设置下次的GTID,现在我们再插入一条并观察日志。

*************************** 8. row ***************************
   Log_name: mysql-bin.000003
        Pos: 416
 Event_type: Gtid
  Server_id: 1
End_log_pos: 481
       Info: SET @@SESSION.GTID_NEXT= 'b7f3c1bc-12b5-11e7-a4ba-5254000d5ada:2'

发现了没有,GTID中冒号后面变成2了。

基于GTID的主从复制已经搭建完成,现在将master down掉。
让slave1提成master,这一过程只需要修改slave2,而且完全不用去看slave1的任何状态。

CHANGE MASETR TO MASTER_HOST='172.25.3.103',MASTER_USER='repl',MASTER_PASSWORD='redhat',MASTER_AUTO_POSITION=1

start slave,
在slave1上插入数据。
这里写图片描述
由图可见,同步成功。十分方便,那么现在再考虑一个问题,如果master恢复了,让master从新成为主如何做呢?
当然还是先数据同步,之后再将MASTER切换成主,但因为有了MASTER_AUTO_POSITION=1,我们同步数据的时候都不需要去查看偏移了(具体原理还没有找到)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值