mysql執行緒掙用問題 MySQL 併發執行緒的理解

2021-10-18 11:52:42 字數 3464 閱讀 5987

這幾天碰到5.7低版本,併發量提公升就會觸發bug,導致伺服器重新啟動現象。

在資源有限的情況下,怎樣去有效的進行控制併發,mysql到底能支援多少併發。

併發實現方式

先分析一下官方對於這方面的建議:

innodb使用作業系統執行緒來處理來自使用者事務的請求。(事務在提交或回滾之前可能會向innodb發出很多請求。)在具有多核處理器的現代作業系統和伺服器上,上下文切換非常有效,大多數工作負載執行良好,併發執行緒的數量沒有任何限制。

在有助於減少執行緒之間的上下文切換的情況下,innodb可以使用許多技術來限制併發執行的作業系統執行緒的數量.當innodb從乙個使用者會話接收到乙個新的請求時,如果併發執行的執行緒數量達到了預先定義的限制,那麼這個新請求會在再次嘗試之前休眠一段時間。在休眠後無法重新排程的請求被放入先入/先出佇列並最終被處理。等待鎖的執行緒不會計算在併發執行的執行緒數中。

具體實現通過以下**:

mysql裡可通過設定引數,來限制併發執行緒的數量。從mysql 服務端接收到相應的請求之後,分配到執行緒,這時執行緒數量達到限制之後,分配的執行緒放入乙個佇列 並同時休眠幾微秒,但進入的時候對應的拿到票據,並執行對應的事務,當票據用完之後還需要重新排隊。

併發控制引數

這個變數的範圍是0到1000。值0(預設值)被解釋為無限併發性(沒有併發性檢查)。

禁用執行緒併發性檢查使innodb能夠建立它需要的執行緒。

0的值也會禁用innodb內部的查詢和顯示innodb狀態輸出的行操作部分的佇列計數器中的查詢。

如果mysql例項與其他應用程式共享cpu資源,或者工作負載或併發使用者數量不斷增加,就需要考慮設定此變數。

正確的設定取決於工作負載、計算環境和執行的mysql版本。需要測試一系列值,以確定提供最佳效能的設定。innodb_thread_concurrency是乙個動態變數,它允許在乙個實時測試系統上試驗不同的設定。如果某個特定設定執行得很差,可以快速將innodb_thread_concurrency設定回0。

如果工作負載的併發使用者執行緒數小於64,則設定innodb_thread_concurrency=0。

如果工作負載一直很重,或者偶爾會出現峰值,可以從設定innodb_thread_concurrency=128開始,然後將其值降低到96、80、64等等,直到找到能夠提供最佳效能的執行緒數為止。假設您的系統通常有40到50個使用者,但是這個數字會周期性地增加到60、70甚至200。會發現,在80個併發使用者時,效能是穩定的,但在這個數字之上,效能開始出現回歸。在這種情況下,您應該設定innodb_thread_concurrency=80以避免影響效能。

如果你不想讓innodb為使用者執行緒使用超過一定數量的虛擬cpu(例如,20個虛擬cpu),可以將innodb_thread_concurrency設定為這個數(或者更低,取決於效能結果)。如果您的目標是將mysql與其他應用程式隔離開來,那麼可以考慮將mysqld程序專門繫結到虛擬cpu。

innodb_thread_concurrency值過高會導致系統內部和資源爭用增加,從而導致效能下降。

定義innodb執行緒在加入innodb佇列之前睡眠的時間,以微秒為單位。預設值是10000。值為0將禁用睡眠。可以設定innodb_adaptive_max_sleep_delay為innodb_thread_sleep_delay的最大值,而innodb會根據當前的執行緒排程活動自動調整innodb_thread_sleep_delay的上下調整。這種動態調整有助於執行緒排程機制在系統輕負載或接近滿負荷執行時順利工作。

