我是如何開始閱讀MySQL源碼的?
1. 為什麼要閱讀MySQL源碼?
之前已經看過 高性能MySQL 和 MySQL技術內幕InnoDB存儲引擎, 但總覺得只是看看書上這麼說還是不夠.
比如 高性能MySQL 里畫的有B-Tree索引的示意圖,可是B-Tree索引究竟長什麼樣子,在MySQL里是怎麼存儲的,沒什麼概念; 裡邊還提到關聯查詢的」泳道圖」,在代碼層面到底是怎麼執行的,也不清楚.
2. 從哪兒開始?
直接看MySQL的源碼有點困難.
好在有一本講MySQL的書, 叫 Understanding.MySQL.Internals, 書雖然有點老,但看起來是個不錯的開始.大概過一下書的內容,發現大部分內容還是看不下去. 只有第4章 Client/Server Communication 還能看.
3. Protocol
Understanding.MySQL.Internals 的第4章 Client/Server Communication 講了MySQL Server和客戶端溝通的協議, 結合著wireshark, 很快就能搞明白.
http://heguangyu5.github.io/mysql/1-protocol.html
4. main() -> mysqld_main()
MySQL是由C++寫的,入口函數main()直接調用了mysqld_main().
Server啟動的代碼都在這裡,大部分都看不懂.直到最後的 handle_connections_sockets().5. handle_connections_sockets()
讀過UNP的看這部分代碼應該都沒問題.
poll()accept()thread_scheduler->add_connection()pthread_create() or thead_cache
handle_one_connection()
for (;;) { while (connection_alive()) { do_command(); } cache_thread();}
do_command() -> dispatch_command()
http://heguangyu5.github.io/mysql/2-handle-connections-sockets.html
6. dispatch_command()
這裡已經能夠看到很多熟悉的詞語了,CHANGE_USER,STMT_EXECUTE,STMT_FETCH.
不過最關鍵的執行SQL語句的部分, COM_QUERY, 看不懂.
mysql_parse() -> MYSQLparse()
Understanding.MySQL.Internals 的第9章 Parser and Optimizer, 是講這部分的.
在Parse Tree部分有提到SQL語句最終在 mysql_execute_command() 里執行.http://heguangyu5.github.io/mysql/3-dispatch-command.html
7. mysql_execute_command()
case SQLCOM_CREATE_DB: mysql_create_db();case SQLCOM_CREATE_TABLE: mysql_create_table();case SQLCOM_INSERT: mysql_insert();case SQLCOM_SELECT: execute_sqlcom_select();
mysql_create_db()好理解.
mysql_create_table()里有創建一個.frm文件,要是有文檔說明下.frm文件的格式就好了.於是就找到了這個 https://dev.mysql.com/doc/internals/en/fileformats.html
從這往篇文檔可以看出, MySQL的歷史真的太久了,官方文檔對很多欄位的說明都是always, ??.看了這個文檔還是搞不明白.frm文件的格式.http://heguangyu5.github.io/mysql/4-mysql-execute-command.html
8. .MYD and .MYI
由於之前看過InnoDB技術內幕,顯然InnoDB比MyISAM要複雜多了.
MySQL Internals Manual 裡邊有一章講MyISAM的,仔細分析了.MYD和.MYI文件的格式,講的挺清楚的.
.MYD的文件格式挺簡單的.
.MYI的就複雜很多了. 對著文檔寫個小程序讀取並解析.MYI文件,有很大幫助.http://heguangyu5.github.io/mysql/5-MyISAM.html
https://github.com/heguangyu5/heguangyu5.github.io/blob/master/mysql/read-MYI.c搞清楚了.MYD和.MYI的文件格式,很多名詞術語也混個臉兒熟了.
回過頭來再看.frm.9. .frm
創建.frm文件的代碼在 mysql_create_frm() 里.
努力一番後,再寫個小程序讀取並解析下.frm文件,總算搞清楚其格式了.http://heguangyu5.github.io/mysql/6-frm.html
https://github.com/heguangyu5/heguangyu5.github.io/blob/master/mysql/read-frm.c在創建完.frm後,又調用了Storage Engine的ha_create()方法創建了其它相關的文件,比如MyISAM就創建了.MYD和.MYI文件.
10. plugin_init, mysql_insert, execute_sqlcom_select
這個時間回過頭來再看下啟動代碼里的plugin_init部分,還是相對容易的搞清楚了Stroage Engine是怎麼載入的了.
自己編譯一個debug版本的mysqld會有一些幫助.
mysql_insert()還是比較簡單的.
execute_sqlcom_select()就複雜了.
結合著Understanding.MySQL.Internals 的第9章 Parser and Optimizer, 總算看到」泳道圖」是怎麼執行的了.11. 下一步
OK, 萬事開頭難. 到此也算是開了個頭了.
緩一緩後邊再看下這個 23 Writing a Custom Storage Engine
推薦閱讀:
※MySQL學習筆記(二)索引與視圖
※R markdown 連接mysql數據
※一個MySQL語句的優化
※專精 Oracle 還是 MySQL?
※mongodb寫入數據要注意的一些細節
TAG:MySQL |