gdb backtrace
PageとかRecordとかの状態変化を観察するために色々logを出させて見たいのだけれども、コードを突っ込む場所としてはどこがいいのかあまり検討がつかない。logが出るタイミングにしても、こちらの意図したときに意図した範囲の内容が出るようにしたい。数日前にやってたha_innobase::openに突っ込むやり方は不細工過ぎる。
というわけでgdbを使っていろいろbacktraceを観察してみる。
InnoDBは関数名からの推測でbreakを突っ込むのが難しいので、ソースファイルと関数の命名規則が比較的シンプルなMyISAMにてまず確認し、Handlerレベルまでの経路をいろいろ見て当て感を良くしてから再度InnoDBに行きたい。
まずMyISAMに対するINSERT文の実行時。
#0 0x0838b786 in mi_write () #1 0x081d0802 in write_record () #2 0x081cfafc in mysql_insert () #3 0x08180170 in mysql_execute_command () #4 0x08186780 in mysql_parse () #5 0x0817c561 in dispatch_command () #6 0x0817c08d in do_command () #7 0x0817b602 in handle_one_connection () #8 0x4002ab63 in start_thread () from /lib/tls/libpthread.so.0 #9 0x4023418a in clone () from /lib/tls/libc.so.6
次が、MyISAMに対するUPDATE文の実行時。
#0 0x0838acc6 in mi_update () #1 0x081d9b29 in mysql_update () #2 0x0817eb65 in mysql_execute_command () #3 0x08186780 in mysql_parse () #4 0x0817c561 in dispatch_command () #5 0x0817c08d in do_command () #6 0x0817b602 in handle_one_connection () #7 0x4002ab63 in start_thread () from /lib/tls/libpthread.so.0 #8 0x4023418a in clone () from /lib/tls/libc.so.6
次が、MyISAMに対するDELETE文の実行時。
#0 0x0838e8e6 in mi_delete () #1 0x081dd036 in mysql_delete () #2 0x0817ee41 in mysql_execute_command () #3 0x08186780 in mysql_parse () #4 0x0817c561 in dispatch_command () #5 0x0817c08d in do_command () #6 0x0817b602 in handle_one_connection () #7 0x4002ab63 in start_thread () from /lib/tls/libpthread.so.0 #8 0x4023418a in clone () from /lib/tls/libc.so.6
固定長なMyISAMテーブルに対するFullScanなSELECT文の実行時。
#0 _mi_read_rnd_static_record () #1 0x083a1fb4 in mi_scan () #2 0x0823d443 in ha_myisam::rnd_next () #3 0x08230ae7 in rr_sequential () #4 0x081d3dc9 in sub_select () #5 0x081d38db in do_select () #6 0x081c4112 in JOIN::exec () #7 0x081c4579 in mysql_select () #8 0x081bf9d2 in handle_select () #9 0x08186ed1 in mysql_execute_command () #10 0x0818f882 in mysql_parse () #11 0x081851fa in dispatch_command () #12 0x08184ac8 in do_command () #13 0x08183c98 in handle_one_connection () #14 0x4002ab63 in start_thread () from /lib/tls/libpthread.so.0 #15 0x4023418a in clone () from /lib/tls/libc.so.6
なんというか、gdb便利すぎ。なんでこのツールをもっと早く使い出していなかったのかと小一時間凹む。数日前にmysql_execute_commandまで目視で呼び出し追跡した時にはそれだけで1時間以上かかってた。まあそれはそれでその過程で大量の付随コードを読むので意味がまったく無いというわけではない、と信じたいが。
ということで同じテーブルをalter tableでInnoDBにしたバージョン
#0 row_search_for_mysql () #1 0x08243941 in ha_innobase::index_read () #2 0x08243e70 in ha_innobase::index_first () #3 0x08244022 in ha_innobase::rnd_next () #4 0x08230ae7 in rr_sequential () #5 0x081d5012 in join_init_read_record () #6 0x081d3da6 in sub_select () #7 0x081d38db in do_select () #8 0x081c4112 in JOIN::exec () #9 0x081c4579 in mysql_select () #10 0x081bf9d2 in handle_select () #11 0x08186ed1 in mysql_execute_command () #12 0x0818f882 in mysql_parse () #13 0x081851fa in dispatch_command () #14 0x08184ac8 in do_command () #15 0x08183c98 in handle_one_connection () #16 0x4002ab63 in start_thread () from /lib/tls/libpthread.so.0 #17 0x4023418a in clone () from /lib/tls/libc.so.6
でもって、以下はrow_search_for_mysqlの関数コメント。
Searches for rows in the database. This is used in the interface to MySQL. This function opens a cursor, and also implements fetch next and fetch prev. NOTE that if we do a search with a full key value from a unique index (ROW_SEL_EXACT), then we will not store the cursor position and fetch next or fetch prev must not be tried to the cursor!
ということらしいですよ。