主頁 > 資料庫 > X偵探所事件薄 | 一次記憶體溢位之謎

X偵探所事件薄 | 一次記憶體溢位之謎

2020-11-02 19:39:34 資料庫

作者 姜宇祥,曾就職于達夢和攜程,目前在CDB/CynosDB資料庫內核團隊擔任TXSQL云資料庫內核研發,多年深耕資料庫領域,為國內早期一批資料庫內核研發人員,過去曾在達夢經歷了新一代達夢從零開始的整個研發程序,并參與多個版本的迭代與架構調整;還曾在攜程率先開啟MySQL的定制開發,為線上業務提供支持,另一方面,他也積極參與MySQL開源社區在中國成長程序,通過技術宣講與文章撰寫助力MySQL在中國的傳播,

引言

在數字領域,TX王國是一個統御著“成T上P”資料子民的大國,這里的T和P是極大極大的數,用成千上萬來形容資料量之多并不為過,X偵探事務所就是TX王國中負責MySQL領域管理資料子民的有關部門,而事務所中探員們就是專門負責解決各種各樣突發事件的戰斗精英,

我們將要講述的是關于這些探員的偵探故事,他們擅長在海量的資料中追尋蛛絲馬跡,屢破奇案,這次,我們將要講述的是一個連環宕機血案的偵破故事,

案發現場

一天,探員T因遇到了一個棘手的MySQL實體宕機問題而頭疼不已,通過內部的監控系統發現一個MySQL資料服務使用的記憶體就像坐了加了速的小汽車一樣飛速上漲,作業系統為了保證整個系統的運行,不得不將該MySQL服務殺死,以釋放足夠的資源用于系統正常運轉,這是一個很嚴重的問題,任何服務的宕機以及記憶體不正常現象都是要優先進行排查并處理,

記憶體溢位(Out Of Memory)

一般是由于程式撰寫者對記憶體使用不當,如沒有及時釋放申請的記憶體資源,導致該記憶體一直不能被再次使用而使計算機記憶體被耗盡的現象,殺死行程或重啟計算機可從作業系統層面解決問題,但根本解決辦法還是對代碼進行改進,

image.png

案件經過

面對這種緊急情況,經驗豐富的探員T迅速登錄服務器查看情況,首先懷疑的是打開的表太多,導致大量的表物件占用了記憶體空間,經過對frm檔案和ibd檔案的底層粗略查詢,該MySQL實體上有20多萬張的表,那么,大量的表物件占用了記憶體空間的必要條件就成立了,于是進一步查看,限制表打開數目的變數“table_definition_cache”是否設定的過大,導致占用的記憶體過多,

但是,該變數并未如預期中設定的過大,屬于合理范圍,那么為什么記憶體還會占用如此之多?探員T此刻陷入了深深的思考,現在案件似乎走入了一個死胡同,也就是存在大量的表但是對打開表的資源限制在了一個合理的范圍內,這似乎是一個悖論,關鍵問題來了,到底是哪里占用了大量的資源呢?

作為一個優秀的探員,探員T立刻意識到事件發生的現場應該還會存有大量的案發資訊,于是他立刻又回到案發現場,努力嘗試重現該事件發生的整個程序,這是一個很重要的環節,很多問題的定位都是通過還原重現場景來完成的,經過對線上管控人員的細致調查,發現了一條可疑地SQL陳述句,每當執行該陳述句的時候,記憶體使用就會不可遏制的向上增長,這條陳述句就是:


SELECT table_schema, table_name, partition_name, table_rows

FROM information_schema.partitions

WHERE partition_name IS NOT NULL	

ORDER BY table_schema, table_name;

通過對該陳述句的跟蹤,發現該陳述句主要完成兩件事情:

(1)遍歷打開MySQL實體的所有表并獲取這些表資訊

(2)現在將這些資訊寫入臨時創建的表中

