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

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

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題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關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        探索MySQL源代碼之SQL歷險記

        來源:懂視網 責編:小采 時間:2020-11-09 14:37:26
        文檔

        探索MySQL源代碼之SQL歷險記

        探索MySQL源代碼之SQL歷險記:本文從一個select語句的執行過程出發,遍歷MySQL的多個幾子系統。 先放圖一張, 按圖索驥開始我們的歷險. 當客戶端連接上MySQL服務端之后,發出請求之前,服務端的線程是阻塞在do_command(sql/parse.cc)里的my_net_read函數中(就是socket里的r
        推薦度:
        導讀探索MySQL源代碼之SQL歷險記:本文從一個select語句的執行過程出發,遍歷MySQL的多個幾子系統。 先放圖一張, 按圖索驥開始我們的歷險. 當客戶端連接上MySQL服務端之后,發出請求之前,服務端的線程是阻塞在do_command(sql/parse.cc)里的my_net_read函數中(就是socket里的r

        本文從一個select語句的執行過程出發,遍歷MySQL的多個幾子系統。 先放圖一張, 按圖索驥開始我們的歷險. 當客戶端連接上MySQL服務端之后,發出請求之前,服務端的線程是阻塞在do_command(sql/parse.cc)里的my_net_read函數中(就是socket里的read). 當客戶端鍵

        本文從一個select語句的執行過程出發,遍歷MySQL的多個幾子系統。

        先放圖一張, 按圖索驥開始我們的歷險.

        當客戶端連接上MySQL服務端之后,發出請求之前,服務端的線程是阻塞在do_command(sql/parse.cc)里的my_net_read函數中(就是socket里的read).

        當客戶端鍵入sql語句(本文例子select * from zzz)發送到服務端之后, my_net_read返回, 并從tcpbuffer中讀取數據寫入到packet這個字符串.

        1. packet_length= my_net_read(net);

        packet的第一個字節是個標志位, 決定數據包是查詢還是命令,成功,或者出錯。

        接下來就進入dispatch_command(sql/sql/parse.cc)這個函數, 數據類型不再需要.

        1. return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));

        進入dispatch_command, 我們可見

        1. statistic_increment(thd->status_var.questions, &LOCK_status);

        這個就是show status questions的值累加.

        接下的mysql_parse(sql/sql_parse.cc), 該函數是sql語句解析的總路口.

        進入該函數后首先碰到的是query_cache_send_result_to_client,故名思義這個函數是在QCache里查詢是否有相同的語句, 有則立即從QCache返回結果, 于是整個sql就結束了.

        QCache里不存在的sql則繼續前進來到parse_sql(sql/sql_parse.cc),這個函數主要就是調用了MYSQLparse. 而MYSQLparse其實就是bison/yacc里的yyparse(^_^),

        1. #define yyparse MYSQLparse

        是的開始解析sql了. 關于詞法分析和語法匹配簡單說幾下.

        對于一條像select * from zzz的語句首先進入詞法分析,找到2個token(select, from), 然后根據token進行語法匹配, 規則在sql/yacc.yy里, 我把幾個匹配到的pattern和action貼出來.

        1. select:
        2. select_init
        3. {
        4. LEX *lex= Lex;
        5. lex->sql_command= SQLCOM_SELECT;
        6. }
        7. ;
        8. /* Need select_init2 for subselects. */
        9. select_init:
        10. SELECT_SYM select_init2
        11. | '(' select_paren ')' union_opt
        12. ;
        13. select_paren:
        14. SELECT_SYM select_part2
        15. {
        16. LEX *lex= Lex;
        17. SELECT_LEX * sel= lex->current_select;
        18. .....
        19. select_from:
        20. FROM join_table_list where_clause group_clause having_clause
        21. opt_order_clause opt_limit_clause procedure_clause
        22. {
        23. Select->context.table_list=
        24. Select->context.first_name_resolution_table=
        25. (TABLE_LIST *) Select->table_list.first;
        26. }
        27. ....
        28. select_item_list:
        29. select_item_list ',' select_item
        30. | select_item
        31. | '*'
        32. {
        33. THD *thd= YYTHD;
        34. Item *item= new (thd->mem_root)
        35. Item_field(&thd->lex->current_select->context,
        36. NULL, NULL, "*");
        37. if (item == NULL)
        38. MYSQL_YYABORT;
        39. if (add_item_to_list(thd, item))
        40. MYSQL_YYABORT;
        41. (thd->lex->current_select->with_wild)++;
        42. }
        43. ;
        44. select_item:
        45. remember_name select_item2 remember_end select_alias
        46. {
        47. THD *thd= YYTHD;
        48. DBUG_ASSERT($1 < $3);
        49. if (add_item_to_list(thd, $2))
        50. MYSQL_YYABORT;
        51. if ($4.str)
        52. ...

        可以看到action里最關鍵的就是add_item_to_list 和table_list的賦值.

        解析后對于需要查詢的表(zzz)和字段(*)這些信息都寫入到thd->lex這個結構體里了.

        例如其中thd->lex->query_tables就是表(zzz)的狀況, thd->lex->current_select->with_wild 是表示該語句是否使用了*等等.

        1. (gdb) p *thd->lex->query_tables
        2. $7 = {next_local = 0x0, next_global = 0x0, prev_global = 0x855a458, db = 0x85a16b8 "test", alias = 0x85a16e0 "zzz",
        3. table_name = 0x85a16c0 "zzz", schema_table_name = 0x0, option = 0x0, on_expr = 0x0, prep_on_expr = 0x0, cond_equal = 0x0,

        sql解析完了, 優化呢? 別急接著往下看.

        接著進入mysql_execute_command函數,這個函數是所有sql命令的總入口.

        由于是這個sql是一個select, 于是execute_sqlcom_select就是我們下個要執行的函數,又然后進入了mysql_select(^_^怒了如此復雜).

        mysql_select 就是優化器的模塊, 這個模塊代碼比較復雜. 我們可以清楚看到創建優化器,優化,執行的3個步驟, 優化細節不表.

        1. if (!(join= new JOIN(thd, fields, select_options, result)))
        2. ...
        3. if ((err= join->optimize()))
        4. ...
        5. join->exec();

        結束了優化,我們要具體執行join->exec(),該函數實際進入的是JOIN::exec()(sql_select.cc)。

        exec()首先向客戶端發送字段title的函數send_fields, 沒數據但字段也是要的。

        然后再進入do_select(),根據表的存儲引擎跳入到引擎具體的實現(zzz是myisam表)。

        這里mi_scan就是myisam引擎掃描文件的函數,再看到

        1. (gdb) p info->filename
        2. ./test/zzz

        這不就是zzz表對應的物理文件嗎。

        通過一系列的mi函數訪問磁盤拿到數據之后,會通過send_data發送數據給client,并從dispatch_command返回.最后在net_end_statement結束整個sql。

        一個簡單的select語句背后的執行過程是非常復雜的,上面的步驟都只是點到就止。

        ps: 在sql_yacc.yy可見MySQL對于Oracle中常用的dual表的嘲諷。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        探索MySQL源代碼之SQL歷險記

        探索MySQL源代碼之SQL歷險記:本文從一個select語句的執行過程出發,遍歷MySQL的多個幾子系統。 先放圖一張, 按圖索驥開始我們的歷險. 當客戶端連接上MySQL服務端之后,發出請求之前,服務端的線程是阻塞在do_command(sql/parse.cc)里的my_net_read函數中(就是socket里的r
        推薦度:
        標簽: 一個 代碼 sql
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲视频无码高清在线| 中文在线观看免费网站| 日本h在线精品免费观看| 国产亚洲av片在线观看播放| 四虎影视在线看免费观看 | 毛片无码免费无码播放 | 97在线视频免费播放| 婷婷亚洲综合五月天小说| 精品国产一区二区三区免费| 国产成人亚洲综合无码精品| 两个人日本免费完整版在线观看1| 四虎影视免费永久在线观看| 菠萝菠萝蜜在线免费视频| 国产亚洲精aa在线看| 中文字幕一区二区免费| 国产国产人免费人成成免视频 | 8x8×在线永久免费视频| 久久精品九九亚洲精品| 1000部夫妻午夜免费| 国产一级淫片a免费播放口之| 亚洲国产精品久久久久秋霞小| 国产成人无码免费视频97| 亚洲av日韩综合一区久热| 亚洲国产精品一区二区三区久久 | 久久综合图区亚洲综合图区| 99久热只有精品视频免费看| 亚洲国产av高清无码| 成人免费看黄20分钟| 国产亚洲日韩在线a不卡| 亚洲中文字幕无码久久2017| 玖玖在线免费视频| 麻豆狠色伊人亚洲综合网站| 全免费a级毛片免费看无码| 成人一级免费视频| 亚洲黄色网站视频| 尤物永久免费AV无码网站| 中国国语毛片免费观看视频| 亚洲春色另类小说| 国产在线观看免费完整版中文版 | 亚洲精品视频久久久| 最近中文字幕大全中文字幕免费 |