文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


7.6.3.3 線程池操作

線程池由多個線程群組組成,每個線程群組管理一組用戶端連線。當建立連線時,線程池會以循環方式將它們指派給線程群組。

線程池公開可供用來設定其操作的系統變數

若要設定線程群組的數量,請使用 thread_pool_size 系統變數。預設群組數量為 16。如需設定此變數的準則,請參閱第 7.6.3.4 節,「線程池調整」

每個群組的最大線程數為 4096 個(或在某些系統上為 4095 個,其中一個線程會在內部使用)。

線程池會將連線和線程分開,因此連線和執行從這些連線接收的陳述式的線程之間沒有固定的關係。這與預設的線程處理模型不同,預設模型會將一個線程與一個連線建立關聯,以便指定的線程執行其連線中的所有陳述式。

依預設,線程池會嘗試確保每個群組中在任何時候最多執行一個線程,但有時為了獲得最佳效能,會允許執行更多線程。

  • 每個執行緒群組都有一個監聽器執行緒,負責監聽從指派給該群組的連線傳入的語句。當語句到達時,執行緒群組會立即開始執行,或將其排入佇列以供稍後執行。

    • 如果該語句是唯一接收到的語句,且沒有任何語句正在排隊或執行中,則會立即執行。

      可以透過設定 thread_pool_transaction_delay 來延遲立即執行,此設定會對交易產生節流效果。如需更多資訊,請參閱後續討論中對此變數的說明。

    • 如果由於同時有語句排隊或正在執行中而無法立即開始執行,則會將語句排入佇列。

  • thread_pool_transaction_delay 變數指定交易延遲時間,單位為毫秒。工作執行緒在執行新交易之前會休眠指定的時段。

    在平行交易因資源競爭而影響其他操作效能的情況下,可以使用交易延遲。例如,如果平行交易影響索引建立或線上緩衝池調整大小操作,您可以設定交易延遲,以減少這些操作執行時的資源競爭。延遲會對交易產生節流效果。

    thread_pool_transaction_delay 設定不會影響從具備權限的連線(指派給 Admin 執行緒群組的連線)發出的查詢。這些查詢不受設定的交易延遲影響。

  • 如果發生立即執行,監聽器執行緒會執行它。(這表示群組中暫時沒有執行緒在監聽。)如果語句快速完成,執行緒會返回監聽語句。否則,執行緒池會將該語句視為停滯,並啟動另一個執行緒作為監聽器執行緒(必要時會建立它)。為了確保沒有任何執行緒群組因停滯的語句而受阻,執行緒池有一個背景執行緒,會定期監控執行緒群組狀態。

    透過使用監聽器執行緒執行可以立即開始的語句,如果語句快速完成,則無需建立額外的執行緒。這確保了在並行執行緒數量較少的情況下,盡可能高效地執行。

    當執行緒池外掛程式啟動時,它會為每個群組建立一個執行緒(監聽器執行緒),再加上背景執行緒。在需要執行語句時,會建立額外的執行緒。

  • thread_pool_stall_limit 系統變數的值決定了前述項目中 快速完成 的含義。執行緒被視為停滯的預設時間為 60 毫秒,但最多可以設定為 6 秒。此參數是可設定的,讓您可以針對伺服器工作負載取得適當的平衡。較短的等待值允許執行緒更快啟動。較短的值也更適合避免死鎖情況。較長的等待值對於包含長時間執行語句的工作負載很有用,以避免在當前語句執行時啟動過多新語句。

  • 如果 thread_pool_max_active_query_threads 為 0,則會套用剛才描述的預設演算法來確定每個群組的最大活動執行緒數量。預設演算法會考量停滯的執行緒,並可能會暫時允許更多活動執行緒。如果 thread_pool_max_active_query_threads 大於 0,則會限制每個群組的活動執行緒數量。

  • 執行緒池的重點在於限制同時執行的短時間語句的數量。在執行的語句達到停滯時間之前,它會阻止其他語句開始執行。如果語句執行超過停滯時間,它會被允許繼續執行,但不再阻止其他語句啟動。透過這種方式,執行緒池會盡力確保每個執行緒群組中永遠不會超過一個短時間執行語句,但可能會有多個長時間執行語句。讓長時間執行語句阻止其他語句執行是不可取的,因為可能需要等待的時間沒有限制。例如,在複寫來源伺服器上,將二進位記錄事件傳送到複本的執行緒實際上會永遠執行。

  • 如果語句遇到磁碟 I/O 操作或使用者層級鎖定(資料列鎖定或表格鎖定),則會變成被封鎖的狀態。封鎖會導致執行緒群組變得未使用,因此會回呼執行緒池,以確保執行緒池可以立即在此群組中啟動新執行緒來執行另一個語句。當被封鎖的執行緒返回時,執行緒池允許它立即重新啟動。

  • 有兩個佇列,一個高優先順序佇列和一個低優先順序佇列。交易中的第一個語句會進入低優先順序佇列。如果交易正在進行中(其語句已開始執行),則該交易的任何後續語句都會進入高優先順序佇列,否則會進入低優先順序佇列。佇列指派可能會受到啟用 thread_pool_high_priority_connection 系統變數的影響,該變數會導致工作階段的所有排隊語句都進入高優先順序佇列。

    如果啟用 autocommit,則非交易儲存引擎或交易引擎的語句會被視為低優先順序語句,因為在這種情況下,每個語句都是一個交易。因此,如果混合使用 InnoDBMyISAM 表格的語句,除非啟用 autocommit,否則執行緒池會優先處理 InnoDB 的語句,而不是 MyISAM 的語句。啟用 autocommit 時,所有語句都具有低優先順序。

  • 當執行緒群組選取排隊的語句來執行時,它會先查看高優先順序佇列,然後查看低優先順序佇列。如果找到語句,它會從其佇列中移除,並開始執行。

  • 如果語句在低優先順序佇列中停留太久,執行緒池會將其移至高優先順序佇列。thread_pool_prio_kickup_timer 系統變數的值控制移動前的時間。對於每個執行緒群組,每 10 毫秒(每秒 100 個)最多會將一個語句從低優先順序佇列移至高優先順序佇列。

  • 執行緒池會重複使用最活躍的執行緒,以獲得更好的 CPU 快取使用率。這是一個小調整,但對效能產生了很大的影響。

  • 當執行緒從使用者連線執行語句時,效能架構檢測會將執行緒活動計入使用者連線。否則,效能架構會將活動計入執行緒池。