當乙個執行緒嘗試進入innodb時,如果執行緒的數量已經達到併發限制,那麼它將被放置在乙個佇列中。當乙個執行緒被允許進入innodb時,它會得到乙個等於innodb_concurrency_tickets值的「票據」,這個執行緒可以自由地進入和離開innodb,直到它的票據用完。在這之後,當執行緒下一次嘗試進入innodb時,它再次受到併發性檢查(和可能的排隊)的影響。

使用乙個較小值:只需要處理幾行的小事務與處理多行的大事務公平競爭。較小的innodb_concurrency_tickets值的缺點是,大型事務在完成之前必須通過佇列多次迴圈,這就延長了完成任務所需的時間。

使用較大的值:大事務等待佇列末端位置(由innodb_thread_concurrency控制)的時間更少,獲取行所需的時間更多。大型事務還需要更少的佇列訪問來完成它們的任務。較大的innodb_concurrency_tickets值的缺點是,太多同時執行的大事務會讓較小的事務等待更長的時間,從而餓死。

對於乙個非零的innodb_thread_concurrency值,您可能需要向上或向下調整innodb_concurrency_tickets值,以在較大和較小的事務之間找到最佳平衡。顯示引擎innodb狀態報告顯示當前通過佇列的執行事務的剩餘票數。還可以從information_schema的trx_concurrency_tickets列獲得該資料。innodb_trx表。

允許innodb根據當前的工作負載自動調整innodb_thread_sleep_delay的值。任何非零值都可以自動動態調整innodb_thread_sleep_delay值,直到innodb_adaptive_max_sleep_delay選項中指定的最大值。該值表示微秒數。這個選項對於大於16個innodb執行緒的繁忙系統非常有用。(在實踐中,它對於同時有數百或數千個連線的mysql系統最有價值。)

同時可以提交的執行緒數。值0(預設值)允許同時提交任意數量的事務。

innodb_commit_concurrency的值不能在執行時從0更改為非0,反之亦然。該值可以從乙個非零值更改為另乙個非零值。

總結1.從上述引數上看到併發範圍應該在0~1000以內,超過範圍應該存在很大問題。

2.實際場景下,基本innodb_thread_concurrency採用預設值0,交給mysql系統自行管理。

3.那問題來了,什麼情況下進行調整。

如果乙個工作負載中,併發使用者執行緒的數量小於64,建議設定innodb_thread_concurrency=0;

如果工作負載一直較為嚴重甚至偶爾達到頂峰,建議先設定innodb_thread_concurrency=80

mysql與其他應用隔離,可以考慮繫結mysqld程序到專有的虛擬cpu

高併發下機器效能已經無法支撐的時候,特別是一些低配置的虛擬機器環境

定期檢測和分析系統,負載量、使用者數,有效的對引數進行調整

多個例項部署在乙個伺服器上,某個例項效能佔比比較高

主從延遲的一種控制手段

執行緒安全讀取mysql 多執行緒讀寫mysql資料庫

該樓層疑似違規已被系統摺疊 隱藏此樓檢視此樓 unsigned int stdcall scan pvoid pm char ip 20 strcpy ip,char pm mysql mysql mysql res result 初始化mysql控制代碼 mysql init mysql 連線my...

c語言多執行緒mysql 多執行緒讀寫mysql資料庫

該樓層疑似違規已被系統摺疊 隱藏此樓檢視此樓 unsigned int stdcall scan pvoid pm char ip 20 strcpy ip,char pm mysql mysql mysql res result 初始化mysql控制代碼 mysql init mysql 連線my...

在cmd下用mysql客戶機連線mysql伺服器

在cmd下用mysql客戶機連線mysql伺服器 開啟cmd後,輸入mysql h localhost u root p 語法 mysql當然是告訴cmd,這是mysql的命令了 引數 h 是伺服器位址,在此我們以本機為例輸入localhost u 是mysql的使用者名稱 我們用mysql 的預設...