1. MySQL数据复制的原理
mysql复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新、删除等等)。因此,要进行复制,必须在主服务器上启用二进制日志。每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,并在本机上执行相同的更新。然后封锁并等待主服务器通知新的更新。从服务器执行备份不会干扰主服务器,在备份过程中主服务器可以继续处理更新。
mysql使用3个线程来执行复制功能(其中1个在主服务器上,另两个在从服务器上)。当发出start slave时,从服务器创建一个I/O线程,以连接主服务器并让它发送记录在其二进制日志中的语句。主服务器创建一个线程将二进制日志中的内容发送到从服务器。该线程可以即为主服务器上show processlist输出中的Binlog Dump线程。从服务器I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到从服务器数据目录中的本地文件中,即中继日志。第3个线程是sql线程,由从服务器创建,用于读取中继日志并执行日志中包含的更新。在从服务器上,读取和执行更新语句被分成两个独立的任务。当从服务器启动时,其I/O线程可以很快地从主服务器索取所有二进制日志内容。
2. 分类
全同步复制(Fully synchronous replication)
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能会受到影响。
异步复制(Asynchronous replication)
MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主库如果crash掉了,此时主库上已经提交的事务可能并没有传到从库上,如果此时,强行将从库提升为主库,可能导致新主库上的数据不完整。
半同步复制(Semisynchronous replication)
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
3. 配置方法
主要配置思路为:
(1)异步复制
主库:首先更改主库MySQL配置文件,开启二进制日志,配置主服务器id号(唯一);然后在主服务器上为从服务器创建一个用来连接主服务器的用户,并设置replication slave权限;导出主服务器数据,以备之后将其导入从服务器,使主从服务器的初始状态保持一致。
从库:首先修改从库MySQL配置文件,开启中继日志,配置库服务器id号(唯一);然后导入主库数据。
重启所有库,从服务器配置主服务器数据并开启复制功能,检验从服务器俩线程是否保持YES状态即可。
(2)全同步复制
使用MyISAM或者InnoDB存储引擎的MySQL本身并不支持同步复制,可以使用分布式复制块设备(简称DRBD)在下层的文件系统提供同步复制。
(3)半同步复制
MySQL5.4版本及更低版本需要在主从服务器上安装插件才能实现半同步复制,而5.5版本提供了接口实现半同步复制机制,更在5.6版本进行了优化和改进:更加简单的配置与多库多线程(了解更多:传送门)。
(4)主主复制
顾名思义服务器之间互为主从,具体实现不再赘述。
4. 应用场景
使用数据库主从复制主要是来降低数据库压力的,主库负责写操作,而从库负责读操作(需要将从库设置为只读防止从库更改数据),以此来实现读写分离,一旦主库崩溃还可以使用其他从库作为主库使用。一般搭配Nginx或Dubbo实现负载均衡,Dubbo偏向于服务层面而Nginx偏向于Http层面,可以使用IP_Hash,轮询,随机,加权平均等算法来实现,在此不做过多讨论。如果流量过大还可以搭配分库分表使用。