最近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