欢迎来到HugNew-拥抱变化,扫一扫右边二维码关注微信订阅号:Martin说 或 加QQ群:427697041互相交流,Stay hungry, Stay foolish.

Mysql半复制浅谈

mysql Martin 3118℃ 1评论

简介

先简单介绍下介绍下Mysql异步复制、同步复制、半同步复制的概念

  异步复制

MySQL本身支持单向的、异步的复制。异步复制意味着在把数据从一台机器拷贝到另一台机器时有一个延时 – 最重要的是这意味着当应用系统的事务提交已经确认时数据并不能在同一时刻拷贝/应用到从机。通常这个延时是由网络带宽、资源可用性和系统负载决定的。然而,使用正确的组件并且调优,复制能做到接近瞬时完成。
当主库有更新的时候,主库会把更新操作的SQL写入二进制日志(Bin log),并维护一个二进制日志文件的索引,以便于日志文件轮回(Rotate)。在从库启动异步复制的时候,从库会开启两个I/O线程,其中一个线程连接主库,要求主库把二进制日志的变化部分传给从库,并把传回的日志写入本地磁盘。另一个线程则负责读取本地写入的二进制日志,并在本地执行,以反映出这种变化。较老的版本在复制的时候只启用一个I/O线程,实现这两部分的功能。

同步复制

同步复制可以定义为数据在同一时刻被提交到一台或多台机器,通常这是通过众所周知的“两阶段提交”做到的。虽然这确实给你在多系统中保持一致性,但也由于增加了额外的消息交换而造成性能下降。
使用MyISAM或者InnoDB存储引擎的MySQL本身并不支持同步复制,然而有些技术,例如分布式复制块设备(简称DRBD),可以在下层的文件系统提供同步复制,允许第二个MySQL服务器在主服务器丢失的情况下接管(使用第二服务器的复本)。

半同步复制

MYSQL 5.5开始,支持半自动复制。之前版本的MySQL Replication都是异步(asynchronous)的,主库在执行完一些事务后,是不会管备库的进度的。如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),这时备库中的数据就是不完整的。简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了。
MySQL复制默认情况下是异步的。Semisynchronous Replication(半同步复制)则一定程度上保证提交的事务已经传给了至少一个备库。半同步复制中,仅仅保证事务的已经传递到备库上,但是并不确保已经在备库上执行完成了,如果master在完成事务并将其发送给slave的时候崩溃,仍然可能造成数据丢失。只是相比于传统的异步复制,semi-synchronous replication能极大地提升数据安全。更为重要的是,它并不慢,MHA的作者都说他们在facebook的生产环境中使用了semi-synchronous(这里),所以我觉得真心没必要担心它的性能问题,除非你的业务量级已经完全超越了facebook或者google。在这篇文章里面已经提到,MySQL 5.7之后已经使用了Loss-Less Semi-Synchronous replication,所以丢数据的概率已经很小了。
工作原理:
  1. 从库连接主库时指明时从库否有半同步能力
  2. 主库启动半同步复制且至少有一个半同步从库,主库线程执行事务提交之后将会阻塞直到任一半同步从库确认接收到该事务的所有事件或者超时
  3. 从库确认接收到事务的所有事件之后写入到中继日志并刷新到磁盘
  4. 如果超时没有任何从库确认事务,主库恢复到异步复制,保障业务的正常使用,直到一台从库追赶上之后,继续切换到半同步模式
  5. 半同步复制必须主从两端同时启用,如任意一端禁止将使用异步复制
当主库被阻塞时(已经提交的事务等待从从库确认),不会向执行事务的session返回信息;当主库阻塞结束后,返回session执行结果。此时,主库事务已提交,至少一台从库确认接收到事务。如果主备网络故障或者从库崩溃,主库在事务提交后等待10秒(rpl_semi_sync_master_timeout默认值)后,主从复制将自动降级为异步模式。     半同步复制确实有一定的性能影响,因为需要等待的从库确认。这是对增加数据的完整性的折衷。
半同步复制是通过plugin实现的,master和slave使用不同的plugin。默认情况下没有安装该plugin,插件位于CMAKE_INSTALL_PREFIX/lib/plugin/。安装完插件之后,还需要手动设置系统参数以开启半同步复制模式。

配置

1.查看插件路径

mysql> show variables like "%plugin_dir%";
+---------------+-------------------------------+
| Variable_name | Value                         |
+---------------+-------------------------------+
| plugin_dir    |  /usr/local/mysql/lib/plugin  |
+---------------+-------------------------------+
1 row in set (0.00 sec)

