1.什么是主从复制

用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数据库一般是准实时的业务数据库

2.主从复制的作用

1、做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
2、架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
3、读写分离,使数据库能支撑更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。

3.主从复制原理(重点)

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

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

3.让其在从数据库的realylog重做日志文件再执行一次这些sql语句即可

下面的主从配置就是围绕这个原理配置,具体需要三个线程来操作

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

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

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

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

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

在这里插入图片描述

4.主从复制存在的一些问题

  1. 负载均衡,由于复制的时间差,不能保证同步读,而且写仍然单点,没法多点写,我对这个理解就是半吊子的读写均衡。
  2. 容灾,基本都是有损容灾,因为数据不同步,谁用谁知道,半吊子的容灾。

5.从数据库的读的延迟问题了解吗?如何解决?

原因:当主库的TPS并发较高时,产生的DDL数量超过slave一个sql线程所能承受的范围,那么延时就产生了,当然还有就是可能与slave的大型query语句产生了锁等待,还有网络延迟。

谈到MySQL数据库主从同步延迟原理,得从mysql的数据库主从复制原理说起,mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生binlog,binlog是顺序写,所以效率很高;slave的Slave_IO_Running线程会到主库取日志,效率会比较高,slave的Slave_SQL_Running线程将主库的DDL和DML操作都在slave实施。DML和DDL的IO操作是随机的,不是顺序的,因此成本会很高,还可能是slave上的其他查询产生lock争用,由于Slave_SQL_Running也是单线程的,所以一个DDL卡主了,需要执行10分钟,那么所有之后的DDL会等待这个DDL执行完才会继续执行,这就导致了延时。有朋友会问:“主库上那个相同的DDL也需要执行10分,为什么slave会延时?”,答案是master可以并发,Slave_SQL_Running线程却不可以。

常见原因:Master负载过高、Slave负载过高、网络延迟、机器性能太低、MySQL配置不合理。

解决办法:

(1)最简单的减少slave同步延时的方案就是在架构上做优化,尽量让主库的DDL快速执行。还有就是主库是写,对数据安全性较高,而slave则不需要这么高的数据安全,完全可以讲sync_binlog设置为0或者关闭binlog,innodb_flushlog也可以设置为0来提高sql的执行效率。另外就是使用比主库更好的硬件设备作为slave。

(2)数据放入缓存中,更新数据库后,在预期可能马上用到的情况下,主动刷新缓存->(Redis的角度)

(3)对于比较重要且必须实时的数据,比如用户刚换密码,所以在这种需要读取实时数据的时候最好从 Master 直接读取,避免 Slaves 数据滞后现象发生。

6.主服务器挂了怎么办?

Mysql主库宕机情况分类:

1.硬件问题,(服务器、ecs、虚拟主机等等)宕机

硬件问题我们可以查看IDC巡检记录,或通过远程控制卡查看硬件运行状态,根据事实情况就行硬件故障报修进行处理。

2.service问题,Mysql宕机,服务异常,端口异常等

1)首先要做的就是判断是否影响业务,是否需要切库,保证业务运行时首要任务

2)如果此时需要切从库,按照如下步骤进行:

1> 先查看MySQL 从库状态

**解决的思路:**在我看来都应该围绕bin log日志和从服务器上的relay log 等文件还有就是数据的备份。所以说做好数据备份才是王道,这样能最大程度上保证数据不会丢失。

7.读写分离的实现

为了减轻数据库的压力,一般会进行数据库的读写分离,

实现方法一是通过分析sql语句是insert/select/update/delete中的哪一种,从而对应选择主从。
二是通过拦截方法名称的方式来决定主从的,如:save*()、insert*() 形式的方法使用master库,select()开头的使用slave库。

虽然大多数都是从程序里直接实现读写分离的,但对于分布式的部署和水平和垂直分割,一些代理的类似中间件的软件还是挺实用的,如 MySQL Proxy比较。