지난 글 https://sarc.io/index.php/mariadb/1382-mysqlbinlog-no-space-left-on-device

에서 mysqlbinlog 커맨드를 통하여 binary log file 을 변환 시킬 때 루트볼륨의 tmp영역을 사용하는 이슈를 소개드렸습니다.

이번 글에서는 mysqlbinlog 를 수행하는 프로세스를 디버깅하여 왜 해당영역을 사용하게 되는지에 대해 살펴보겠습니다.

작업은 gdb 라는 디버깅 툴을 사용하는데 따로 gdb 설치방법이나 사용방법에 대해서는 다루지 않고 자세한 내용은 구글링을 통해 확인해보시기 바랍니다.

 

-.1 gdb tool을 통해 mysqlbinlog process attach

 

[root@ TEST]# gdb /engn001/masvc01/TEST/bin/mysqlbinlog

GNU gdb (GDB) Amazon Linux (7.6.1-64.33.amzn1)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-amazon-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /engn001/masvc01/TEST/bin/mysqlbinlog...done.


(gdb) b main
Breakpoint 1 at 0x1f710: file /engn001/masvc01/TEST/client/mysqlbinlog.cc, line 2657.

(gdb) run /data001/masvc01/mysql-bin.000069
Starting program: /engn001/masvc01/TEST/bin/mysqlbinlog /data001/masvc01/mysql-bin.000069
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
 
=> gdb로 디버깅하려는 프로그램을 실행한 뒤 해당 프로그램의 main 함수를 break point 로 설정 후 run

 

-2. mysqlbinlog 프로세스 디버깅 

 
(gdb) next
2661      MY_INIT(argv[0]);
(gdb) next
2657    {
(gdb) next
2661      MY_INIT(argv[0]);
(gdb) next
2669      load_defaults_or_exit("my", load_groups, &argc, &argv);
(gdb) next
.
.
.(gdb) next
2740      tmpdir.list= 0;
(gdb) next
2741      if (!dirname_for_local_load)
(gdb) next
2743        if (init_tmpdir(&tmpdir, 0))
 
=> next 로 처음 동작부터 흐름을 따라가다 보면 init_tmpdir 함수 부분을 찾을 수 있음
 
(gdb) step
init_tmpdir (tmpdir=0x7fffffffe260, pathlist=0x0) at /engn001/masvc01/TEST/mysys/mf_tempdir.c:35
35        if (!pathlist || !pathlist[0])
(gdb) step
38          pathlist=getenv("TMPDIR");  /* Use this if possible */
(gdb) step
45          if (!pathlist || !pathlist[0])
(gdb) step
38          pathlist=getenv("TMPDIR");  /* Use this if possible */
(gdb) step
45          if (!pathlist || !pathlist[0])
(gdb) step
46            pathlist= DEFAULT_TMPDIR;
.
.(gdb) step
init_tmpdir (tmpdir=0x7fffffffe260, pathlist=0x5555555e3e12 "/tmp") at /engn001/masvc01/TEST/mysys/mf_tempdir.c:52
52          strmake(buff, pathlist, (uint) (end-pathlist));
=> step 커맨드로 init_tmpdir을 자세히 살펴보면
tmpdir의 값을 넘겨주게 되는 pathlist 변수에 처음엔 서버의 TMPDIR 설정값을 가져오려 시도함
해당 값이 설정되어 있지 않으면 DEFAULT_TMPDIR 값을 사용하게 되고  결국 DEFAULT_TMPDIR 인 /tmp을 사용하게 되는 것을 확인할 수 있음

 

-3. TMPDIR 설정 후 디버깅

 
[root@/ ]# export TMPDIR=/data001
(gdb) step
init_tmpdir (tmpdir=0x7fffffffe260, pathlist=0x7fffffffe78b "/data001") at /engn001/masvc01/TEST/mysys/mf_tempdir.c:52
52          strmake(buff, pathlist, (uint) (end-pathlist));
=> TMPDIR를 /data001/로 설정 후 다시 디버깅 해보면 이번엔 tmpdir을 /data001로 사용하는것을 확인할 수 있음