MySQL 实战 45 讲
林晓斌
网名丁奇,前腾讯云数据库负责人
224874 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
实践篇 (37讲)
特别放送 (1讲)
结课测试 (1讲)
MySQL 实战 45 讲
15
15
1.0x
00:00/00:00
登录|注册

29 | 如何判断一个数据库是不是出问题了?

判定慢问题
主备库都需要进行更新检测
在系统库中创建一个表,定期执行更新语句
空间满后的问题
在系统库中创建一个表,定期执行查询语句
并发线程数限制对判断结果的影响
select 1成功返回并不能说明主库没问题
HA系统发起切换
主库出问题
将从库接到新主库上
切换客户端流量到备库
切换客户端流量到备库
读写分离中的DDL问题
业务系统的高可用需求
不同方法的权衡和选择
性能损耗和选择合适的统计项
使用MAX_TIMER判断数据库是否出问题
使用performance_schema库统计IO请求时间
更新判断
查表判断
select 1判断
被动切换
主动切换
一主多从架构
一主一备架构
总结
内部统计
判断主库问题的方法
主备切换场景
主备切换流程
如何判断一个数据库是不是出问题了?

该思维导图由 AI 生成,仅供参考

我在第2527篇文章中,和你介绍了主备切换流程。通过这些内容的讲解,你应该已经很清楚了:在一主一备的双 M 架构里,主备切换只需要把客户端流量切到备库;而在一主多从架构里,主备切换除了要把客户端流量切到备库外,还需要把从库接到新主库上。
主备切换有两种场景,一种是主动切换,一种是被动切换。而其中被动切换,往往是因为主库出问题了,由 HA 系统发起的。
这也就引出了我们今天要讨论的问题:怎么判断一个主库出问题了?
你一定会说,这很简单啊,连上 MySQL,执行个 select 1 就好了。但是 select 1 成功返回了,就表示主库没问题吗?

select 1 判断

实际上,select 1 成功返回,只能说明这个库的进程还在,并不能说明主库没问题。现在,我们来看一下这个场景。
set global innodb_thread_concurrency=3;
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into t values(1,1)
图 1 查询 blocked
我们设置 innodb_thread_concurrency 参数的目的是,控制 InnoDB 的并发线程上限。也就是说,一旦并发线程数达到这个值,InnoDB 在接收到新请求的时候,就会进入等待状态,直到有线程退出。
这里,我把 innodb_thread_concurrency 设置成 3,表示 InnoDB 只允许 3 个线程并行执行。而在我们的例子中,前三个 session 中的 sleep(100),使得这三个语句都处于“执行”状态,以此来模拟大查询。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

