MySQL一次沒有報錯的關閉

xuexiaogang發表於2022-01-04

我的公眾號原文連結:

一次沒有資料庫報錯的資料庫關閉 (qq.com)


遇到 一個問題如圖:之前沒見過。背景是資料庫自己關閉了。MySQL8

但是輸出的第一行報錯不是資料庫自己的日誌,而是terminate called after throwing an instance of 'std::bad_alloc' what():  std::bad_alloc。從字面分析錯誤的分配。 懷疑和記憶體溢位有關。結合監控看到了 SWAP開始大量釋放。

   MySQL的記憶體給了20G,不大但是也不算小。懷疑是大事務導致 連續記憶體不足,而導致溢位。解析一下binlog,發現有些的確是比較大的。

std::bad_alloc這個報錯經過查詢是C++的輸出,該異常是因為在使用new分配記憶體空間時,記憶體空間不夠時就會丟擲該異常。這麼一想就通了。MySQL是C寫的。那麼一定是資料庫需要記憶體而沒有,導致了資料庫異常退出。

    為此我特意去官網上查Bug發現沒有。進而我們看看整個機制。malloc分配記憶體是先在虛擬記憶體中分配地址的,到實際使用時才真正的對映到實體記憶體

     到了MySQL真正要對映實體記憶體時,首先分配實體記憶體,此時top的res增加。如果實體記憶體不夠用了,分配swap,此時效能很差,此時top的res增加

所以,如果由於機器記憶體使用不當,到了MySQL真正要對映實體記憶體時,如果實體記憶體(記憶體+swap)不足了,就會出錯甚至退出。

(為什麼資料庫物理機相對來說好,這又是一個佐證)

    結論:innodb_buffer_pool_size在mysqld啟動時在虛擬記憶體中分配地址,在使用過程中再對映到實體記憶體,如果實體記憶體(記憶體+swap)不足了,就會出錯甚至退出。

    一般來說其實記憶體也夠用,即使不夠用也就是慢。因為記憶體和磁碟大量互動。而直接退出這個的確不常見。我依然懷疑這個是大事務造成,而且是連續性的。這裡不得不說這個機器的背景,就是用來做大量分析。其實這不是MySQL擅長的。我們們不能因為講MySQL就說MySQL什麼都好,也不能說其他就不行。尺有所短寸有所長。如果使用MySQL做分析,請使用MySQL雲端的企業版,配上heatwave外掛。

      資料庫選型是個學問,最好是懂資料庫的人一錘定音,而不是負責應用開發的人發表想法。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/637517/viewspace-2850479/,如需轉載,請註明出處,否則將追究法律責任。

相關文章