思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)

在前面三篇,bingxialex聊了关于innodbhashlist、以及动态数组的实现方法,这三个结构比较常用。讲完前9篇内容,本篇会描述在windows环境下debug mysql的方法,强烈建议通过debug的方式进行学习。在本篇里,bingxialex会聊到windows下常用的调试mysql代码的方法,仅供参考。

1)在windowslinux下调试的异同?

Bingxi:“alex,咱们看myslq代码的方法,是通过windows看好呢,还是linux/unix下看呢,两者之间最大的差异是什么?”

Alex:“在mysql 5.1的高版本开始,windows环境与linux环境使用同一套代码。我电脑里面正好有两个版本的代码,我们看下mysql-6.0.4-alpha目录下的INSTALL-WIN-SOURCE文件,其中有这么一段:

To build MySQL on Windows from source, you must satisfy the

following system, compiler, and resource requirements:

* Windows 2000, Windows XP, or newer version. Windows Vista is

not supported until Microsoft certifies Visual Studio 2005 on

Vista.

* CMake, which can be downloaded from http://www.cmake.org.

After installing, modify your path to include the cmake

binary.

* Microsoft Visual C++ 2005 Express Edition, Visual Studio .Net

2003 (7.1), or Visual Studio 2005 (8.0) compiler system.

* If you are using Visual C++ 2005 Express Edition, you must

also install an appropriate Platform SDK. More information and

links to downloads for various Windows platforms is available

from http://msdn.microsoft.com/platformsdk/.

* If you are compiling from a BitKeeper tree or making changes

to the parser, you need bison for Windows, which can be

downloaded from

http://gnuwin32.sourceforge.net/packages/bison.htm.Download

the package labeled "Complete package, excluding sources".

After installing the package, modify your path to include the

bison binary and ensure that this binary is accessible from

Visual Studio.

* Cygwin might be necessary if you want to run the test script

or package the compiled binaries and support files into a Zip

archive. (Cygwin is needed only to test or package the

distribution, not to build it.) Cygwin is available from

http://cygwin.com.

* 3GB to 5GB of disk space.

可以通过这样的方式来生成一份代码,然后用vs2005或者更高版本来调试。

Bingxi:“alex,你电脑里面的另外一个软件包是mysql-5.1.7的吧。”

Alex:“嗯,这个版本是mysql5.1.7代码刚出来的时候进行下载的。这个版本的代码直接解压缩之后,可以直接用vs2003进行编译调试。对innodb而言,用这个版本的就可以了,innodb的变化不大,如果需要理解查询引擎,则需要使用更新的版本进行学习。”

Bingxi:“mysql-5.1.7-beta-win-src.zip,这个软件包的内容,我们学了之后,会不会和linux下不一样,有人会有这样的疑问,毕竟在很多公司里面,mysql是运行在linux/unix环境的。我们知道windowslinux/unix的差异还是存在的,尤其是底层的系统函数。”

Alex:“嗯,这个是很多人的疑问。其实mysql进行了代码的封装,比如在5.1.7windows版本的代码中,也是可以看到系统函数的封装。比如event semaphore。看下对应的代码:

/*************************************************************

Creates an event semaphore, i.e., a semaphore which may just have two

states: signaled and nonsignaled. The created event is manual reset: it

must be reset explicitly by calling sync_os_reset_event. */

os_event_t

os_event_create(

/*============*/

/* out: the event handle */

const char* name) /* in: the name of the event, if NULL

the event is created without a name */

{

#ifdef __WIN__

os_event_t event;

event = ut_malloc(sizeof(struct os_event_struct));

event->handle = CreateEvent(NULL,/* No security attributes */

TRUE, /* Manual reset */

FALSE, /* Initial state nonsignaled */

(LPCTSTR) name);

if (!event->handle) {

fprintf(stderr,

"InnoDB: Could not create a Windows event semaphore; Windows error %lu\n",

(ulong) GetLastError());

}

#else /* Unix */

os_event_t event;

UT_NOT_USED(name);

event = ut_malloc(sizeof(struct os_event_struct));

os_fast_mutex_init(&(event->os_mutex));

#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)

ut_a(0 == pthread_cond_init(&(event->cond_var),

pthread_condattr_default));

#else

ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));

#endif

event->is_set = FALSE;

event->signal_count = 0;

#endif /* __WIN__ */

/* Put to the list of events */

os_mutex_enter(os_sync_mutex);

UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);

os_event_count++;

