久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Mysql中Connection Manager的作用是什么

144次閱讀
沒有評論

共計 5613 個字符,預計需要花費 15 分鐘才能閱讀完成。

這篇文章給大家介紹 Mysql 中 Connection Manager 的作用是什么,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

1. 連接的線程數

  Mysql 支持單線程和多線程兩種連接線程數。如果是單線程,則在同一時刻,只能有一個 connection 連接到 Mysql,

其他的連接會被掛起。如果是多線程,則同一時刻可以支持多個 connection 同時連接到服務器。

  可以通過設置服務器的啟動參數來設定連接的線程數:

mysqld.exe –thread-handling=no-threads

mysqld.exe –thread-handling=one-thread-per-connection

服務器如何通過參數來選擇使用哪種方式的呢?且看服務器中的分支代碼:

#ifdef EMBEDDED_LIBRARY

  one_thread_scheduler(thread_scheduler);

#else

  if (global_system_variables.thread_handling =

  SCHEDULER_ONE_THREAD_PER_CONNECTION)

  one_thread_per_connection_scheduler(thread_scheduler);

  else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS)

  one_thread_scheduler(thread_scheduler);

  else

  pool_of_threads_scheduler(thread_scheduler);  /* purecov: tested */

#endif

這段代碼出現在 get_options 函數中,此函數是根據傳入的服務器參數,設置相應參數的模式。由這段代碼可以看出,如果定義了 EMBEDDED_LIBRARY 宏定義 (估計應該是嵌入式使用),則調用 one_thread_scheduler,即使用單線程。如果參數小于等于 SCHEDULER_ONE_THREAD_PER_CONNECTION,則調用 one_thread_per_connection_scheduler,即每個連接一個線程,即多線程。至于 global_system_variables.thread_handling 是如何進行設置的呢?其實就是根據我們傳遞給服務器的參數 –thread-handling 進行設置的,參數的設置統一在函數 get_options 中,其調用 mysqld_get_one_option,其中有個分支,代碼如下:

case OPT_THREAD_HANDLING:

  {

  global_system_variables.thread_handling=

  find_type_or_exit(argument, thread_handling_typelib, opt- name)-1;

  break;

  }

對參數初始化有興趣的可以具體的看下 get_options 這個函數,這里就不詳細講解了。我們來看下 one_thread_scheduler 和 one_thread_per_connection_scheduler 的源代碼,看下他們都做了些什么?

void one_thread_scheduler(scheduler_functions* func)

{

  func- max_threads= 1;

#ifndef EMBEDDED_LIBRARY

  func- add_connection= handle_connection_in_main_thread;

#endif

  func- init_new_connection_thread= init_dummy;

  func- end_thread= no_threads_end;

}

void one_thread_per_connection_scheduler(scheduler_functions* func)

{

  func- max_threads= max_connections;

  func- add_connection= create_thread_to_handle_connection;

  func- end_thread= one_thread_per_connection_end;

}

  原來就是設置了一個結構體中 scheduler_functions 的參數,只不過這些參數是一些函數指針罷了,也就是說在具體的調用中,

只需要調用 add_connection 或 end_thread 即可,不需要知道到底是調用了哪個函數,這大概就是一種變形的多態性吧。

2. 初始化網絡配置

  網絡配置比較簡單,就是設置端口,創建套接字,綁定端口,監聽端口。實現全部集中在 network_init 函數中,由于這個函數確

實沒什么好講的,如果對 socket 不熟悉的話,可以去網上搜索下相關知識。這里直接給出相應的偽代碼:

network_init

{

  set_ports; // 設置端口號,#define MYSQL_PORT  3306

  socket;// 創建套接字

  bind;  // 綁定端口號

  listen;// 監聽端口號

}

3. 連接的方式

  進程間通信的方式不止是 SOCKET,還有其他很多方式。Mysql 支持三種連接方式:namepipe、socket 和 shared memory,

即命名管道、套接字和共享內存的方式。這三種方式是可以共存的。默認只使用套接字。

  TCP/IP 套接字方式是 MySQL 在任何平臺下都提供的連接方式,也是網絡中使用得最多的一種方式。這種方式在 TCP/IP 連接上建立

一個基于網絡的連接請求,一般情況下客戶端在一臺服務器上,而 MySQL 實例在另一臺服務器上,這兩臺機器通過一個 TCP/IP 網絡連接。

例如,我可以在 Windows 服務器下請求一臺遠程 Linux 服務器下的 MySQL 實例。

  在 Windows 2000、Windows XP、Windows 2003 和 Windows Vista 以及在此之后的 Windows 操作系統中,如果兩個需要通

信的進程在同一臺服務器上,那么可以使用命名管道,SQL Server 數據庫默認安裝后的本地連接也使用命名管道。在 MySQL 數據庫中,

需在配置文件中啟用 –enable-named-pipe 選項。在 MySQL 4.1 之后的版本中,MySQL 還提供了共享內存的連接方式,在配置文件中

添加 –shared-memory。如果想使用共享內存的方式,在連接時,Mysql 客戶端還必須使用 -protocol=memory 選項。

  啟動時可以通過下面的參數進行設置。

mysqld.exe –enable-named-pipe

mysqld.exe –shared-memory

除了在啟動時進行參數設置外,也可以通過修改 MY.INI 文件進行設置。我們來看下中選擇連接方式的分支函數 handle_connections_methods:

