解決MySQL堵塞問題INSERT DELAYED

由於對MySQL的併發插入數據能力沒有一個很好的評估,因此在些多進程併發程序時,忽略了MySQL的堵塞問題

以至程序時不時因爲MySQL的堵塞,導致子進程一直在等待MySQL釋放堵塞,完成INSERT 指令。
故障現象:
  • 堵塞的子進程都是 sbwait 狀態
  • 父進程,一直在等待子進程結束,是wait狀態
  • 如果不手工kill掉堵塞的子進程,這些進程一直存在
原因排查:
  開始懷疑是socket部分的問題。以爲是由於連接服務器時,在等待對方關閉連接而引起的堵塞。
  花了很長一段時間來檢查和調試socket部分的代碼,幾次以爲已經解決了的時候,又出現故障,都是以失敗告終。
  這個週末,重新將整個socket連接,數據庫連接逐一檢查。發現,sbwait 狀態時,是由於MySQL的堵塞引起的。多進程併發的情況下,同時搶佔MySQL的資源。而MySQL默認表類型,是表鎖定的。當A子進程鎖定進行插入時,B子進程只能等待。以至併發時,發生堵塞現象。
解決辦法:
  • 優化表結構和數據結構
  • 更改INSERT INTO爲 INSERT DELAYED INTO
  • 更改程序結構,讓每個子進程各自打開一個MySQL連接
說明: INSERT DELAYED INTO,是客戶端提交數據給MySQL,MySQL返回OK狀態給客戶端。而這是並不是已經將數據插入表,而是存儲在內存裏面等待排隊。當mysql有空餘時,再插入。
  這樣的好處是,提高插入的速度,客戶端不需要等待太長時間。壞處是,不能返回自動遞增的ID,以及系統崩潰時,MySQL還沒有來得及插入數據的話,這些數據將會丟失。
觀測:
  做這些調整後,運行了一天,沒有出現堵塞情況。並且運行時間也縮短了。
通過phpMyAdmin觀測MySQL的進程,提交後,會有一些用戶爲DELAYED,狀態爲Waiting for INSERT的進程。過一會,數據完全插入後就消失了。
總結:
  一個系統的東西,就要系統的去考慮存在的問題和可能將要發生的問題。不能過於片面的自以爲是。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章