mysql 主从复制_mysql主从复制

MySQL Replication是一个异步复制过程,用于将Master数据库的数据复制到Slave数据库,以实现数据备份、主从热备和集群。复制过程涉及Master的IO和Sql进程以及Slave的IO和Sql进程,依赖于Master的bin-log。复制级别有Statement、Row和Mixed,各有利弊。配置包括在Master和Slave上启用二进制日志,设置server-id,授权和配置从服务器连接信息。
摘要由CSDN通过智能技术生成

MySQL Replication浅析

MySQL Replication是MySQL非常出色的一个功能,该功能将一个MySQL实例中的数据复制到另一个MySQL实例中。整个过程是异步进行的,但由于其高效的性能设计,复制的延时非常小。MySQL复制功能在实际的应用场景中被广泛的应用于保证数据系统数据的安全性和可扩展设计中。

1、MySQL Replication功能的意义

互联网应用系统中,一个设计恰当的WEB应用服务器在绝大多数情况下都是无状态的(Session除外,Session共享可通过WEB容器解决),故WEB应用服务器的扩展和集群相对简单。但数据库的集群和复制就不那么容易了。各个数据库厂商也一直在努力使自己的产品能够像WEB应用服务器一样能够方便的复制和集群。

MySQLReplication的出现使我们能够非常方便将某一数据库中的数据复制到多台服务器中,从而实现数据备份、主从热备、数据库集群等功能。这样有效的提高了数据库的处理能力,提高了数据安全性等。

2、MySQLReplication实现原理

MySQL的复制(replication)是一个异步的复制,从一个MySQLinstace(称之为Master)复制到另一个MySQLinstance(称之Slave)。整个复制操作主要由三个进程完成的,其中两个进程在Slave(Sql进程和IO进程),另外一个进程在Master(IO进程)上。

要实施复制,首先必须打开Master端的binarylog(bin-log)功能,否则无法实现。因为整个复制过程实际上就是Slave从Master端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。复制的基本过程如下:

(1)Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;

(2)Master接收到来自Slave的IO进程的请求后,通过负责复制的IO进程根据请求信息读取指定日志指定位置之后的日志信息,返回给Slave的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置;

(3)Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log的某个位置开始往后的日志内容,请发给我”;

(4)Slave的Sql进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的内容,并在自身执行。

3、复制实现级别

MySQL的复制有三种模式:Statement Level、Row Level、Mixed Level。复制级别的不同,会导致Master端二进制日志文件的生成形式的不同。

3.1 Statement Level复制

该模式是最早的复制模式,主要的流程是Master端将每一条会修改数据的Query记录下来,Slave端在复制的时候会根据二进制文件重新执行相同的Query。这种模式的优点是Master端不需要记录每一行数据的变化,二进制日志文件量小,IO成本低,速度快。

相应的,该模式存在的缺点如下:由于记录的是执行语句,就需要额外的知道每条语句执行的上下文信息,以保证该相同的操作在Slave端执行时能够得到和Master同样的结果。但由于MySQL功能的不断增多,这种复制模式需要考虑的情况也就越来越多,出现bug的几率也就也大。从MySQL 5.0开始,MySQL复制解决了大量的之前版本中出现的无法复制或复制错误的问题,但随着MySQL的发展,这种挑战将会日趋严峻。

3.2 Row Level复制

MySQL开发人员意识到Statement Level存在的问题,于5.1.5开始提供Row Level模式。该模式的主要流程是,MySQL二级制日志文件会将每一行数据修改都记录下来,然后在Slave端进行同样的修改。这种模式的优点是:日志文件不会将SQL语句执行的上下文记录下来,只是记录哪一条数据修改了,修改成什么样子了;这样做可以避免如某些特定情况下存储过程、trigger的调用和触发没有被正确执行等复制问题。

同样,该模式也存在缺点:日质量的成倍增加。例如:执行alter table之类的语句的时候,由于表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中。这样就大增加了复制过程的IO成本,导致速度下降、性能下降。

3.3 Mixed Level复制

MySQL从5.1.8开始,提供Mixed Level。该模式结合了之前两种模式的优点,规避了二者的缺点。在该模式下,MySQL会根据执行的每一条语句来区分记录日志文件的格式。举例说明,当涉及到复杂的存储过程时,采用Row Level,规避Statement Level存在的某些场景无法复制的问题;当涉及到Alter table等操作时,采用Statement Level来规避Row Level带来的日志量巨大的问题。

4、MySQL Replication详细配置

4.1 环境介绍

4.1.1 Master环境介绍

1)操作系统:CentOS Linux release 7.6.1810 (Core)

2)Mysql版本:5.7.27 (CentOS )

3)IP:47.**.***.**

4.1.2 Slave环境介绍:

1)操作系统:CentOS Linux release 7.2.1511 (Core)

2)Mysql版本:5.7.26 (CentOS )

3)P:47.**.***.**

4.2 配置

4.2.1 Master配置

1)my.cnf配置

代码:# vi /etc/my.cnf

e72f5f8ed8be230a7f96d94f2a1a12c5.png

加入如下三行代码:

[mysqld]

log-bin=mysql-bin   //[必须]启用二进制日志,将mysql二进制日志取名为mysql-bin

binlog_format=mixed //二进制日志的格式,有三种:statement/row/mixed,具体分别不多做解释,这里使用mixed

server-id=101       //[必须]服务器唯一ID,默认是1,一般取IP最后一段

配置完成,:wq 保存,重启mysql

重启mysql命令:# service mysqld restart

同样的,进入从服务器,配置从服务器的my.cnf,重复步骤1即可,

唯一的区别是,server-id要改成从服务器的ip尾位,即server-id=101;其他两项是一样的,保存,并重启mySQL

2)重启mysql

sudo /etc/init.d/mysql restar

3)在主服务器上建立帐户并授权slave

在主服务器上为从服务器分配一个账号,就像一把钥匙,从服务器拿着这个钥匙,才能到主服务器上来共享主服务器的日志文件。

进入主服务器的mysql界面,

命令: # mysql -u root -p 111111     //我这里mysql账号是root,密码是111111

在mysql操作界面下,输入下面一行命令:

mysql>GRANT REPLICATION SLAVE ON *.* to 'mysync'@'%' IDENTIFIED BY'123456';

//一般不用root帐号,“%”表示所有客户端都可能连,只要帐号,密码正确,

211d3e06f92a6b24bcc353c8b2546a00.png

4) 登录mysql,查询master的状态

查看主服务器BIN日志的信息(执行完之后记录下这两值,然后在配置完从服务器之前不要对主服务器进行任何操作,因为每次操作数据库时这两值会发生改变)

mysql>show master status;

45e64db2916c0178361980657d1b651b.png

注:执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化。

4.2.2 Slave配置

1)my.cnf配置

#vi /etc/mysql/my.cnf

[mysqld]

log-bin=mysql-bin   //[必须]启用二进制日志

server-id=57       //[必须]服务器唯一ID,默认是1,一般取IP最后一段

关闭slave(如果你以前配置过主从的话,一定要先关闭)

命令:stop slave;

2)重启mysql

3)配置从服务器Slave:

开始配置:

输入下面代码即可:

97f7178fe5cf20459e24345c86904e8a.png

mysql>change master to master_host='192.168.245.140',master_user='mysync',master_password='123456',master_log_file='mysql-bin.000004',master_log_pos=308;   //注意不要断开,“248”无单引号。

参数解释:MASTER_HOST  :  设置要连接的主服务器的ip地址

MASTER_USER  :  设置要连接的主服务器的用户名

MASTER_PASSWORD  :  设置要连接的主服务器的密码

MASTER_LOG_FILE  :  设置要连接的主服务器的bin日志的日志名称,即第3步得到的信息

MASTER_LOG_POS  :  设置要连接的主服务器的bin日志的记录位置,即第3步得到的信息,(这里注意,最后一项不需要加引号。否则配置失败)

mysql>start slave;    //启动从服务器复制功能

4) 检查从服务器复制功能状态及否配置成功:

mysql> show slave status\G

c2b1eb43fd081b82766da2270e44745e.png

注:Slave_IO及Slave_SQL进程必须正常运行,即YES状态,否则都是错误的状态。

MySQL数据同步,出现Slave_SQL_Running:no和slave_io_running:no问题的解决方法

mysql replication 中slave机器上有两个关键的进程,死一个都不行,一个是slave_sql_running,一个是Slave_IO_Running,一个负责与主机的io通信,一个负责自己的slave mysql进程。

如果是Slave_SQL_Running:no:

f4b514960209ce3519f7be08ef57ee02.png

解决办法如下:

> stop slave;

> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE;

> stop slave;

> show slave status\G

如果是slave_io_running:no

97265cb999ef410772eb3cf98f18b846.png

解决办法如下:

1、查看主服务器

> show master status\G

9f71ea2b4fd1f84abcb239dd6005a449.png

2、在从服务器上查看

520291acefbe79950dfe93ee0112a6b9.png

问题所在:发现Master_Log_File没有对应。

3、出现Slave_IO_Running: No的机器上操作

> stop slave;

>CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000026', MASTER_LOG_POS=0;

> start slave;

> show slave status\G

4.3 主从服务器测试

主服务器Mysql,建立数据库,并在这个库中建表插入一条数据,观看从库是否也增加了相应的数据库、数据表、数据。

5、MySQL Replication常用架构总结

5.1 主从备份架构设计

3152be0b11881fa24be224337d3b885d.png

简述:两台mysql服务器如果其中有一台mysql服务器挂掉后,另外一台能立马接替其进行工作。因此我们就必须保证两台mysql数据库的数据完全一样,而且当挂掉的那一台重新启动的话,不再会被客户端继被访问,而是会充当备机跟现在工作的mysql进行数据同步,一直到提供服务的那台挂掉后再接替其工作。如此周而复始的实现了mysql的高可用。注意:Slave不对外提供服务;Slave和Master在同一个局域网内,以此保证主从复制的速度和连接的稳定性。

5.2 主主备份架构设计A

5405ac42c92fd86dbc6b88811dbc2551.png

简述:Mysql主主备份架构A——两台服务器互为主备,即A写的数据可以同步到B中去,B写的数据可以同步到A中去。代理服务器负责对读写进行负载均衡。

缺点:自增主键的冲突问题无法解决;写操作频繁时,会导致并发问题。

适用场景:写操作不多;无自增主键;主、备机同时承担读写任务,节省机器,适用于机器紧张的场景。

5.3 主主备份架构设计B

e78fdfb7920f86209d0754ab43399152.png

Mysql主主备份架构B——两台服务器互为主备,即A写的数据可以同步到B中去,B写的数据可以同步到A中去。但是,应用服务器通过keepalived只向Master(即其中之一)进行写入操作,代理服务器负责对读操作进行负载均衡。

缺点:需要额外解决读写分离的问题

优点:不需要额外的脚本控制主备角色转换;数据一致性保证

主从复制存在的问题以及解决办法

主库宕机之后,数据可能会丢失

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

解决方法:

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

并行复制--解决从库复制延时的问题

MySQL 5.7并行复制

此配置只在slave上进行

在进行以下配置之前首先可以通过一条命令看一下结果(得到的结果条目很少):

mysql> show processlist;

然后配置vim /etc/my.cnf

#添加以下内容(前面的配置继续保留):

slave-parallel-type=LOGICAL_CLOCK

slave-parallel-workers=16

master_info_repository=TABLE

relay_log_info_repository=TABLE

relay_log_recovery=ON

master_info_repository解释

开启MTS功能后,务必将参数master_info_repostitory设置为TABLE,这样性能可以有50%~80%的提升。这是因为并行复制开启后对于元master.info这个文件的更新将会大幅提升,资源的竞争也会变大。在之前InnoSQL的版本中,添加了参数来控制刷新master.info这个文件的频率,甚至可以不刷新这个文件。因为刷新这个文件是没有必要的,即根据master-info.log这个文件恢复本身就是不可靠的。在MySQL 5.7中,Inside君推荐将master_info_repository设置为TABLE,来减小这部分的开销。

slave_parallel_workers解释

若将slave_parallel_workers设置为0,则MySQL 5.7退化为原单线程复制,但将slave_parallel_workers设置为1,则SQL线程功能转化为coordinator线程,但是只有1个worker线程进行回放,也是单线程复制。然而,这两种性能却又有一些的区别,因为多了一次coordinator线程的转发,因此slave_parallel_workers=1的性能反而比0还要差

重启mysql服务,然后再次执行:

mysql> show processlist;

b4176008ee3332033673b2b65502cbb7.png

结果增加了16条,就是配置slave-parallel-workers=16的作用,也就是开启了并行复制的结果。

mysql半同步

半同步复制简介

何为半同步复制模式呢?在此我们先了解异步复制模式,这是MySQL的默认复制选项。异步复制即是master数据库把binlog日志发送给slave数据库,然后就没有了然后了。在此暴露一个问题,当slave服务器发生故障了,那么肯定会导致主从数据库服务器的数据不一致。

为了解决上面的问题,MySQL5.5引入一种叫做半同步复制模式。开启这种模式,可以保证slave数据库接收完master数据库发送过来的binlog日志并写入自己的中继日志中,然后反馈给master数据库,告知已经复制完毕。

开启这种模式后,当出现超时,主数据库将会自动转为异步复制模式,直到至少有一台从服务器接受到主数据库的binlog,并且反馈给主数据库。这时主数据库才会切换回半同步复制模式。

mysql> show variables like ‘have_dynamic_loading’;

#确保value为YES

c4f15c646a7c568a2b01b02275904c3c.png

注意:半同步复制模式必须在主服务器和从服务器同时中开启,否则将会默认为异步复制模式。

半同步复制需要安装插件,而插件的位置如下:

cd7061ddced0b87243dc9022d9f3561c.png

master上安装插件

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';

mysql> set global rpl_semi_sync_master_enabled=ON;

75ca246b61c14cb17356939a0a2b74cc.png

slave上安装插件

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

mysql> set global rpl_semi_sync_slave_enabled=ON;

mysql> show variables like '%semi%';

03e7f8afe98b7a24e9f35dc3fc783a78.png

测试:首先在master上查看以下参数:

d6936883cab4abb26ffa05db8672d64b.png

然后slave上关闭io_thread

mysql> stop slave io_thread;

然后在master上执行数据库操作,比如插入等,结果就是操作会等待10s返回结果,这时候退回异步复制,slave上没有接收到数据,这时候我们去查看master上的相关状态,此时插入数据会有一个10s的timeout,所以会卡顿一会,有些参数的值也变了

8f530d8b91846ebcfb576ae34d3e57f7.png

show status like ‘%rpl_semi_sync%’;

会发现部分参数的值改变了(Rpl_semi_sync_master_clients、Rpl_semi_sync_master_no_tx等)

然后我们开启 slave的io_thread再去查看数据库的变化,发现数据同步了

mysql> start slave io_thread;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值