MySQL vs2010编译调试和命令扩展

上一篇 / 下一篇  2012-01-10 09:41:02

 最近Mysql数据库应用越来越广泛,所以,决定学学Mysql,把Mysql的源码下载了,希望能有利于对它的学习,看到淘宝测试人员能扩展mysql命令,自己决定也试一下 
这里记录一下windows平台下编译Mysql的过程,以及命令扩展的过程,与大家分享一下。
 


平台环境 
操作系统:windows7 企业版 
编译环境:VS2010旗舰版 
辅助工具:CMake2.8【windows版本】 
Mysql版本:mysql-5.1.60 
Bison版本:bison-2.4.1 


编译过程: 


1. 下载mysql-5.1.60源码,解压到D:\mysql

2. 使用CMake2.8生成vs2010工程(源码自带的脚本只支持到vs2008)

 

3. 打开D:\mysql\sql\sql_local.cc文件,另存为UTF-8格式(带BOM头),覆盖原文件

4. 打开D:\mysql\sql\mysqld.cc,  4352行:DBUG_ASSERT(0);改为DBUG_ASSERT(1);或者注释掉整个IF语句

5. 将D:\mysql\win\data目录拷贝到D:\mysql\sql下

6. 用vs2010打开D:\mysql\MySql.sln 编译全部


调试过程
1. 进入D:\mysql\sql\Debug\,  输入命令 mysqld --debug --standalone, 这时3306端口开启侦听(用netstat -anp tcp)

2. 在VS2010中附加进程调试中选择“mysqld.exe”

3. 在D:\mysql\sql\sql_show.cc 的make_db_list方法中设一个断点

4. 进入 D:\mysql\client\Debug, 输入命令 mysql -u root -p ,进入mysql命令行客户端

5. 在mysql命令行客户端,输入命令show databases;就会跳到vs2010中设定的断点处

6. 进入D:\mysql\client\Debug, 输入命令 mysqladmin shutdown -u root -p   关闭mysql服务

现在有了源码,而且可以方便的在vs2010设定断点跟踪,可以好好学习了




命令扩展过程
主要参考:《Expert MySQL》第8章第3节

现有SQL不能满足需要,自定义函数也解决不了,可以考虑新增SQL命令。

通过修改源代码的方法,扩展MySQL功能,比较复杂和繁琐。

1. 修改解析器(D:\mysql\sql\sql_yacc.yy)

2. 添加命令路由(D:\mysql\sql\sql_parse.cc)

3. 添加命令实现函数代码(D:\mysql\sql\sql_show.cc)

具体步骤:
1.修改解析器
1.1 在lex.h 增加命令符号,
在符号表数组static SYMBOL symbols[] = {}中增加,自定义符号DISK_USAGE
{ "DISK",  SYM(DISK_SYM)}, 
{ "DISK_USAGE",  SYM(DISK_USAGE_SYM)}, /*guoping.gugp add*/ 
{ "DISTINCT",  SYM(DISTINCT)},

1.2 在sql_lex.h 增加助记符,命令路由时用
在命令助记符枚举表enum enum_sql_command{}中,增加助记符SQLCOM_SHOW_DISK_USAGE
SQLCOM_SHOW_COLUMN_TYPES, SQLCOM_SHOW_STORAGE_ENGINES, SQLCOM_SHOW_PRIVILEGES, 
SQLCOM_SHOW_DISK_USAGE, /*guoping.gugp add*/ 
SQLCOM_HELP, SQLCOM_CREATE_USER, SQLCOM_DROP_USER, SQLCOM_RENAME_USER,

1.3 把新增符号添加到解析器(把1.1和1.2的符号关联起来)
在sql_yacc.yy中增加符号
%token  DISK_SYM 
%token  DISK_USAGE_SYM     /* guoping.gugp add */ 
%token  DISTINCT                      /* SQL-2003-R */
在sql_yacc.yy中的show:增加符号处理, 注意竖线不能缺
/* guoping.gugp add */ 
 SHOW DISK_USAGE_SYM 
 { 
  LEX *lex=Lex; 
  lex->sql_command=SQLCOM_SHOW_DISK_USAGE; 
 }| 

          SHOW
         {

2. 添加命令路由
2.1 在mysql_priv.h增加新命令执行函数的申明
bool mysqld_show_authors(THD *thd); 
bool show_disk_usage_command(THD *thd); /*guoping.gugp add*/ 
bool mysqld_show_contributors(THD *thd);

2.2 在sql_parse.cc的命令路由中增加新命令路由(1.3中解析器关联到新命令的执行函数show_disk_usage_command)
case SQLCOM_SHOW_AUTHORS: 
    res= mysqld_show_authors(thd); 
    break; 
case SQLCOM_SHOW_DISK_USAGE:    /*guoping.gugp add*/ 
   res= show_disk_usage_command(thd); 
   break; 

case SQLCOM_SHOW_CONTRIBUTORS: 
    res= mysqld_show_contributors(thd); 
    break;

3. 添加命令实现函数代码
在sql_show.cc中增加命令实现函数
/* guoping.gugp add begin */ 
bool show_disk_usage_command(THD *thd) 

 List<Item> field_list; 
 Protocol *protocol= thd->protocol; 
 DBUG_ENTER("show_disk_usage");
 /* send fields */ 
 field_list.push_back(new Item_empty_string("CBU_Database",50)); 
 field_list.push_back(new Item_empty_string("CBU_Size (kb)",30));
 if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 
  DBUG_RETURN(TRUE);
 /* send test data */ 
 protocol->prepare_for_resend(); 
 protocol->store("B2B_CBU_ROW", system_charset_info); 
 protocol->store("1024", system_charset_info); 
 if(protocol->write()) 
  DBUG_RETURN(TRUE);
 my_eof(thd);
 DBUG_RETURN(FALSE); 
}/* guoping.gugp add end */

4. 重新编译 
4.1 在windows编译,会有符号未定义错误,需在sql_yacc.cc 中增加定义 
/* Substitute the variable and function names.  */ 
#define yyparse      MYSQLparse 
#define yylex          MYSQLlex 
#define yyerror        MYSQLerror 
#define yylval          MYSQLlval 
#define yychar         MYSQLchar 
#define yydebug       MYSQLdebug 
#define yynerrs         MYSQLnerrs 


4.2 使用bison,重新生成解析器代码 
bison -y -d sql_yacc.yy 
会生成两个新文件y.tab.c 和y.tab.h,分别替换掉之前原有的sql_yacc.cc和sql_yacc.h 


4.3 大功告成,重新编译mysql 
启动mysql服务器  D:\mysql\sql\Debug\mysqld --debug --standalone 
启动mysql客户端  D:\mysql\client\Debug\mysql -u root 
执行新命令 show DISK_USAGE 

 

TAG: 命令扩展 性能 MySQL mysql vs2010 Windows windows 编译 调试

 

评分:0

我来说两句

Open Toolbar