以下是一些執行緒群組可能會啟動多個執行緒來執行語句的情況範例

  • 一個執行緒開始執行語句,但執行時間長到被視為停滯。即使第一個執行緒仍在執行,執行緒群組也會允許另一個執行緒開始執行另一個語句。

  • 一個執行緒開始執行語句,然後被封鎖,並將此情況回報給執行緒池。執行緒群組允許另一個執行緒開始執行另一個語句。

  • 一個執行緒開始執行語句,被封鎖,但沒有回報它被封鎖,因為封鎖沒有發生在已使用執行緒池回呼進行檢測的程式碼中。在這種情況下,執行緒對於執行緒群組來說似乎仍在執行。如果封鎖持續的時間長到語句被視為停滯,群組會允許另一個執行緒開始執行另一個語句。

執行緒池的設計目的是為了可以跨越不斷增加的連線數量進行擴展。它也旨在避免因限制活動執行語句數量而可能產生的死鎖。重要的是,沒有回報給執行緒池的執行緒不會阻止其他語句執行,進而導致執行緒池陷入死鎖。以下是這類語句的範例

  • 長時間執行的語句。這些語句會導致所有資源僅被少數語句使用,並可能會阻止所有其他語句存取伺服器。

  • 讀取二進位記錄並將其傳送至複本的二進位記錄傾印執行緒。這是一種長時間運行的 語句,它會運行很長時間,且不應阻止其他語句執行。

  • 因資料列鎖定、表格鎖定、休眠或任何其他沒有透過 MySQL 伺服器或儲存引擎回報給執行緒池的封鎖活動而封鎖的語句。

在每種情況下,為了防止死鎖,當語句沒有快速完成時,它會被移至停滯類別,以便執行緒群組允許另一個語句開始執行。透過這種設計,當執行緒執行或被封鎖較長時間時,執行緒池會將執行緒移至停滯類別,且在語句的其餘執行時間內,它不會阻止其他語句執行。

可能發生的最大執行緒數是 max_connectionsthread_pool_size 的總和。這種情況可能會發生在所有連線都處於執行模式,並且每個群組都會建立額外的執行緒來監聽更多語句的情況下。這不一定是經常發生的狀態,但理論上是可能的。

具備權限的連線

如果達到 thread_pool_max_transactions_limit 定義的限制,且新的連線或使用現有連線的新交易出現掛起狀態,直到一個或多個現有交易完成為止,儘管對 thread_pool_longrun_trx_limit 進行了任何調整,導致所有現有連線都被封鎖或長時間執行,則存取伺服器的唯一方法可能是使用具備特權的連線。

要建立具備特權的連線,發起連線的使用者必須擁有 TP_CONNECTION_ADMIN 權限。具備特權的連線會忽略 thread_pool_max_transactions_limit 定義的限制,並允許連線到伺服器以增加限制、移除限制或終止正在執行的交易。 TP_CONNECTION_ADMIN 權限必須明確授予。預設情況下,不會授予任何使用者此權限。

具備特權的連線可以執行語句並開始交易,並會被分配到指定為 Admin 執行緒群組的執行緒群組。

當查詢 performance_schema.tp_thread_group_stats 表格時,該表格會報告每個執行緒群組的統計資訊,Admin 執行緒群組的統計資訊會在結果集的最後一列報告。例如,如果 SELECT * FROM performance_schema.tp_thread_group_stats 回傳 17 列 (每個執行緒群組一列),則 Admin 執行緒群組的統計資訊會在第 17 列報告。