MySql轻松入门系列——第二站 使用visual studio 对mysql进行源码级调试
一:背景
1. 讲故事
上一篇说了mysql的架构图,很多同学反馈说不过瘾,毕竟还是听我讲故事,那这篇就来说一说怎么利用visual studio 对 mysql进行源码级调试,毕竟源码面前,不谈隐私,圣人面前,皆为蝼蚁。
二:工具合集
mysql是C++写的,要想在windows上编译,还需要下载几个必备小工具。
- mysql-5.7.12.zip
- cmake-3.17.3-win64-x64.msi
- boost_1_59_0.tar.gz
- bison-2.4.1-setup.exe
- windows 10 x64
这里简单说一下:可以用cmake
将源码生成 *.sln
可打开的解决方案,比如可以通过它最终生成 MySQL.sln
。boost
是C++中非常强大的基础库, bison
一个流行的语法分析器程序,用于给mysql提供语法分析,最后就是下载正确的mysql版本 5.7.12
。
三. 详细安装
我会写的比较细,毕竟我也花了一下午时间,寒酸(┬_┬)
1. cmake-3.17.3-win64-x64.msi 和 bison-2.4.1-setup.exe
cmake 和 bison 安装起来比较方便,一键安装就可以了,不过这里有一个大坑注意了,在安装Bison
的时候,千万不要使用默认路径,因为默认路径有空格,会导致你后面vs编译的时候卡住,又不显示什么原因,可气!!! 所以我换成自定义的: C:\2\GnuWin32
。
最后确保 cmake
和 bison
的bin文件都在 环境变量中即可。
2. mysql-5.7.12.zip
这里我用 C:\2
作为根文件夹,所有的小工具都在这里,如图:
接下来将 mysql-5.7.12.zip
解压一下,然后进入解压后的文件夹,新建一个boost文件夹,将boost_1_59_0.tar.gz
放入其中,然后再新建一个 brelease
文件夹可用于存放最终生成的MySql.sln
。。
3. cmake编译
都准备好了之后,可以开始cmake编译了。
PS C:\2\mysql-5.7.12\brelease> cmake .. -DDOWNLOAD_BOOST=1 -DWITH_BOOST="C:\2\mysql-5.7.12\boost\boost_1_59_0.tar.gz"
-- Building for: Visual Studio 16 2019
CMake Deprecation Warning at CMakeLists.txt:26 (CMAKE_POLICY):
The OLD behavior for policy CMP0018 will be removed from a future version
of CMake.
-- Cannot find wix 3, installer project will not be generated
-- COMPILE_DEFINITIONS: _WIN32_WINNT=0x0601;WIN32_LEAN_AND_MEAN;NOGDI;NOMINMAX;HAVE_CONFIG_H
-- CMAKE_C_FLAGS: /DWIN32 /D_WINDOWS /W3 /MP /wd4800 /wd4805 /wd4996
-- CMAKE_CXX_FLAGS: /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MP /wd4800 /wd4805 /wd4996 /we4099
-- CMAKE_C_FLAGS_DEBUG: /MTd /Z7 /Ob1 /Od /RTC1 /EHsc -DENABLED_DEBUG_SYNC -DSAFE_MUTEX
-- CMAKE_CXX_FLAGS_DEBUG: /MTd /Z7 /Ob1 /Od /RTC1 /EHsc -DENABLED_DEBUG_SYNC -DSAFE_MUTEX
-- CMAKE_C_FLAGS_RELWITHDEBINFO: /MT /Z7 /O2 /Ob1 /DNDEBUG /EHsc -DDBUG_OFF
-- CMAKE_CXX_FLAGS_RELWITHDEBINFO: /MT /Z7 /O2 /Ob1 /DNDEBUG /EHsc -DDBUG_OFF
-- Configuring done
-- Generating done
-- Build files have been written to: C:/2/mysql-5.7.12/brelease
当看到最后一句 Build files have been written to: C:/2/mysql-5.7.12/brelease
,恭喜你,MySQL.sln
生成好了。
4. 打开 MySQL.sln 编译项目
我的电脑安装的是visual studio 2019
,接下来打开MySql.Sln
整体编译,需要等个十几分钟,看到下面的输出就算安装成功。
三: 启动mysql并调试insert
1. mysql的初始化
这里要做两件事情,第一件事是将mysql的调试模式打开,第二件事就是附加 --initialize
启动参数。
<1> mysql 调试模式打开
修改C:\2\mysql-5.7.12\sql\mysqld.cc
中的 test_lc_time_sz
方法中的 DBUG_ASSERT(0);
改成 DBUG_ASSERT(1);
如下图:
<2> vs的command增加启动参数
上一篇大家都知道了,mysqld项目是mysql的启动项目,main函数也在其中,在F5调试之前增加初始化参数 --console --initialize
,如下图:
2. 继续入坑出坑
启动之后,有103个报错,气人呀。。。看错误信息应该是编码问题,如下图:
修改起来也很简单,将 C:\2\mysql-5.7.12\sqlsql_locale.cc
用 [utf-8 + BOM] 格式保存一下,然后对mysqld
项目Rebuild再Ctrl+F5
直接运行,终于谢天谢地,从输出可以看到,搞定啦。。。太不容易啦。
从上图中可以看到,默认密码是:zJDE>IC5o+ya
,先记录下这个密码,然后再把CommandLine Arguments 中的--initialize去掉再重启Console。
可以看到,3306端口已开启,然后用刚才的 zJDE>IC5o+ya
连接即可,这里我使用navicat。
连接上去后会提示修改默认密码,设置我就设置为: 123456
,嘿嘿,一切搞定~~~
3. 继续追踪 write_row
上一篇我们追踪到了 write_row
就断掉了,我当时说它是一个虚方法,由底层具体的存储引擎去调用,代码如下:
int handler::ha_write_row(uchar *buf)
{
MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_WRITE_ROW, MAX_KEY, 0,{ error= write_row(buf); })
}
//这是一个虚方法
virtual int write_row(uchar *buf __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
到底这话虚不虚,这次我亲自调试一下给大家看看,证据先行哈。。。为了方便,我生成一条创表sql。
drop database if exists `datamip`;
create database `datamip`;
drop table if exists `datamip`.`customer`;
create table `datamip`.`customer` (
`customerID` int NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`customerName` varchar(50) COMMENT '用户姓名',
`email` varchar(50) COMMENT '邮箱地址',
`desc` varchar(50) COMMENT '描述',
primary key (`customerID`)
) ENGINE=InnoDB charset=utf8 collate=utf8_bin;
接下来,大家看仔细了,在源码 int handler::ha_write_row(uchar *buf)
方法处下一个断点,然后F5调试应用程序。
接下来可以执行insert操作,这地方会命中断点的。
insert into `datamip`.`customer`(customerName,email,`desc`) values('mary','123456789@qq.com','vip');
可以看到,断点命中了,然后进行单步调试,最终你会看到代码会进入到 C:\2\mysql-5.7.12\storage\innobase\handler\ha_innodb.cc
中的 int ha_innobase::write_row
方法,如下图:
然后找几个局部变量和调用堆栈看看。。。
四: 总结
这就是我花了一下午的时间总结出的进坑出坑指南,希望能帮助大家节省时间,还是那句话,源码面前,不谈隐私,若还能进行调试,那一切皆为蝼蚁!
如您有更多问题与我互动,扫描下方进来吧~

MySql轻松入门系列——第二站 使用visual studio 对mysql进行源码级调试的更多相关文章
- MySql轻松入门系列————第一站 从源码角度轻松认识mysql整体框架图
一:背景 1. 讲故事 最近看各大技术社区,不管是知乎,掘金,博客园,csdn基本上看不到有小伙伴分享sqlserver类的文章,看样子这些年sqlserver没落了,已经后继无人了,再写sqlser ...
- Visual Studio Code - 在 JS 源码(TS、压缩前代码)上使用断点
步骤: 在构建工具(webpack.gulp 等)的配置中开启生成 source map 将 VSCode 配置中的debug.allowBreakpointsEverywhere设置为true(重要 ...
- MySQL安装总是失败,提示缺少Visual Studio 2013 Redistributable
MySQL安装总是失败,提示缺少Visual Studio 2013 Redistributable,但是很疑惑,我明明已经安装了呀,原来问题出在版本上,以下提供了一个可以匹配新版本mysql的版本: ...
- java io系列12之 BufferedInputStream(缓冲输入流)的认知、源码和示例
本章内容包括3个部分:BufferedInputStream介绍,BufferedInputStream源码,以及BufferedInputStream使用示例. 转载请注明出处:http://www ...
- java io系列15之 DataOutputStream(数据输出流)的认知、源码和示例
本章介绍DataOutputStream.我们先对DataOutputStream有个大致认识,然后再深入学习它的源码,最后通过示例加深对它的了解. 转载请注明出处:http://www.cnblog ...
- Spring Boot 2.0系列文章(五):Spring Boot 2.0 项目源码结构预览
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/04/15/springboot2_code/ 项目结构 结构分析: Spring-boot-pr ...
- java io系列13之 BufferedOutputStream(缓冲输出流)的认知、源码和示例
本章内容包括3个部分:BufferedOutputStream介绍,BufferedOutputStream源码,以及BufferedOutputStream使用示例. 转载请注明出处:http:// ...
- HTML与CSS入门经典(第9版)试读 附随书源码 pdf扫描版
HTML与CSS入门经典(第9版)是经典畅销图书<HTML与CSS入门经典>的最新版本,与过去的版本相同,本书采用直观.循序渐进的方法,为读者讲解使用HTML5与CSS3设计.创建并维护世 ...
- 《Visual C++ 2010入门教程》系列一:关于Visual Studio、VC和C++的那些事
原文:http://www.cnblogs.com/Mrt-02/archive/2011/07/24/2115606.html 作者:董波 日期:2010.6.15 写在前面 在我还在上学的时候,我 ...
随机推荐
- 5.2 Go 包与函数
5.2 Go 包与函数 在多个包中相互调用函数,需要用到Go包的知识. 代码组织如下: 思路: 1.定义功能函数calc放入到utils.go,将utils.go放在utils文件夹/包中,当其他文件 ...
- Python操作MongoDB代码示例
import pymongo #pip install pymongo安装python操作mongodb的模块 myclient=pymongo.MongoClient(host='127.0.0.1 ...
- SSL F5
应用交付领域经常提到SSL加速,但SSL加速到底是什么意思?SSL加速和F5指什么意思呢?在网上查询和整理了一些关于SSL加速和F5的相关解释,仅供参考:SSL加速:加密套接层协议(简称SSL)是网络 ...
- Oracle数据库连接、存储过程及调用
Oracle数据库连接.存储过程及调用 1. 定义一个存储过程 create or replace procedure getuser(eid in number, na out varchar, e ...
- mysql全方位知识大盘点
一.mysql都有哪些存储引擎?各自的特点是什么? 引擎 事务 锁 主键 索引 外键 数据结构 适用场景 InnoDB 支持 行锁.表锁 必须有主键,没有设置会自动创建 主键索引和数据在一起,其他索引 ...
- 16-3 update语句
--打开和关闭查询窗口:ctrl+R --更新语句: --update 表名 set 列=新值,列2=新值2,... where 条件 --update语句,如果不加where条件,那么表示对表中所有 ...
- es6的数组操作
//foreach 迭代 var arr = [1, 2, 3]; var sum = 0; arr.forEach(function(value, index, array) { console.l ...
- vue端口号被占用
今天在启动一个Vue项目的时候,遇到了一个问题. 得知是Vue项目端口号占用的问题. 解决方法: 换一个端口号. 在调用 npm run dev 的时候,实际上是在调用根目录下的 package ...
- 循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理
在我开发的很多系统里面,包括Winform混合框架.Bootstrap开发框架等系列产品中,我都倾向于动态配置菜单,并管理对应角色的菜单权限和页面权限,实现系统对用户权限的控制,菜单一般包括有名称.图 ...
- PIC单片机编译器自带的延时程序
https://wenku.baidu.com/view/3c94e2934028915f814dc205.html