天天看點

MySQL核心月報 2014.09-MySQL· 參數故事·thread_concurrency

<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 &lt; 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>