參考文獻
前言
之前聽同事們之間交流經常會聽到dump這個詞,但是一直不明白dump是什么東西,今天特地整理一下這方面的資料。我們稱dump為轉儲,但這邊我們說的dump不是SQL Server本身的DUMP備份命令,而是指通過sqldumper.exe中的dump。那什么是dump呢,dump指的是將某種內容轉換為另外一種更具可讀性的方式。在ORACLE中,有專門的dump命令可以dump出數據文件等的內容,其trace也相當於另外一種dump。通過dump,我們便可以了解整個系統的運行原理。SQL Server這方面的資料很少,當然,這也符合了微軟不開源的策略。不過這幾年來,關於這方面的資料比較多了,通過google可以獲得相關的內容。
最早對此感興趣的是碰到了很多人經常問的.mdmp文件,mdmp的叫mini dmp,也可以叫memory dmp,這是由於SQL Server 在運行過程中,遇到了一些bug或者錯誤而進行轉儲以便記錄出錯信息的文件。一般對這類文件的處理,都是建議打包后提交給微軟分析的。在無法獲得微軟幫助的情況,就需要自己對此類文件進行分析了,然后找出問題原因,從而進行解決。
一、SQLDumper.exe介紹
前面介紹了SQL Server 會在運行時自動產生一些dump文件,我們也可以手工產生dump文件,產生dump文件的方式,就是通過Sqldumper來進行的。自 SQL Server 2000 Service Pack 3 (SP3) 起,Microsoft SQL Server 2000 中開始附帶 Sqldumper.exe。Sqldumper.exe 可根據任一 Microsoft Windows 應用程序的需要生成轉儲文件。Sqldumper.exe不僅可以轉儲SQL Server,還可以轉儲其他的windows application。
我使用的環境是SQL Server 2012,因此SQLDumper位於C:\Program Files\Microsoft SQL Server\110\Shared下,我們可以運行SQLDumper /? 查看其使用方法,16進制代碼是控制標識符。查詢SQLDumper用處的代碼如下所示:
C:\Program Files\Microsoft SQL Server\110\Shared>SqlDumper.exe /? Usage: SqlDumper.exe [ProcessID [ThreadId [Flags[:MiniDumpFlags] [SqlInfoPtr [DumpDir [ExceptionRecordPtr [ContextPtr [ExtraFile]]]]]]]] [-I<InstanceName>] [-S<ServiceName>][-remoteservers:[print|dump|freeze|resume|remote:guid\dumporigin\signature\localId\port\operationType]] Flags: dbgbreak = 0x0001 nominidump = 0x0002 validate_image = 0x0004 referenced_memory = 0x0008 all_memory = 0x0010 dump_all_threads = 0x0020 match_file_name = 0x0040 no_longer_used_flag = 0x0080 verbose = 0x0100 wait_at_exit = 0x0200 send_to_watson = 0x0400 defaultflags = 0x0800 maximumdump = 0x1000 mini_and_maxdump = 0x2000 force_send_to_watson = 0x4000 full_filtered_dump = 0x8000 no_auto_remote_dump_invocation = 0x40000 MiniDumpFlags: Normal = 0x0000 WithDataSegs = 0x0001 WithFullMemory = 0x0002 WithHandleData = 0x0004 FilterMemory = 0x0008 ScanMemory = 0x0010 WithUnloadedModules = 0x0020 WithIndirectlyReferencedMemory = 0x0040 FilterModulePaths = 0x0080 WithProcessThreadData = 0x0100 WithPrivateReadWriteMemory = 0x0200 WithoutOptionalData = 0x0400 WithFullMemoryInfo = 0x0800 WithThreadInfo = 0x1000
從上面的命令可以看出,要想對某一application進行dump,需要先找出其pid(processes id),然后加上一些Flags的控制標識來控制dump內容。比如,我現在想對SQL Server 進行dump,先找到SQL Server 的pid 為1672(可以在sql server configure management中找到sql server 2012服務的ProcessID),想dump所有的內存信息,那就可以用下面的命令來進行:
C:\Program Files\Microsoft SQL Server\110\Shared>SqlDumper.exe 1672 0x0010
其中,0x0010 表示all_memory,這樣,在C:\Program Files\Microsoft SQL Server\110\Shared目錄下會產生SQLDmpr0001.mdmp和SQLDUMPER_ERRORLOG.log這兩個文件,這就是轉儲文件(.mdmp)。
以下是幾個比較常見的dump 標識:
0x0120 - Minidump --這個flag只dump 一個Process的堆棧和載入模塊的信息,這是最小的轉儲方式,也是SQL Server自動產生dump文件的方式。 0x01100 – Full Dump --這個flag會轉儲Process的整塊信息,如果在64位的系統上,其文件大小還是很大的。 0x8100 – Filtered Dump --這個flag用來轉儲用於於其他服務器用途(包括過程緩存)的內存信息
二、SQL Server方式的DUMP
使用Sqldumper只是手工產生dump文件的一種方式,當然,產生dmp文件的方式還是很多的,SQL Server內部也提供了這樣的工具。主要是DBCC STACKDUMP 和DBCC dumptrigger 這兩個命令。當然還可以通過TraceFlag來控制是否產生dmp文件或者遇到什么錯誤時才產生文件。比如,我們想產生一個Full Dump,必須打開Trace Flag 2544 和 2546,然后執行DBCC STACKDUMP ,命令如下:
--DBCC stackdump dbcc traceon(2544, -1) go dbcc traceon(2546, -1) go dbcc stackdump dbcc traceon(2544, -1) go dbcc traceon(2546, -1) go
在執行完上述命令以后,我們會發現在D:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\Log(我將sqlserver2012的示例安裝在了D盤)目錄下多出了如下圖所示的三個文件:
再次執行上述命令,又會多出下圖所示的三個文件:
而SQLDUMPER_ERRORLOG.log和ERRORLOG這兩個文件是公用的。
如果想讓SQL Server 只針對 某個錯誤而產生轉儲文件,可以使用dbcc dumptrigger,下面是一個例子
--DBCC dumptrigger --設置dump的觸發器為錯誤802 dbcc dumptrigger('set', 802) go -- 查看當期的dump觸發器內容 dbcc traceon(3604, -1) go dbcc dumptrigger('display') go dbcc traceoff(3604, -1) go -- 關閉當期的dump觸發器。 dbcc dumptrigger('clear', 802) go
執行上述命令以后,在SSMS中顯示如下信息:
DBCC execution completed. If DBCC printed error messages, contact your system administrator. DBCC execution completed. If DBCC printed error messages, contact your system administrator. Dump Triggers DebugBreak = 0 CExDumpTriggers @0x00000001ECBD4140 Exception = 802 DBCC execution completed. If DBCC printed error messages, contact your system administrator. DBCC execution completed. If DBCC printed error messages, contact your system administrator. DBCC execution completed. If DBCC printed error messages, contact your system administrator.
三、分析mdmp文件的一些知識說明
以上只是介紹了mdmp的產生,以及如何自己手工產生mdmp文件,但如何對mdmp文件進行分析才是重點。曾經對其進行了一些分析,但道行有限,能獲得的信息不多。把如何分析mdmp文件的過程分享出來,希望更厲害的人能從中找到一些SQL Server的運行原理。
1、調試
由於SQL Server 也是在windows平台是運行的一款程序,有問題時,把它當成一款普通的windows程序來進行調試就行了。在windows上,有兩方面的調試,一個是內核模式調試,一個是用戶模式調試。內核調試是針對Windows操作系統進行調試的,反應windows OS內部和硬件設備的運行。用戶模式的調試就是對應用程序進行調試,因為應用程序就是運行在用戶模式上的。二者的調試是不同的,這邊就不做過多的介紹,有疑問,就google吧。
調試還有另外一個區別:是在程序運行時對其調試(live-debugging),還是讀取mdmp分析調試(post-mortem debugging)。這二者也是不一樣的。在live-debugging時會使程序掛起,然后設置bp(break point),觀察程序的運行行為。這邊主要介紹post-mortem debugging.
在調試過程中,我們最常見的是分析線程(thread)的堆棧(stack)的跟蹤信息。因為在windows平台上,application是以process來運行的,而一個process又包含了thread,thread才是真正在運行一些函數功能。我們可以通過如下命令來看運行SQL Server的線程信息:
use master select spid,kpid from sys.sysprocesses
查詢結果如下:
spid kpid ------ ------ 1 3260 2 3356 3 3352 4 3252 5 3256 6 3236 7 3368 8 3372 10 0 11 3436 12 3380 13 3264 14 4016 15 3768 16 3348 17 3284 18 0 19 0 20 0 21 0 22 0 23 0 24 3576 25 4024 26 0 28 4020 29 2368 30 2556 31 4028 51 0 52 3364 53 0 56 0 57 0
查看線程信息也可以通ProcessExplorer查看,如下圖所示:
不過這得windbg的支持才可以,windbg可以在Download and Install Debugging Tools for Windows下載到,我使用的是Install Debugging Tools for Windows as a Standalone Component,也就將windbg作為一個單獨的組件進行安裝。
四、使用windbg
在了解上述知識后,就可以使用windbg來進行分析了。
1、windbg環境的配置
到微軟的網站下載windbg后直接安裝,安裝完成后,需要配置symbols的path,打開windbg,File --> Symbols File Path 在彈出的對話框輸入
srv*D:\app\symbols*http://msdl.microsoft.com/download/symbols
其中D:\app\symbols是本地硬盤的文件夾,在使用時,windbg會到http://msdl.microsoft.com/download/symbols下載相關的symbols,我這邊下載的一共有6.27MB大小。
2、打開mdmp文件
打開windbg,File --> Open Crash Dump,選擇mdump文件,在彈出的對話框里點擊yes,這里我選擇的是在C:\Program Files\Microsoft SQL Server\110\Shared目錄下會產生SQLDmpr0001.mdmp。
3、分析mdmp
在下面的對話框輸入“~”,如下圖所示:
敲回車以后會出現線程的信息,信息如下:

