![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CZiVDO5YjM0IjMjJWM2UWZlJ2YkdDN3kDMjZTZ3gzN38CX1AzLclDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLzM3Lc9CX6MHc0RHaiojIsJye.png)
-
Main thread
初始化核心子產品和線程。Main線程最後一部分用watchdog做mysql work線程和idle線程的heartbeat檢查,如果超過20次則重新開機proxy,如果設定restart,則無限重新開機。
-
Admin thread
核心循環:admin_main_loop,是Admin子產品最重要的循環
建立并監聽Admin端口(預設的6032),為每個admin連接配接建立一個新的線程。
加載各種配置資訊,以及管理配置變更(動态加載、持久化到sqlite)等。
如果配置HTTP Server,AdminRestApiServer,還會負責啟動這些Server并處理web請求。
這裡有一個比較trick的事情,admin這個管理賬号隻能local連接配接,其他賬号可以遠端連接配接,其他這些賬号都是一樣的管理者權限。如果硬要解釋,那就是coder的情懷了~
-
MySQL workers threads & MySQL idle threads
worker thread負責處理活躍的用戶端mysql請求,是主要的工作線程。
idle thread主要就是監聽非活躍的Session是否有新的請求,然後移交給worker線程處理。
當活躍連接配接遠小于非活躍連接配接的時候,idle和worker搭配可以很好地提高性能。官網資料可處理連接配接能到1百萬。
idle thread和work thread是1:1建立的。其互動流程入下圖所示。
ProxySQL源碼分析4-線程分析 -
Monitor threads
産生5類生産者線程:connection checks、ping checks、read-only checks、replication lag checks、group replication monitoring
排程消費線程池:一方面負責check任務; 另一方面就是處理上面的check結果,比如ping失敗之類的。處理主要是通過更新 MyHGM->p_update_mysql_error_counter狀态來實作,如下代碼。
void *monitor_ping_thread(void *arg) {
MySQL_Monitor_State_Data *mmsd = (MySQL_Monitor_State_Data *) arg;
if (mmsd->interr) { // ping failed
MyHGM->p_update_mysql_error_counter(p_mysql_error_type::proxysql, mmsd->hostgroup_id, mmsd->hostname,
mmsd->port, mysql_errno(mmsd->mysql));
} else {
if (crc == false) {
GloMyMon->My_Conn_Pool->put_connection(mmsd->hostname, mmsd->port, mmsd->mysql);
mmsd->mysql = NULL;
}
}
...
if (ping_success) {
__sync_fetch_and_add(&GloMyMon->ping_check_OK, 1);
} else {
__sync_fetch_and_add(&GloMyMon->ping_check_ERR, 1);
}
}
-
Query Cache purge thread
對query cache執行一個垃圾回收的功能
// ProxySQL_Admin::load_proxysql_servers_to_runtime(bool _lock)
// char *query=(char *)"SELECT hostname, port, weight, comment FROM proxysql_servers ORDER BY hostname, port";
void ProxySQL_Cluster_Nodes::load_servers_list(SQLite3_result *resultset, bool _lock) {
for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin(); it != resultset->rows.end(); ++it) {
...
if (ite == umap_proxy_nodes.end()) {
...
// 每個Server都建立所有連接配接
if (pthread_create(&a->thrid, &attr, ProxySQL_Cluster_Monitor_thread, (void *) a) != 0) {
...
}
} else {
...
}
}
}