中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

探索MYSQL源代碼–SQL歷險(xiǎn)記

2019-02-26    來源:多智時代

容器云強(qiáng)勢上線!快速搭建集群,上萬Linux鏡像隨意使用

本文從一個select語句的執(zhí)行過程出發(fā),遍歷MySQL的多個幾子系統(tǒng)。

先放圖一張, 按圖索驥開始我們的歷險(xiǎn).

探索MYSQL源代碼–SQL歷險(xiǎn)記

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

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

packet_length= my_net_read(net);

packet的第一個字節(jié)是個標(biāo)志位, 決定數(shù)據(jù)包是查詢還是命令,成功,或者出錯。

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

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

進(jìn)入dispatch_command, 我們可見

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

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

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

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

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

#define yyparse MYSQLparse

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

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

select:

select_init

{

LEX *lex= Lex;

lex->sql_command= SQLCOM_SELECT;

}

;

/* Need select_init2 for subselects. */

select_init:

SELECT_SYM select_init2

| '(' select_paren ')' union_opt

;

select_paren:

SELECT_SYM select_part2

{

LEX *lex= Lex;

SELECT_LEX * sel= lex->current_select;

.....

select_from:

FROM join_table_list where_clause group_clause having_clause

opt_order_clause opt_limit_clause procedure_clause

{

Select->context.table_list=

Select->context.first_name_resolution_table=

(TABLE_LIST *) Select->table_list.first;

}

....

select_item_list:

select_item_list ',' select_item

| select_item

| '*'

{

THD *thd= YYTHD;

Item *item= new (thd->mem_root)

Item_field(&thd->lex->current_select->context,

NULL, NULL, "*");

if (item == NULL)

MYSQL_YYABORT;

if (add_item_to_list(thd, item))

MYSQL_YYABORT;

(thd->lex->current_select->with_wild)++;

}

;

select_item:

remember_name select_item2 remember_end select_alias

{

THD *thd= YYTHD;

DBUG_ASSERT($1 if (add_item_to_list(thd, $2))

MYSQL_YYABORT;

if ($4.str)

...

可以看到action里最關(guān)鍵的就是add_item_to_list 和table_list的賦值.

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

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

(gdb) p *thd->lex->query_tables

$7 = {next_local = 0x0, next_global = 0x0, prev_global = 0x855a458, db = 0x85a16b8 "test", alias = 0x85a16e0 "zzz",

table_name = 0x85a16c0 "zzz", schema_table_name = 0x0, option = 0x0, on_expr = 0x0, prep_on_expr = 0x0, cond_equal = 0x0,

sql解析完了, 優(yōu)化呢? 別急接著往下看.

接著進(jìn)入mysql_execute_command函數(shù),這個函數(shù)是所有sql命令的總?cè)肟?

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

mysql_select 就是優(yōu)化器的模塊, 這個模塊代碼比較復(fù)雜. 我們可以清楚看到創(chuàng)建優(yōu)化器,優(yōu)化,執(zhí)行的3個步驟, 優(yōu)化細(xì)節(jié)不表.

if (!(join= new JOIN(thd, fields, select_options, result)))

...

if ((err= join->optimize()))

...

join->exec();

結(jié)束了優(yōu)化,我們要具體執(zhí)行join->exec(),該函數(shù)實(shí)際進(jìn)入的是JOIN::exec()(sql_select.cc)。

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

然后再進(jìn)入do_select(),根據(jù)表的存儲引擎跳入到引擎具體的實(shí)現(xiàn)(zzz是myisam表)。

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

(gdb) p info->filename

./test/zzz

這不就是zzz表對應(yīng)的物理文件嗎。

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

一個簡單的select語句背后的執(zhí)行過程是非常復(fù)雜的,上面的步驟都只是點(diǎn)到就止。

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

在不久的將來,云計(jì)算一定會徹底走入我們的生活,有興趣入行未來前沿產(chǎn)業(yè)的朋友,可以收藏云計(jì)算,及時獲取人工智能、大數(shù)據(jù)、云計(jì)算和物聯(lián)網(wǎng)的前沿資訊和基礎(chǔ)知識,讓我們一起攜手,引領(lǐng)人工智能的未來!

標(biāo)簽: isp Mysql 大數(shù)據(jù) 代碼 云計(jì)算

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:向云服務(wù)供應(yīng)商提問:10個災(zāi)備問題

下一篇:CIO解析中美兩國云計(jì)算技術(shù)發(fā)展與應(yīng)用