一:背景0 }7 D$ y A- }; y% X% w e
1. 讲故事 3 g9 I8 d( h/ D% r3 c最近看各大技术社区,不管是知乎,掘金,博客园,csdn基本上看不到有小伙伴分享sqlserver类的文章,看样子这些年sqlserver没落了,已经后继无人了,再写sqlserver是不可能再写了,这辈子都不会写了,只能靠技术输出mysql维持生活这样子。' l0 U2 `3 ^$ u
1 p9 |8 f# x2 W+ l<1> 客户端请求被 create_thread_to_handle_connection 接管及调用栈追踪# s7 B5 l9 z+ Y; S- L$ c- e& a
& i; M* g) A( [) |! f2 @' x O
void create_thread_to_handle_connection(THD *thd) ' y! G1 D: U0 X$ D- ^{ 9 J2 J/ x! r# m6 | if ((error= mysql_thread_create(key_thread_one_connection, &thd->real_id, &connection_attrib, 5 s: p# Q& ]' z( v+ V% Z handle_one_connection,(void*) thd))){} " Y$ T2 b% E- H+ U" R4 a, y; ?4 T}6 H1 E& e; D7 Q+ G
//触发回调函数 handle_one_connection 4 H# R/ L; [! q& e/ f: J9 ?pthread_handler_t handle_one_connection(void *arg)3 l4 k+ b& |8 E7 u5 L% G9 A/ I% O
{! t% E! i1 j1 q/ d: v* a+ H# T
do_handle_one_connection(thd); $ i. s2 W6 L: A# Z* h}8 S& |; g5 q6 Z8 O: k
//继续处理/ Q* S# ~, l. m: D7 ], n, x; b
void do_handle_one_connection(THD *thd_arg){% H+ M. M- V% u$ `1 o. g2 K; p
while (thd_is_connection_alive(thd)) - Q2 l! m' G( @+ U& F: @& G2 | {1 |, A! p8 r/ l, J. t
mysql_audit_release(thd);3 b% g! t- h* x& Y; G. |. w! C7 G8 o
if (do_command(thd)) break; //这里的 do_command 继续处理 |9 U1 L4 b7 | } % B O3 c8 Z3 o, ?+ X3 D}" U6 x1 Y1 Y/ Z- u1 a# N
//继续分发5 t4 c* a" U0 F" k
bool do_command(THD *thd) ( {! ~) j- @* i) ?0 \{ ' l( r$ L* a. R' \ return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));3 j9 x8 B `! w5 O2 C( H/ e! @0 ^
}2 T0 [: g! X" E" L" G/ T, p5 ^
bool dispatch_command(enum enum_server_command command, THD *thd, char* packet, uint packet_length): {& p% d% A) f% Z
{ . \4 ~1 ~, V5 L/ L' `, o switch (command) {( c8 Y" a/ b- P
case COM_INIT_DB: .... break;: u8 U4 O% }! k: e
...* \* s+ t. f7 U8 I
case COM_QUERY: //查询语句: insert xxxx& y7 ~! k, H7 `8 y$ j! x ?* b; p
mysql_parse(thd, thd->query(), thd->query_length(), &parser_state); //sql解析" d2 s0 @' C) O# n' m$ |
break; 6 T- j" @ ^; J } $ l) m' p" B, @+ ^0 O}' w6 A% l& t3 |
//sql解析模块 5 {& m! N2 D3 p# m/ ~. cvoid mysql_parse(THD *thd, char *rawbuf, uint length, Parser_state *parser_state)# g; j% R1 c. W6 r" K4 m
{ 3 Z( b6 k% p3 `; z error= mysql_execute_command(thd); : Y% v& F& ?, {# c9 q1 n} 3 D/ m/ U( ^$ A7 U, r, X `- h4 m
$ r# h* Z( n8 F3 w2 Z6 O<2> 到这里它的Parse,Optimizer,Cache都追完了,接下来看sql的CURD类型,继续追。。。( e3 m* V$ R3 x/ S8 m# H
1 V# W7 k0 }! s$ U8 q' T, h
//继续执行0 U- d7 s& Z; S$ ~" A9 ]
int mysql_execute_command(THD *thd) ; R X; c0 F; @0 T$ q2 i{ " [8 S1 r6 N- T# T, E; h A switch (lex->sql_command) / E/ |1 d- F1 P
{4 O1 j9 S, r P/ z' O
case SQLCOM_SELECT: res= execute_sqlcom_select(thd, all_tables); break;. ~. S$ |) B( w- \* p B
9 y) ~+ T/ |. J) g: P //这个 insert 就是我要追的' i& J4 M9 k+ x1 D% v9 y* }
case SQLCOM_INSERT: res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,' ]) U5 G# X/ @4 S; F
lex->update_list, lex->value_list,, w( s) N- e, ? N
lex->duplicates, lex->ignore);# v' w U. s$ O1 B6 c
}) |: w# T0 C* ]! N
}7 L* P, v/ O( X/ `5 X+ _3 y# ^) n
//insert插入操作处理 ; z1 o) a* `- B8 `bool mysql_insert(THD *thd,TABLE_LIST *table_list,List<Item> &fields, List<List_item> &values_list, ' Q* a: w6 Y7 c8 } List<Item> &update_fields, List<Item> &update_values, % a9 B w, k! z+ ~; j5 u' O
enum_duplicates duplic, bool ignore) 6 p( `0 G2 ?* w. t) w{$ B: G, m$ M: ?
while ((values= its++)) 3 i$ G# ~* ~4 Y" v5 V; O {2 f! ?% M2 U" m* T
error= write_record(thd, table, &info, &update);# G7 k+ h- @& d
}0 f# H `7 X$ \0 @/ a. j, H$ {) G+ p
} 1 Y3 A, F, k/ l$ A$ c$ y# d//写入记录: z" X9 O5 U9 e& U% t- Z, k
int write_record(THD *thd, TABLE *table, COPY_INFO *info, COPY_INFO *update), `; T" j A" @7 r
{% X9 H t: q2 `/ b
if (duplicate_handling == DUP_REPLACE || duplicate_handling == DUP_UPDATE) 4 L: b- f: \) Z6 O( y {; W8 C, ~5 ^) p/ p& T
// ha_write_row 重点是这个函数 . {: Q: O) |8 v" u, f1 p' D: A while ((error=table->file->ha_write_row(table->record[0])))' U5 T3 g- H/ r
{ 5 W# X d" }6 k) c ^ ....7 ^. b u0 ~) m; p& W
}3 b1 X; q6 w, O
}9 I! ]/ n1 p" _" g |# w
}9 C2 C" m4 k- C8 e& C7 T! t |
4 T2 |% d. B3 l8 `/ J2 e
' L3 W& m/ f9 H( C9 a% A6 D5 W( e# _/ a# T8 O. r* v
可以看到,调用链还是挺深的,追到 ha_write_row 方法基本上算是追到头了,再往下的话就是 MySql Server 给 Storage Engine提供的接口实现了,不信的话继续看呗。。。; T+ \3 B& g {: Y. j- o
3 s; y# E% o; q. J& {3 ^: @<3> 继续挖 ha_write_row0 i2 c' O. G9 q) Y/ J