用INSERT DELAYED解決MySQL堵塞問題

由於對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還沒有來得及插入數據的話,這些數據將會丟失。
from http://kiddymeet.blog.51cto.com/20194/41137
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章