暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MYSQL-note25, 如何判断主库故障

kids and edu 2021-08-20
821

主备切换有两种场景,一种是主动切换,一种是被动切换。被动切换,往往是因为主库出问题了,由 HA 系统发起的。那么怎么判断一个主库出问题了?

 

select 1

判断实际上,select 1 成功返回,只能说明这个库的进程还在,并不能说明主库没问题

 

设置 innodb_thread_concurrency 控制 InnoDB 的并发线程上限。也就是说,一旦并发线程数达到这个值,InnoDB 在接收到新请求的时候,就会进入等待状态,直到有线程退出。建议把 innodb_thread_concurrency 设置为 64~128 之间的值。

 

show processlist 的结果里,看到的几千个连接,指的就是并发连接。而“当前正在执行”的语句,才是我们所说的并发查询


并发连接数大会多占一些内存,连接释放不掉,容易导致数据库内存不足,无法接收新的请求。

这里我们关注的是并发查询,因为并发查询太高是 CPU 杀手。这也是为什么我们需要设置 innodb_thread_concurrency 参数的原因。

 

InnoDB 在设计时,遇到进程进入锁等待的情况时,将并发线程的计数减 1 的设计,是合理而且是必要的。因为,进入锁等待的线程已经不吃 CPU 了;更重要的是,必须这么设计,才能避免整个系统锁死。

 

 

查表判断

为了能够检测 InnoDB 并发线程数过多导致的系统不可用情况,我们需要找一个访问 InnoDB 的场景。


一般的做法是,在系统库(mysql 库)里创建一个表,比如命名为 health_check,里面只放一行数据,然后定期执行查询。可以检测出由于并发线程过多导致的数据库不可用的情况。

更新事务要写 binlog,当binlog 所在磁盘的空间占用率达到 100%,所有的更新语句和事务提交的 commit 语句就都会被堵住。但是,系统这时候还是可以正常读数据的。

 

更新判断

既然要更新,就要放个有意义的字段,常见做法是放一个 timestamp 字段,用来表示最后一次执行检测的时间

如果用更新来检测主库的话,那么备库也要进行更新检测。双 M 结构,如果主库 A 和备库 B 都用相同的更新命令,就可能出现行冲突,也就是可能会导致主备同步停止。所以 mysql.health_check 这个表就不能只有一行数据。可以mysql.health_check 表上存入多行数据,并用 A、B 的 server_id 做主键

更新判断是一个相对比较常用的方案了,不过依然存在一些问题。其中,“判定慢”一直是让 DBA 头疼的问题。检测使用的 update 命令,需要的资源很少,所以可能在拿到 IO 资源的时候就可以提交成功,并且在超时时间 N 秒未到达之前就返回给了检测系统。

 

 

内部统计

MySQL 5.6 版本以后提供的 performance_schema 库,就在 file_summary_by_event_name 表里统计了每次 IO 请求的时间。每一次操作数据库,performance_schema 都需要额外地统计这些信息,这个统计功能是有性能损耗的。如果打开所有的 performance_schema 项,性能大概会下降 10% 左右。

先看看file_summary_by_event_name表里面的

event_name='wait/io/file/innodb/innodb_log_file’这一行。


第一列 EVENT_NAME 表示统计的类型。COUNT_STAR 是所有 IO 的总次数,接下来四列是具体的统计项, 单位是皮秒;前缀 SUM、MIN、AVG、MAX,顾名思义指的就是总和、最小值、平均值和最大值。

 

打开 redo log 的时间监控

mysql> update setup_instruments set ENABLED='YES', Timed='YES'

 where name  like '%wait/io/file/innodb/innodb_log_file%';

 

可以设定阈值,单次 IO 请求时间超过 200 毫秒属于异常,然后使用类似下面这条语句作为检测逻辑。

 

mysql> 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*1000000000;

 

发现异常后,取到你需要的信息,再通过下面这条语句:

 

mysql> truncate table

performance_schema.file_summary_by_event_name;

 

把之前的统计信息清空。后面的监控再次出现这个异常,可以加入监控累积值了。


文章转载自kids and edu,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论