Mysql 一條語句的執行過程(2) 補充

2021-09-24 10:10:48 字數 3596 閱讀 4178

欄位名稱有誤的sql解析

select * from test2 where kkk=2;

有興趣測了下這個kkk列不存在的時候什麼時候出錯已了解下對sql的解析過程

對應的**路徑:

breakpoint 1, dispatch_command (thd=0x7efac40124f0, com_data=0x7efb3a9e2d80, command=com_query)

at /root/mysql-5.7.25/sql/sql_parse.cc:1460

mysql_parse (thd=0x7efac40124f0, parser_state=0x7efb3a9e2610) at /root/mysql-5.7.25/sql/sql_parse.cc:5458

mysql_execute_command (thd=0x7efac40124f0, first_level=true) at /root/mysql-5.7.25/sql/sql_parse.cc:2445

execute_sqlcom_select (thd=0x7efac40124f0, all_tables=0x7efac4016bb0)

at /root/mysql-5.7.25/sql/sql_parse.cc:5099

st_select_lex::prepare (this=0x7efac4015cc0, thd=0x7efac40124f0) at /root/mysql-5.7.25/sql/sql_resolver.cc:97

97 dbug_enter("select_lex::prepare");

setup_fields (thd=0x7efac40124f0, ref_pointer_array=..., fields=..., want_privilege=1,

sum_func_list=0x7efac4015e20, allow_sum_func=true, column_update=false)

at /root/mysql-5.7.25/sql/sql_base.cc:8927

//這步裡面沒問題

st_select_lex::setup_conds (this=0x7f18ac0058d0, thd=0x7f18ac000b70)

at /root/mysql-5.7.25/sql/sql_resolver.cc:1154

1154 dbug_enter("select_lex::setup_conds");

item_func::fix_fields (this=0x7f18ac006e80, thd=0x7f18ac000b70, ref=0x7f18ac0059a8)

at /root/mysql-5.7.25/sql/item_func.cc:213

213 dbug_assert(fixed == 0 || basic_const_item());

item_field::fix_fields (this=0x7f18ac006d60, thd=0x7f18ac000b70, reference=0x7f18ac006f28)

at /root/mysql-5.7.25/sql/item.cc:5840

5840 dbug_assert(fixed == 0);

find_field_in_tables (thd=0x7f18ac000b70, item=0x7f18ac006d60, first_table=0x7f18ac0067c0, last_table=0x0,

ref=0x7f18ac006f28, report_error=ignore_except_non_unique, want_privilege=1, register_tree_change=true)

at /root/mysql-5.7.25/sql/sql_base.cc:7769

7772 const char *name= item->field_name;

(gdb) p item->field_name

$145 = 0x7f18ac006440 "kkk"

find_field_in_table_ref (thd=0x7f18ac000b70, table_list=0x7f18ac0067c0, name=0x7f18ac006440 "kkk", length=3,

item_name=0x7f18ac006440 "kkk", db_name=0x0, table_name=0x0, ref=0x7f18ac006f28, want_privilege=1,

allow_rowid=true, cached_field_index_ptr=0x7f18ac006e38, register_tree_change=true,

actual_table=0x7f192c0506a8) at /root/mysql-5.7.25/sql/sql_base.cc:7546

7546 dbug_enter("find_field_in_table_ref");

find_field_in_table (thd=0x7f18ac000b70, table=0x7f18ac00f6c0, name=0x7f18ac006440 "kkk", length=3,

allow_rowid=true, cached_field_index_ptr=0x7f18ac006e38) at /root/mysql-5.7.25/sql/sql_base.cc:7438

7438 uint cached_field_index= *cached_field_index_ptr;

field *cur_field=

find_field_in_table_ref(thd, cur_table, name, length,

item->item_name.ptr(), db, table_name, ref,

(thd->lex->sql_command == sqlcom_show_fields) ?

0 : want_privilege,

allow_rowid,

&(item->cached_field_index),

register_tree_change,

&actual_table);

這這裡迴圈查詢

(gdb) n

7464 for (; *field_ptr; ++field_ptr)

(gdb) n

7465 if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))

(gdb) p (*field_ptr)->field_name

$160 = 0x7f18bc011564 "name"

(gdb) p name

$161 = 0x7f18ac006440 "kkk"

而且發現mysql 的解析器,優化器,執行器感覺**都在一塊。

在sql_parse.cc:7057 parse_sql() 我感覺可以理解是語法和詞法分析,但是這步並沒有對where 列的判斷。

而是在執行的「執行的這裡面判斷」 這執行的裡面還包含了對許可權,有沒有ddl 等判斷。還有優化。

這給人的感覺沒有明顯的**的區分,也不知道如何去分別。這部分感覺很亂,而且很複雜。

MySQL中一條SQL語句的執行過程

查詢語句的執行順序 客戶端通過tcp連線傳送連線請求到mysql聯結器,聯結器會對該請求進行許可權驗證及連線資源分配 max connections,8小時超時 建立連線後客戶端傳送一條語句,mysql收到該語句後,通過命令分發器判斷其是否是一條select語句,如果是,在開啟查詢快取的情況下,先在...

一條SQL語句的執行過程

1.1連線層 提供連線協議 tcp ip,socket 提供驗證 使用者 密碼 ip socket 提供專用連線線程 接收使用者sql,返回結果 通過以下語句可以檢視鏈結執行緒的基本情況 mysql show processlist 1.2sql層 重點 接收上層傳送的sql語句 語法驗證模組 驗證...

MYSQL 一條sql的執行過程

1 sql介面,負責接收處理收到的sql語句。2 查詢解析器,負責對sql語句進行解析,讓mysql能看懂sql語句,按照sql語法解析出這條sql要幹啥。3 查詢優化器,選擇最優的查詢路徑,指定執行計畫 全表掃瞄還是走索引 4 呼叫儲存引擎介面真正開始執行sql語句。儲存引擎就是用來執行sql的,...