mysql 執行緒池 c MySQL執行緒池

2021-10-18 21:03:46 字數 2896 閱讀 7251

mysql執行緒池

在麼mysql中,執行緒池指的是用來管理處理mysql客戶端連線任務的執行緒的一種機制。 如果把執行緒看做系統資源那麼執行緒池本質上是對系統資源的管理,對應作業系統來說執行緒的建立和銷毀是比較消耗系統資源的,頻繁的建立與銷毀執行緒必然給系統帶來不必要的資源浪費,特別是在高負載的情況下。執行緒池技術一方面可以減少執行緒重複建立與銷毀這部分開銷,從而

更好地利用已經建立的執行緒資源,另一方面也可以控制線程的建立與系統的負載

核心引數thread_pool_size:指的是執行緒組大小,預設是cpu核心數,執行緒池初始化的時候會根據這個數字來生成執行緒組,每個執行緒組初始化乙個poolfd控制代碼

thread_pool_stall_limit:timer thread 迭代的時間間隔,預設是500ms

thread_pool_oversubscribe:用於計算執行緒組是否過於活躍或者太過繁忙,即系統的負載程度,用於在一定場景決策新的工作執行緒是否被建立於和任務是否被除了,預設值為3

thread_pool_idle_timeout:工作執行緒最大空閒時間,工作執行緒超過這個數還空閒的話就退出,這個值預設是60秒

thread_pool_high_prio_mode: 這個引數可用於控制任務佇列的使用,可取三個值: transactionsstatementsnone 當為statements的時候則執行緒組只使用優先佇列,當值為none的時候,則只使用普通佇列,當值為transactions的時候配合thread_pool_high_prio_tickets引數生效,用於控制任務被放入優先佇列的最大次數。

mysql執行緒池的大致架構

執行緒組mysql執行緒池在初始化的時候根據宿主機的cpu核心數設定thread_pool_size,也就是執行緒池的執行緒組個數。每個執行緒組在初始化之後會通過底層的io庫分配乙個網路特殊的控制代碼與之關聯,io庫可以通過這個控制代碼監聽與之繫結的socket控制代碼就緒的io任務,執行緒組的結構體定義如下:

struct thread_group_t my_aligned(512);

worker執行緒

執行緒組內有0個或多個執行緒,和netty有些不同,netty中有固定的執行緒用於輪詢io事件,工作執行緒只負責處理io任務,而在mysql執行緒池中listener只是一種角色,每個執行緒的角色可以是listener或者是worker,工作執行緒為listener的時候負責從poolfd中讀取就緒的io任務,處於worker角色的時候負責處理這些io任務,我們需要區分工作執行緒的以下幾種狀態:

1、活躍狀態:當工作執行緒處於正在處理任務且狀態未被阻塞的狀態。如果worker執行緒將自己設定為listener則不算進執行緒組的活躍執行緒狀態

2、空閒狀態:沒有任務處理而被處於空閒狀態

3、等待狀態:如果工作執行緒在執行命令的過程中由於io、鎖、條件、sleep等需要等待則執行緒池將被通知將這些工作執行緒記作等待狀態,

在正常工作的情況下,當工作執行緒檢索任務的時候,如果執行緒組太活躍即使有任務工作執行緒也不會執行,如果不是太繁忙才會考慮高優先順序的任務,對於低優先順序的任務只有當執行緒組不是太繁忙的時候才會執行。

check stall機制

如果後來的io任務被前面的執行時間過長的任務影響會怎麼樣?這必然會導致一些無辜的任務(或是乙個簡單的insert操作)被影響,結果是有可能回被延遲處理。執行緒池中有乙個timer thread類似我們很多系統裡面的timeout thread執行緒,這個執行緒每隔一定時間間隔就會進行一次迭代,迭代中做的如下二部分事情

1、檢查執行緒組的負載情況進行工作執行緒的喚醒與建立

2、檢查與處理超時的客戶端連線

這裡主要介紹第一部分工作也就是check stall機制。timer thread週期性檢查執行緒組內的執行緒是否被阻塞,所謂阻塞也就是新來的任務但是執行緒組內沒有執行緒來處理。timer thread通過queue_event_count和io任務佇列釋放為空來判斷執行緒組釋放為阻塞狀態,每次工作執行緒檢索任務的時候queue_event_count都會累加,累加意味著任務唄正常處理,工作執行緒正常工作,在每一次check_stall之後queue_event_count會被清零,因此如果在一定時間間隔後的下一次迭代中,io任務對壘不為空並且queue_event_count為空,則說明這段時間間隔內都沒有工作執行緒來處理io任務,那麼check stall機制會嘗試喚醒或者建立乙個工作執行緒,喚醒執行緒的邏輯很簡單,如果waiting_threads中有空閒執行緒則喚醒乙個空閒執行緒,否則需要嘗試建立乙個工作執行緒,建立執行緒不一定會建立成果,建立的條件如下

1、如果沒有空閒執行緒並且沒有貨源執行緒則立馬建立,這個時候可能是因為沒有任務工作或者工作執行緒都被阻塞了,或者存在潛在的死鎖

2、否則如果距離上次建立的時間大於一定閾值才建立執行緒,這個閾值由執行緒組內的執行緒決定

任務佇列

任務佇列也就是listener每次從poolfd輪詢出來的就緒任務,分為優先佇列和普通任務佇列,優先佇列中的io任務會先被除了,然後普通佇列中的任務才能被處理。滿足以下二個條件為優先執行

1、連線處於事務中

2、連線關聯的priority tickets值大於0

引數priority tickets的設計是為了防止高優先順序的任務總是被處理,而一些非高優先順序的任務處於較長時間的飢餓狀態,當高優先順序的任務每一次被放入高優先順序佇列之後都會對priority tickets的值進行減1,因此達到一定次數priority tickets的值必然會小於等於0,因此避免了永久高優先順序的問題。另外佇列的使用受引數thread_pool_high_prio_mode影響。當就緒io任務唄輪詢出來放入佇列之後會對io_event_count進行累加,當io任務從佇列取出處理的時候會對queue_event_count進行計數

listener執行緒

listener做的事情主要是從poolfd中輪詢與其繫結的socket控制代碼的就緒io事件,事件以任務的形式被放入任務佇列並做相應處理.

如果任務佇列不為空,也不一定會有執行緒來及時處理任務,這就導致了耗時任務影響了後來任務的執行,未來可能通過摒棄每個執行緒只保持乙個活躍執行緒的規則來避免網路任務長時間得不到處理

mysql 執行緒池 Mysql 執行緒池

why 在5.6以前,mysql會對每個連線建立乙個執行緒,請求結束後銷毀執行緒。在高併發的情況下,為了避免頻繁建立和釋放連線,可以通過thread cache將執行緒快取起來,請求來了先嘗試從cache中獲取,重複利用執行緒資源。問題在低併發的情況下,thread cache可以成為乙個有效的優化...

mysql 執行緒池測試 MySQL執行緒池測試

mysql執行緒池 thread pool 的處理 在預設的mysql的連線模型中,乙個連線對應乙個mysql伺服器的執行緒來處理連線請求 很類似於oracle的專用伺服器連線 在某些情況這種配置可能會導致一些問題,比如以下情形 1,伺服器同時太多活動連線線程,而cpu個數有限,會導致context...

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...