mysql 的sleep線程過多處理方法

來源:互聯網
上載者:User

標籤:

什麼是長串連?

其實長串連是相對於通常的短串連而說的,也就是長時間保持用戶端與服務端的串連狀態。

通常的短串連操作步驟是:

串連-》資料轉送-》關閉串連

而長串連通常就是:

串連-》資料轉送-》保持串連-》資料轉送-》保持串連-》…………-》關閉串連

這就要求長串連在沒有資料通訊時,定時發送資料包,以維持串連狀態,短串連在沒有資料轉送時直接關閉就行了

什麼時候用長串連,短串連?

長串連主要用於在少數用戶端與服務端的頻繁通訊,因為這時候如果用短串連頻繁通訊常會發生Socket出錯,並且頻繁建立Socket串連也是對資源的浪費。

但是對於服務端來說,長串連也會耗費一定的資源,需要專門的線程(unix下可以用進程管理)來負責維護串連狀態。

總之,長串連和短串連的選擇要視情況而定。

 

首先,如果使用了長串連而長期沒有對資料庫進行任何操作,那麼在timeout值後,mysql server就會關閉此串連,而用戶端在執行查詢的時候就會得到一個類似於“MySQL server has gone away“這樣的錯誤。

在使用mysql_real_connect串連資料庫之後,再使用mysql_options( &mysql, MYSQL_OPT_RECONNECT, … ) 來設定為自動重連。這樣當mysql串連丟失的時候,使用mysql_ping能夠自動重連資料庫。如果是在mysql 5.1.6之前,那麼則應在每次執行完real_connect 之後執行mysql_options( &mysql, MYSQL_OPT_RECONNECT, … ) ,如果是mysql 5.1.6+,則在connect之前執行一次就夠了。

 

查看mysql串連數

mysqladmin -uroot -p  processlist

實際的測試中我發現,當設定了MYSQL_OPT_RECONNECT為1時,逾時後再查看processlist,則自動建立的串連不在列表中,但事實上串連確實建立並被使用了。

 

在MYSQL的預設設定中,如果一個資料庫連接超過8小時沒有使用(閑置8小時),伺服器將斷開這條串連,後續在該串連上進行的查詢操作都將失敗。網路上對該問題的描述非常多。也提供了相應的解決辦法。我在這裡提一些我自己的看法。

解決辦法一:修改MYSQL伺服器的配置參數

道理非常簡單,MYSQL的預設設定是在資料庫連接超過8小時沒有使用後將其斷開,如果我們將這個時間改成更大的數值,那麼連線逾時所需的時間就會更長,也就意味著更不容易逾時。網路上提供的修改方法一般是修改/etc/my.cnf,在這個檔案中添加一行wait_timeout=你需要設定的逾時時間 。實際上有一種比較簡單的方法來修改這個參數:

首先作為超級使用者登入到MYSQL,注意必須是超級使用者,否則後面會提示沒有修改許可權。然後輸入

show global variables like ‘wait_timeout‘;

斷行符號執行後顯示目前的逾時時間:

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| wait_timeout | 28800 |

+---------------+-------+

1 row in set (0.00 sec)

上面顯示的是預設的逾時時間,即8個小時(單位是秒)。現在重新設定該參數,例如我們要將逾時時間設定成10個小時,可以輸入:

set global wait_timeout=36000;

斷行符號執行,顯示:

Query OK, 0 rows affected (0.00 sec)

表示設定成功,可以重新使用show global variables like ‘wait_timeout‘來驗證。

這種方法比較直觀,而且設定的參數立即生效。但如果/etc/my.cnf中沒有配置,則重啟服務後,global變數會從/etc/my.cnf中讀取新的變數值。

 

下邊是一段範例程式碼:

if(!mysql_real_connect(&logdb, my_hostname, my_user, my_password, my_dbname, my_port, my_sock, 0)){ 
        ast_log(LOG_ERROR, "Failed to connect to mysql database %s on %s.\n", my_dbname, my_hostname); 
        use_mysql = 0; 
} else { 
       char value = 1; 
       mysql_options(&logdb, MYSQL_OPT_RECONNECT, (char*)&value); 
        use_mysql = 1; 
}

 

 

wait_timeout和interactive_timeout總結

 

(1)interactive_timeout:
參數含義:伺服器關閉互動式串連前等待活動的秒數。互動式用戶端定義為在mysql_real_connect()中使用CLIENT_INTERACTIVE選項的用戶端。
參數預設值:28800秒(8小時)

(2)wait_timeout:
參數含義:伺服器關閉非互動串連之前等待活動的秒數。
線上程啟動時,根據全域wait_timeout值或全域interactive_timeout值初始化會話wait_timeout值,取決於用戶端類型(由mysql_real_connect()的串連選項CLIENT_INTERACTIVE定義)。

參數預設值:28800秒(8小時)

問題1:這裡為什麼要同時設定interactive_timeout,wait_timeout的設定才會生效?
答:    不設定interactive_timeout,wait_timeout也會生效。
問題2:interactive的值如果設定的和wait_timeout不同,為什麼Interactive_timeout會覆蓋wait_timeout?
答:在互動模式下(CLIENT_INTERACTIVE),interactive_timeout才生效,非互動模式下,不生效。

問題3:在進行MySQL最佳化時,因為interactive_timeout決定的是互動串連的時間長短,而wait_timeout決定的是非互動串連的時間長短。如果在進行串連配置時mysql_real_connect()最後一個參數client_flag不設定為CLIENT_INTERACTIVE,是不是interactive_timeout的值不會覆蓋wait_timeout?
答:可以做實驗試試。

問題4:為了減少長串連的數量,在設定最佳化時是不是可以將interactive_timeout的值設定的大些,而wait_timeout的值設定的小些?但是問題2的描述好像又不允許這樣。。。

答:如2所述,在互動模式下,interactive_timeout取代wait_timeout。這樣,如果有的用戶端是互動模式方式串連mysql server。那麼用戶端的timeout受制於interactive_timeout。如果有的用戶端是非互動模式,長串連mysql server。那麼用戶端的timeout受制於wait_timeout。(是否是互動模式的串連,由用戶端決定)

 

http://blog.csdn.net/sasafeng/article/details/8778038

mysql 的sleep線程過多處理方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.