<b>提要</b>
thread_concurrency參數用于向作業系統建議期望的并發線程數,參數在mysqld啟動的時候使用。但mysql 5.6 從源碼中删除了這個參數,不再使用。
<b>參數背景</b>
源碼:
可以看到thread_concurrency的限制:
<dl><dd><dl></dl></dd></dl>
<dd>1. thread_concurrency不能用在gnu/linux平台上,而隻能在old solaris versions < 9才能work。</dd>
<dd>2. os層面隻提供了hint建議,并不能提供足夠的資訊,控制和診斷都不夠靈活。</dd>
<dd>3. os無法獲得mysql層面提供的所有線程的狀态,包括語句的執行,阻塞,目前事務狀态等資訊,是以os終究不能根據事務型軟體系統量身定制并發控制。</dd>
一句話,os層面無法把并發控制做精細,是以放棄使用。
那麼并發控制究竟在什麼地方進行控制最好,控制為多少合适呢?
<b>并發控制</b>
<b>并發控制點:</b>
<dl><dd><dl><dd>并發控制的目的是最大化提高系統的資源使用率,并減少管理和排程開銷。在mysql執行個體中,主要處理sql請求,是以期望系統資源最大化提供給sql的執行過程。</dd></dl></dd></dl>
sql的執行牽涉到server層和引擎層:
<dd>1. server層:比如cost計算,生成sql執行計劃的過程</dd>
<dd>2. innodb層:比如根據執行計劃,查找和更新資料page的過程</dd>
是以在mysql執行個體中,有兩個最佳的并發控制點:
<dd>1. server層:sql開始執行時。 mysql在5.6後,在server層引入了thread pool進行并發控制</dd>
<dd>2. innodb層:記錄查找和記錄更新時。 innodb存儲引擎,使用innodb_thread_concurrency參數進行并發控制</dd>
<b>并發控制大小:</b>
<dd>設定過大:造成系統排程消耗過大</dd>
<dd>設定過小:不能完全的使用系統資源,造成資源浪費</dd>
經驗值:# try number of cpu's*2 for thread_concurrency
但還需要配合具體的平台和業務系統進行測試,才能找到最佳值。
<b>innodb并發控制</b>
innodb使用參數innodb_thread_concurrency控制并發線程的個數,源碼中使用一對函數:
<dd>innodb_srv_conc_enter_innodb</dd>
<dd>innodb_srv_conc_exit_innodb</dd>
innodb實作語句級的并發控制,在語句執行結束,stmt commit的時候,強制釋放資源。
<b>權衡和優化</b>
<dl></dl>
<dd>1. 一方面進行并發控制,提高資源使用率,</dd>
<dd>2. 另一方還需要控制排程公平,防餓死等。</dd>
innodb引入了n_tickets_to_enter_innodb參數,sql進入innodb執行時進行初始化,預設值500。
在執行過程中,依次進行遞減,遞減到0時,強制退出并發線程,重新搶占。
好處:
<dl><dd></dd></dl>
<dd>1. 一方面單條sql可能寫入或者更新多條記錄,節省每次enter innodb的線程搶占代價。</dd>
<dd>2. 另一方面防止單條sql過多的長時間占用并發線程,導緻其它線程餓死的情況。</dd>