mysql 自旋鎖

 自旋(spin)是一種經過不間斷地測試來查看一個資源是否變爲可用狀態的等待操做,用於僅須要等待很短的時間等待所需資源的場景。使用自旋這種「空閒循環(busy-loop)」來完成資源等待的方式要比經過上下文切換使線程轉入睡眠狀態的方式要高效得多。但若是自旋了一個很短的時間後其依然沒法獲取資源,則仍然會轉入前述第二種資源等待方式。html

innodb_sync_spin_loops參數是自旋鎖的輪轉數,能夠經過show engine innodb status來查看。相較於系統等待,自旋鎖是低成本的等待;不過它是一個活躍的等待,會浪費一些cpu資源。所以若是看到大量的自旋等待和自旋輪轉,則很顯然它浪費了不少cpu資源。浪費cpu時間和無謂的上下文切換之間能夠經過該值來平衡。mysql

innodb_spin_wait_delay算法

    Vadim Tkachenko 在http://www.mysqlperformanceblog.com/2011/12/02/kernel_mutex-problem-or-double-throughput-with-single-variable/中對該參數進行了測試,並給出告終論。sql

    Peter Zaitsev在http://www.mysqlperformanceblog.com/2011/07/28/how-innodb-contention-may-manifest-itself/中也進行了解釋在不一樣情況下,該值的影響。並在http://www.mysqlperformanceblog.com/2006/07/17/show-innodb-status-walk-through/中詳細解釋了show innodb status的輸出進行了詳細解釋。服務器

 

innodb_thread_concurrency併發

關於innodb_thread_concurrency參數

http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_thread_concurrencyapp

Command-Line Format	--innodb_thread_concurrency=#
Option-File Format	innodb_thread_concurrency
Option Sets Variable	Yes, innodb_thread_concurrency
Variable Name	innodb_thread_concurrency
Variable Scope	Global
Dynamic Variable	Yes
 	Permitted Values
Type	numeric
Default	0
Range	0 .. 1000

InnoDB tries to keep the number of operating system threads concurrently inside InnoDB less than or equal to the limit given by this variable. Once the number of threads reaches this limit, additional threads are placed into a wait state within a FIFO queue for execution. Threads waiting for locks are not counted in the number of concurrently executing threads.less

The correct value for this variable is dependent on environment and workload. Try a range of different values to determine what value works for your applications. A recommended value is 2 times the number of CPUs plus the number of disks.ide

The range of this variable is 0 to 1000. A value of 0 (the default) is interpreted as infinite concurrency (no concurrency checking). Disabling thread concurrency checking enables InnoDB to create as many threads as it needs.函數

參數的含義是: InnoDB內部的併發線程數.
能夠動態修改
具體解析: InnoDB 試圖保持InnoDB內部的併發操做系統的線程數少於innodb_thread_concurrency設置的值
若是innodb併發線程數快要到達innodb_thread_concurrency=x,其餘的innodb線程會被設置爲等待狀態,隊列的算法是FIFO
處於等待拿鎖狀態的線程數,不會被計算入正在執行的併發線程數

innodb_thread_concurrency=x,x該設怎樣的值,視服務器配置和服務器的負載狀況。
默認推薦的值是 (cpu的數量+磁盤數量)x2 (個人理解,對於raid10的磁盤陣列,應該是磁盤總數/2)

參數取值範圍 0-1000 當爲默認值的時候,不是說0個併發線程。 而是被解釋爲無限併發(沒有併發檢查)
當innodb_thread_concurrency=0的時候,能夠理解爲 禁用線程併發檢查,使InnoDB按照請求的需求, 創造儘量多的線程.

 

http://www.dbathink.com/2012/10/trouble-shooting-the-high-sys-cpu-in-mysql-server/

 


併發控制

  併發控制點:

併發控制的目的是最大化提升系統的資源利用率,並減小管理和調度開銷。在MySQL實例中,主要處理sql請求,因此指望系統資源最大化提供給sql的執行過程。

  sql的執行牽涉到server層和引擎層:

1. server層:好比cost計算,生成sql執行計劃的過程
2. Innodb層:好比根據執行計劃,查找和更新數據page的過程

  因此在MySQL實例中,有兩個最佳的併發控制點:

1. server層:sql開始執行時。 MySQL在5.6後,在server層引入了thread pool進行併發控制
2. Innodb層:記錄查找和記錄更新時。 Innodb存儲引擎,使用innodb_thread_concurrency參數進行併發控制


  併發控制大小:

設置過大:形成系統調度消耗過大
設置太小:不能徹底的使用系統資源,形成資源浪費

  經驗值:# Try number of CPU's*2 for thread_concurrency

  但還須要配合具體的平臺和業務系統進行測試,才能找到最佳值。


Innodb併發控制

  Innodb使用參數innodb_thread_concurrency控制併發線程的個數,源碼中使用一對函數:

innodb_srv_conc_enter_innodb
innodb_srv_conc_exit_innodb

  Innodb實現語句級的併發控制,在語句執行結束,stmt commit的時候,強制釋放資源。

權衡和優化

1. 一方面進行併發控制,提升資源利用率,
2. 另外一方還須要控制調度公平,防餓死等。

  Innodb引入了n_tickets_to_enter_innodb參數,sql進入innodb執行時進行初始化,默認值500。

  在執行過程當中,依次進行遞減,遞減到0時,強制退出併發線程,從新搶佔。

  好處:

1. 一方面單條sql可能寫入或者更新多條記錄,節省每次enter innodb的線程搶佔代價。
2. 另外一方面防止單條sql過多的長時間佔用併發線程,致使其它線程餓死的狀況。
相關文章
相關標籤/搜索