2.查看半同步复制插件

######查看半同步插件
ls /usr/local/mysql/lib/plugin
semisync_master.so     #用于Master服务器安装的半同步插件
semisync_slave.so      #用于Slave服务器安装的半同步插件

3.Master与Slave服务器分别安装半同步插件

######在Master服务器安装半同步插件
[root@master ~]# mysql
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; #安装Master半同步插件
mysql> set global rpl_semi_sync_master_enabled = 1;    #开启Master半同步功能
mysql> set global rpl_semi_sync_master_timeout = 1000;
=========================================================================
######在Slave服务器安装半同步插件
[root@slave ~]# mysql
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; #安装Slave半同步插件
mysql> set global rpl_semi_sync_slave_enabled = 1;      #开启Slave半同步功能
mysql> stop slave io_thread;start slave io_thread;      #重启IO线程生效
也可以修改配置文件/etc/my.cnf使半同步永久生效,改完之后记得重启下mysqld服务
主机:
[root@master ~]# vim /etc/my.cnf
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000
从机:
[root@slave ~]# vim /etc/my.cnf
rpl_semi_sync_slave_enabled=1

4.查看半同步开启状态

######在Master服务器上查看
mysql> show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     | # 有多少slave设置了半同步模式
| Rpl_semi_sync_master_net_avg_wait_time     | 0     | # 事务提交后,等待备库响应的平均时间
| Rpl_semi_sync_master_net_wait_time         | 0     | # 网络响应等待的总时间
| Rpl_semi_sync_master_net_waits             | 0     | # 网络等待总次数
| Rpl_semi_sync_master_no_times              | 0     | # 一共有几次从Semi-sync跌回普通状态
| Rpl_semi_sync_master_no_tx                 | 0     | # 备库未及时响应的事务次数
| Rpl_semi_sync_master_status                | ON    | #表示当前是异步模式还是半同步模式,on为半同步
| Rpl_semi_sync_master_timefunc_failures     | 0     | # 时间函数未正常工作的次数
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     | # 开启Semi-sync,事务返回需要等待的平均时间
| Rpl_semi_sync_master_tx_wait_time          | 0     | # 事务等待备库响应的总时间
| Rpl_semi_sync_master_tx_waits              | 0     | # 事务等待备库响应的总次数
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     | # 改变当前等待事务记录最小二进制日志的次数
| Rpl_semi_sync_master_wait_sessions         | 0     | # 当前有几个线程在等待备库响应
| Rpl_semi_sync_master_yes_tx                | 0     | # 备库成功响应的事务次数
+--------------------------------------------+-------+
mysql> show global variables like '%rpl%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_recovery_rank                  | 0     |
| rpl_semi_sync_master_enabled       | ON    | # 是否启动半同步复制,默认关闭
| rpl_semi_sync_master_timeout       | 1000  | # 等待从服务器告诉接受到的超时时间,如果时间到了,还没接受到,自动降级为异步
| rpl_semi_sync_master_trace_level   | 32    | # 运行级别
| rpl_semi_sync_master_wait_no_slave | ON    | # 没有slave的时候是否也需要等待,默认为也需要等待
+------------------------------------+-------+
=========================================================================
######在Slave服务器上查看
mysql> show global status like 'rpl_semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |         #已经为开启状态
+----------------------------+-------+
mysql> show global variables like '%rpl%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_recovery_rank               | 0     |
| rpl_semi_sync_slave_enabled     | ON    |    # 是否启动半同步复制,默认关闭
| rpl_semi_sync_slave_trace_level | 32    |    # 运行级别
+---------------------------------+-------+

5.查看Slave线程是否启动

[root@slave ~]# mysql -e 'show slave status\G;' | grep Running
            Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
PS:这两项必须为”Yes”,如果是”No”说明启动失败

6.取消半同步复制的插件

######在Master服务器上取消半同步复制插件
[root@master ~]mysql
mysql > uninstall plugin rpl_semi_sync_master;
mysql > show status like "%semi%"
######在Slave服务器上取消半同步复制插件
[root@slave ~]mysql
mysql > uninstall plugin rpl_semi_sync_slave;

mysql > show status like "%semi%"

转载请注明:HugNew » Mysql半复制浅谈

喜欢 (0)or分享 (0)
发表我的评论
取消评论

表情
(1)个小伙伴在吐槽