这篇文章介绍了如何判断数据库健康状态以及相应的监控和应对措施。首先讲解了主备切换的流程,包括主动切换和被动切换。重点讨论了如何判断主库是否出现问题,指出了简单的select 1并不能完全判断主库的正常运行状态。文章详细介绍了InnoDB的并发线程控制参数innodb_thread_concurrency的作用,以及如何通过设置一个健康检查表来检测并发线程数过多导致的数据库不可用情况。同时,提到了当binlog所在磁盘空间满了以后,更新语句和事务提交的影响,以及如何改进监控语句来应对这种情况。另外,还介绍了在MySQL内部发现数据库问题的方法,通过performance_schema库的file_summary_by_event_name表统计每次IO请求的时间来判断数据库是否出问题。总结了几种方法存在的问题和演进的逻辑,以及对于业务系统高可用需求的思考。整体来说,通过具体的案例和技术原理,帮助读者了解了如何判断数据库是否出现问题,以及如何进行相应的监控和应对措施。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《MySQL 实战 45 讲》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(60)

  • 最新
  • 精选
  • 某、人
    目前是只有一台服务器来做判断,是否数据库出问题了,就是采用的update的方式。如果是主从架构就一条语句,如果是双主的话就是两条update语句。但是这种方式有很大的弊端,只有一个进程来判断数据库出问题的话,会出现单点判断的问题。所以后续准备多个单数进程来做判断,如果超过了半数以上的监控进程都认为数据库出问题,才做切换。 老师我有两个问题: 1.innodb_thread_concurrency的设置是不是应该跟计算机核数成正比,一般是1.5倍-2倍左右? 2.怎么之前遇到空间满了,数据库都登不上了,所有的连接都连不上,更不用执行select语句了,这个是什么原因啊?

    作者回复: 1. 虽然理论上是核数的2倍左右最好,但是现在很多人把MySQL创建在虚拟机上,就分1~2个核,我怕那么写,有同学会认为innodb_thread_concurrency建议设置成4。。 2. 空间满本身是不会导致连不上的。但是因为空间满,事务无法提交,可能会导致接下来外部事务重试,新重试的业务还是堵在提交阶段,持续累积可能会把连接数用满

    2019-01-20
    4
    77
  • StarkYanng
    老师,我有个疑问,您说外部检测是采用定时轮询的方式。那内部检测通过'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; '的方法,不是也需要定时轮询来执行这个语句么?

    作者回复: 对,但是这个方法本质上是“内部把一段时间内的统计信息存在这里”,只是“定期来取”,去到的是“一段时间内的信息” 而前面的几种方法,都是“检测那个时间点的信息”

    2019-02-16
    2
    54
  • 老杨同志
    现在很多公司都是使用dubbo或者类似dubbo的rpc调用。说说我对dubbo的理解 dubbo 存活检测感觉分为下面三个层面 服务端与注册中心的链接状态 通常注册中心是zookeeper,服务端注册临时节点,客户端注册这个节点的watch事件,一但服务端失联, 客户端将把该服务从自己可用服务列表中移除。(一个服务通常有多个提供者,只是把失联的提供者移除)。 zookeeper是通过心跳发现服务提供者失联的,心跳实际上就是以固定的频率(比如每秒)发送检测的数据包; 客户端与注册中心的链接状态 客户端与zookeeper失联,会暂时使用自己缓存的服务提供者列表。如果每个提供者多次调不通,把它移除。 客户端与服务单的链接状态 服务端提供类似于echo的方法,客户定时调用。部分返回正常,认为服务处于亚健康状态,如果超过阀值,会被降级 从服务提供者列表移除。被移除的方法可能会在超过一定时间后,拿回来重试,可以恢复成正常服务,也可能继续降级。

    作者回复: 很好的实践分享。 是不是还有配套一些服务的RT时间的报告? 毕竟echo是一个比较轻量的调用,正确率可能比实际业务调用的正确率高

    2019-01-18
    5
    30
  • IceGeek17
    对于使用 GTID 等位点的方案做读写分离,对大表做DDL的问题, 有一种做法是先在从库上设置 set_log_bin = off,在从库上先做DDL,完成后做一下主从切换。然后再在之前的主库上同样操作一遍。 但这会有一个问题,当先在从库上做DDL(大表DDL时间会比较长,比如10分钟),在这段时间内,此时如果读写请求都走主库的话,如果写请求对于DDL的改动是有依赖的,那这些写请求在主库就可能会失败;同样此时对于主库上的读请求,也可能会读到“过期”的数据(读请求希望读到DDL之后的数据,但此时DDL在从库执行,主库上还是DDL之前的),老师怎么看这个问题 ?

    作者回复: 是这样的,我们说DDL,一般是指加减索引,增加字段在最后一列,这种操作…

    2019-01-29
    8
    15
  • 强哥
    1.基础监控,包括硬盘,CPU,网络,内存等。 2.服务监控,包括jvm,服务端口,接入上下游服务的超时监控等。 3.业务监控,主要是监控业务的流程是否出现问题。

    作者回复: 👍,这里的“超时监控”,是怎么得到的? 是单独有命令检测,还是去看业务请求的返回时间?

    2019-01-18
    2
    14
  • 专栏用户
    问个和本课不太相关的问题,自己开了general log,然后看到有很多set autocommit=0,之后set autocommit=1的日志,查了一下,看说是关闭/开启自动提交模式,所以就有点不懂为何会爱挨着出现这两个语句?

    作者回复: 这个是框架做的吧? 我知道有些框架喜欢用 set autocommit=0, 表示开启事务 set autocommit=1,表示提交事务 虽然也对, 但比较建议用begin 和 commit

    2019-03-30
    12
  • 长杰
    老师请教一个问题,在gtid模式下,对于大的ddl操作,采用在备库执行sql_log_bin=0的方式先执行,然后再切换主备的方式在主库再执行,这种情况下,ddl操作是不记录binlog的,不知道对gtid的计数有什么影响,是按顺序递增还是会跳过这个序列号? 另外补充一下有些dl操作是不适合这个主备切换的方式,比如drop一个列,如果先在备库执行就可能导致主备同步异常。这个场景适合osc方式或把读请求切到主库,先在主库执行这两种方案。

    作者回复: 如果set sql_log_bin=0, 就不记录binlog,就不会给这个事务分配gtid。 你说得对,drop列是很麻烦的,尽量不做。毕竟业务代码直接无视这个列就好了。。

    2019-01-18
    2
    12
  • Mr.Strive.Z.H.L
    老师您好: 关于 主备同步停止 的问题,看了您的回复。 我是这么理解的: insert into mysql.health_check(id, t_modified) values (1, now()) on duplicate key update t_modified=now(); 按照您说的场景,主备分别执行这句话后,复制给彼此。 如果单单看这句话,就算是主库执行备库复制过来的这句话,也不会出现异常呀。(因为如果主键冲突就会更新时间) 但是这种场景会导致 主备同步停止, 所以实际上主库在应用备库这句话的binlog的时候,发现主键冲突,自然就会报错。 不知道是不是这样,因为如果单单看这句sql,即使主键冲突也没关系呀?

    作者回复: 啊 主键冲突为啥没关系? 是这样的,这两个语句如果同时执行,那么在主库和备库上就都是“insert行为” 写到binlog里面就都是Write rows event 这个冲突就会导致主备同步停止哦

    2019-01-22
    6
    10
  • 慧鑫coming
    老师,文中提到的“但是,如果主库 A 和备库 B 都用相同的更新命令,就可能出现行冲突,也就是可能会导致主备同步停止。”,这个能展开说一下吗,这个行冲突指什么?它们会都更新各自检测表的同一字段我觉得会带来不准确的问题,怎么导致主从同步停止了呢?

    作者回复: 好问题 比如两个表刚开始都是空表, 然后第一个语句执行 insert into mysql.health_check(id, t_modified) values (1, now()) on duplicate key update t_modified=now(); 就会两边各写入一个insert语句的binlog日志,传到对面就导致同步停止了

    2019-01-22
    10
    9
  • 路平
    你好,这两天一路看下来,收获不少。 提个表设计相关的问题: 用一个表存储文件全路径,删除某个文件(一行记录)时使用逻辑删除。怎么设计表及其索引(如果有)? 需要考虑: 1. 文件被删除后有可能会再创建一个同名的文件; 2. 新创建的文件也可能再次被逻辑删除; 3. 第二个文件被删除后还可能创建第三同名文件,以此类推; 4. 未删除的文件路径不能有重复值。 不知道作者是否还会回复留言。如果回复了,我是会收到提醒吗?

    作者回复: 如果你是要保存“历史”,可以加两个字段:版本号和状态(表示是否删除) 【编辑跟我说会有提醒~】

    2019-04-23
    3
    8
收起评论
显示
设置
留言
60
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部