mysql数据库主从


1、主从复制
前提是master上必须开启二进制日志

原理:
1)master 将数据更新记录到二进制日志文件中

2)slave 通过 I/O 线程向master请求二进制日志文件(要让 slave 知道请求的是哪个master以及位置)

3)master 接收到 slave 的 I/O 请求之后,就会从相应的位置点开始,给 slave 传日志

4)slave 接收到日志后,会写入本地的中继日志中

5)slave 通过 sql 线程读取中继日志中的内容,在数据库中执行相应的操作,使 slave 和 master 上的数据一致,而后 slave 服务器进入等待状态,等待master的后续更新

总结:两个线程,两个日志


2、主从延迟

  • 情况一: 从服务器配置过低导致延迟
    这类延迟场景的出现往往是主节点拥有较大规格的配置,而只读节点却购买了一个最小规格的配置。
    只读节点的数据为了和主节点保持同步,采用了MySQL binlog复制技术,由一个IO线程和一个SQL线程来完成,IO线程负责将主库的binlog拉取到只读节点,SQL线程负责消费这些binlog日志,这两个线程会消耗掉只读节点的IO资源,所以当只读节点IOPS配置不够的时候,则会导致只读节点的数据出现延迟。
    解决办法: 升级从服务器的配置,让只读节点的配置大于或者等于主节点的配置即可
  • 情况二: 主库的QPS过高导致只读节点延迟
    由于只读节点与主库的同步采用的是单线程同步,而主库的压力是并发多线程写入,这样势必会导致只读节点的数据延迟
    解决办法: 开启只读节点的并行复制 (mysql5.6.3以后支持多线程复制)
  • 情况三: 主库的DDL语句导致只读节点延迟
    可能1:只读节点与主库的DDL同步是串行进行的,如果DDL操作在主库执行时间很长,那么同样在备库也会消耗同样的时间.
    比如在主库对一张500W的表添加一个字段耗费了10分钟,那么在只读节点上也同样会耗费10分钟,所以只读节点会延迟600S
    可能2:只读节点上有一个执行时间非常长的的查询正在执行,那么这个查询会堵塞来自主库的DDL,读节点表被锁,直到查询结束为止,进而导致了只读节点的数据延迟。
    在只读节点上可以通过执行show processlist命令查看连接的状态处于: Waiting for table metadata lock
    解决办法: 对于可能1,只能说执行操作之前对可能带来的影响要有考量; 对于情况2,可以kill掉只读节点上的大查询进行,就可以恢复只读节点与主节点的数据同步
  • 情况四: 主库执行大事务导致延迟
    主库执行了一条insert … select非常大的插入操作,该操作产生了近几百G的binlog文件传输到只读节点,进而导致了只读节点出现应用binlog延迟。
    解决办法: 将大事务拆分成为小事务进行排量提交,这样只读节点就可以迅速的完成事务的执行,不会造成数据的延迟。
  • 情况五:无主键的表进行DML操作导致延迟
    如:mysql> update test set kk=‘fafa01’;
    由于表中没有主键,所以导致了每一个事务条目的更新都是全表扫描,如果表中很很多的数据,则备库执行该更新的事务条目的时候,就会出现很多的全表扫描更新;
    进一步说明就是,由于表中没有主键,在ROW模式下,每删一条数据都会做全表扫,也就是说一条delete,如果删了10条,会做10次全表扫,所以slave会一直卡住;
    解决办法: 每张表在设计的时候都加上一个主键。