一次mongo查詢不存在字段引起的事故

  話說今天的一個小小的查詢失誤給了我比較深入的教訓,也讓我對mongo有了更深入的理解,下面咱們來講說這個事情的原委:mysql

咱們常用阿里雲子帳號在DMS上查詢線上數據庫數據,今天也是日常的一次操做sql

集合:數據庫

XXXX_message
數據量約 600萬

我執行了下面的mongo查詢:數據結構

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

可是上述語句中的 "channel_id" 字段不存在,真實字段應該是channel(有索引),屬於失誤操做阿里雲

在執行過程當中,我發現查詢時間好久,因而中斷了查詢又重試了兩次,仍是好久,最後中斷了查詢,我意識到我想查的字段可能錯了,因而看了下集合索引,使用正確的字段檢索獲得結果日誌

但就在這時候,一場事故也在悄然醞釀,2分鐘後,阿里雲監控中心打來告警電話,mongo數據庫cpu、iops異常升高blog

 

 

起初並無意識到是這個查詢致使的,還覺得是半小時前發佈的版本可能有問題,因而當即回滾了版本並開始項目檢查索引

查了許久,並無查到可能形成本次數據庫異常告警的緣由,項目對該庫的依賴的操做的地方很是少。文檔

當咱們苦苦想不到緣由的時候,咱們去查了下相關慢sql日誌,果真一道耗時約1800000ms的慢sql日誌引發了咱們的注意it

這時候我彷佛意識到了點什麼,我立馬查阿里雲控制檯查詢歷史覈對了我剛纔查詢的時間和數據庫cpu、磁盤iops異常升高的時間節點

徹底對上了,該起事故持續半小時左右,那條沒有被成功中斷的sql也執行了半小時左右

 

 

這讓我很震驚,一次控制檯查詢竟然致使整個數據庫出現如此嚴重的問題,mongo底層沒有考慮過不存在字段查詢問題嗎?

我慢慢平復心情,仔細回顧這件事情,我嘗試着從mongo和mysql的底層去理解這個問題

mongo自己是集合型數據庫,意味着每一個集合文檔均可以有本身獨立的數據結構,和mysql等關係型數據庫的很重要的區別就是它沒有固定的表結構,它包容且隨性

當在查詢一個不存在的字段的時候,它仍然按照普通查詢檢索數據,這時候它會全表掃描,也就是說在上述失誤語句中,mongo底層檢索了整個集合的數據集,

遍歷了該集合全部的磁盤塊,這才致使磁盤iops升高且cpu升高。

此次經歷讓我以爲我有必要記錄下相關心得,可能對於不少高級技術人員,這些東西都是很容易理解和規避的事情,但大多數人對此可能並無深入認識

此次事故讓我對技術多了一層敬畏,這有助於我在從此的代碼實踐和操做中更加謹慎和多一層思考,但願你們以此爲戒!

此文共勉!

相關文章
相關標籤/搜索