http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_thread_concurrency
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.
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.
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過多的長時間占用並發線程,導致其它線程餓死的情況
