龙空技术网

MySQL 主从复制,GTID主从复制、并行复制、半同步

奋发有为风铃jC 260

前言:

而今看官们对“mysql主从复制主备切换”大致比较关注,我们都想要分析一些“mysql主从复制主备切换”的相关内容。那么小编也在网络上搜集了一些关于“mysql主从复制主备切换””的相关资讯,希望看官们能喜欢,各位老铁们一起来学习一下吧!

主从复制

1.作用:

(1)做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。

(2)架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。

(3)读写分离,使数据库能支撑更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。

2.原理

1.数据库有个bin-log二进制文件,记录了所有sql语句。

2.我们的目标就是把主数据库的bin-log文件的sql语句复制过来。

3.让其在从数据的relay-log重做日志文件中再执行一次这些sql语句即可。

4.具体需要三个线程来操作:

(1)binlog输出线程:每当有从库连接到主库的时候,主库都会创建一个线程然后发送binlog内容到从库。

在从库里,当复制开始的时候,从库就会创建两个线程进行处理:

(2)从库I/O线程:当START SLAVE语句在从库开始执行之后,从库创建一个I/O线程,该线程连接到主库并请求主库发送binlog里面的更新记录到从库上。从库I/O线程读取主库的binlog输出线程发送的更新并拷贝这些更新到本地文件,其中包括relay log文件。

(3)从库的SQL线程:从库创建一个SQL线程,这个线程读取从库I/O线程写到relay log的更新事件并执行。

可以知道,对于每一个主从复制的连接,都有三个线程。拥有多个从库的主库为每一个连接到主库的从库创建一个binlog输出线程,每一个从库都有它自己的I/O线程和SQL线程。

实验环境: (selinux:disabled ;火墙:关闭)

mysql主机:server1 172.25.19.1

mysql从机:server2 172.25.19.2

一、mysql主从复制

Mysql复制特点:

1.异步复制:主节点中一个用户请求一个写操作时,主接点不需要把写的数据在本地操作完成同时发送给从服务器并等待从服务器反馈写入完成,在响应用户,主机点只需要把写入操作在本地完成,就响应用户。但是,从节点中的数据有可能会落后主服务

2.这种复制方法容易造成主从数据不一致。

默认情况下,MySQL的复制功能是异步的,异步复制可以提供最佳的性能, 主库把binlog日志发送给从库,这一动作就结束了,并不会验证从库是否接收完毕,这一过程,也就意味着有可能出现当主服务器或从服务器端发生故障的时候,有可能从服务器没有接收到主服务器发送过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢复时造成数据的丢失

3.设置主库复制

[root@server1 ~]# mysql -p

Enter password:

mysql> grant replication slave on *.* to repl@'172.25.19.%' identified by 'Redhat-1'; ##在主库上建立账户并授权;repl:master用户;172.25.19.% :这个网段的ip

mysql> show master status; ##查看主库状态。 二进制文件;pos号

[root@server1 ~]# cd /var/lib/mysql

[root@server1 mysql]# cat mysql-bin.index ##索引二进制日志文件

./mysql-bin.000001 ##这些里面记录了所有sql语句

./mysql-bin.000002

5.测试从库主机可登陆上主mysql

[root@server2 ~]# mysql -h 172.25.19.1 -u repl -p

Enter password:

Welcome to the MySQL monitor. Commands end with ; or \g.

6.设置从库复制主库(复制前必须保证主从库数据一致)

[root@server2 ~]# mysql -p

Enter password:

mysql> change master to master_host='172.25.19.1',master_user='repl',master_password='Redhat-1',master_log_file='mysql-bin.000002',master_log_pos=983;

##在从库上建立账户并授权。master主机ip;主从复制用户;用户密码;二进制文件;pos号

mysql> start slave; ###开启slave

mysql> show slave status\G ##查看slave状态

*************************** 1. row ***************************

Slave_IO_State:

Master_Host: 172.25.19.1 ##master

Master_User: repl ##主从复制用户

Master_Port: 3306 ##服务接口3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000002 ##二进制文件(哪个文件)

Read_Master_Log_Pos: 983 ##pos号(的哪个位置)

Relay_Log_File: server2-relay-bin.000001 ##复制到哪个文件

Relay_Log_Pos: 4 ##从这个文件的哪个位置开始输入

Relay_Master_Log_File: mysql-bin.000002

Slave_IO_Running: Yes ##当为No:IO连接错误

Slave_SQL_Running: Yes ##当为No:数据不一致