handle_connections_methods()

{

if (hPipe != INVALID_HANDLE_VALUE)

{

  handler_count++;

  if (pthread_create( hThread, connection_attrib,

  handle_connections_namedpipes, 0))

  {

  sql_print_warning(Can t create thread to handle named pipes

  handler_count–;

  }

}

  if (have_tcpip !opt_disable_networking)

  {

  handler_count++;

  if (pthread_create( hThread, connection_attrib,

  handle_connections_sockets, 0))

  {

  sql_print_warning(Can t create thread to handle TCP/IP

  handler_count–;

  }

  }

if (opt_enable_shared_memory)

  {

  handler_count++;

  if (pthread_create( hThread, connection_attrib,

  handle_connections_shared_memory, 0))

  {

  sql_print_warning(Can t create thread to handle shared memory

  handler_count–;

  }

  }

}

由于對于 namepipe 和 memory share 的通信方式不太了解,這里只研究 socket 的通信方式。從代碼中可以看出,handle_connections_sockets 便是 socket 的設置,我們就來看下它。

4.socket 管理創建新線程 socket 管理其實比較簡單,直接給出其偽代碼:

handle_connections_sockets

{

  select; // 監視 socket 文件描述符

  new_socket = accept;// 處理到來的客戶端連接

  thd = new THD;創建 THD 類

  vio_tmp = vio_new(new_socket,VIO_TYPE_TCPIP, 0);  // 初始化 VIO 結構體

  my_net_init(thd- net, vio_tmp);// 初始化 thd 的 net 結構體

  create_new_thread(thd);// 為這個連接創建一個新的線程,如果是單線程模式的話,就不會創建一個新線程

}

首先是 select 函數進行監視 socket 端口,如果監控到有連接,則通過 accept 函數接受客戶端的連接,然后新建一個 THD 類,將連接參數全部設置到 THD 類的參數上,最后調用 create_new_thread 函數,這個函數便是重點。我們進入這個函數,看下做了啥。

create_new_thread

{

  ++connection_count;// 全局連接數自增

  thread_count++;  // 全局線程數自增

  thread_scheduler.add_connection(thd);// 真正創建線程

}

  So easy, 首先將全局連接數 +1,全局線程數 +1,然后調用 add_connection 函數,這個函數就是我們在上面第一步設置連接的

線程數中,one_thread_scheduler 和 one_thread_per_connection_scheduler 中設置的一個參數。這兩者的區別便是是否創建了

一個新的線程來處理到來的連接。one_thread_scheduler 是單線程方式,木有新建線程。我們重點研究 one_thread_per_connection_scheduler,其設置的 add_connection 函數為 create_thread_to_handle_connection:

create_thread_to_handle_connection(THD *thd)

{

  thread_created++;

  threads.append(thd); // 創建線程數自增,并加入到 threads 鏈表上

  pthread_create(thd- real_id, connection_attrib,

  handle_one_connection,

  (void*) thd);// 這就是真正創建線程的地方了,函數便是 handle_one_connection

}

  可見,最后調用了 pthread_create 函數,這個函數便是創建一個新的線程,新線程的處理函數為 handle_one_connection.

5. 新線程處理流程

  新線程處理函數為 handle_one_connection,到此位置,一個新的 connection 被一個新創建的線程所單獨處理。我們看下其中

是如何進行處理的。

handle_one_connection(void *arg)

{

  for (;;)

  {

  lex_start(thd); // 初始化詞法分析結構體

  login_connection(thd); // 用戶認證,失敗報錯

  prepare_new_connection_state(THD* thd);//Initialize THD to handle queries

  while (!net- error net- vio != 0   // 循環處理 command

  !(thd- killed == THD::KILL_CONNECTION))

  {

  if (do_command(thd))

  break;  // 處理失敗跳出

   }

  end_connection(thd);  // 關閉連接

  close_connection(thd, 0, 1);

  thread_scheduler.end_thread(thd,1);// 結束線程

  return 0;

  }

}

  首先進行了詞法分析結構體的初始化,然后進行用戶認證,認證成功后通過 do_command 循環執行客戶端發過來的命令。

6. 總結

  整個 connection manager 的流程十分清晰,單線程的連接一般很少使用,大多使用多線程方式。多線程連接中其實還涉及到線程緩沖

池的概念,即如果一個連接斷開后,其所創建的線程不會被銷毀掉,而是放到緩沖池中,等待下一個新的 connection 到來時,首先去線程

緩沖池查找是否有空閑的線程,有的話直接使用,木有的話才去創建新的線程來管理這個 connection。這些屬于 Thread Manage 的內容,

關于 Mysql 中 Connection Manager 的作用是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-03發表,共計5613字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 大邑县| 江阴市| 邯郸市| 九江县| 江安县| 军事| 修水县| 苏尼特左旗| 翁源县| 汉阴县| 贵德县| 民县| 苏州市| 永城市| 镇沅| 紫金县| 屯留县| 思南县| 浮山县| 射洪县| 班玛县| 依安县| 曲松县| 新和县| 如东县| 洞头县| 霍州市| 瑞安市| 呼和浩特市| 西乌珠穆沁旗| 景泰县| 沙雅县| 禄丰县| 潼南县| 高密市| 棋牌| 神木县| 纳雍县| 抚顺县| 岗巴县| 德惠市|