By utahta, on 1月 24th, 2010%
mysqld (MySQL 5.1.41) ソースコードざっくり勉強メモ。
関数の呼び出し順番とかを主に。そして適当に。
動作環境は CentOS 5.4。
オプション解析
my.cnf とか。
sql/mysqld.cc main():4301
init_common_variables() が出発点
sql/mysqld.cc init_common_variables():3286
load_defaults()
mysys/default.c load_defaults():383
my_load_defaults()
mysys/default.c my_load_defaults():427
my_search_option_files() 通過後、argc, argv を読み込んで、値を整形。
mysys/default.c my_search_option_files():153
my.cnf を fgets() してる
sql/mysqld.cc init_common_variables():3289
get_options()
sql/mysqld.cc get_options():8495
handle_options()
mysys/my_getopt.c handle_options():112
オプション構造体や変数に設定値を格納してる
ネットワーク初期化
listen socket 作成とか。
sql/mysqld.cc main():4403
network_init()
sql/mysqld.cc network_init():1619
socket(), bind(), listen() してる。
接続受付
accept とか。
sql/mysqld.cc main():4517
handle_connections_sockets() を呼んでる。
sql/mysqld.cc handle_connections_sockets():4993
select(), accept() してる。
成功したら create_new_thread() を呼んでる。
受信
パケット受信とか。
sql/mysqld.cc create_new_thread():4918
accept 後など、コネクションに対して新しくスレッドを作成するとき呼ばれると思われる関数。
いろいろ設定後、scheduler_functions::add_connection() を呼んでる。
add_connection() は関数ポインタで create_thread_to_handle_connection() がセットされてる。
sql/mysqld.cc create_thread_to_handle_connection():4853
実際にスレッドを作成してる関数。
特に何事もなければ handle_one_connection() をコールバック関数にしてスレッドを作成してる。
sql/sql_connect.cc handle_one_connection():1074
1コネクションに対するスレッドのハンドラ。
スレッド初期化とかパケット受信とかコマンド発行とかしてる。
1080行目で、scheduler_functions::init_new_connection_thread() を呼んでる。
init_new_connection_thread() は関数ポインタで init_new_connection_handler_thread() がセットされてる。
sql/sql_connect.cc init_new_connection_handler_thread:611
1コネクションに対するスレッドの初期化処理が行われる関数と思われる。
618行目で、my_thread_init() を呼んでる。
By utahta, on 11月 26th, 2009%
MySQL 5.1.41 を GDB 使って解析するメモ。取っかかり編。
環境 : CentOS 5.2
ダウンロード
MySQL 5.1.41 のソースをダウンロードする。
インストール
/usr/local/mysql-5.1.41 へインストールする。
$ tar zxvf mysql-5.1.41.tar.gz
$ cd mysql-5.1.41
$ ./configure --prefix=/usr/local/mysql-5.1.41 --with-unix-socket-path=/usr/local/mysql-5.1.41/tmp/mysql.sock --with-charset=utf8 --with-extra-charsets=all --enable-thread-safe-client --with-plugins=innodb_plugin --with-readline --with-debug
$ make
$ make install
$ cd /usr/local/mysql-5.1.41
$ sudo cp share/mysql/my-medium.cnf /etc/my.cnf
GDB
最初に mysqld を gdb 経由で実行する。
$ gdb ./libexec/mysqld
GNU gdb Red Hat Linux (6.5-25.el5rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
立ち上がったら続けて、main に break ポイントを打ってみる。
(gdb) b main
Breakpoint 1 at 0x81b697a: file mysqld.cc, line 4261.
main は sql/mysqld.cc の 4261 行目にある。
とりあえず実行。
(gdb) r
Starting program: /usr/local/mysql-5.1.41/libexec/mysqld
[Thread debugging using libthread_db enabled]
[New Thread -1209051440 (LWP 10008)]
[Switching to Thread -1209051440 (LWP 10008)]
Breakpoint 1, main (argc=1, argv=0xbf96e304) at mysqld.cc:4261
4261 MY_INIT(argv[0]); // init my_sys library & pthreads
MY_INIT(argv[0]) のとこで止まった。(ちなみに MY_INIT() はマクロで、include/my_sys.h の 40 行目にある)
いま止まってるとこ付近のソースを表示する。
(gdb) l
4256 int win_main(int argc, char **argv)
4257 #else
4258 int main(int argc, char **argv)
4259 #endif
4260 {
4261 MY_INIT(argv[0]); // init my_sys library & pthreads
4262 /* nothing should come before this line ^^^ */
4263
4264 /* Set signal used to kill MySQL */
4265 #if defined(SIGUSR2)
main の直後 に MY_INIT() が呼ばれており、#else 〜 #endif で windows とそれ以外で main を切り分けてるのがなんとなく分かる。
ステップ実行して MY_INIT() に入る。
(gdb) s
my_init () at my_init.c:73
73 if (my_init_done)
Current language: auto; currently c
my_init() へ辿り着いた。my_init() は MY_INIT() の中で呼ばれており、mysys/my_init.c の 73 行目にある。
my_init_done の値を確認する。
(gdb) p my_init_done
$1 = 0 '\0'
0 が入ってる。my_init() 実行前だから当然っちゃ当然。(my_init_done は my_bool型(typedef char))
やっぱりステップ実行は便利ですね。
参考
GDB マニュアル
By utahta, on 6月 14th, 2009%
すぐ忘れる脳の為に、よくやる MySQL 設定メモ。
configure オプション
./configure \
--prefix=/usr/local/mysql-5.1.35 \
--with-unix-socket-path=/usr/local/mysql-5.1.35/tmp/mysql.sock \
--with-charset=utf8 \
--with-extra-charsets=all \
--enable-thread-safe-client \
--with-plugins=ndbcluster, innobase, partition \
--with-readline \
--with-debug=full
with-readline = 日本語入力など。
with-debug = デバッグしたいときなど。
my.cnf
max_connections=300
connect_timeout=86400
interactive_timeout=86400
debug=d:t:o,/usr/local/mysql-5.1.35/tmp/mysqld.trace
max_connections = 接続受付数
connect_timeout = 接続タイムアウトまでの秒数
interactive_timeout = 接続先から何も要求がない状態タイムアウトまでの秒数
debug = デバッグトレースなど。