MySQL/MariaDB数据库的半同步复制
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.MySQL半同步复制概述
1>.MySQL默认的异步复制
默认情况下,MySQL的复制功能是异步的,异步复制可以提供最佳的性能,主库把binlog日志发送给从库即结束,并不验证从库是否接收完毕。
这意味着当主服务器或从服务器端发生故障时,有可能从服务器没有接收到主服务器发送过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢复时造成数据的丢失的风险。
2>.MySQL的半同步复制
为了方便说明,我画了一个草图,如下图所示:
我们模拟在生产环境中半同步复制的场景,正如我图中所示,现在的MySQL架构是一主两从的架构。当用户访问数据库的流程大致如下:
1>.用户通过调度器访问到master节点,要求进行写操作,如果只是读操作起始也可以请求到任意一台slave节点;
2>.当master节点完成客户端提交的事务后,并不会立即响应客户端,而是需要等待它的两个从节点中的任意一个节点完成信息同步;
3>.当slave节点中任意一个节点数据和master数据同步后,master节点就立即响应客户端说操作执行成功,而不会等待另一个节点也同步完成。
温馨提示:
在某种特殊的场景下,复制过程可能需要较长时间,如果在规定时间内(这个时间有咱们根据业务需求来自定义),所有的slave节点都无法完成数据库同步,其实master也会返回给客户端执行完毕。
如果真有这种情况发生,这就意味着只有主库的数据是准确的,因为没有任何一个从节点数据是准确的!这个时候我们就会意识到一个道理,主从复制并不能代替备份!因此当我们做了主从复制时,千万要记得备份master节点数据啊!(不仅如此,二进制日志也是相当重要的,强烈建议和数据文件分开存放)这样即使当master节点挂掉我们也可以通过它的二进制日志配合slave节点快速手动完成数据同步。
3>.半同步复制的应用场景
通过上面的分析,我们已经对半同步复制的原理有所了解,它不确保所有数据库都同步,它只需要确定有任意一台slave节点和master节点数据同步即可。
那这种模式的应用场景在哪呢?
我们应该从它的优点和缺点进行分析,然后选择合适的场景。
优点:当master挂掉后,我们可以从一个之前和master同步数据的slave节点快速恢复生产环境使用,这个过程不需要太多时间,因为我们知道有一台slave节点数据和master是同步的。
缺点:当master完成客户端提交的事务后,此时需要等待slave节点同步数据,这个过程会降低mysql的性能,因为master节点已经完成了任务,等待slave同步的过程用户也是需要承担的。
综上分析,我个人决定它适合使用在对数据可靠性较高的且对MySQL的延迟时间可以忍受的场景。
二.半同步复制实战案例
1>.试验环境说明
半同步复制概述: 当主库执行一个更新操作事物时,提交操作会被阻止直到至少有一个半同步的复制slave确认依据接收到本次更新操作,主库的提交操作才会继续。 半同步复制的slave发送确认消息只会在本次更新操作已经记录到本地的relay log之后 如果没有任何slave发送确认消息而导致超时时,半同步复制会转换成异步复制。 半同步复制会对MySQL性能产生影响,因为主库的提交动作只有在收到至少一个从库的确认消息之后才能执行。但这个功能是性能和数据可靠性方面的权衡。 需要开启的系统参数包括: rpl_semi_sync_master_enabled:在主库配置,确保主库的半同步复制功能开启。 rpl_semi_sync_master_timeout:配置主库等待多少毫秒时间来保证接收备库的确认消息,当超时这个时间时,半同步变成异步方式。 rpl_semi_sync_slave_enabled:在从库配置,确保从库的半同步复制功能开启。 半同步复制是通过插件的方式建立,要分别在主库和从库安装一个插件半同步复制的前提条件: MySQL 5.5版本及以上。 have_dynamic_loading参数必须是YES代表可以安装插件并动态加载。 实现建立好异步复制关系
相关插件安装文件会在plugin_dir文件夹下,并以semisync_master和semisync_slave名称开头。下面是本次试验角色分配: node102.yinzhengjie.org.cn : master节点 node103.yinzhengjie.org.cn : slave节点 node104.yinzhengjie.org.cn : slave节点
2>.配置node102.yinzhengjie.org.cn节点与其它两个节点主从复制
[root@node102.yinzhengjie.org.cn ~]# cat /etc/my.cnf [mysqld] server-id = 102 binlog_format = row log_bin = /data/mysql/logbin/master-102 character-set-server = utf8mb4 default_storage_engine = InnoDB datadir = /var/lib/mysql socket = /var/lib/mysql/mysql.sock [mysqld_safe] log-error = /var/log/mariadb/mariadb.log pid-file = /var/run/mariadb/mariadb.pid !includedir /etc/my.cnf.d [root@node102.yinzhengjie.org.cn ~]#