Golang mysql 上線的一個坑 Db.close重要性


急沖沖完成的mysql的一個監控自動處理程序上線了,線下處理是正常的,沒想到線上才半小時就奔潰了。

現在時間是晚上11點,心慌焦慮涌上心頭,需要熬夜?腎上腺素激增。

程序主要是一個定時任務的處理程序,主要是對mysql 的處理,初看沒啥問題,操作語句都是網上搬下來的,檢查了下代碼,

奔潰都在什么rows.close,stmt.close,還有query這時候,非法defer,這個奔潰的最多次,還都是內存指針異常。。。 golang這調試,說實在連c++都不如,在可能我還用不慣吧,我用的是liteide

隨便截取段代碼:

rows, err := db.Query("select * from user;")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

基本上網上大部分都是這種情況,rows.close,stmt.close 等都有,但是唯獨沒有db.close。為什么? 他們說有

Db.SetMaxOpenConns(200)
Db.SetMaxIdleConns(100)
Db.Ping()

  線程池。所有代碼中都說不需要close,但是那是有條件的。

我們查看官方的解釋

// It is rare to Close a DB, as the DB handle is meant to be
// long-lived and shared between many goroutines.

但在實際使用中,都說了是定時任務自然是go func的,然后使用一個公共的Db,還有一個注意的問題,雖然連接放進連接池,但是服務器依然會單方面斷開一個的連接。

關鍵是而且使用Db.Ping()依然不能解決這個問題,原因沒細查。

現在知道了原因,解決起來就容易多了,結尾一定加

Db.Close()

什么rows.close,stmt.close反而不重要,后面測試發現可有可無,凌晨1點了,收工。

 

今早上起來,一切OK,運行了1個晚上

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM