文章目录
主从复制(replication)的工作原理
复制(replication)是MySQL数据库提供的一种高可用高性能的解决方案,一般用来建立大型的应用。总体来说,replication的工作原理分为以下3个步骤:1)主服务器(master)把数据更改记录到二进制日志(binlog)中。2)从服务器(slave)把主服务器的二进制日志复制到自己的中继日志(relaylog)中。3)从服务器重做中继日志中的日志,把更改应用到自己的数据库上,以达到数据的最终一致性。复制的工作原理并不复杂,其实就是一个完全备份加上二进制日志备份的还原。不同的是这个二进制日志的还原操作基本上实时在进行中。这里特别需要注意的是,复制不是完全实时地进行同步,而是异步实时。这中间存在主从服务器之间的执行延时,如果主服务器的压力很大,则可能导致主从服务器延时较大。
主从复制bin log 日志有几种记录方式,说说各自的优缺点
Replication之所以能够工作,主要还是归结于binlog(binary log),所以在 Replication 模式下必须开启binlog功能;slave从masters 上增量获取 binlog 信息,并在本地应用日志中的变更操作(即 “重放”)。变更操作将根据选定的格式类型写入binlog文件,目前支持三种format:statement-based Replication(SBR) :master将SQL statements语句写入binlog,slave 也将statements 复制到本地执行;简单而言,就是在 master 上执行的 SQL 变更语句,也同样在 slaves 上执行。SBR 模式是 MySQL 最早支持的类型,也是Replication默认类型。row-based Replication(RBR): master将每行数据的变更信息写入binlog,每条 binlog 信息表示一行(row)数据的变更内容,对于 slaves 而言将会复制 binlog 信息,然后单条或者批量执行变更操作;mix-format Replication:混合模式,在这种模式下,master将根据根据存储引擎、变更操作类型等,从SBR、RBR中来选择更合适的日志格式,默认为 SBR;具体选择那种格式,这取决于变更操作发生的存储引擎、statement 的类型以及特征,优先选择“数据一致性” 最好的方式(RBR),然后才兼顾性能,比如 statement 中含有 “不确定性” 方法或者批量变更,那么将选择RBR方式,其他的将选择 SBR 以减少binlog 的大小。我们建议使用mix方式。SBR 和 RBR 都有各自的优缺点,对于大部分用而言,mix 方式在兼顾数据完整性和性能方面是最佳的选择。
SBR的优点:
因为 binlog 中只写入了变更操作的statements,所以日志量将会很小;
当使用 SQL 语句批量更新、删除数据时,只需要在 binlog 中记录 statement 即可,可以大大减少log文件对磁盘的使用
当然这也意味着 slave 复制信息量也更少,以及通过binlog恢复数据更加快速;
SBR的缺点 :有些变更操作使用 SBR 方式会带来数据不一致的问题,一些结果具有不确定性的操作使用SBR将会引入数据不一致的问题。
statement 中如果使用了 UDF(User Defination Fuction),UDF 的计算结果可能依赖于SQL 执行的时机和系统变量,这可能在 slave 上执行的结果与 master 不同,此外如果使用了trigger,也会带来同样的问题;
statement 中如果使用了如下函数的(举例):UUID(),SYSDATE(),RAND() 等,不过NOW() 函数可以正确的被Replication(但在 UDF 或者触发器中则不行);这些函数的特点就是它们的值依赖于本地系统,RAND() 本身就是随机所以值是不确定的。如果 statement 中使用了上述函数,那么将会在日志中输出warning信息;
对于 “INSERT … SELECT” 语句,SBR 将比 RBR 需要更多的行锁。(主要是为了保障数据一致性,需要同时锁定受影响的所有的行,而RBR则不必要);
对于 InnoDB,使用 “AUTO_INCREMENT” 的 insert 语句,将会阻塞其他 “非冲突” 的INSERT。(因为AUTO_INCREMENT,为了避免并发导致的数据一致性问题,只能串行,但 RBR 则不需要);
对于复杂的SQL语句,在 slaves 上仍然需要评估(解析)然后才能执行,而对于RBR,SQL 语句只需要直接更新相应的行数据即可;在 slave 上评估、执行 SQL 时可能会发生错误,这种错误会随着时间的推移而不断累加,数据一致性的问题或许会不断增加。
RBR的优点:
所有的变更操作,都可以被正确的Replication,这事最安全的方式;
对于 “INSERT … SELECT”、包含 “AUTO_INCREMENT” 的 inserts、没有使用索引的UPDATE/DELETE,相对于SBR 将需要更少的行锁。(意味着并发能力更强);
RBR的缺点:
最大的缺点:就是 RBR 需要更多的日志量。任何数据变更操作都将被写入log,受影响的每行都要写入日志,日志包含此行所有列的值(即使没有值变更的列);因此RBR 的日志条数和尺寸都将会远大于SBR,特别是在批量的 UPDATE/DELETE 时,可能会产生巨大的 log 量,反而对性能带来影响,尽管这确实保障了数据一致性,确导致Replication的效率较低;
主从复制有几种方式?
异步复制
MySQL主从集群默认采用的是一种异步复制的机制。Master处理事务过程中,将其写入Binlog就会通知Dumpthread线程处理,然后完成事务的提交,不会关心是否成功发送到任意一个slave中。主服务在执行用户提交的事务后,写入binlog日志,然后就给客户端返回一个成功的响应了。而binlog会由一个dump线程异步发送给Slave从服务,由于这个发送binlog的过程是异步的。主服务在向客户端反馈执行结果时,是不知道binlog是否同步成功了的。这时候如果主服务宕机了,而从服务还没有备份到新执行的binlog,那就有可能会丢数据。
半同步复制
半同步复制机制是一种介于异步复制和全同步复制之前的机制。主库在执行完客户端提交的事务后,并不是立即返回客户端响应,而是等待至少一个从库接收并写到relay log中,才会返回给客户端。MySQL在等待确认时,默认会等10秒,如果超过10秒没有收到ack,就会降级成为异步复制。
这种半同步复制相比异步复制,能够有效的提高数据的安全性。但是这种安全性也不是绝对的,他只保证事务提交后的binlog至少传输到了一个从库,并且并不保证从库应用这个事务的binlog是成功的。另一方面,半同步复制机制也会造成一定程度的延迟,这个延迟时间最少是一个TCP/IP请求往返的时间。整个服务的性能是会有所下降的。而当从服务出现问题时,主服务需要等待的时间就会更长,要等到从服务的服务恢复或者请求超时才能给用户响应。
Master 处理事务过程中,提交完事务后,必须等至少一个Slave 将收到的binlog写入relaylog返回ack 才能继续执行处理用户的事务。相关配置rpl_semi_sync_master_wait_point=AFTER_COMMIT【这里MySQL5.5并没有这个配置,MySQL5.7 为了解决半同步的问题而设置的】rpl_semi_sync_master_wait_for_slave_count=1 (最低必须收到多少个slave的ack)rpl_semi_sync_master_timeout=100(等待ack的超时时间)
半同步复制需要基于特定的扩展模块来实现。mysql从5.5版本开始,往上的版本都默认自带了这个模块。这个模块包含在mysql安装目录下的lib/plugin目录下的semisync_master.so和semisync_slave.so两个文件中。需要在主服务上安装semisync_master模块,在从服务上安装semisync_slave模块。
增强半同步复制
增强半同步和半同步不同是,等待ACK时间不同rpl_semi_sync_master_wait_point=AFTER_SYNC(唯一区别)半同步的问题是因为等待ACK的点是Commit 之后,此时Master已经完成数据变更,用户已经可以看到最新数据,当Binlog 还未同步到Slave时,发生主从切换,那么此时从库是没有这个最新数据的,用户又看到老数据。增强半同步将等待ACK的点放在提交Commit 之前,此时数据还未被提交,外界看不到数据变更,此时如果发送主从切换,新库依然还是老数据,不存在数据不一致的问题。