【MySQL】数据库系统中的“黑天鹅”

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 一 前言  纳西姆.尼古拉斯.塔勒布的经典著作《黑天鹅》中对“黑天鹅现象”的定义是 - 不可预测,人们事前往往低估其发生的可能性 - 造成极大影响 - 事后回头再看,又觉得此事发生的有理 二 分析   稳定性是一项衡量基础系统是否永续服务的绝对指标,作为资深DBA从业人员,相信大多数公司运维团队都会制定稳定性的SLA指标达到N个9,为用户提供Full-Time 服务。
一 前言
 纳西姆.尼古拉斯.塔勒布的经典著作《黑天鹅》中对“黑天鹅现象”的定义是
  1. - 不可预测,人们事前往往低估其发生的可能性
  2. - 造成极大影响
  3. - 事后回头再看,又觉得此事发生的有理
二 分析
  稳定性是一项衡量基础系统是否永续服务的绝对指标,作为资深DBA从业人员,相信大多数公司运维团队都会制定稳定性的SLA指标达到N个9,为用户提供Full-Time 服务。然而前一段时间各种"黑天鹅”式的因素导致一系列的系统故障,严重影响了C端B端的用户的使用体验。是数据库系统或者说业务系统的“脆弱性”表现。什么是导致业务故障的“黑天鹅”呢?例举最近遇到的和数据库相关的场景:
a 程序异常,比如异常传参导致本应该获取1行数据的结果去调用14w行,高压力下慢查询将数据库会话占满,引发”雪崩效应“。
b 正常分页调用,但是遇到大分页查询高频访问db,同样会导致慢查询引发“雪崩效应”。
c 第三方业务开发不了解api的使用方法 ,选择全量拉取而非增量拉取业务数据,导致大量慢查询。
上述三个例子的共性基本都含有慢查询,高频访问。找到导致问题发生的数据库层面的原因,剩下的就是发挥产品/开发DBA的特长了,获取到慢查询,然后各个击破之。本文举例几个具有代表性的sql
案例一 大分页查询优化
    商家会使用第三方软件拉取订单数据进行对账,使用limit N,M  分页查询每次拉取50 或者100页,小批量数据时比如N小于 10000时性能表现正常,但是遇到大的商家比如罗辑思维 ,糕妈优选等大商家,拉取数据的时间会随着N 的增加而增大。
  1. select * from so where 1 and `bb` = 'xxxxx' and `cc` in ('5') and `dd` in ('0','1','2','3') order by id desc limit 70000,100;
优化方法
1 利用索引的有序性,更确切的是利用 where条件的索引有序性,尽可能使用到组合索引的created_time有序性代替使用order by id查询,MySQL在使用索引的时候 只能利用一个有效索引,order by id 可能会导致优化器选择主键而非 cc,dd,created_time这样的组合索引。
2 通常我们推荐使用 延迟关联 的方法来优化大分页查询--- 利用覆盖 取复合条件的记录的主键id,然后驱动表根据主键来访问想要的数据,这样的访问速度要比limit 顺序扫描全索引然后回表的速度要快很多。
  1. select a.* from so a,(select id from so where 1 and `bb` = 'xxxxx' and `cc` in ('5') and `dd` in ('0','1','2','3') order by created_time desc limit 70000,101 ) b where a.id=b.id;
3 应用层优化商家本质上是想要获取全量数据,之前的方式是每天或者每周固定时间点定期获取某个时间段内的全量数据,换个思路我们的业务提供push推送任务,专门主动推送商家的增量数据,这样可以避免大批量的拉取全量数据,减少db的不稳定性也同时节约公司的带宽成本。
案例二 join 查询优化
大致的业务逻辑根据商品交易信息获取商家售卖销量,相关sql 以及表结构信息 
  1. select count(o.ono) as num from so o, oi i where o.ono = i.ono and `o`.`kid` = 'xxxx' and `i`.`gid` = 'yyyy';
  1. oi 表的索引
  2.   KEY `idx_sid` (`idx_sid`) USING BTREE,
  3.   KEY `idx_ono` (`idx_ono`) USING BTREE,
  4.   KEY `idx_created` (`created`)
  5. so 表的索引
  6.   key idx_kid(kid,cc,created_time)
  在MySQL中,目前而言只有一种join算法 也即是nested loop join:是通过驱动表(from后的第一个表)的结果集作为循环的基础数据,然后将结果集中的数据作为过滤条件一条条地到下一个表中查询数据,最后合并结果。本案例中可以理解为 以so kid=16553711 的结果数据 去匹配 oi 表中gid=yyyy 符合记录的数据,然后做count操作。通常我们对于join查询的 优化原则
  1. 1 减少nested loop的循环次数,使用小结果集驱动大结果集。
  2. 2 优先优化Nested Loop的内层循环,内循环中的where条件一定要使用最优的索引。
  3. 3 保证join语句中被驱动表的join条件字段已经被索引;
  4. 4 如果无法保证被 驱动表的Join条件字段被索引且内存充足的情况下,可以通过调join_buffer_size来设置join buffer的大小 。
