复制的概述
复制是MySQL数据库提供的一种高可用高性能的解决方案,一般用来建立大型的应用。总体来说,replication的工作原理分为以下3个步骤:
- 主服务器(master)把数据更改记录到二进制日志(binlog)中。
- 从服务器(slave)把主服务器的二进制日志复制到自己的中继日志(relay log)中。
- 从服务器重做中继日志中的日志,把更改应用到自己的数据库上,以达到数据的最终一致性。
之前已经说过MySQL的复制是异步实时的,并非完全的主从同步,若用户要想得知当前的延迟,可以通过命令 SHOW SLAVE STATUS
和 SHOW MASTER STATUS
得知。因为slave的还原操作是单线程的,所以当master负载很大时,slave可能延迟增加。
复制的原理
1、master节点的Binlog dump Thread,当slave节点与master正常连接的时候,master把更新的binlog内容推送到slave节点。
2、slave节点的I/O Thread ,该线程通过读取master节点binlog日志名称以及偏移量信息将其拷贝到本地relay log日志文件。
3、slave节点的SQL Thread,该线程读取relay log日志信息,将在master节点上提交的事务在本地回放,达到与主库数据保持一致的目的。
一般复制出现延迟主要在两个方面:
1)SQL线程忙不过来(可能大事物操作数据量较大。可能和从库本身的一些操作有关,有锁和资源的冲突。主库可以并发写,SQL线程不可以。这些是主要原因。)
2)网络抖动导致IO线程复制延迟(次要原因)。
MySQL 5.6 开始支持针对每个database开启相应的独立线程。即每个库有一个单独的SQL thread,如果线上业务中只有一个database,则无意义。
MySQL 5.7 引入了新的机制来实现并行复制,不再有基于库的并行复制限制,主要思想就是slave服务器的回放与主机是一致的,即master服务器上是怎么并行执行,slave上就怎样进行并行回放。
基于行的复制与基于语句的复制
基于行的复制二进制日志采用ROW格式,基于语句的复制二进制日志采用STATEMENT格式。
发送复制事件到其他备库
一主库多备库(主从复制)
对于从数据库数据延迟的问题,对脏数据很敏感的请求可以直接读主数据库,也可以在应用层做标记,如果用户修改了某个内容,再次查询时就查询主数据库等。
读写分离
快照 + 复制的备份架构