從以往的經驗來看,臨時創建的表不會占用太多的資源,而且理論上二十多萬行的資料也不會占用太多空間,于是遍歷所有表這個操作就變得愈發可疑,這也聯系上了之前的猜測,“打開的表太多,導致大量的表物件占用了記憶體空間”,事情排插到了這一步,探員T 直覺推測很可能就是該操作導致的OOM,真相只有一個,那么 探員T該如何印證這個猜想呢?

工欲善其事,必先利其器,想要快速的定位問題,探員們必須熟練掌握并使用恰當的排障工具,而MySQL就提供了這樣一個強大的實時運行工具箱——performance_schema,之所以稱之為工具箱,是因為它是很多工具的集合,今天我們要用的是這個工具箱中關于記憶體的工具,其他的工具我們將來會有專門的專題來講述,

現在我們需要在組態檔中增加如下配置以開啟對記憶體使用的監控:

image.png

并通過該陳述句查詢記憶體使用情況:

Select * from performance_schema.memory_summary_by_thread_by_event_name order by CURRENT_COUNT_USED

desc limit 10;

通過上面的操作,探員T 發現確實是表物件打開的過多,不過這些表物件不是MySQL Server層打開的物件,而是存盤引擎層innobase打開幾乎全部的表物件并進行快取,從而沒有及時釋放導致了大量記憶體的占用,但對于一個成熟的程式來說不會不回收資源,那么innodb為什么沒有回收資源呢?原來對于表的記憶體物件回收是在下面這個后臺執行緒進行回收的

image.png

如下代碼所示,在srv_master_thread的后臺執行緒函式中,會在active和idle兩種情況下進行資源回收,

image.png

在頻繁有操作的環境下,idle場景是不會被觸發;而在active場景下,結合如下代碼分析,平均47秒才會有一次主動的記憶體回收,

image.png

image.png

俗話說辦法總比問題多,既然定位了問題,那么就可以解決問題了,探員T在被動釋放記憶體物件的基礎上,innobase每次打開表時檢測記憶體中表物件的打開數量,當超過指定的閾值就進行釋放,從而解決了問題,

再次案發

至此,探員T已經完成了OOM問題的定位和解決,在其他相關部門相互協作下,將修改好的新版本發布到了線上,但就在大家覺得問題已經解決,可以放松一下的時候,噩耗傳來,新版本竟又出現了宕機,一波未平一波又起,還未來得及好好休息的探員T又再次披掛上陣來解決問題,

首先要分析是不是新修改引進的問題,一般會用兩個方法:

(1) 快速回滾發布到線上的版本,對于觸發頻繁的實體,該方法為首選,因為可以快速驗證;

(2) 另一個是審查修改后的源代碼,對于改動較少的版本來說,這個方法可以作為首選,

探員T 首先重新審查了修改的代碼,這次修改只增加89行的內容,理論上可以很快就定位到問題,而且線上問題的出現頻率并不是很高,

經過反復從代碼層面進行分析,卻并沒有能找到引發錯誤的任何蛛絲馬跡,用于回收innobase記憶體物件的函式是經過驗證的函式,這個函式已經伴隨著MySQL發布的很多版本,無論如何都不應該也不會出現,那么問題的根本原因會是什么呢?

此時在 探員T腦海中開始回想事情發生的整個經過:首先是針對innobase記憶體物件優化的修改而引發的服務崩潰,其次是通過線上實體的堆疊了解到問題是發生在執行前文中提到的information_schema查詢陳述句,最后通過分析新增代碼的邏輯確認該改動沒有問題,

在這種情況下,就不能僅憑靜態的現場進行分析了,正所謂“紙上得來終覺淺,覺知此事要躬行”,需要能夠復現事件的發生,通過coredump或者gdb的斷點是解決這類只有靜態現場但并無思路的好辦法,很多人以為重現問題很簡單,但由于大多數時候的問題是并發造成的,并發的偶然性就造成了問題出現的偶然性,嘗試重現有兩個好處,一是能摸清楚問題發生的規律,這本身就能幫助我們將問題限定在某個范圍;二是,穩定重現可以幫助我們在不停嘗試斷點的設定,同樣會不斷縮小問題的范圍,最終通過背景關系環境,進而推斷出問題原因,

