MySQL主从复制(六):数据库是否可用

news2025/1/12 12:12:12

select 1判断


场景示例:

-- 设置innodb并发度为3,从而限制并发查询
set global innodb_thread_concurrency=3;

-- 创建表t
CREATE TABLE `t` (
 `id` int(11) NOT NULL,
 `c` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB;

-- 插入1行数据 insert into t values(1,1)
insert into t values(1,1);

查询blocked:

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

上图中,前三个session 中的sleep(100), 使得这三个语句都处于“执行”状态, 以此来模拟大查询。

session D里面, select 1是能执行成功的, 但是查询表t的语句会被堵住。 也就是说, 如果这时候我们用select 1来检测实例是否正常的话, 是检测不出问题的。

通常情况下, 建议把innodb_thread_concurrency设置为64~128之间的值。

问1:并发线程数设置为128够干啥, 线上的并发连接数动不动就上千了?

答:产生这个疑问的原因, 是搞混了并发连接和并发查询。

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

并发连接数达到几千个影响并不大, 就是多占一些内存而已。 我们应该关注的是并发查询, 因为并发查询太高才是CPU杀手。 这也是为什么我们需要设置innodb_thread_concurrency参数的原因。

问2:如果把innodb_thread_concurrency设置为128的话, 那么出现同一行热点更新的问题时, 是不是很快就把128消耗完了, 这样整个系统是不是就挂了呢?

答:在线程进入锁等待以后,并发线程的计数会减一,也就是说等行锁(也包括间隙锁)的线程是不算在128里面的。MySQL这样设计是非常有意义的。 因为, 进入锁等待的线程已经不吃CPU了。

问3:为什么进入锁等待的线程不吃CPU可以避免整个系统锁死?

答:假设处于锁等待的线程也占并发线程的计数,可以设想一下这个场景:

1)线程1执行begin; update t set c=c+1 where id=1, 启动了事务trx1, 然后保持这个状态。 这时候, 线程处于空闲状态, 不算在并发线程里面。

2)线程2到线程129都执行 update t set c=c+1 where id=1; 由于等行锁, 进入等待状态。 这样就有128个线程处于等待状态。

3)如果处于锁等待状态的线程计数不减一, InnoDB就会认为线程数用满了, 会阻止其他语句进入引擎执行(包括commit), 这样线程1不能提交事务。 而另外的128个线程又处于锁等待状态, 整个系统就堵住了。

系统锁死状态图:

这时候InnoDB不能响应任何请求, 整个系统被锁死。 而且, 由于所有线程都处于等待状态, 此时占用的CPU却是0, 而这明显不合理。 所以, 我们说InnoDB在设计时, 遇到进程进入锁等待的情况时, 将并发线程的计数减1的设计, 是合理而且是必要的。

注:虽然说等锁的线程不算在并发线程计数里, 但如果它在真正地执行查询, 就比如我们上面例子中前三个事务中的select sleep(100) from t, 还是要算进并发线程的计数的。

因此上述select 1示例中,同时在执行的语句超过了设置的innodb_thread_concurrency的值, 这时候系统其实已经不行了, 但是通过select 1来检测系统, 会认为系统还是正常的。

总结:

  • Select 1判断:定期执行select 1成功返回,表示DB是连通的。
  • 使用场景:主要用于检测MySQL连通性。
  • 存在问题:不完善,如果使用select 1检测DB的可用性,可能出现DB连接畅通,但引擎层并发压力已达上限,导致DB不可用。
  • 解决办法:使用查表判断方案可解决该问题。

查表判断


为了能够检测InnoDB并发线程数过多导致的系统不可用情况, 我们需要找一个访问InnoDB的场景。 一般的做法是, 在系统库(mysql库) 里创建一个表, 比如命名为health_check, 里面只放一行数据, 然后定期执行:

select * from mysql.health_check;

使用这个方法, 我们可以检测出由于并发线程过多导致的数据库不可用的情况。

问:如果空间满了,使用该方法检测数据库是否可用,是否有问题?

答:更新事务要写binlog, 而一旦binlog所在磁盘的空间占用率达到100%, 那么所有的更新语句和事务提交的commit语句就都会被堵住。 但是, 系统这时候还是可以正常读数据的。也就是说,此时该方法无法检测数据库是否是可用的。

因此,需要把查询语句改为更新语句。

