這篇文章我想探究下SQL Server里完全不同的領域:如果使用WinDbg(來自針對Windows的調試工具)調試SQL Server。在我們進入枯澀細節之前,我想詳細解釋下為什么選擇這樣晦澀的話題來寫這篇文章。
緣由當使用SQL Server時,你到底需不需要像WinDbg這樣的調試器?簡單回答:從不需要!SQL Server是一個穩定的產品,使用它提供的技術(擴展事件,DMVs/DMFs)進行故障排除已經可以了,從不會用到WinDbg。如果你有疑問的話,在你獨自嘗試調試討厭的SQL Server問題前,你應該首先聯系PSS。那使用像WinDbg的調試器的原因是什么?對我來說主要是教學,學習在SQL Server內部是如何工作的,還有關系數據庫引擎是如何實現的。當我處理SQL Server問題時,有時候會看到在SQL Server里瘋狂的事情,這是我要去解釋的。因此我對SQL Server知道得更多,還有SQL Server如何工作的,對我來說是越好。
我使用WinDbg只出于教育目的,只在非生產的測試系統,為了更好的理解當執行查詢時,SQL Server內部發生了什么。為此我們還要了解更多Windows系統的概念,用戶模式調試,64位匯編語言,還有64位機器架構等。另外也要翻閱大量白皮書介紹關系數據庫引擎是如何實現的。使用WinDbg我可以從內部看SQL Server,用哪個方式SQL Server實現它的功能,還有這些是如何一起工作的。最重要的是:像極客(geeky)一樣去使用WinDbg調試器,大家都樂此不彼。
正題在我們進入如何詳細配置WinDbg對SQL Serve調試前,首先我想給你講下SQL Server里最重要的DLL文件,在調試時我們會用到。我們來看下面圖片:
我們知道,SQL Server本身是在可執行的sqlservr.exe里實現。在啟動期間,sqlservr.exe會加載多個DLL文件到它的進程空間。從調試角度來說——下列是重要的幾個DLL文件:
為了使用WinDbg,你需要先安裝這個調試工具,它可以從微軟免費下載:用于 Windows 的獨立調試工具 (WinDbg)。
https://msdn.microsoft.com/zh-cn/windows/hardware/gg463028#Download_windows
(貌似微軟網站都很難下載,現提供單獨下載地址:
x86位版本下載:【微軟官方安裝版】
x64位版本下載:【微軟官方安裝版】
)
安裝完成后,在開始菜單里就可以找到這個程序:
當你啟動WinDbg時,請確認你的賬戶有管理員權限,不然的話你是不能附加到像sqlservr.exe這樣的進程。為了使用WinDbg,你需要配置符號表(symbols)。符號表文件是用來解碼內存地址,對應函數名稱,這樣更容易我們調試和理解。當你使用符號表是,你要區分公共和私有符號表。除了微軟能訪問公共符號,我們只能訪問私有符號。公共符號是私有符號的子集,不包括更有趣的東西,例如:
公共符號僅提供你函數名稱——沒別的信息!與私有符號相比,我們需要習慣它的巨大限制。但是另一方面,微軟想要保護它們的知識產權。不過只拿到用于調用堆棧(call-stacks)完整函數名稱,在它們上面設置斷點,通過它們調試,就可以大大幫助你理解SQL Server內部是如何工作的。只要你正確配置了WinDbg,對于你調試的指定內建SQL Server,你拿到自動正確的公共符號。你也可以嘗試本地內核模式調試(local Kernel Mode Debugging),你甚至可以拿到內核模式的正確符號——但這是另外一回事……在WinDbg里你要配置微軟公共符號的服務器地址,這樣的WinDbg就可以正常下載它們。地址是:
http://msdl.microsoft.com/download/symbols
我是用批處理命令運行WinDbg,設置正確的符號服務器地址,直接附加到sqlservr.exe進程。
首先我們在命令提示符里切換到WinDbg所在目錄:
CD C:/Program Files/Debugging Tools for Windows (x86)
然后使用如下命令:
windbg -y srv*g:/symbols*http://msdl.microsoft.com/download/symbols -pn sqlservr.exe
你必須確保只有一個SQL Server實例在運行,因為WinDbg是通過進程名稱sqlservr.exe來附加的。如果你有多個SQL Server實例運行,你要指定正確的PID,這個可以從任務管理器拿到。
使用如下的命令:
windbg -y srv*g:/symbols*http://msdl.microsoft.com/download/symbols -p 384
路徑g:/symbols是你電腦上的位置,用來存儲下載的符號表。那個位置的大小會改變,因為你會不停的下載大量的符號文件。我本地的符號文件現在有1G的大小……如果一切正常,你現在應該可以附加到sqlservr.exe:
程序執行現在已經停止了,因為你碰到了ntdll模塊里的斷點。ntdll是系統提供的一個簡單的封裝DLL,用來進行用戶模式到內核模式的轉換。這也意味著現在SQL Server里的“每個”線程都已經停止了,不能進行任何操作!!!請不要嘗試在生產環境里將WinDbg附加到sqlservr.exe!!如果你像恢復sqlservr.exe的運行,按鍵盤上的F5即可——SQL Server就再次恢復運行了。如果你想再次中斷程序執行,你需要設置sqlservr.exe的進程空間里的斷點,或者通過鍵盤快捷鍵CTRL+BREAK。
如果你用那個快捷鍵中斷運行,WinDbg會把你放在sqlservr.exe的某個特定線程上。如果你想分析特定內存地址或者像設置具體斷點用作進一步的故障排除,推薦你這么做。在WinDbg里一個非常重要呢個的命令是x命令:它會返回你指定模塊里所有定義的符號。我們來看下面的命令:
x sqlmin!*BTree*
這個WinDbg命令會返回你所有名稱包含“BTree”的函數名列表。這樣的話,你就可以在指定的函數名上設置斷點進行分析。返回函數名稱如下格式:
module_name!class_name::function_name
例如sqlmin!BTreeMgr::Seek。如果你像返回BTreeMgr類定義的所有函數,可以使用下列命令:
x sqlmin!BTreeMgr::*
X命令是一個非常強大的命令,用來探索SQL Server實現的各個類。給你留點家庭作業,回答下列問題:
歡迎在評論里回答上述問題。
小結這篇文章我已經給你介紹了WinDbg的入門,還有你如何使用這個調試器附加到SQL Server。你已看到,sqlservr.exe進程空間里包含多個DLL文件,在那里每個DLL實現了SQL Server的各個組件功能。當你已經正確配置好公共符號的路徑,你就可以獲得組成SQL Server的各個類和函數的元數據信息。這里WinDbg的x命令是你的好助手。
希望你會喜歡這個特別的文章,下次我會為你介紹如何使用WinDbg指令來調試和執行SQL Server查詢。
感謝關注!
新聞熱點
疑難解答