MySQL Innodb 併發涉及參數

1 參數做用

    MySQL的各個插件式引擎中,都會對事務及線程作必定的處理和優化。在Innodb引擎中,老是嘗試保持 innodb內 操做系統的線程數(暫命名爲innodb_thread) 應該小於或等於 系統可提供給innodb處理事務的線程數(暫命名爲system_innodb_thread)。在大多數狀況下,innodb_thread都不會指定一個限制值,而是讓它想要多少直接申請多少。html

    當 innodb_thread 大於system_innodb_thread 時,持續時間較長時,會致使服務器的線程資源被數據庫使用,CPU可能居高不下,甚至引起宕機。mysql

    這個時候,Innodb內部能夠提供一個參數來限制 併發線程(同一時刻可處理的請求數),當併發數達到 併發線程限制數時,再接收到一個新的請求,那麼這個請求須要在下次請求前先sleep一段時間,若是sleep後再請求仍是沒有多餘線程提供其執行,那麼,它就會進入到先進先出的隊列中等待執行。這裏注意下,等待線程,不計入 innodb_thread 。innodb_thread_concurrency 參數所以而來。sql

   能夠經過innodb_thread_concurrency 來調節  併發線程數的限制值,使用innodb_thread_sleep_delay來調整當 併發 thread 到達 innodb_thread_concurrency時須要sleep的時間。當請求被innodb接受的時候,會得到一個 消費憑證 innodb_concurrency_tickets (默認5000次),當這個請求中有多個SQL被執行的時候,每執行一次,消費一次tickets,在次數用完以前,該線程從新請求時無須再進行前面 thread 是否達到 併發限制值的檢查。數據庫

   同時 innodb_commit_concurrency也控制了多線程併發提交的數量。若是 innodb_thread_concurrency  設置的有點大innodb_commit_concurrency應該作出相應的調整,不然會形成大量線程阻塞。服務器

   因此,跟併發相關的有這幾個參數設置:innodb_thread_concurrency、innodb_thread_sleep_delay、innodb_concurrency_tickets、innodb_commit_concurrency多線程

跟innodb_thread_concurrency類似的參數有 thread_concurrency ,可是它在5.6版本的官方文檔中已被標識爲過期,在5.7.2版本廢除了該參數,因此咱們這裏不涉及對該參數的測試及描述。併發

2 參數設置

2.1 innodb_thread_concurrency

2.1.1 默認值

   innodb_thread_concurrency默認是0,則表示沒有併發線程數限制,全部請求都會直接請求線程執行。注意:當 innodb_thread_concurrency 設置爲0時,則innodb_thread_sleep_delay的設置將會被忽略,不起做用。若是數據庫沒出現性能問題時,使用默認值便可。性能

2.1.2 大於0

   當innodb_thread_concurrency>0,則表示有 併發數限制,當一個新的請求發起時,會檢查當前併發線程數是否達到了 innodb_thread_concurrency的限制值,若是有,則須要sleep一段時間(sleep的設置詳見下一部分),而後再再次請求,若是再次請求時,當前併發數仍是達到限制值,那麼就會進入FIFO隊列等待執行。當進入到內核執行時,會獲得一個 消費憑證 ticket,則這個線程,在後面的屢次進入innodb執行操做是都不須要重複上面的檢查步驟,當把次數消費完,那麼這個線程就會被驅逐,等待下次再次進入Innodb,再從新分配ticket。測試

2.1.3 建議配置(來自官網)

  • 當併發用戶線程數量小於64,建議設置innodb_thread_concurrency=0;
  • 若是負載不穩定,時而低,時而高到峯值,建議先設置innodb_thread_concurrency=128,並經過不斷的下降這個參數,96, 80, 64等等,直到發現可以提供最佳性能的線程數,例如,假設系統一般有40到50個用戶,但按期的數量增長至60,70,甚至200。你會發現,性能在80個併發用戶設置時表現穩定,若是高於這個數,性能反而降低。在這種狀況下,建議設置innodb_thread_concurrency參數爲80,以免影響性能;
  • 若是DB服務器上還容許其餘應用,須要限制mysql的線程使用狀況,則能夠設置可分配給DB的線程數,可是不建議DB上跑其餘應用,也不建議這麼設置,由於這樣可能致使數據庫沒有對硬件最優使用;
  • 設置太高值,可能會由於系統資源內部爭奪致使性能降低;
  • 在大多數狀況下,最佳的值是小於並接近虛擬CPU的個數;
  • 按期監控和分析DB,由於隨着數據庫負載的變化,業務的增長,innodb_thread_concurrency也須要動態的調整。

2.2 innodb_thread_sleep_delay

   5.6.3版本前,須要反覆測試才能肯定innodb_thread_sleep_delay值,而且固定爲一個值,在5.6.3版本後,由於 Innodb 自動調整innodb_thread_sleep_delay參數:優化

  • Innodb_adaptive_max_sleep_delay:最大sleep的時間,微秒爲單位

能夠經過設置參數 innodb_adaptive_max_sleep_delay 來限制 innodb_thread_sleep_delay的最大值,不設置 innodb_thread_sleep_delay的取值狀況,讓Innodb自動跟進負載來調整,當系統負荷較高時,Innodb動態調整slee時間可以使得數據庫穩定運行。

2.3 innodb_commit_concurrency

   該值只能爲默認值0,mysql不限制併發提交。大於0表示容許N個事務在同一時間點提交,N的範圍是0-1000。 

    注意事項:mysqld運行時,不準把innodb_commit_concurrency 的值從0改成非0,或非0的值改成0;但容許從N改成M(N及M均大於0)

2.4 innodb_concurrency_tickets

   默認是5000(基於5.6,5.7)。

   若是innodb_concurrency_tickets設置小些,適用於小事物操做較多的系統,能夠快速使用完線程後退出來,提供給其餘請求使用;而對於大事務來講,可能會循環進入等待隊列中等待執行完成,這會耗費更多時間及資源;若是innodb_concurrency_tickets設置大些,適用於大事務頻繁操做的系統,這樣大事務則不須要頻繁進入queue等待隊列,能夠經過較少的請求來處理;可是對於小事務來講,則意味着他們要等待更長的時候,才能排隊進入到內核執行。因此,當innodb_thread_concurrency>0時,須要上下調整 innodb_concurrency_tickets ,使其達到最佳性能。能夠經過show engine innodb status 的queue查看,也能夠經過INFORMATION_SCHEMA.INNODB_TRXTRX_CONCURRENCY_TICKETS查看消費次數狀況。

相關文章
相關標籤/搜索