上一篇說了mysql的架構圖,不少同窗反饋說不過癮,畢竟仍是聽我講故事,那這篇就來講一說怎麼利用visual studio 對 mysql進行源碼級調試,畢竟源碼面前,不談隱私,聖人面前,皆爲螻蟻。mysql
mysql是C++寫的,要想在windows上編譯,還須要下載幾個必備小工具。sql
這裏簡單說一下:能夠用cmake
將源碼生成 *.sln
可打開的解決方案,好比能夠經過它最終生成 MySQL.sln
。boost
是C++中很是強大的基礎庫, bison
一個流行的語法分析器程序,用於給mysql提供語法分析,最後就是下載正確的mysql版本 5.7.12
。windows
我會寫的比較細,畢竟我也花了一下午時間,寒酸(┬_┬)bash
cmake 和 bison 安裝起來比較方便,一鍵安裝就能夠了,不過這裏有一個大坑注意了,在安裝Bison
的時候,千萬不要使用默認路徑,由於默認路徑有空格,會致使你後面vs編譯的時候卡住,又不顯示什麼緣由,可氣!!! 因此我換成自定義的: C:\2\GnuWin32
。架構
最後確保 cmake
和 bison
的bin文件都在 環境變量中便可。函數
這裏我用 C:\2
做爲根文件夾,全部的小工具都在這裏,如圖:工具
接下來將 mysql-5.7.12.zip
解壓一下,而後進入解壓後的文件夾,新建一個boost文件夾,將boost_1_59_0.tar.gz
放入其中,而後再新建一個 brelease
文件夾可用於存放最終生成的MySql.sln
。😄😄😄。ui
都準備好了以後,能夠開始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
生成好了。spa
個人電腦安裝的是visual studio 2019
,接下來打開MySql.Sln
總體編譯,須要等個十幾分鍾,看到下面的輸出就算安裝成功。
這裏要作兩件事情,第一件事是將mysql的調試模式打開,第二件事就是附加 --initialize
啓動參數。
修改C:\2\mysql-5.7.12\sql\mysqld.cc
中的 test_lc_time_sz
方法中的 DBUG_ASSERT(0);
改爲 DBUG_ASSERT(1);
以下圖:
上一篇你們都知道了,mysqld項目是mysql的啓動項目,main函數也在其中,在F5調試以前增長初始化參數 --console --initialize
,以下圖:
啓動以後,有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
,😁😁嘿嘿,一切搞定~~~
上一篇咱們追蹤到了 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
方法,以下圖:
而後找幾個局部變量和調用堆棧看看。。。
這就是我花了一下午的時間總結出的進坑出坑指南,但願能幫助你們節省時間,仍是那句話,源碼面前,不談隱私,若還能進行調試,那一切皆爲螻蟻!