MySQL45讲 第29讲 如何判断一个数据库是不是出问题了?——阅读总结
文章目录
- MySQL45讲 第二十九讲 如何判断一个数据库是不是出问题了?——阅读总结
- 一、检测数据库实例健康状态的重要性
- 二、常见检测方法及问题分析
- (一)select 1 判断法
- (二)查表判断法
- (三)更新判断法
- 三、基于内部统计的高级检测方法
- (一)performance_schema 库的作用
- (二)检测逻辑与阈值设定
- 四、总结与思考
MySQL45讲 第二十九讲 如何判断一个数据库是不是出问题了?——阅读总结
在 MySQL 数据库的运维管理中,及时准确地判断数据库实例是否出现问题至关重要。这不仅关系到数据的可用性和完整性,还直接影响到业务系统的正常运行。讨如何判断一个 MySQL 数据库实例是否出问题,详细介绍多种检测方法及其优缺点。
一、检测数据库实例健康状态的重要性
在一主一备的双 M 架构或一主多从架构中,主备切换是保障数据库高可用性的关键操作。而主备切换通常由 HA 系统发起,其中被动切换往往是因为主库出现问题。因此,准确判断主库是否出问题是实现高效主备切换、确保业务连续性的前提。
二、常见检测方法及问题分析
(一)select 1 判断法
-
原理与局限性:很多人认为通过执行
select 1
语句,若能成功返回则表示数据库实例正常。然而,实际情况并非如此。例如,设置innodb_thread_concurrency 参数为 3
(控制 InnoDB 并发线程上限),并开启三个包含select sleep (100) from t
语句的会话(模拟大查询),**此时再执行 select 1 可以成功,但查询表 t 的语句会被阻塞。**这表明 select 1 成功返回仅能说明数据库进程存在,无法全面反映数据库实例的健康状况,如无法检测出 InnoDB 并发线程数过多导致的系统不可用情况。 -
并发连接与并发查询概念辨析:这里需要明确并发连接和并发查询的区别。
show processlist
结果中的几千个连接指的是并发连接,而 “当前正在执行” 的语句才是并发查询。并发连接数达到几千个对系统影响主要是多占内存,而并发查询过高才是 CPU 杀手,这也是设置innodb_thread_concurrency
参数的重要原因。
(二)查表判断法
- 改进思路:为检测 InnoDB 并发线程数过多导致的问题,可在系统库(mysql 库)创建一个只含一行数据的表(如 health_check),定期执行
select * from mysql.health_check
语句。这样,当并发线程过多导致数据库不可用时,该查询语句也会受到影响,从而检测出问题。 - 空间满问题的挑战:然而,当 binlog 所在磁盘空间占用率达到 100% 时,所有更新语句和事务提交的 commit 语句会被阻塞,但系统仍可正常读数据。此时,上述查询语句无法检测出这种因空间满导致的数据库问题,需要进一步改进检测方法。
(三)更新判断法
- 具体操作与优势:将检测语句改为更新语句,如
update mysql.health_check set t_modified = now ()
,并在表中增加一个 timestamp 字段用于记录最后一次执行检测的时间。同时,为避免主备库检测命令行冲突(主备库都执行相同更新命令可能导致主备同步停止),可在mysql.health_check
表中存入多行数据,以主、备库的server_id
做主键,因为 MySQL 规定主库和备库的server_id
必须不同。这样,主备库各自的检测命令就不会发生冲突,该方法能够在一定程度上更有效地检测数据库实例的健康状态。 - 判定慢问题剖析:**尽管更新判断法相对常用,但存在 “判定慢” 的问题。**例如,在日志盘 IO 利用率为 100% 的情况下,虽然系统响应极慢已需主备切换,但由于 IO 利用率 100% 表示系统 IO 仍在工作,检测使用的 update 命令可能在拿到 IO 资源时提交成功并在超时时间内返回,导致检测系统误判数据库正常。这是因为外部检测基于定时轮询,具有随机性,系统可能在两次轮询间隔内出现问题,而运气不好时可能多次轮询都无法发现,从而导致切换慢。
三、基于内部统计的高级检测方法
(一)performance_schema 库的作用
针对外部检测方法的局限性,MySQL 5.6 版本以后提供的 performance_schema
库提供了更可靠的检测途径。该库中的 file_summary_by_event_name
表统计了每次 IO 请求的时间,
例如 event_name = 'wait/io/file/innodb/innodb_log_file'
这一行统计了 redo log 的写入时间,包括所有 IO 类型的统计(COUNT_STAR 表示总次数,SUM、MIN、AVG、MAX_TIMER_WAIT 分别表示总和、最小值、平均值和最大值,单位为皮秒)、读操作统计(SUM_NUMBER_OF_BYTES_READ
统计总共从 redo log 里读的字节数)、写操作统计以及对其他类型数据(如 fsync)的统计。binlog 对应的是 event_name = "wait/io/file/sql/binlog"
这一行,其统计逻辑与 redo log 相同。
(二)检测逻辑与阈值设定
通**过查看 MAX_TIMER_WAIT
的值,我们可以判断数据库是否存在问题。**例如,设定单次 IO 请求时间超过 200 毫秒为异常,使用类似 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')
的语句作为检测逻辑。发现异常后,可使用 truncate table performance_schema.file_summary_by_event_name
语句清空之前的统计信息,以便后续监控再次出现异常时能准确累积监控值。不过,开启 performance_schema
的统计功能会有一定性能损耗,测试结果显示性能大概会下降 10% 左右,因此建议仅开启所需的统计项,如通过 update setup_instruments set ENABLED = 'YES', Timed = 'YES' where name like '% wait/io/file/innodb/innodb_log_file%'
语句开启 redo log 的时间监控。
四、总结与思考
我们介绍了多种检测 MySQL 实例健康状态的方法:
- select 1 判断法:虽然简单但不准确;
- 查表判断法:无法检测磁盘空间满的情况;
- 更新判断法:一定程度上检测主备库问题,但存在判定慢的问题;
- 基于 performance_schema 库的内部统计检测法:虽能在而内部统计检测法虽然更精确,但会带来性能损耗。
每个方法都有其改进的逻辑,但也都存在一定问题。例如,在实际应用中,需要根据业务需求和实际情况权衡选择合适的检测方法。