如何判断MySql是否可用

在一主一从或一主多从的mysql架构中,当主库不可用时,需要及时切换到从库,那么,如何判断主库是否可用?

通过select 1来判断

方案

在sql中执行"select 1",如果失败,则认为sql服务不可用。

优点

简单,速度快

缺点

只能检测sql服务器进程是否存在,并不能真正识别服务的可用性。
比如,当innodb_thread_concurrency设置过小时(比如=1),大部分查询可能因为需要排队等待而无法实时响应时,select 1反而可以实时响应。

通过实际的查表语句来检测

方案

在系统库mysql库中创建一个 health_check表,并且里面只放一行数据,然后定期执行"select * from mysql.health_check"

优点

简单,可以检测出因为并发线程过多而导致的数据库不可用的情况。

缺点

由于只采用读来检测,所以类似磁盘满而导致的服务不可用问题,是无法检测出来的。

通过更新表来检测

方案

简单地改进上一种方法,通过更新表来实现可用性检测。
update mysql.health_check set t_modified = now();
上述语句执行时,会写binlog文件,如果磁盘满时,执行会失败,因此,可以检测出磁盘不可用等io问题。

缺点

在主从的mysql结构里面,如果主备关系是双M结构,这时如果在备库也执行这个命令,就会出现主备冲突,导致主备同步停止。

改进

在health_check表中创建两列,一列是id,一列是t_modified_time,每个服务器只update id=自己的serverid的行,这样就可以 保证主备库各自的检测命令不冲突。

改进后的缺点

改进后的更新表方案已经相对比较完善了,但是还是有些问题,主要的问题是可能出现“判定慢”。当服务器由于资源紧张时,大部分复杂的查询更新语句可能实质上已经超时,但是由于检测语句相对比较简单,可能不会超时(或者有时候超时,有时候会成功),因此出现判定慢或者判定不准确的问题。

通过sql内部的性能数据来检测可用性

方案

通过统计mysql的每一次io请求的时间,来判定服务是否可用。
mysql 5.6版本以后提供了performance_schema库,在file_summary_by_event_name表里面统计了每次io请求的时间。
performance_schema是可选项,全部打开性能统计会影响mysql的性能,大概下降10%左右。因此只需要enable少数需要的项进行统计。
比如打开 redo log的时间监控,可以执行:
update setup_instruments set ENABLED=‘YES’, Timed = ‘YES’ where name like ‘%wait/io/file/innodb/innodb_log_file%’;
假设已经打开了redo log和binlog这两个统计信息,接下来就是检测是否存在每次IO请求超过200ms的事件:
select event_name, MAX_TIMER_WAIT from performance_schema.file_summary_by_event_name where event_name in (‘wait/io/file/innodb/innodb_log_file’, ‘wait/io/file/sql/binlog’) and MAX_TIMER_WAIT > 200 * 100010001000;
发现异常以后,可以读取需要的信息,然后通过以下语句清空之前的统计信息,以便监控后续可能出现的异常:
truncate table performance_shema.file_summary_by_event_name;

优点

比较可靠

缺点

太复杂

猜你喜欢

转载自blog.csdn.net/weixin_40735752/article/details/88077362