首先嘗試的是運行前文中提到的SQL陳述句,但在多次運行后并未觸發服務崩潰的問題,同時結合上線前跑過的MySQL基本測驗,可以判定該問題為并發模式下被觸發,這里介紹一款比較熱門的工具sysbench,因其易安裝易使用的特點,在DBA和測驗人員中被廣泛的使用,首先通過sysbench創建了2萬張資料表并在每張表中插入兩條資料,然后發起壓力測驗,測驗期間運行上文中的SQL陳述句,在多次嘗試后,問題再次出現,并通過該方法穩定的重現,得到了出問題的core dump,

以下是在打開表時出現錯誤的堆疊以及出錯時出現問題的變數,

image.png

image.png

以下是運行時出錯位點出現宕機的斷言

image.png

斷言

MySQL在運行時進行狀態檢查的一種手段,用于斷定某種情況的必然成立,所以被稱為斷言,

通過對core dump的分析,發現問題是發生在打開表的程序中,快速獲取的資料表記憶體物件出現了記憶體訪問出錯,也就是通過如下方式獲取的記憶體物件,

image.png

為什么會在這一步獲取的記憶體物件會出現錯誤?從這里看,和之前修改有什么必然關聯?探員T 又開始回顧出問題時的變數,如下圖所示:

image.png

以其豐富的經驗看,此時m_share中的index物件已經被釋放,聯系之前的改動是innodb在打開表達到閾值時釋放記憶體物件,那么也就是說在釋放記憶體物件的時候沒有進行回應的保護,如果是這樣的話的,那么也就是在innodb在進行active/idle作業時也會出錯,只是由于對于釋放操作函式srv_master_evict_from_table_cache的呼叫不夠頻繁,所以出現問題的概率降低到非常低,于是嘗試修改代碼,提高釋放記憶體物件的頻率,代碼修改如下:

image.png

重新運行測驗驗證,Bingo,得到了同樣的結果,社區版的MySQL同樣會出現宕機的情況,至此,終于確定了問題的根本原因,那么接踵而至的是,為什么share物件中的表記憶體物件沒有被保護,在innodb進行active/idle作業時被釋放?此時需要進行追本溯源,對get_share/free_share和dict_table_open/dcit_table_close的程序進行分析,發現如下在innodb中打開表的順序存在問題,如下圖,當active/idle后臺執行緒釋放了記憶體中的表物件后,事務執行緒恰好獲取了share物件則該share物件中的表記憶體物件都是無效的,

image.png

這里就是涉及到撰寫代碼的一個原則,兩個不同資源的獲取與釋放,在獲取時,被依賴的資源需要放在前面獲取,在釋放時,先獲取資源要后釋放,如下圖所示:

image.png

按照這個原則進行代碼修改,在進行測驗驗證,記憶體問題再也沒有出現,至此對OOM問題的修改所引發的隱藏問題也得到解決,這就是撰寫代碼中經常碰到的,當我們修復了一個問題后,極有可能會觸發另外一個隱藏的問題,而D偵探事務所的 探員T,就是將兩個問題串聯起來進行分析,才能順利定位根本原因并進行修正,

后記

探員T寄語:案件終于順利解決了,希望此類案件以后不會再發生了,這種一個bugfix暗戳戳自帶了一個bug真是防不勝防啊,不過我們的探員T經驗足夠豐富所以此次有驚無險,在MySQL這個領域有X偵探所各位身懷絕技的探員們為大家保駕護航,請大家放心~接下來我們還有其他探員的故事,敬請大家期待~

本文由博客一文多發平臺 OpenWrite 發布!

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/199918.html

標籤:其它

上一篇:oracle創建資料庫和用戶、表空間,管理表空間和資料檔案簡介

下一篇:誰是銀行核心資料庫的破局者?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more