一、問題描述 最近遇到了一個奇怪的MySql資料庫問題,好幾次前一天晚上歷史數據還正常存儲,第二天早上來了看實時數據存儲還正常,歷史數據不存儲了。找了好久也沒找到問題。後來仔細想了想,歷史數據設置了變化才存儲,是不是數據一直不變,就一直沒有往資料庫寫數據,導致MySql的連接太久不用自動斷開了。 ...
一、問題描述
最近遇到了一個奇怪的MySql資料庫問題,好幾次前一天晚上歷史數據還正常存儲,第二天早上來了看實時數據存儲還正常,歷史數據不存儲了。找了好久也沒找到問題。後來仔細想了想,歷史數據設置了變化才存儲,是不是數據一直不變,就一直沒有往資料庫寫數據,導致MySql的連接太久不用自動斷開了。然後就百度了一下,Mysql空閑連接有效時長,一看都說是8個小時就自動斷開了。嗯,有點感覺了,應該就是這個原因。
二、問題排查
根據查到的資料查看MySql 有兩個參數,可以設定空閑連接的有效時長,分別是interactive_timeout
和wait_timeout
,可以在mysql配置文件中設置。根據這一點,可以來進行排查了。
- 使用
show variables like '%timeout%';
命令查詢以上兩個參數的值,一查都是28800(單位是秒,剛好8小時)。 - 在mysql配置文件中修改
interactive_timeout
和wait_timeout
都為100,這樣連接100秒不使用就自動關閉了。 - 重啟mysql服務,開始向資料庫中插入數據,中間暫停3分鐘(確保空閑連接已經斷開),可以使用
show status like 'Threads%'
命令來查看當前的連接數,查詢結果中Threads_connected
即為當前連接數。 - 繼續向mysql插入數據,一看數據果然沒有存儲上,問題成功復現並找到原因。
三、解決問題
- 查看數據存儲部分代碼,發現代碼中有做斷開重連,但是判斷連接是否有效的部分寫的有問題,也沒有校驗
mysql_query
的返回值,所以數據存儲失敗的時候沒有產生日誌。 - 修改代碼,連接斷開後自動重連,校驗
mysql_query
的返回值並產生日誌,使每次資料庫操作結果都有記錄。註意:mysql c/c++ APImysql_query
返回 0為操作成功,非0為操作失敗。
四、一點反思
這個問題完全是由於代碼寫的不嚴謹造成的,如果代碼寫的嚴謹,該校驗的地方都加上校驗,就算出現問題也能快速定位。吃一塹,長一智以後需要多註意,養成良好的代碼習慣。還有就是需要找時間系統的學習一下資料庫方面的內容,項目鍛煉是能夠快速學習一些內容,但是都是用到哪部分學哪部分,不系統。還是需要自己多花時間系統的學。