温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

semi-sync原主库加入集群阻塞问题分析

发布时间:2020-08-11 15:15:28 阅读:276 作者:沃趣科技 栏目:MySQL数据库
开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

沃趣科技  彭许生


前段时间支持客户处理问题的时候,发现一个semi-sync复制主从切换原master加入集群时,复制同步阻塞,无法继续同步数据的问题,非常有参考意义,整理一下,供大家参考。

问题现象

客户在一个一主两从的半同步复制环境下做了手工切换,然后尝试把原主库加入集群中,结果发现新集群中的数据一直无法同步到slave(原主库)中来,查看slave(原主库)同步状态,IO线程和SQL线程都是YES状态,但是Seconds_Behind_Master大于0.

	
	
		
	

	
		mysql> show slave status\G
	

	
		
	

	
		*************************** 1. row ***************************
	

	
		
	

	
		 Slave_IO_State: Waiting for master to send event
	

	
		 ..............................................
	

	
		 Master_Log_File: mysql-bin.000007 
	

	
		 Read_Master_Log_Pos: 540 
	

	
		 Relay_Log_File: mysql-relay-bin.000006 
	

	
		 Relay_Log_Pos: 367 
	

	
		 Relay_Master_Log_File: mysql-bin.000007 
	

	
		  
	

	
		  
	

	
		 .............................................. 
	

	
		  
	

	
		 Slave_SQL_Running_State: Waiting for semi-sync ACK from slave 
	

	
		1 row in set (0.00 sec) 
	


查看show processlist状态, 发现SQL线程一直处于Waiting for semi-sync ACK from slave状态,可是这个slave(原主库)下已经没有从库了。为什么还需要等待slave返回的ACK呢?

	
	
		mysql> show processlist; 
	

	
		+----+-------------+-----------+------+---------+------+--------------------------------------+------------------+ 
	

	
		| Id | User | Host | db | Command | Time | State | Info | 
	

	
		+----+-------------+-----------+------+---------+------+--------------------------------------+------------------+ 
	

	
		| 1 | system user | | NULL | Connect | 540 |  | NULL | 
	

	
		| 2 | system user | | NULL | Connect | 2191 | Waiting for master to send event | NULL | 
	

	
		| 4 | root | localhost | test | Query | 0 | starting | show processlist | 
	

	
		+----+-------------+-----------+------+---------+------+--------------------------------------+------------------+ 
	

	
		3 rows in set (0.00 sec)
	


问题分析

从SQL线程等待的的半同步问题出发,先查看semi-sync状态和设置

	
	
		mysql> show global status like 'rpl_semi_sync%'; 
	

	
		+--------------------------------------------+-------+ 
	

	
		| Variable_name | Value | 
	

	
		+--------------------------------------------+-------+ 
	

	
		| Rpl_semi_sync_master_clients | 0 | 
	

	
		| 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 | 
	

	
		| Rpl_semi_sync_master_no_tx | 0 | 
	

	
		| 
	

	
		| Rpl_semi_sync_master_timefunc_failures | 0 | 
	

	
		| Rpl_semi_sync_master_tx_avg_wait_time | 0 | 
	

	
		| 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 | 
	

	
		| 
	

	
		+--------------------------------------------+-------+ 
	

	
		15 rows in set (0.00 sec)
	


通过上面semi-sync的状态变量,可以发现semi-sync运行状态Rpl_semi_sync_master_status=ON、Rpl_semi_sync_slave_status=ON。这里最奇怪的是Rpl_semi_sync_master_status=ON。

根据半同步复制原理:主库发生数据变更写binlog,然后等待从库接收并返回ACK,最后在存储引擎层提交数据。这也就是为什么在从库(原主库)一直查不到新主库变更后的数据原因。在默认情况下,半同步复制只有在等待ACK超出 rpl_semi_sync_master_timeout设置的时间才会自动降为异步复制。

这里slave(原主库)被认为是半同步的master,但是没有从库连接他,所以一直在等待从库返回的ACK。等待的时间我们查看rpl_semi_sync_master_timeout变量取值

	
	
		mysql> show global variables like 'rpl_semi_sync%'; 
	

	
		+-------------------------------------------+------------+ 
	

	
		| Variable_name | Value | 
	

	
		+-------------------------------------------+------------+ 
	

	
		| 
	

	
		| 
	

	
		| rpl_semi_sync_master_trace_level | 32 | 
	

	
		| rpl_semi_sync_master_wait_for_slave_count | 1 | 
	

	
		| rpl_semi_sync_master_wait_no_slave | ON | 
	

	
		| rpl_semi_sync_master_wait_point | AFTER_SYNC | 
	

	
		|
		| rpl_semi_sync_slave_trace_level | 32 | 
	

	
		+-------------------------------------------+------------+ 
	

	
		8 rows in set (0.00 sec) 
	


查看semi-sync参数发现从库同时开启了rpl_semi_sync_master_enabled=ON、rpl_semi_sync_slave_enabled=ON和rpl_semi_sync_master_timeout=10000000(1万秒,默认10秒)。

客户竟然把rpl_semi_sync_master_timeout设置为10万秒,也就是说,原主库要等待10万秒才能自动变为异步并加入集群中同步数据,slave(原主库)无法从集群中继续同步数据的根本原因就在这里。

跟客户沟通后,客户之所以将rpl_semi_sync_master_timeout设置这么大的值,是强调数据强一致性,不希望在任何情况下半同步复制结构降为异步复制,最大限度保证数据一致性。

原理分析

前面涉及到几个sc 复制参数,可能有些同学不太了解,下面给大家简单讲解一下MySQL semi-sync 复制安装配置和原理。 
在MySQL 5.7版本里如果要开启半同步复制,需要在master端安装semisync_master.so库并配置my.cnf

	
	
		mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
	

	
		mysql> set global rpl_semi_sync_master_enabled=ON; 
	


在slave端安装semisync_slave.so库并配置my.cnf

	
	
		mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
	

	
		mysql> set global rpl_semi_sync_slave_enabled=ON; 
	


  • 在master端看到Rpl_semi_sync_master_status状态变量显示ON状态,就表示master进入半同步复制模式。
	
	
		mysql> show global status like 'rpl_semi_sync_master_status';
	

	
		+-----------------------------+-------+
	

	
		| Variable_name | Value |
	

	
		+-----------------------------+-------+
	

	
		| Rpl_semi_sync_master_status | ON |
	

	
		+-----------------------------+-------+
	


  • 此时,在slave端会看到Rpl_semi_sync_slave_status显示ON状态,也就表示slave进入半同步复制模式。
	
	
		mysql> show global status like 'rpl_semi_sync_slave_status';
	

	
		+-----------------------------+-------+
	

	
		| Variable_name | Value |
	

	
		+-----------------------------+-------+
	

	
		| Rpl_semi_sync_slave_status | ON |
	

	
		+-----------------------------+-------+
	


进入半同步复制,客户端在master每提交一个事务,master MySQL将对应事务写入binlog,然后等待slave返回的ACK,之后在存储引擎层提交,最后返回给客户端写入成功的消息。 
如果slave没有返回,master将等待指定超时时间;超过超时时间后,会自动降为异步复制模式。
 
semi-sync原主库加入集群阻塞问题分析

  • 如果master在超时时间内(rpl_semi_sync_master_timeout超时时间,默认10000毫秒)没有收到指定数量(rpl_semi_sync_master_wait_for_slave_count接收slave返回ACK数量,默认1)的slave的ACK回包,master自动降为异步复制模式。
  • 当半同步复制降为异步复制模式,在master端可以看到Rpl_semi_sync_master_status=OFF,在save端可以看到Rpl_semi_sync_slave_status=OFF。
  • 上述master等待行为都发生在rpl_semi_sync_master_wait_no_slave=ON(默认值)情况下。如果rpl_semi_sync_master_wait_no_slave设置为OFF时,连接master的slave的数量少于rpl_semi_sync_master_wait_for_slave_count设置的值,master不会等待超时,立刻自动降为异步复制模式。

    建议

    如果把rpl_semi_sync_master_timeout设置非常大,在主从切换时导致原主库加入集群时同步阻塞,建议把rpl_semi_sync_master_wait_no_slave=OFF。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:http://blog.itpub.net/28218939/viewspace-2128548/

AI

开发者交流群×