<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專(zhuān)題視頻專(zhuān)題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專(zhuān)題1關(guān)鍵字專(zhuān)題50關(guān)鍵字專(zhuān)題500關(guān)鍵字專(zhuān)題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專(zhuān)題關(guān)鍵字專(zhuān)題tag2tag3文章專(zhuān)題文章專(zhuān)題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專(zhuān)題3
        問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
        當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

        Mysql源碼學(xué)習(xí)――ConnectionManager_MySQL

        來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-09 18:11:37
        文檔

        Mysql源碼學(xué)習(xí)――ConnectionManager_MySQL

        Mysql源碼學(xué)習(xí)――ConnectionManager_MySQL:bitsCN.com 1.連接的線程數(shù) Mysql支持單線程和多線程兩種連接線程數(shù)。如果是單線程,則在同一時(shí)刻,只能有一個(gè)connection連接到Mysql, 其他的連接會(huì)被掛起。如果是多線程,則同一時(shí)刻可以支持多個(gè)connection同時(shí)連接到服務(wù)器。 可以通過(guò)設(shè)置服務(wù)器
        推薦度:
        導(dǎo)讀Mysql源碼學(xué)習(xí)――ConnectionManager_MySQL:bitsCN.com 1.連接的線程數(shù) Mysql支持單線程和多線程兩種連接線程數(shù)。如果是單線程,則在同一時(shí)刻,只能有一個(gè)connection連接到Mysql, 其他的連接會(huì)被掛起。如果是多線程,則同一時(shí)刻可以支持多個(gè)connection同時(shí)連接到服務(wù)器。 可以通過(guò)設(shè)置服務(wù)器

        bitsCN.com

        1.連接的線程數(shù)

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

        其他的連接會(huì)被掛起。如果是多線程,則同一時(shí)刻可以支持多個(gè)connection同時(shí)連接到服務(wù)器。

        可以通過(guò)設(shè)置服務(wù)器的啟動(dòng)參數(shù)來(lái)設(shè)定連接的線程數(shù):

        mysqld.exe --thread-handling=no-threads

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

          

        服務(wù)器如何通過(guò)參數(shù)來(lái)選擇使用哪種方式的呢?且看服務(wù)器中的分支代碼:

        #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

          

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

        case OPT_THREAD_HANDLING:

        {

        global_system_variables.thread_handling=

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

        break;

        }

          

        對(duì)參數(shù)初始化有興趣的可以具體的看下get_options這個(gè)函數(shù),這里就不詳細(xì)講解了。 我們來(lái)看下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;

        }

          

        原來(lái)就是設(shè)置了一個(gè)結(jié)構(gòu)體中scheduler_functions的參數(shù),只不過(guò)這些參數(shù)是一些函數(shù)指針罷了,也就是說(shuō)在具體的調(diào)用中,

        只需要調(diào)用add_connection或end_thread即可,不需要知道到底是調(diào)用了哪個(gè)函數(shù),這大概就是一種變形的多態(tài)性吧。

        2.初始化網(wǎng)絡(luò)配置

        網(wǎng)絡(luò)配置比較簡(jiǎn)單,就是設(shè)置端口,創(chuàng)建套接字,綁定端口,監(jiān)聽(tīng)端口。實(shí)現(xiàn)全部集中在network_init函數(shù)中,由于這個(gè)函數(shù)確

        實(shí)沒(méi)什么好講的,如果對(duì)socket不熟悉的話(huà),可以去網(wǎng)上搜索下相關(guān)知識(shí)。這里直接給出相應(yīng)的偽代碼:

        network_init

        {

        set_ports; //設(shè)置端口號(hào),#define MYSQL_PORT 3306

        socket;//創(chuàng)建套接字

        bind; //綁定端口號(hào)

        listen;//監(jiān)聽(tīng)端口號(hào)

        }

        3.連接的方式

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

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

        TCP/IP套接字方式是MySQL在任何平臺(tái)下都提供的連接方式,也是網(wǎng)絡(luò)中使用得最多的一種方式。這種方式在TCP/IP連接上建立

        一個(gè)基于網(wǎng)絡(luò)的連接請(qǐng)求,一般情況下客戶(hù)端在一臺(tái)服務(wù)器上,而MySQL實(shí)例在另一臺(tái)服務(wù)器上,這兩臺(tái)機(jī)器通過(guò)一個(gè)TCP/IP網(wǎng)絡(luò)連接。

        例如,我可以在Windows服務(wù)器下請(qǐng)求一臺(tái)遠(yuǎn)程Linux服務(wù)器下的MySQL實(shí)例。

        在Windows 2000、Windows XP、Windows 2003和Windows Vista以及在此之后的Windows操作系統(tǒng)中,如果兩個(gè)需要通

        信的進(jìn)程在同一臺(tái)服務(wù)器上,那么可以使用命名管道,SQL Server數(shù)據(jù)庫(kù)默認(rèn)安裝后的本地連接也使用命名管道。在MySQL數(shù)據(jù)庫(kù)中,

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

        添加--shared-memory。如果想使用共享內(nèi)存的方式,在連接時(shí),Mysql客戶(hù)端還必須使用-protocol=memory選項(xiàng)。

        啟動(dòng)時(shí)可以通過(guò)下面的參數(shù)進(jìn)行設(shè)置。

        mysqld.exe --enable-named-pipe

        mysqld.exe --shared-memory

          

        除了在啟動(dòng)時(shí)進(jìn)行參數(shù)設(shè)置外,也可以通過(guò)修改MY.INI文件進(jìn)行設(shè)置。我們來(lái)看下源碼中選擇連接方式的分支函數(shù)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--;

        }

        }

        }

          

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

        4.socket管理創(chuàng)建新線程socket管理其實(shí)比較簡(jiǎn)單,直接給出其偽代碼:

        handle_connections_sockets

        {

        select; //監(jiān)視socket文件描述符

        new_socket = accept;//處理到來(lái)的客戶(hù)端連接

        thd = new THD;創(chuàng)建THD類(lèi)

        vio_tmp = vio_new(new_socket,VIO_TYPE_TCPIP, 0); //初始化VIO結(jié)構(gòu)體

        my_net_init(&thd->net, vio_tmp);//初始化thd的net結(jié)構(gòu)體

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

        }

          

        首先是select函數(shù)進(jìn)行監(jiān)視socket端口,如果監(jiān)控到有連接,則通過(guò)accept函數(shù)接受客戶(hù)端的連接,然后新建一個(gè)THD類(lèi),將連接參數(shù)全部設(shè)置到THD類(lèi)的參數(shù)上,最后調(diào)用create_new_thread函數(shù),這個(gè)函數(shù)便是重點(diǎn)。 我們進(jìn)入這個(gè)函數(shù),看下做了啥。

        create_new_thread

        {

        ++connection_count;//全局連接數(shù)自增

        thread_count++; //全局線程數(shù)自增

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

        }

          

        So easy,首先將全局連接數(shù)+1,全局線程數(shù)+1,然后調(diào)用add_connection函數(shù),這個(gè)函數(shù)就是我們?cè)谏厦娴谝徊皆O(shè)置連接的

        線程數(shù)中,one_thread_scheduler和one_thread_per_connection_scheduler中設(shè)置的一個(gè)參數(shù)。這兩者的區(qū)別便是是否創(chuàng)建了

        一個(gè)新的線程來(lái)處理到來(lái)的連接。one_thread_scheduler是單線程方式,木有新建線程。我們重點(diǎn)研究one_thread_per_connection_scheduler,其設(shè)置的add_connection函數(shù)為create_thread_to_handle_connection:

        create_thread_to_handle_connection(THD *thd)

        {

        thread_created++;

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

        pthread_create(&thd->real_id,&connection_attrib,

        handle_one_connection,

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

        }

          

        可見(jiàn),最后調(diào)用了pthread_create函數(shù),這個(gè)函數(shù)便是創(chuàng)建一個(gè)新的線程,新線程的處理函數(shù)為handle_one_connection.

        5.新線程處理流程

        新線程處理函數(shù)為handle_one_connection,到此位置,一個(gè)新的connection被一個(gè)新創(chuàng)建的線程所單獨(dú)處理。我們看下其中

        是如何進(jìn)行處理的。

        handle_one_connection(void *arg)

        {

        for (;;)

        {

        lex_start(thd); //初始化詞法分析結(jié)構(gòu)體

        login_connection(thd); //用戶(hù)認(rèn)證,失敗報(bào)錯(cuò)

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

        while (!net->error && net->vio != 0 && //循環(huán)處理command

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

        {

        if (do_command(thd))

        break; //處理失敗跳出

        }

        end_connection(thd); //關(guān)閉連接

        close_connection(thd, 0, 1);

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

        return 0;

        }

        }

          

        首先進(jìn)行了詞法分析結(jié)構(gòu)體的初始化,然后進(jìn)行用戶(hù)認(rèn)證,認(rèn)證成功后通過(guò)do_command循環(huán)執(zhí)行客戶(hù)端發(fā)過(guò)來(lái)的命令。

        6.總結(jié)

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

        池的概念,即如果一個(gè)連接斷開(kāi)后,其所創(chuàng)建的線程不會(huì)被銷(xiāo)毀掉,而是放到緩沖池中,等待下一個(gè)新的connection到來(lái)時(shí),首先去線程

        緩沖池查找是否有空閑的線程,有的話(huà)直接使用,木有的話(huà)才去創(chuàng)建新的線程來(lái)管理這個(gè)connection。這些屬于Thread Manage的內(nèi)容,

        下節(jié)進(jìn)行Thread Manage的學(xué)習(xí)。

        PS. 上周六迎來(lái)第一個(gè)雙休,結(jié)果還是被叫道公司改BUG,我忍。不過(guò),BOSS,前幾個(gè)月的加班費(fèi)啥時(shí)候發(fā)啊?不準(zhǔn)拖欠民工工資…

        踏著落葉,追尋著我的夢(mèng)想。轉(zhuǎn)載請(qǐng)注明出處



        摘自 心中無(wú)碼 bitsCN.com

        聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Mysql源碼學(xué)習(xí)――ConnectionManager_MySQL

        Mysql源碼學(xué)習(xí)――ConnectionManager_MySQL:bitsCN.com 1.連接的線程數(shù) Mysql支持單線程和多線程兩種連接線程數(shù)。如果是單線程,則在同一時(shí)刻,只能有一個(gè)connection連接到Mysql, 其他的連接會(huì)被掛起。如果是多線程,則同一時(shí)刻可以支持多個(gè)connection同時(shí)連接到服務(wù)器。 可以通過(guò)設(shè)置服務(wù)器
        推薦度:
        標(biāo)簽: mysql manager mysq
        • 熱門(mén)焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門(mén)推薦

        專(zhuān)題
        Top
        主站蜘蛛池模板: 亚洲人成电影网站国产精品| 国内精品免费视频精选在线观看 | 天堂亚洲国产中文在线| 一个人看的免费高清视频日本| 亚洲免费黄色网址| 亚洲婷婷五月综合狠狠爱| 亚洲福利电影一区二区?| 老司机69精品成免费视频| 免费少妇a级毛片| 国产精品自拍亚洲| 午夜亚洲国产成人不卡在线| 亚洲精品无码少妇30P| 久久精品网站免费观看| 亚洲视频在线观看免费视频| 日本免费在线观看| 亚洲精品乱码久久久久久蜜桃不卡 | 亚洲AV一宅男色影视| 99热精品在线免费观看| 亚洲自国产拍揄拍| 日本特黄特黄刺激大片免费| 欧洲美女大片免费播放器视频| 在线播放亚洲第一字幕| 久久精品中文字幕免费| 亚洲xxxxxx| 凹凸精品视频分类国产品免费| 一级毛片免费全部播放| 99久久精品国产亚洲| 在线观看免费为成年视频| 免费播放国产性色生活片| 国产亚洲精品无码成人| 最近中文字幕电影大全免费版| 亚洲熟妇无码八V在线播放| 啊v在线免费观看| 日韩精品无码专区免费播放| 亚洲第一区二区快射影院| 亚洲国产小视频精品久久久三级 | 嫩草影院在线免费观看| 香蕉视频在线免费看| 亚洲天堂2016| 亚洲精品无码专区久久同性男| 日本xxxx色视频在线观看免费|