0:000> ~ . 0 Id: 688.e68 Suspend: 1 Teb: 000007ff`fffde000 Unfrozen 1 Id: 688.f2c Suspend: 1 Teb: 000007ff`fffd5000 Unfrozen 2 Id: 688.2ec Suspend: 1 Teb: 000007ff`fff9e000 Unfrozen 3 Id: 688.2184 Suspend: 1 Teb: 000007ff`fff9a000 Unfrozen 4 Id: 688.ba0 Suspend: 1 Teb: 000007ff`fff98000 Unfrozen 5 Id: 688.f94 Suspend: 1 Teb: 000007ff`fff96000 Unfrozen 6 Id: 688.dc4 Suspend: 1 Teb: 000007ff`fff94000 Unfrozen 7 Id: 688.fdc Suspend: 1 Teb: 000007ff`fff92000 Unfrozen 8 Id: 688.1fdc Suspend: 1 Teb: 000007ff`fff90000 Unfrozen 9 Id: 688.d60 Suspend: 1 Teb: 000007ff`fff8e000 Unfrozen 10 Id: 688.d64 Suspend: 1 Teb: 000007ff`fff8c000 Unfrozen 11 Id: 688.d58 Suspend: 1 Teb: 000007ff`fff8a000 Unfrozen 12 Id: 688.d48 Suspend: 1 Teb: 000007ff`fff88000 Unfrozen 13 Id: 688.1c58 Suspend: 1 Teb: 000007ff`fff86000 Unfrozen 14 Id: 688.1b7c Suspend: 1 Teb: 000007ff`fff84000 Unfrozen 15 Id: 688.1ecc Suspend: 1 Teb: 000007ff`fff82000 Unfrozen 16 Id: 688.20f8 Suspend: 1 Teb: 000007ff`fff80000 Unfrozen 17 Id: 688.2288 Suspend: 1 Teb: 000007ff`fff7e000 Unfrozen 18 Id: 688.f0c Suspend: 1 Teb: 000007ff`fff7c000 Unfrozen 19 Id: 688.2260 Suspend: 1 Teb: 000007ff`fff7a000 Unfrozen 20 Id: 688.c14 Suspend: 1 Teb: 000007ff`fff78000 Unfrozen 21 Id: 688.a54 Suspend: 1 Teb: 000007ff`fff76000 Unfrozen 22 Id: 688.b9c Suspend: 1 Teb: 000007ff`fff74000 Unfrozen 23 Id: 688.1838 Suspend: 1 Teb: 000007ff`fffd7000 Unfrozen 24 Id: 688.82c Suspend: 1 Teb: 000007ff`fff6e000 Unfrozen 25 Id: 688.fd0 Suspend: 1 Teb: 000007ff`fff6c000 Unfrozen 26 Id: 688.8e4 Suspend: 1 Teb: 000007ff`fff6a000 Unfrozen 27 Id: 688.c84 Suspend: 1 Teb: 000007ff`fff68000 Unfrozen 28 Id: 688.c80 Suspend: 1 Teb: 000007ff`fff66000 Unfrozen 29 Id: 688.c8c Suspend: 1 Teb: 000007ff`fff64000 Unfrozen 30 Id: 688.cb0 Suspend: 1 Teb: 000007ff`fff60000 Unfrozen 31 Id: 688.cb4 Suspend: 1 Teb: 000007ff`ffeae000 Unfrozen 32 Id: 688.cf0 Suspend: 1 Teb: 000007ff`ffea8000 Unfrozen 33 Id: 688.cec Suspend: 1 Teb: 000007ff`ffea6000 Unfrozen 34 Id: 688.f14 Suspend: 1 Teb: 000007ff`ffea2000 Unfrozen 35 Id: 688.11f0 Suspend: 1 Teb: 000007ff`ffea0000 Unfrozen 36 Id: 688.6ec Suspend: 1 Teb: 000007ff`ffe9c000 Unfrozen 37 Id: 688.d3c Suspend: 1 Teb: 000007ff`ffe9a000 Unfrozen 38 Id: 688.548 Suspend: 1 Teb: 000007ff`ffe92000 Unfrozen 39 Id: 688.dc0 Suspend: 1 Teb: 000007ff`ffe86000 Unfrozen 40 Id: 688.246c Suspend: 1 Teb: 000007ff`ffe94000 Unfrozen 41 Id: 688.1b5c Suspend: 1 Teb: 000007ff`ffe90000 Unfrozen 42 Id: 688.1a08 Suspend: 1 Teb: 000007ff`fff70000 Unfrozen 43 Id: 688.1e28 Suspend: 1 Teb: 000007ff`ffea4000 Unfrozen 44 Id: 688.2a3c Suspend: 1 Teb: 000007ff`fffdc000 Unfrozen 45 Id: 688.2728 Suspend: 1 Teb: 000007ff`fff72000 Unfrozen 46 Id: 688.2b54 Suspend: 1 Teb: 000007ff`ffeac000 Unfrozen 47 Id: 688.ffc Suspend: 1 Teb: 000007ff`ffe9e000 Unfrozen 48 Id: 688.34b0 Suspend: 1 Teb: 000007ff`fffd9000 Unfrozen 49 Id: 688.3698 Suspend: 1 Teb: 000007ff`fffd3000 Unfrozen 50 Id: 688.1f64 Suspend: 1 Teb: 000007ff`fff9c000 Unfrozen 51 Id: 688.1740 Suspend: 1 Teb: 000007ff`fff62000 Unfrozen
3、其他
windbg的功能是很強大的,是通往sql server內部一個強大工具。要想了解的話,估計得好好研究下<windows internal>,有興趣的可以自行深入。