tmp_table in THDオブジェクト
本題に戻る前に、友人から依頼されて1件、ソース解析ちゅう。
TEMPORARY TABLEに関する不具合の疑いについての調査。
とりあえずTHDを漁る。
(gdb) p sizeof(THD) $2 = 5168
でかいよー。dddのData Windowに収まりきらん。
THD->tmp_tableってのがあるのだが、sql_class.hの1300行目付近
uint tmp_table;
とりあえずTHDにあるのはuintらしい。
(gdb) p thd->tmp_table $4 = 0
初期値が0ってのは妥当なところ。
[test] > create temporary table foo (bar int); Query OK, 0 rows affected (0.00 sec) [test] > select * from foo;
temporary tableを作ってから再度アクセス。
(gdb) p thd->tmp_table $5 = 1
ふーむ。
[test] > create temporary table foo2 (bar2 int); Query OK, 0 rows affected (0.01 sec) [test] > select * from foo;
もう1個作って見ると、
(gdb) p thd->tmp_table $8 = 2
単にカウントアップされるだけっぽ。mysql_selectなんかにbを仕込んだおいらが悪かった模様。
次はがっつりmysql_execute_commandあたりからいくどー。 mysql_create_tableってのがあるじゃん。
はいはい、仕切り直しー。
初めて読む関数だからbtをおいておきまふ。
#1 0x0825eea8 in mysql_create_table (thd=0x8abdc50, db=0x8aa9970 "test", table_name=0x8adcf70 "foo3", create_info=0x8abe1d8, fields=@0x8abe0fc, keys=@0x8abe0f0, internal_tmp_table=false, select_field_count=0) at sql_table.cc:1569 #2 0x081a2a10 in mysql_execute_command (thd=0x8abdc50) at sql_parse.cc:2896 #3 0x081a9e80 in mysql_parse (thd=0x8abdc50, inBuf=0x8adcf10 "create temporary table foo3 (bar3 int)", length=38) at sql_parse.cc:5695 #4 0x081a00a6 in dispatch_command (command=COM_QUERY, thd=0x8abdc50, packet=0x8ad4ee1 "create temporary table foo3 (bar3 int)", packet_length=39) at sql_parse.cc:1736 #5 0x0819f8f0 in do_command (thd=0x8abdc50) at sql_parse.cc:1522 #6 0x0819ed25 in handle_one_connection (arg=0x8abdc50) at sql_parse.cc:1165 #7 0x4002ab63 in start_thread () from /lib/tls/libpthread.so.0 #8 0x4023418a in clone () from /lib/tls/libc.so.6
"create temporary table..."のときは、mysql_create_table関数の処理中に以下のifブロックに入るっ! sql_table.cc line1691.
if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { /* Open table and put in temporary table list */ if (!(open_temporary_table(thd, path, db, table_name, 1))) { (void) rm_temporary_table(create_info->db_type, path); goto end; } thd->tmp_table_used= 1; }
THDへのアクセスきたよー。
TABLE *open_temporary_table(THD *thd, const char *path, const char *db, const char *table_name, bool link_in_list) { TABLE *tmp_table; ... if (link_in_list) { tmp_table->next=thd->temporary_tables; thd->temporary_tables=tmp_table; if (thd->slave_thread) slave_open_temp_tables++; } DBUG_RETURN(tmp_table); }
link_in_listは値1がハードコーディングで渡されるので、ifブロックに必ず入るっ! でもってreplication slave以外は入れ子のifブロックにははいらな−い。
要はthd->temporary_tablesを見れということですな。でもって、各tmp_tableはLinkedList構造になっていると。
THDの基底クラスに*temporary_tablesがあったよー(><
class Open_tables_state { public: /* open_tables - list of regular tables in use by this thread temporary_tables - list of temp tables in use by this thread handler_tables - list of tables that were opened with HANDLER OPEN and are still in use by this thread */ TABLE *open_tables, *temporary_tables, *handler_tables, *derived_tables; ... }