os_mutex_exit(os_sync_mutex);

return(event);

}

os_event_create函数体,屏蔽了系统的差异性。开发人员在开发时,需要创建event,只需要os_event_create就行了。

Bingxi:“alex,那么按照这个思路,是不是可以获得两个信息:1)如果需要debug系统封装函数,还是建议在linux/unix下也调试下,2)对我们查看非系统函数,在windowslinux/unix下调试,两者都是可以的。”

Alex:“嗯,用哪种调试方法都是可以的。用哪个版本的也是可以的,本系列以描述innodb存储为主,因此使用5.1.7就可以了。”

2)搭建windows环境下的mysql5.1.7的调试环境

Bingxi:“好吧,那我们就开始搭建环境吧。”

Alex:“ok,我们先将代码找一个目录进行解压缩,本文中的解压缩位置为d:\。使用vs2003打开D:\bin-mysql-5.1.7-beta\mysql.sln项目文件。

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第1张图片Bingxi,打开之后会有46project,我们要编译其中哪些工具呢?

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第2张图片

Bingxi:“ok,至少要包含下面三个内容:1)服务端程序,2)客户端程序,3mysqladmin工具(用于退出调试时使用,直接使用中断调试太暴力了)。顺着这个思路,我们一步步来编译。

首先编译服务端程序,也就是编译mysqld项目。这里有三个建议,1)因为本系列主要调试mysqld的代码,因此需要将mysqld设置为启动项目,2)设置启动方式为console方法,这样可以在console窗口中看到打印信息,3)将D:\bin-mysql-5.1.7-beta下的data文件夹进行压缩保存,这样,我们需要恢复到原始的数据,直接用保存的data进行覆盖就可以了。

设置为启动项目:

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第3张图片

设置为console启动方式:

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第4张图片

根据个人习惯,决定是否将data进行压缩保存。

接着,我们编译mysqld项目、mysql项目、mysqladmin项目。编译产生的工具在D:\mysql-5.1.7-beta\client_debug目录。

设置断点,比如查询的总入口是handle_select函数(在sql_select.cpp文件中)。使用“进入单步执行新实例”进行调试。如图:

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第5张图片

执行时,停止在main函数开始处(可以一步步看看mysql是如何启动的),我们按F5,程序会直接执行,如果断点被执行,那么就会停在断点处,因为我们此处设置的是查询函数,所以没有被执行。因此,我们需要通过客户端执行一条语句,来触发断点对应的代码被执行。

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第6张图片

执行show databases命令之后,我们可以看到断点生效了。

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第7张图片

这样我们通过F10\F11\F5\shift+F11等常用的快捷键进行调试了。如果需要退出调试状态,则使用mysqladmin,如图(图中打印的一行错误信息不用理它,是系统的一个bug):

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第8张图片

3)调试的技巧

Alex:“bingxi,这个我理解了,有没有一些常用的技巧。Alex常用的是通过快速监控,见下面的两图。

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第9张图片

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第10张图片

这样,我们可以看到变量的值。但是,遇到想测试函数,或者看宏的值就有点麻烦了。Bingxi,你给我讲讲。

Bingxi:“最常用的方法是直接分析算法,如果有些确实不太明白,可以通过自己写测试函数的方法进行调试。如果我想知道某一页属于哪个簇描述符,可以在fsp0fsp.c的文件尾加上我们自己的测试函数,同时设置断点:

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第11张图片

接着在该文件的文件头(添加内容为红色选中处),声明定义:

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第12张图片

接着找一个函数,进行调用函数test_bingxi,这里我们选择fsp_get_space_header函数,因为这个函数在同一个文件,并且启动的时候会被执行。添加调用,添加内容为红色选中处。

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第13张图片

然后,我们启动调试,按F5进入断点。通过j值就可以知道UNIV_PAGE_SIZE的值,如果是多个宏计算后的值,也是一样的方法。通过i1值就可以知道xdes_calc_descriptor_page(0)的返回值。

思考mysql内核之初级系列10---mysql内核调试方法(摘自老杨)_第14张图片

类似这样的方法,我们可以通过添加测试代码,将疑问的地方进行测试。今天调试的就说到这儿吧。

Alex:“ok,说完调试,开始正式进入innodb存储了。咱们也是初学者,需要多debug来解惑。今天不说晚安了,马上6点了,早安。”

Bingxi:“早安。”

你可能感兴趣的:(mysql,windows,linux,unix,OS)