29 | 如何判断一个数据库是不是出问题了?
29 | 如何判断一个数据库是不是出问题了?
讲述:林晓斌
时长14:31大小13.26M
select 1 判断
查表判断
更新判断
内部统计
小结
上期问题时间
赞 46
提建议
精选留言(56)
- 某、人2019-01-20目前是只有一台服务器来做判断,是否数据库出问题了,就是采用的update的方式。如果是主从架构就一条语句,如果是双主的话就是两条update语句。但是这种方式有很大的弊端,只有一个进程来判断数据库出问题的话,会出现单点判断的问题。所以后续准备多个单数进程来做判断,如果超过了半数以上的监控进程都认为数据库出问题,才做切换。 老师我有两个问题: 1.innodb_thread_concurrency的设置是不是应该跟计算机核数成正比,一般是1.5倍-2倍左右? 2.怎么之前遇到空间满了,数据库都登不上了,所有的连接都连不上,更不用执行select语句了,这个是什么原因啊?展开
作者回复: 1. 虽然理论上是核数的2倍左右最好,但是现在很多人把MySQL创建在虚拟机上,就分1~2个核,我怕那么写,有同学会认为innodb_thread_concurrency建议设置成4。。 2. 空间满本身是不会导致连不上的。但是因为空间满,事务无法提交,可能会导致接下来外部事务重试,新重试的业务还是堵在提交阶段,持续累积可能会把连接数用满
共 4 条评论73 - StarkYanng2019-02-16老师,我有个疑问,您说外部检测是采用定时轮询的方式。那内部检测通过'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; '的方法,不是也需要定时轮询来执行这个语句么?
作者回复: 对,但是这个方法本质上是“内部把一段时间内的统计信息存在这里”,只是“定期来取”,去到的是“一段时间内的信息” 而前面的几种方法,都是“检测那个时间点的信息”
共 2 条评论51 - 老杨同志2019-01-18现在很多公司都是使用dubbo或者类似dubbo的rpc调用。说说我对dubbo的理解 dubbo 存活检测感觉分为下面三个层面 服务端与注册中心的链接状态 通常注册中心是zookeeper,服务端注册临时节点,客户端注册这个节点的watch事件,一但服务端失联, 客户端将把该服务从自己可用服务列表中移除。(一个服务通常有多个提供者,只是把失联的提供者移除)。 zookeeper是通过心跳发现服务提供者失联的,心跳实际上就是以固定的频率(比如每秒)发送检测的数据包; 客户端与注册中心的链接状态 客户端与zookeeper失联,会暂时使用自己缓存的服务提供者列表。如果每个提供者多次调不通,把它移除。 客户端与服务单的链接状态 服务端提供类似于echo的方法,客户定时调用。部分返回正常,认为服务处于亚健康状态,如果超过阀值,会被降级 从服务提供者列表移除。被移除的方法可能会在超过一定时间后,拿回来重试,可以恢复成正常服务,也可能继续降级。展开
作者回复: 很好的实践分享。 是不是还有配套一些服务的RT时间的报告? 毕竟echo是一个比较轻量的调用,正确率可能比实际业务调用的正确率高
共 5 条评论28 - IceGeek172019-01-29对于使用 GTID 等位点的方案做读写分离,对大表做DDL的问题, 有一种做法是先在从库上设置 set_log_bin = off,在从库上先做DDL,完成后做一下主从切换。然后再在之前的主库上同样操作一遍。 但这会有一个问题,当先在从库上做DDL(大表DDL时间会比较长,比如10分钟),在这段时间内,此时如果读写请求都走主库的话,如果写请求对于DDL的改动是有依赖的,那这些写请求在主库就可能会失败;同样此时对于主库上的读请求,也可能会读到“过期”的数据(读请求希望读到DDL之后的数据,但此时DDL在从库执行,主库上还是DDL之前的),老师怎么看这个问题 ?展开
作者回复: 是这样的,我们说DDL,一般是指加减索引,增加字段在最后一列,这种操作…
共 8 条评论14 - 强哥2019-01-181.基础监控,包括硬盘,CPU,网络,内存等。 2.服务监控,包括jvm,服务端口,接入上下游服务的超时监控等。 3.业务监控,主要是监控业务的流程是否出现问题。
作者回复: 👍,这里的“超时监控”,是怎么得到的? 是单独有命令检测,还是去看业务请求的返回时间?
共 2 条评论13 - 专栏用户2019-03-30问个和本课不太相关的问题,自己开了general log,然后看到有很多set autocommit=0,之后set autocommit=1的日志,查了一下,看说是关闭/开启自动提交模式,所以就有点不懂为何会爱挨着出现这两个语句?
作者回复: 这个是框架做的吧? 我知道有些框架喜欢用 set autocommit=0, 表示开启事务 set autocommit=1,表示提交事务 虽然也对, 但比较建议用begin 和 commit
11 - 长杰2019-01-18老师请教一个问题,在gtid模式下,对于大的ddl操作,采用在备库执行sql_log_bin=0的方式先执行,然后再切换主备的方式在主库再执行,这种情况下,ddl操作是不记录binlog的,不知道对gtid的计数有什么影响,是按顺序递增还是会跳过这个序列号? 另外补充一下有些dl操作是不适合这个主备切换的方式,比如drop一个列,如果先在备库执行就可能导致主备同步异常。这个场景适合osc方式或把读请求切到主库,先在主库执行这两种方案。展开
作者回复: 如果set sql_log_bin=0, 就不记录binlog,就不会给这个事务分配gtid。 你说得对,drop列是很麻烦的,尽量不做。毕竟业务代码直接无视这个列就好了。。
共 2 条评论11 - Mr.Strive.Z.H.L2019-01-22老师您好: 关于 主备同步停止 的问题,看了您的回复。 我是这么理解的: 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 这个冲突就会导致主备同步停止哦
共 6 条评论9 - 慧鑫coming2019-01-22老师,文中提到的“但是,如果主库 A 和备库 B 都用相同的更新命令,就可能出现行冲突,也就是可能会导致主备同步停止。”,这个能展开说一下吗,这个行冲突指什么?它们会都更新各自检测表的同一字段我觉得会带来不准确的问题,怎么导致主从同步停止了呢?
作者回复: 好问题 比如两个表刚开始都是空表, 然后第一个语句执行 insert into mysql.health_check(id, t_modified) values (1, now()) on duplicate key update t_modified=now(); 就会两边各写入一个insert语句的binlog日志,传到对面就导致同步停止了
共 10 条评论9 - 路平2019-04-23你好,这两天一路看下来,收获不少。 提个表设计相关的问题: 用一个表存储文件全路径,删除某个文件(一行记录)时使用逻辑删除。怎么设计表及其索引(如果有)? 需要考虑: 1. 文件被删除后有可能会再创建一个同名的文件; 2. 新创建的文件也可能再次被逻辑删除; 3. 第二个文件被删除后还可能创建第三同名文件,以此类推; 4. 未删除的文件路径不能有重复值。 不知道作者是否还会回复留言。如果回复了,我是会收到提醒吗?展开
作者回复: 如果你是要保存“历史”,可以加两个字段:版本号和状态(表示是否删除) 【编辑跟我说会有提醒~】
共 3 条评论8 - 一大只😴2019-01-21老师,我想问下,我的ECS上是8核CPU,只跑一个MySQL实例,那innodb_thread_concurrency如果设成2倍,那就是16哈。看并发查询的数量,是不是关注Threads_running是否超过innodb_thread_concurrency就可以了。
作者回复: Thread running 是包含“锁等待”状态的线程的, 超过点也没事😄
共 2 条评论6 - Mr.Strive.Z.H.L2019-01-22老师您好: 本章有个疑惑: ”外部检测的时候,主备使用同一条更新语句,造成行冲突,导致主备同步停止” 上面这句话实在想不通。外部检测是只是看更新语句的返回时间,health_check表在主库备库都有,为啥会造成行冲突?为啥会导致主备同步停止?即使是相同的binlog,也没啥影响呀。展开
作者回复: 比如两个表刚开始都是空表, 然后第一个语句执行 insert into mysql.health_check(id, t_modified) values (1, now()) on duplicate key update t_modified=now(); 就会两边各写入一个insert语句的binlog日志,传到对面就导致同步停止了
5 - lzh2019-10-02难道就没人问为啥SELECT 1不算入并发线程中吗?难道因为没查表吗?只有查了表涉及IO的才会算入并发线程?共 6 条评论3
- heat nan2019-01-19老师,一直有个疑问,想咨询下。innodb buffer 会缓存表的数据页和索引页。现在我想知道如何确认一个查询的行已经被缓存在内存中了。 我想了一下,第一种方法是直接去内存中遍历这个表相关的数据页。这样的话,因为内存中的页可能是分散的,可能不构成一个完成的索引结构,可能不能利用b+树叶子节点的路由功能。 这里有点模糊,希望老师有空可以解释一下
作者回复: “因为内存中的页可能是分散的,可能不构成一个完成的索引结构,可能不能利用b+树叶子节点的路由功能。” 这里不对哈 放在内存里是b+树组织的,可以利用b+树叶子节点的路由功能的
3 - 布衣骇客2019-01-18作为一个开发我也很想了解一下我们自己生产库上的监控情况,接触到最多的就是Datasource,以及user,password,port(基本上是基于连接那种级别,最多就是加锁),等等参数,大部分都是基于业务开发。站在个人层面或者业务开发层面(很少能接触到DBA,以及看到DBA是怎么设置这些参数情况,除非库挂掉了就会和DBA一起看这些)怎么去修改和观看以及使用这些参数鸭
作者回复: 有DBA就不要自己去修改线上的参数啦 如果说观察,一个比较好的管控系统,是会能够让你看到这些值的 如果没有,就让dba给你一份线上的my.cnf的配置,然后你在测试环境自己用这个配置启动实例来观察
3 - Ryoma2019-01-18现在的服务中只加了一个healthCheck的接口,和MySQL中使用select判断比较类似。当服务依赖的MySQL及Redis等第三方资源发生问题时,还是不能有效的判断2
- Shiki珠2019-08-07老师您好!请教下,我们这边每天白天几乎每个整点,业务那边有定时批量任务,那几分钟内CPU会彪到100%。活跃线程数也在200左右,QPS峰值20000+,此时也会出现平时不慢的“慢sql”,如果把innodb_thread_concurrency从0改为128或者更低,是否会有所缓解呢?但是如果限制了那有很多连接会排队等待是否会延迟,而造成业务很慢呢?共 3 条评论1
- IT橘子2019-07-29老师,当innodb并发线程数过多导致的系统不可用问题,进行主备切换后问题就可以解决吗?备库上的innodb并发线程会不会也在一段时间之后也达到阈值呢?1
- alias cd=rm -rf2019-02-121、判断进程是否可用:ping的方案(类似select 1) 2、根据业务的需求一般会设置一个阈值以及策略(如:单位时间失败的次数,响应时间超过多少阈值)如何进行熔断、扩容等方案。1
- 黄文晓2023-01-17 来自广东判断数据库是否可用的方法: 1、select 1 :只能判断数据库进程,没有触及到引擎层,不能发现并发线程数过多导致的数据库不可用问题(ps:线程进入锁等待,并发线程数计数减一) 2、查表:可以发现并发线程数过多导致的数据库不可用问题,但是不能发现由于binlog所在磁盘满了导致所有事务不能提交导致数据库不可用问题 3、更新表:可以发现由于binlog所在磁盘满了导致所有事务不能提交导致数据库不可用问题,但是具有随机性 4、内部统计:performance_schema库的file_summary_by_event_name表MAX_TIMER_WAIT展开