化方法
  1 根据优化原则我们将 oi表的idx_ono 索引调整为 idx_gid_ono(gid,ono),使用覆盖索引解决内循环回表的IO消耗。可能会有人会咨询为什么不调整表的顺序,其实第一个想到优化的就是调整顺序,但是在现有索引条件下调整驱动表的顺序并没有提高查询效率。
  2 其实作为一个服务电商业务线的老司机,我认为涉及C端应用调用应该避免或者说禁止使用join查询,业务增长带来访问量透传给DB的压力,很可能将上面的优化结果轻松覆盖。最优化的方式尽可能的使用kv查询,单表查询。好在我们公司给力的开发同学王野已经将该优化业务迁移到es中,直接通过es获取结果。
案例三 并发count(*) 优化
     因为业务逻辑处理不力,导致数据库并发count 进程数飙高到200左右,严重影响到其他业务的正常请求。其实对于count操作的优化相对比较有限 
     1 确保where条件一定利用到最优索引。
     2 业务层面避免并发count操作,可以使用缓存来规避直接访问db。
     关于count的优化文章可以参考 拙作 《 性能优化之 count(*) VS count(col) 》 
三 小结
    最近一个多月一直紧跟公司的慢查询这块做集中优化,到目前为止效果相当不错,基本将慢查询减少了90%左右。从slow log文件大小来看,此次优化将文件大小从1M 减少到4k 左右,解决了绝大多数的潜在的系统风险。 

诚然通过优化慢查询,使用缓存 ,并无法绝对避免“黑天鹅”式故障发生,系统的稳定性是应用层的健壮性,底层基础服务 网络,机器硬件,数据库层面等各个环节息息相关的,我们要做的就是通过提高数据库系统和业务系统的 “反脆弱性”,提高抗击打能力,为用户提供可持续的稳定的服务。
四 推荐文章
[1] 《黑天鹅:如何应对不可知的未来
[2] 《反脆弱:从不确定性中获益
[3] 《关于高可用的系统

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
9天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
24 1
|
11天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
27 4
|
18天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
86 1
|
20天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
61 2
|
23天前
|
存储 关系型数据库 MySQL
MySQL vs. PostgreSQL:选择适合你的开源数据库
在众多开源数据库中,MySQL和PostgreSQL无疑是最受欢迎的两个。它们都有着强大的功能、广泛的社区支持和丰富的生态系统。然而,它们在设计理念、性能特点、功能特性等方面存在着显著的差异。本文将从这三个方面对MySQL和PostgreSQL进行比较,以帮助您选择更适合您需求的开源数据库。
90 4
|
6天前
|
运维 关系型数据库 MySQL
安装MySQL8数据库
本文介绍了MySQL的不同版本及其特点,并详细描述了如何通过Yum源安装MySQL 8.4社区版,包括配置Yum源、安装MySQL、启动服务、设置开机自启动、修改root用户密码以及设置远程登录等步骤。最后还提供了测试连接的方法。适用于初学者和运维人员。
45 0
|
29天前
|
存储 关系型数据库 MySQL
如何在MySQL中创建数据库?
【10月更文挑战第16天】如何在MySQL中创建数据库?
|
19天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
47 0
|
28天前
|
存储 监控 关系型数据库
MySQL并发控制与管理:优化数据库性能的关键
【10月更文挑战第17天】MySQL并发控制与管理:优化数据库性能的关键
119 0
|
28天前
|
存储 SQL 关系型数据库
MySQL Workbench支持哪些数据库引擎
【10月更文挑战第17天】MySQL Workbench支持哪些数据库引擎
21 0