话说今天的一个小小的查询失误给了我比较深刻的教训,也让我对mongo有了更深刻的理解,下面我们来说说这个事情的原委:

我们经常使用阿里云子账号在DMS上查询线上数据库数据,今天也是平常的一次操作

集合:

XXXX_message
数据量约 600万

我执行了下面的mongo查询:

db.XXXX_message.find({"channel_id": "1000000009XXXX700XXXX"}).limit(20);

但是上述语句中的 "channel_id" 字段不存在,真实字段应该是channel(有索引),属于失误操作

在执行过程中,我发现查询时间很久,于是中断了查询又重试了两次,还是很久,最后中断了查询,我意识到我想查的字段可能错了,于是看了下集合索引,使用正确的字段检索得到结果

但就在这时候,一场事故也在悄然酝酿,2分钟后,阿里云监控中心打来告警电话,mongo数据库cpu、iops异常升高

起初并没有意识到是这个查询导致的,还以为是半小时前发布的版本可能有问题,于是立即回滚了版本并开始项目检查

查了许久,并没有查到可能造成本次数据库异常告警的原因,项目对该库的依赖的操作的地方非常少。

当我们苦苦想不到原因的时候,我们去查了下相关慢sql日志,果然一道耗时约1800000ms的慢sql日志引起了我们的注意

这时候我似乎意识到了点什么,我立马查阿里云控制台查询历史核对了我刚才查询的时间和数据库cpu、磁盘iops异常升高的时间节点

完全对上了,该起事故持续半小时左右,那条没有被成功中断的sql也执行了半小时左右

这让我很震惊,一次控制台查询居然导致整个数据库出现如此严重的问题,mongo底层没有考虑过不存在字段查询问题吗?

我慢慢平复心情,仔细回顾这件事情,我尝试着从mongo和mysql的底层去理解这个问题

mongo本身是集合型数据库,意味着每个集合文档都可以有自己独立的数据结构,和mysql等关系型数据库的很重要的区别就是它没有固定的表结构,它包容且随性

当在查询一个不存在的字段的时候,它仍然按照普通查询检索数据,这时候它会全表扫描,也就是说在上述失误语句中,mongo底层检索了整个集合的数据集,

遍历了该集合所有的磁盘块,这才导致磁盘iops升高且cpu升高。

这次经历让我觉得我有必要记录下相关心得,可能对于很多高级技术人员,这些东西都是很容易理解和规避的事情,但大多数人对此可能并没有深刻认识

这次事故让我对技术多了一层敬畏,这有助于我在今后的代码实践和操作中更加谨慎和多一层思考,希望大家以此为戒!

此文共勉!

一次mongo查询不存在字段引发的事故的更多相关文章

  1. 整理最近用的Mongo查询语句

    背景 最近做了几个规则逻辑.用到mongo查询比较多,就是查询交易信息跑既定规则筛选出交易商户,使用聚合管道进行统计和取出简单处理后的数据,用SQL代替业务代码逻辑的判断. 方法 MongoDB聚合使 ...

  2. 创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段

    创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段 添加查询功能 本文将实现通过Name查询用户信息. 首先更新GetAll方法以启用查询: public async ...

  3. oracle查询出的字段加引号

    SELECT 'list.add("' || t.dummy || '");' as listFROM dual t where rownum < 600; 执行结果: SE ...

  4. left join 等连接查询遇到同名字段覆盖问题

    可以在查询时给字段赋别名,但是需要注意以下:*的位置要在最前面,放在其他地方都会出错.这种写法同名覆盖的字段还在,然后在*的后面加上别名字段,已经可以满足所有需求了 SELECT *,r.id as ...

  5. [Elasticsearch] 多字段搜索 (三) - multi_match查询和多数字段 <译>

    multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在“了解你的数据”一节中提 ...

  6. PDO 查询mysql返回字段整型变为String型解决方法

    PDO 查询mysql返回字段整型变为String型解决方法 使用PDO查询mysql数据库时,执行prepare,execute后,返回的字段数据全都变为字符型. 例如id在数据库中是Int的,查询 ...

  7. ElasticSearch 学习记录之ES查询添加排序字段和使用missing或existing字段查询

    ES添加排序 在默认的情况下,ES 是根据文档的得分score来进行文档额排序的.但是自己可以根据自己的针对一些字段进行排序.就像下面的查询脚本一样.下面的这个查询是根据productid这个值进行排 ...

  8. Oracle生成查询包含指定字段名对应的所有数据表记录语句

    应用场合:已知字段名字,查询数据库中所有数据表中包含该字段名的所有数据表 操作办法:指定字段名,数据库表用户,执行下面查询语句即可 --Oracle生成查询包含指定字段名对应的所有数据表记录语句 de ...

  9. mysql 去除重复 Select中DISTINCT关键字的用法 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是 distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了很久,用distinct不能解决的话,

      在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记 ...

随机推荐

  1. flask-mail 机制

    上课无聊,总结下学习的flask-mail 机制 flask-mail 了解 flask-mail 机制中可以用pip 安装也可以用pycharm里面直接安装. flask-mail是一个能调用smt ...

  2. js滑动到页面底部实现

    js实现 1.window.scrollTo(0,document.documentElement.clientHeight);  //js jq实现 2 .var windowHeight = pa ...

  3. 【运行机制】 JavaScript的事件循环机制总结 eventLoop

    0.从个例子开始 //code-01 console.log(1) setTimeout(() => { console.log(2); }); console.log(3); 稍微有点前端经验 ...

  4. 【题解】The Last Hole! [CF274C]

    [题解]The Last Hole! [CF274C] 传送门:\(\text{The Last Hole!}\) \(\text{[CF274C]}\) [题目描述] 给出平面上 \(n\) 个圆的 ...

  5. 学习笔记:Link Cut Tree

    模板题 原理 类似树链剖分对重儿子/长儿子剖分,Link Cut Tree 也做的是类似的链剖分. 每个节点选出 \(0 / 1\) 个儿子作为实儿子,剩下是虚儿子.对应的边是实边/虚边,虚实时可以进 ...

  6. eureka配置说明

    以下配置来源于jar中的源码,采用标准两个空格作为缩进 eureka.yml spring: application: name: APPLICATION_NAME # 应用名,在eureka上注册为 ...

  7. STL——容器(Map & multimap)的排序与遍历

    1. Map & multimap 的排序与遍历 map<T1,T2,less<T1> >  mapA; //该容器是按键的升序方式排列元素.如果未指定less< ...

  8. 【Django admin 中文配置】

    打开settings.py文件,找到语言编码.时区的设置项,将内容改为如下: [其中 zh-Hans是简体中文 zh-Hant是繁体中文] LANGUAGE_CODE = 'zh-Hans' # LA ...

  9. 解决python3 ,ModuleNotFoundError: No module named 'pip'问题

    今天想要装一下PyYmal第三方库来写一下Python的desired_caps.yaml文件,候发现cmd窗口下无法执行pip命令, 出现了:ModuleNotFoundError: No modu ...

  10. Envoy入门实战部署

    一.Envoy介绍 官方文档解释: Envoy是专为大型现SOA(面向服务架构)设置的L7代理和通信总线.该项目源于以下理念:网络对应用程序来说应该是透明的.当网络和应用程序出现问题时,应该很容易确定 ...