总结:

  • 查表判断:在系统库(mysql库)里创建一个表,如health_check,插入一行数据,定期执行查询语句:select * from mysql.health_check;
  • 使用场景:能够检测InnoDB并发线程数过多导致的系统不可用情况。
  • 存在问题:不完善,磁盘问题无法检测到,可能读请求正常,但写请求已阻塞;比如:写binlog,磁盘满了以后,所有事务更新语句都被阻塞;但读请求正常。此时无法检测到DB不可用。
  • 解决方案:使用更新判断方案可解决该问题。

更新判断(推荐使用)


既然要更新, 就要放个有意义的字段, 常见做法是放一个timestamp字段, 用来表示最后一次执行检测的时间。 这条更新语句类似于:

update mysql.health_check set t_modified=now();

注1:节点可用性的检测应该包含主库和备库。 如果用更新来检测主库的话, 那么备库也要进行更新检测。

注2:对于双M结构(A、B互为主备),由于备库B也要写binlog,如果主库A和备库B都用相同的更新命令,则可能出现行冲突,即可能导致主备同步停止。因此mysql.health_check 这个表就不能只有一行数据了。

为了让主备之间的更新不产生冲突, 我们可以在mysql.health_check表上存入多行数据, 并用A、 B的server_id做主键。

CREATE TABLE `health_check` (
 `id` int(11) NOT NULL,
 `t_modified` timestamp NOT NULL DEFAULTCURRENT_TIMESTAMP,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB;

-- 检测命令
insert into mysql.health_check(id, t_modified) values (@@server_id, now()) onduplicate key update t_modified=now();

由于MySQL规定了主库和备库的server_id必须不同,这样就可以保证主、 备库各自的检测命令不会发生冲突。

虽然该方案是比较常用的一种方案,但仍存在“判定慢”问题。

问:更新语句, 如果失败或者超时, 就可以发起主备切换了, 为什么还会有判定慢的问题呢?

这个问题主要涉及的是服务器IO资源分配问题。

所有的检测逻辑都需要一个超时时间N。 执行一条update语句, 超过N秒后还不返回, 就认为系统不可用。

假设一个日志盘的IO利用率已经是100%的场景。 这时候, 整个系统响应非常慢, 已经需要做主备切换了。而我们的检测使用的update命令, 需要的资源很少, 所以可能在拿到IO资源的时候就可以提交成功, 并且在超时时间N秒未到达之前就返回给了检测系统。

检测系统一看, update命令没有超时, 于是就得到了“系统正常”的结论。

之所以会出现这个现象,根本原因是我们上面说的所有方法,都是基于外部检测的。而外部检测天然有一个问题:随机性。

因为, 外部检测都需要定时轮询, 所以系统可能已经出问题了, 但是却需要等到下一个检测发起执行语句的时候, 才有可能发现问题。 而且, 如果你的运气不够好的话, 可能第一次轮询还不能发现, 这就会导致切换慢的问题。

总结:

  • 更新判断:在系统库(mysql库)里创建一个表,如health_check,包含一个timestamp字段,表示最后一次执行检测的时间,插入一行数据,定期执行更新语句:update mysql.health_check set t_modified=now();
  • 使用场景:能够检测InnoDB磁盘无法写入的情况。
  • 存在问题:不完善,无法检测语句执行慢但不超时的场景;如磁盘IO打满,但仍然可以响应请求的场景。
  • 解决方案:使用MySQL内部统计判断方案即可解决该问题。

 内部统计(推荐使用)


MySQL 5.6版本以后提供的performance_schema库, 在file_summary_by_event_name表里统计了每次IO请求的时间。

file_summary_by_event_name表里有很多行数据, 我们先来看看event_name='wait/io/file/innodb/innodb_log_file’这一行。

图中这一行表示统计的是redo log的写入时间, 第一列EVENT_NAME 表示统计的类型。

接下来的三组数据, 显示的是redo log操作的时间统计:

  • 第一组五列,是所有IO类型的统计。其中,COUNT_STAR是所有IO的总次数, 接下来四列是具体的统计项, 单位是皮秒; 前缀SUM、 MIN、 AVG、 MAX, 顾名思义指的就是总和、 最小值、平均值和最大值。
  • 第二组六列,是读操作的统计。 最后一列SUM_NUMBER_OF_BYTES_READ统计的是, 总共从redo log里读了多少个字节。
  • 第三组六列,统计的是写操作。

最后的第四组数据, 是对其他类型数据的统计。 在redo log里, 你可以认为它们就是对fsync的统计。

在performance_schema库的file_summary_by_event_name表里, binlog对应的是event_name = "wait/io/file/sql/binlog"这一行。 各个字段的统计逻辑, 与redo log的各个字段完全相同。

注1:因为我们每一次操作数据库, performance_schema都需要额外地统计这些信息, 所以我们打开这个统计功能是有性能损耗的。

注2:如果打开所有的performance_schema项, 性能大概会下降10%左右。 所以,建议只打开自己需要的项进行统计。

打开或者关闭某个具体项的统计:如果要打开redo log和binlog的时间监控, 你可以执行这个语句:

update setup_instruments set ENABLED='YES', Timed='YES' where name like '%wait/io/file/sql/binlog%';
update setup_instruments set ENABLED='YES', Timed='YES' where name like '%wait/io/file/innodb/innodb_log_file%';

问:假设, 现在你已经开启了redo log和binlog这两个统计信息, 那要怎么把这个信息用在实例状态诊断上呢?

答:可以通过MAX_TIMER的值来判断数据库是否出问题了。 比如, 你可以设定阈值, 单次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') and MAX_TIMER_WAIT>200*1000000000;

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

truncate table performance_schema.file_summary_by_event_name;

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1820008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为昇腾异构计算架构CANN及AI芯片简介

异构计算架构CANN 异构计算架构CANN(Compute Architecture for Neural Networks)是华为针对AI场景推出的异构计算架构,向上支持多种AI框架,包括MindSpore、PyTorch、TensorFlow等,向下服务AI处理器与编程,…

C语言小例程10/100

题目&#xff1a;要求输出国际象棋棋盘。 程序分析&#xff1a;国际象棋棋盘由64个黑白相间的格子组成&#xff0c;分为8行*8列。用i控制行&#xff0c;j来控制列&#xff0c;根据ij的和的变化来控制输出黑方格&#xff0c;还是白方格。 #include<stdio.h>int main() {…

联邦学习权重聚合,联邦学习权重更新

目录 联邦学习权重聚合 model.state_dict() 保存模型参数 加载模型参数 注意事项 联邦学习权重更新 联邦学习权重聚合 model.state_dict() 在PyTorch框架中,model.state_dict() 是一个非常重要的方法,它用于获取模型的参数(即权重和偏置)作为一个有序字典(Order…

边缘计算网关在智慧厕所远程监测与管理的应用

随着智慧城市建设的不断深入&#xff0c;城市公共设施的智慧化管理成为了提升城市品质和居民生活质量的关键建设。公厕作为城市基础设施的重要组成部分&#xff0c;其管理效率和卫生状况直接影响着市民的日常生活体验。在公厕设施建设背景下&#xff0c;边缘计算网关技术的应用…

【ARMv8/ARMv9 硬件加速系列 3 -- SVE 硬件加速向量运算 1】

文章目录 SVE 使用介绍SVE 特点SVE2 特点 SVE 寄存器扩展的向量寄存器可扩展的谓词寄存器.d 与 .b 后缀的区别举例介绍使用 .d 后缀进行64位元素操作使用 .b 后缀进行8位元素操作 ptrue 指令小结 FFR 寄存器 SVE 使用介绍 前面文章:【ARMv8/ARMv9 硬件加速系列 1 – SVE | NEO…

Docker 镜像源更换

实现 替换docker 镜像源 前提要求 安装 docker docker-compose 参考创建一键更换docker国内镜像源 Docker 镜像代理DaoCloud 镜像站百度云 https://mirror.baidubce.com南京大学镜像站

企事业单位安全生产月活动怎样向媒体投稿?

作为一名单位的信息宣传员,我肩负着将每一次重要活动的精彩瞬间转化为文字,向外界传递我们单位声音的重任。初入此行时,我满怀热情,坚信通过传统的方式——电子邮件投稿,能够有效地将我们的故事传播出去。然而,现实却给我上了生动的一课。 记得在筹备“安全生产月”活动的宣传时…

linux系统——wget命令

wget命令可以用于下载指定的url地址文件&#xff0c;支持断点续传&#xff0c;支持ftp&#xff0c;http协议下载&#xff0c;在下载普通文件时&#xff0c;即使网络出现故障&#xff0c;依然会不断尝试下载 wget命令直接加url地址 使用-o参数可以将下载文件改名&#xff0c;-c…

「OC」UI练习(二)——照片墙

「OC」UI练习——照片墙 文章目录 「OC」UI练习——照片墙UITapGestureRecognizer介绍照片墙实现 UITapGestureRecognizer介绍 UITapGestureRecognizer是UIKit框架中的一个手势识别器类&#xff0c;用于检测用户在视图上的轻击手势。它是UIGestureRecognizer的一个子类&#x…

人工智能革命:2024年指数报告揭示AI行业十大趋势

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;正逐渐渗透到我们生活的方方面面。斯坦福大学李飞飞教授领导的斯坦福以人为本人工智能研究所&#xff08;HAI&#xff09;发布的《2024年人工智能指数报告》为我们揭示了AI行业的最新趋势和未来的发展方向。以…

【GIS】全球范围气象站点的逐年平均气温数据(1929-2023年)

数据简介&#xff1a;气象数据包括气象站点温度、湿度、光照等等。提供自1929-2023年以来的全球逐年平均气温数据气象数据下载。数据源为NCDC&#xff08;美国国家气候数据中心&#xff0c;National Climatic Data Center&#xff09;&#xff0c;隶属于NOAA&#xff08;美国国…

Ubuntu server 24 (Linux) Zabbix 7.0 LTS 配置mail邮件报警

1 告警--媒介 选择右边默认模板修改 2 用户设置--配置--报警媒介 3 告警--动作--触发器动作 #测试 sudo systemctl stop zabbix-agent 本文使用postfix自建邮件服务器&#xff0c;如有需要请看

Java项目:110 springboot夕阳红公寓管理系统的设计与实现

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本系统有管理员&#xff0c;租客 管理员权限操作的功能包括对租客&#xff0c;访客&#xff0c;缴费&#xff0c;维修&#xff0c;留言&#xff0c;公…

【PyTorch 新手基础】Regularization -- 减轻过拟合 overfitting

Overfit 过拟合&#xff0c;效果如最右图所示 常见应对方案如下&#xff1a; 增大数据集入手&#xff1a;More data or data argumentation简化模型参数入手&#xff1a;Constraint model complexity (shallow model, regularization) or dropout dropout: torch.nn.Dropout(0…

ElementPlus国际化(将组件的默认语言改为中文)

文章目录 1. Element-plus的默认语言2. 编辑 main.js 文件3. 效果&#xff08;以分页条组件为例&#xff09; 1. Element-plus的默认语言 Element-plus的默认语言是英语&#xff0c;可修改为其它语言 2. 编辑 main.js 文件 import {createApp} from vue import ElementPlus …

【简单介绍下Sass,什么是Sass?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【ARM Cache 与 MMU/MPU 系列文章 1.2 -- Data Cache 和 Unified Cache 的区别是什么?】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 Data Cache and Unified Cache数据缓存 (Data Cache)统一缓存 (Unified Cache)数据缓存与统一缓存的比较小结 Data Cache and Unified Cache 在 ARM架构中&#xff0c;缓存&#xff08…

景芯SoC A72的时钟树分析

innovus的ctslog中的Clock DAG信息可以报出来CTS主要运行步骤的关键信息&#xff0c;比如clustering&#xff0c;balancing做完后的clock tree的长度&#xff0c;clock tree上所用的buffer、inverter&#xff0c;icg cell数量&#xff0c;clock skew等信息。我们以景芯SoC A72 …

掌握WhoisAPI,提升域名管理的效率

在互联网时代&#xff0c;域名管理是网站运营中非常重要的一环。通过域名&#xff0c;我们能够轻松访问和识别不同的网站。然而&#xff0c;域名的注册和管理也是一项复杂的任务&#xff0c;特别是对于大规模拥有许多域名的企业来说。为了提升域名管理的效率&#xff0c;我们可…

【Spring EL<二>✈️✈️ 】SL 表达式结合 AOP 注解实现鉴权

目录 &#x1f37b;前言 &#x1f378;一、鉴权&#xff08;Authorization&#xff09; &#x1f37a;二、功能实现 2.1 环境准备 2.2 代码实现 2.3 测试接口 &#x1f379;三、测试功能 3.1 传递 admin 请求 ​ 3.2 传递普通 user 请求 &#x1f37b;四、章末 &a…