一次Mysql update sql不当引起的生产故障记录


Posted in MySQL onApril 01, 2022

故障表现

  • 一方面 :在阿里云控制台云数据库PolarDB对应的集群管理页面上,在诊断与优化模块里面的一键诊断会话管理中,发现某条update sql 执行时间非常久且非常频繁;

  • 另一方面:业务监控系统中开始不断有业务执行时间发出告警信息提示,且告警的业务数据不断上升,部分操作影响客户使用。

业务背景

由于业务操作涉及到的业务流比较复杂,对纯技术的分享来看,不是重点讨论的话,为了更有利于理解问题发生的原因,使用类比的方式,把复杂的业务类比成如下描述: 有数据库3张表,第一张表t_grandfather (爷表),第二张表为t_father(父表),第三张表t_grandson(子孙表),DDL如下:

CREATE TABLE `t_grandfather ` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `count` int(11) NOT NULL DEFAULT 0 COMMENT '子孙后代数量',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='老爷表';

CREATE TABLE `t_father ` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `grandfather_id` int(11) NOT NULL COMMENT '老爷表id',
  PRIMARY KEY (`id`),
  KEY `idx_grandfather_id` (`grandfather_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='老爸表';

CREATE TABLE `t_grandson` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `grandfather_id` int(11) NOT NULL COMMENT '老爷表id',
  PRIMARY KEY (`id`),
  KEY `idx_grandfather_id` (`grandfather_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='孙子表';

三张表之间的业务逻辑关系为,先生成老爷表,然后这个老爷取很多老婆(业务),会不断的生娃,生一个娃就会生成一张老爸表,同时会更新老爷表的count=count+1,表示新增一个后代了,老爷的老婆(业务)在不断的生娃的时候,之前的生的娃也会有老婆,他们的老婆也会生娃,对老爷来说,就是它有了孙子(产生新的业务数据),那有了孙子之后也需要更新老爷表的count=count+1,表示新增一个后代了,以此类推,子子孙孙无穷尽也(业务数据不断生成) 如下图所示:

一次Mysql update sql不当引起的生产故障记录

祖传代码的逻辑为,只要是t_father表和t_grandson有新增,就去更新t_grandfather。这个逻辑设计上问题不大,不过考虑到孙子表数据量很猛的时候,这里就会出现一个非常严重的性能问题。以下是业务摘取的一部分伪代码

/**
 * 处理 father 的业务
 */
 public void doFatherBusiness  (){
     //do fatherBusiness baba .... 此处省
     // 插入 t_father 表
    if (fatherMapper.inster(father)){
         //update t_grandfather set count=count+1 where id= #{grandfatherId}
         grandfatherMapper.updateCount(father.getGrandfatherId  ())  ;
     }
}


 /**
 * 处理 grandson 的业务
 */
 public void doGrandsonBusiness  (){
     //do grandson baba .... 此处省略
     // 插入 t_grandson 表
     if(grandsonMapper.inster(grandson)){
          //update t_grandfather set count=count+1 where id= #{grandfatherId}
          grandfatherMapper.updateCount(grandson.getGrandfatherId());
     }
}

当多个业务(线程)分别调用上面的方法时,都会对t_grandfather表的更新操作造成巨大的压力,特别是更新同一个id的情况下,mysql server内部对锁的竞争非常激烈。最后表现出来就如前文背景描述的一致。

解决方案

1. 临时处理方案:

一方面,在阿里云控制台,对sql进行限流,在正常阻塞的会话,强制kill掉,让数据的线程不阻塞着,释放资源,另外一方面,在把接收请求的服务减少节点数,目的是减少业务数据量进入;

2. 长久方案

一方面更改掉上面的业务逻辑,插入t_grandson表和t_father表时,不在去更新t_grandfather表的count字段;另一方面,需要用到count统计需求时,全部切换成别的方式;

总结

到此这篇关于一次Mysql update sql不当引起的生产故障的文章就介绍到这了,更多相关Mysql update sql生产故障内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
浅析InnoDB索引结构
Apr 05 MySQL
详解MySQL事务的隔离级别与MVCC
Apr 22 MySQL
正确使用MySQL update语句
May 26 MySQL
MySQL中使用or、in与union all在查询命令下的效率对比
May 26 MySQL
使用ORM新增数据在Mysql中的操作步骤
Jul 26 MySQL
SQL优化老出错,那是你没弄明白MySQL解释计划用法
Nov 27 MySQL
彻底解决MySQL使用中文乱码的方法
Jan 22 MySQL
Windows下载并安装MySQL8.0.x 版本的完整教程
Apr 10 MySQL
MySQL事务操作的四大特性以及并发事务问题
Apr 12 MySQL
MySQL 数据表操作
May 04 MySQL
MYSQL常用函数介绍
May 05 MySQL
MySql按时,天,周,月进行数据统计
Aug 14 MySQL
Mysql超详细讲解死锁问题的理解
Nebula Graph解决风控业务实践
MySQL实现配置主从复制项目实践
Mysql多层子查询示例代码(收藏夹案例)
Mar 31 #MySQL
MySQL Server层四个日志的实现
分享几个简单MySQL优化小妙招
MySQL Server 层四个日志
You might like
2019年中国咖啡业现状与发展趋势
2021/03/04 咖啡文化
mysql_fetch_assoc和mysql_fetch_row的功能加起来就是mysql_fetch_array
2007/01/15 PHP
php Notice: Undefined index 错误提示解决方法
2010/08/29 PHP
PHP的error_reporting错误级别变量对照表
2014/07/08 PHP
php导出CSV抽象类实例
2014/09/24 PHP
Thinkphp和Bootstrap结合打造个性的分页样式(推荐)
2016/08/01 PHP
php 三元运算符实例详细介绍
2016/12/15 PHP
Laravel框架用户登陆身份验证实现方法详解
2017/09/14 PHP
jQuery AJAX回调函数this指向问题
2010/02/08 Javascript
基于jquery的返回顶部效果(兼容IE6)
2011/01/17 Javascript
用js判断是否为360浏览器的实现代码
2015/01/15 Javascript
JavaScript实现获取dom中class的方法
2015/02/09 Javascript
js实现兼容性好的微软官网导航下拉菜单效果
2015/09/07 Javascript
jquery动态遍历Json对象的属性和值的方法
2016/07/27 Javascript
Vue.js常用指令汇总(v-if、v-for等)
2016/11/03 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
详解使用Visual Studio Code对Node.js进行断点调试
2017/09/14 Javascript
ES6之模版字符串的具体使用
2018/05/17 Javascript
axios对请求各种异常情况处理的封装方法
2018/09/25 Javascript
JS利用prototype给类添加方法操作详解
2019/06/21 Javascript
vue仿携程轮播图效果(滑动轮播,下方高度自适应)
2021/02/11 Vue.js
Python中functools模块函数解析
2017/03/12 Python
对PyQt5基本窗口控件 QMainWindow的使用详解
2019/06/19 Python
解决Python中pandas读取*.csv文件出现编码问题
2019/07/12 Python
python中什么是面向对象
2020/06/11 Python
matplotlib交互式数据光标实现(mplcursors)
2021/01/13 Python
Travelstart沙特阿拉伯:廉价航班、豪华酒店和实惠的汽车租赁优惠
2019/04/06 全球购物
SIMON MILLER官网:洛杉矶的生活方式品牌
2020/10/19 全球购物
扩大国家免疫规划实施方案
2014/03/21 职场文书
营销与策划专业求职信
2014/06/20 职场文书
医院深入开展党的群众路线教育实践活动实施方案
2014/08/27 职场文书
运动会加油稿30字
2015/07/21 职场文书
2015初中团委工作总结
2015/07/28 职场文书
创业计划书之服装
2019/10/07 职场文书
浅谈JS和Nodejs中的事件驱动
2021/05/05 NodeJs
python调用ffmpeg命令行工具便捷操作视频示例实现过程
2021/11/01 Python