......

注:

当看到Slave_IO_Running: Yes以及Slave_SQL_Running: Yes,则表示slave库已经正常运行了

当出现Slave_IO_Running: Connecting的提示时,说明主库和从库没有连接上,有以下三点原因:

二、GTID主从复制(mysql5.6以后版本可用)

GTID是一个基于原始mysql服务器生成的一个已经被成功执行的全局事务ID,它由服务器ID以及事务ID组合而成。这个全局事务ID不仅仅在原始服务器器上唯一,在所有存在主从关系 的mysql服务器上也是唯一的。正是因为这样一个特性使得mysql的主从复制变得更加简单,以及数据库一致性更可靠。

GTID的优势:

1)更简单的实现failover,不用以前那样在需要找log_file和log_pos;

2)更简单的搭建主从复制;

3)比传统的复制更加安全;

4)GTID是连续的没有空洞的,保证数据的一致性,零丢失。

GTID的工作原理:

1)当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中;

2)binlog传输到slave,并存储到slave的relaylog后,读取这个GTID的这个值设置gtid_next变量,即告诉Slave,下一个要执行的GTID值;

3)sql线程从relay log中获取GTID,然后对比slave端的binlog是否有该GTID;

4)如果有记录,说明该GTID的事务已经执行,slave会忽略;

5)如果没有记录,slave就会执行该GTID事务,并记录该GTID到自身的binlog,在读取执行事务前会先检查其他session持有该GTID,确保不被重复执行;

6)在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。

1.全局id=uuid+单调递增的传输id

[root@server1 mysql]# cat auto.cnf ##查看uuid

[auto]

server-uuid=3472d0a6-1980-11e9-b8d1-525400963735

[root@server1 mysql]# mysqlbinlog mysql-bin.000002 ##专门可看二进制文件的工具

2.主数据库配置

[root@server1 mysql]# vim /etc/my.cnf

加入:

[root@server1 mysql]# systemctl restart mysqld

3.从数据库配置

[root@server2 mysql]# vim /etc/my.cnf

加入:

[root@server2 mysql]# systemctl restart mysqld

注:也可用下面这种方法临时配置:

mysql> stop slave;

mysql> change master to master_host='172.25.19.1', master_user='repl', master_password='Redhat-1', master_auto_position=1; ###自动更新master_log_file和pos

mysql> start slave;

三、并行复制

1.为什么需要并行复制:

一般主从复制,有三个线程参与,都是单线程:Binlog Dump(主) —–>IO Thread (从) —–> SQL Thread(从)。复制出现延迟一般出在两个地方

1)SQL线程忙不过来(可能需要应用数据量较大,可能和从库本身的一些操作有锁和资源的冲突;主库可以并发写,SQL线程不可以:主要原因)

2)网络抖动导致IO线程复制延迟(次要原因)。

2.什么是并行复制:多线程复制

多线程的思路就是把sql_thread 变成分发线程,然后由一组worker_thread来负责执行。

1)MySQL从5.6开始有了SQL Thread多个的概念,可以并发还原数据,即并行复制技术。

2)在MySQL 5.7中,引入了基于组提交的并行复制(Enhanced Multi-threaded Slaves)

四、半同步 + 无限大超时间(生产中用)

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。

(1)MySQL 5.5 引入了一种半同步复制模式。该模式可以确保从服务器接收完主服务器发送的binlog日志文件并写入到自己的中继日志relay log里,然后会给主服务器一个反馈,告诉主服务器已经接收完毕,这时主服务线程才返回给当前session告知操作完成。

(2)当出现超时情况是,主服务器会暂时切换到异步复制模式,直到至少有一个从服务器从及时收到信息为止。

(3)中继日志的自我修复:

从MySQL 5.5.X 版本开始,增加了relay_log_recovery参数,这个参数的作用是:当slave从库宕机后,假如relay.log损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的relay-log,并且重新从master上获取日志,这样就保证了relay-log的完整性。默认情况下该功能是关闭的,将relay_log_recovery的值设置为1时,可在slave从库上开启该功能,建议开启。

(4)半同步复制与异步复制的切换:

半同步复制的工作原理就是当slave从库IO_Thread线程将binlog日志接收完毕之后,要给master主库一个确认,如果rpl_semi_sync_master_timeout=10000 (10秒)超过10秒未收到slave从库的接受确认信号,那么就会自动切换为传统的异步复制模式。

标签: #mysql主从复制主备切换