SQLServerdump介绍(转载)
转储的英⽂单词是dump,但这边我们说的dump不是SQL Server本⾝的DUMP备份命令,⽽是指通过中的dump。那什么是dump呢,dump指的是将某种
内容转换为另外⼀种更具可读性的⽅式。在ORACLE中,有专门的dump命令可以dump出数据⽂件等的内容,其trace也相当于另外⼀种dump。通过dump,我们便可以了解
整个系统的运⾏原理。
SQL Server这⽅⾯的资料很少,当然,这也符合了微软不开源的策略。不过这⼏年来,关于这⽅⾯的资料⽐较多了,通过google可以获得相关的内容。
最早对此感兴趣的是碰到了很多⼈经常问的.mdmp⽂件,mdmp的叫mini dmp,也可以叫memory dmp,这是由于SQL Server 在运⾏过程中,遇到了⼀些bug或者错误⽽进⾏
转储以便记录出错信息的⽂件。⼀般对这类⽂件的处理,都是建议打包后提交给微软分析的。在⽆法获得微软帮助的情况,就需要⾃⼰对此类⽂件进⾏分析了,然后出问题原因,
从⽽进⾏解决。
⼀、介绍
前⾯介绍了SQL Server 会在运⾏时⾃动产⽣⼀些dump⽂件,我们也可以⼿⼯产⽣dump⽂件,产⽣dump⽂件的⽅式,就是通过Sqldumper 来进⾏的。
⾃ SQL Server 2000 Service Pack 3 (SP3) 起,Microsoft SQL Server 2000 中开始附带 。 可根据任⼀Microsoft Windows 应⽤程序的
需要⽣成转储⽂件。不仅可以转储SQL Server,还可以转储其他的windows application。
我使⽤的环境是SQL Server 2008,因此SQLDumper位于C:\Program Files\Microsoft SQL Server\100\Shared下,我们可以运⾏SQLDumper /? 查看其使⽤⽅法
C:\Program Files\Microsoft SQL Server\100\Shared& /?
Usage: [ProcessID [ThreadId [Flags[:MiniDumpFlags] [SqlInfoPtr [DumpDir [ExceptionRecordPtr [ContextPtr [E xtraFile]]]]]]]] [-I<InstanceName>] [-S<ServiceName>][-remoteservers:[print|dump|freeze|resume|remote:guid\dumporigin\si
gnature\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
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 为900,想dump所有的内存信息,那就可以⽤下⾯的命令来进⾏:C:\Program Files\Microsoft SQL Server\100\Shared& 900 0x0010
其中,0x0010 表⽰all_memory,这样,在C:\Program Files\Microsoft SQL Server\100\Shared⽬录下会产⽣SQLDmprnnn.mdmp的⽂件,这就是转储⽂件(.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 traceon(2544, -1)
go
dbcc traceon(2546, -1)
go
dbcc stackdump
如果想让SQL Server 只针对某个错误⽽产⽣转储⽂件,可以使⽤dbcc dumptrigger,下⾯是⼀个例⼦
dbcc traceon(2544, -1)
go
dbcc traceon(2546, -1)
go
--设置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
⽹上有听说可以使⽤2542 Trace Flag 来控制mdmp⽂件的产⽣,⾄今仍没有去试,有试过的朋友可以分享下。启⽤2542 TF,在启动参数后⾯添加 -T2542就是了。
三、分析mdmp⽂件的⼀些知识说明
以上只是介绍了mdmp的产⽣,以及如何⾃⼰⼿⼯产⽣mdmp⽂件,但如何对mdmp⽂件进⾏分析才是重点。曾经对其进⾏了⼀些分析,但道⾏有限,能获得的信息不多。把如何分析
mdmp⽂件的过程分享出来,希望更厉害的⼈能从中到⼀些SQL Server的运⾏原理。
说到分析mdmp⽂件,也顺便提⼀个⼈,就是The guru guide系列的作者Ken Henderson(),他的
《The Guru's Guide to Transact-SQL》就是中⽂版的《T-SQL权威指南》,其他的两本貌似没有到中⽂版。他在Guru Guide ⾥⾯常常会介绍⼀些微软未公开的内容
(undocument commands),⽽《The Guru's Guide to SQL Server Architecture and Internals》
就是介绍了SQL Server 2000的体系结构很是深⼊的⼀本书。可惜其在2008年已经英年早逝了(),不然肯定能够提供更多关于SQL Server Interal的内容了。
1,调试
由于SQL Server 也是在windows平台是运⾏的⼀款程序,有问题时,把它当成⼀款普通的windows程序来进⾏调试就⾏了。在windows上,有两⽅⾯的调试,⼀个是内核模式调试,
⼀个是⽤户模式调试。内核调试是针对Windows操作系统进⾏调试的,反应windows OS内部和硬件设备的运⾏。⽤户模式的调试就是对应⽤程序进⾏调试,因为应⽤程序就是运⾏在
⽤户模式上的。⼆者的调试是不同的,这边就不做过多的介绍,有疑问,就google吧。
调试还有另外⼀个区别:是在程序运⾏时对其调试(live-debugging),还是读取mdmp分析调试(post-mortem debugging)。这⼆者也是不⼀样的。在live-debugging时会使程序挂起
,然后设置bp(break point),观察程序的运⾏⾏为。这边主要介绍post-mortem debugging.
2,windbg
要调试,当然得有⼯具,这个⼯具就是windbg,其主页为:
www.microsoft/whdc/devtools/debugging/default.mspx
安装完成后,除了有图形界⾯的调试⼯具(windbg),还会有命令⾏的调试⼯具(kd,cdb,ntsd)。
在调试过程中,我们最常见的是分析线程(thread)的堆栈(stack)的跟踪信息。因为在windows平台上,application是以process来运⾏的,⽽⼀个process⼜包含了thread,thread
才是真正在运⾏⼀些函数功能。我们可以通过select spid,kpid from sysprocesses 来看运⾏SQL Server的线程信息,也可以通ProcessExplorer
spidd kpid
------ ------
51 0
52 644
在ProcessExplorer⾥的查看如下,可以看到ProcessExplorer就提供了查看堆栈的功能,但仍有⼀些像 +0x58d36b的内容⽆法查看。
从上图可以看到,stack的内容格式⼀般如下:
MyModule!Func03
MyModule!Func01
从底往上看,Func03是在Func01之后执⾏的。通过windbg,还会看到⼀些指针信息(Child-sp:Stack Pointer)和地址信息(RetAddr:Return Address)
Child-SP RetAddr Call Site
00000000`09cbe9e8 00000000`777b2f60 ntdll!NtSignalAndWaitForSingleObject+0xa
00000000`09cbe9f0 00000000`00bdc99e kernel32!SignalObjectAndWait+0x110sql2000数据库在哪个文件夹
00000000`09cbeaa0 00000000`00bc4575 sqlservr+0x1c99e
00000000`09cbed40 00000000`00bc3ea8 sqlservr+0x4575
00000000`09cbed80 00000000`00bdcfad sqlservr+0x3ea8
00000000`09cbf370 00000000`01139d9c sqlservr+0x1cfad
00000000`09cbf430 00000000`032b34c7 sqlservr+0x579d9c
00000000`09cbf650 00000000`00bd2abb sqlservr!TlsGetValueForMsxmlSQL+0x4706d7
00000000`09cbf6c0 00000000`00bd0fda sqlservr+0x12abb
00000000`09cbf7e0 00000000`00bd2665 sqlservr+0x10fda
00000000`09cbf870 00000000`0117abb0 sqlservr+0x12665
00000000`09cbf8e0 00000000`0117c4b0 sqlservr+0x5babb0
00000000`09cbf9a0 00000000`0117a060 sqlservr+0x5bc4b0
00000000`09cbf9d0 00000000`0117a9ef sqlservr+0x5ba060
00000000`09cbfa60 00000000`734937d7 sqlservr+0x5ba9ef
00000000`09cbfaf0 00000000`73493894 MSVCR80!endthreadex+0x47
00000000`09cbfb20 00000000`7775f56d MSVCR80!endthreadex+0x104
00000000`09cbfb50 00000000`77893281 kernel32!BaseThreadInitThunk+0xd
00000000`09cbfb80 00000000`00000000 ntdll!RtlUserThreadStart+0x21
要看sqlservr+0x579d9c 这样的内容,需要使⽤symbol来map这些16进制的值所表⽰的函数。使⽤symbol后,会得到下⾯的形式的内容。Child-SP RetAddr Call Site
00000000`09cbe9e8 00000000`777b2f60 ntdll!NtSignalAndWaitForSingleObject+0xa
00000000`09cbe9f0 00000000`00bdc99e kernel32!SignalObjectAndWait+0x110
00000000`09cbeaa0 00000000`00bc4575 sqlservr!SOS_Scheduler::SwitchContext+0x84e
00000000`09cbed40 00000000`00bc3ea8 sqlservr!SOS_Scheduler::SuspendNonPreemptive+0xc5
00000000`09cbed80 00000000`00bdcfad sqlservr!EventInternal<Spinlock<149,1,0> >::Wait+0x428
00000000`09cbf370 00000000`01139d9c sqlservr!ResQueueBase::Dequeue+0x19d
00000000`09cbf430 00000000`032b34c7 sqlservr!CheckpointLoop+0x1aa
00000000`09cbf650 00000000`00bd2abb sqlservr!ckptproc+0x47
00000000`09cbf6c0 00000000`00bd0fda sqlservr!SOS_Task::Param::Execute+0x11b
00000000`09cbf7e0 00000000`00bd2665 sqlservr!SOS_Scheduler::RunTask+0xca
00000000`09cbf870 00000000`0117abb0 sqlservr!SOS_Scheduler::ProcessTasks+0x95
00000000`09cbf8e0 00000000`0117c4b0 sqlservr!SchedulerManager::WorkerEntryPoint+0x110
00000000`09cbf9a0 00000000`0117a060 sqlservr!SystemThread::RunWorker+0x60
00000000`09cbf9d0 00000000`0117a9ef sqlservr!SystemThreadDispatcher::ProcessWorker+0x12c
00000000`09cbfa60 00000000`734937d7 sqlservr!SchedulerManager::ThreadEntryPoint+0x12f
00000000`09cbfaf0 00000000`73493894 MSVCR80!endthreadex+0x47
00000000`09cbfb20 00000000`7775f56d MSVCR80!endthreadex+0x104
00000000`09cbfb50 00000000`77893281 kernel32!BaseThreadInitThunk+0xd
00000000`09cbfb80 00000000`00000000 ntdll!RtlUserThreadStart+0x21
在这个例⼦中,我们发现有sqlservr!CheckpointLoop+0x1aa 这个函数调⽤的信息,这就是我们说的checkpoint的实际运⾏信息了。通过select * from sys.dm_exec_requests
可以看出是哪个spid在运⾏checkpoint。
从上⾯也可以看出Call Site的格式⼀般如下:
<module_name>!<function call>
<module_name>!<class_name>::<method/function call>
四、使⽤windbg
在了解上述知识后,就可以使⽤windbg来进⾏分析了。
1,windbg环境的配置
到微软的⽹站下载windbg后直接安装,安装完成后,需要配置symbols的path,打开windbg,File --> Symbols File Path 在弹出的对话框输⼊
srv*c:\symbols*msdl.microsoft/download/symbols
其中c:\symbols是本地硬盘的⽂件夹,在使⽤时,windbg会到msdl.microsoft/download/symbols下载相关的symbols,也可以⾃⼰⼿⼯下载相关操作系统的symbols。
配置好,可以使⽤.reload命令来强制下载某个symbols,如:
.reload /
具体的命令可以参考windbg的帮助⽂档。
2,打开mdmp⽂件
打开windbg,File --> Open Crash Dump,选择mdump⽂件,在弹出的对话框⾥点击yes
3,分析mdmp
在下⾯的对话框输⼊ ~ 会出现线程的信息
0:000> ~
. 0 Id: 384.608 Suspend: 1 Teb: 7ffdd000 Unfrozen
1 Id: 384.698 Suspend: 1 Teb: 7ffda000 Unfrozen
2 Id: 384.6a8 Suspend: 1 Teb: 7ffd9000 Unfrozen
3 Id: 384.6a
4 Suspend: 1 Teb: 7ffd8000 Unfrozen
4 Id: 384.6b0 Suspend: 1 Teb: 7ffd7000 Unfrozen
5 Id: 384.6ac Suspend: 1 Teb: 7ffd6000 Unfrozen
6 Id: 384.6c8 Suspend: 1 Teb: 7ffd5000 Unfrozen
7 Id: 384.6dc Suspend: 1 Teb: 7ffd4000 Unfrozen
8 Id: 384.6e0 Suspend: 1 Teb: 7ffd3000 Unfrozen
9 Id: 384.108 Suspend: 1 Teb: 7ff9f000 Unfrozen
10 Id: 384.6e8 Suspend: 1 Teb: 7ff9e000 Unfrozen
11 Id: 384.6e4 Suspend: 1 Teb: 7ff9d000 Unfrozen
12 Id: 384.604 Suspend: 1 Teb: 7ff9c000 Unfrozen
13 Id: 384.714 Suspend: 1 Teb: 7ff9b000 Unfrozen
14 Id: 384.718 Suspend: 1 Teb: 7ff9a000 Unfrozen
15 Id: 384.71c Suspend: 1 Teb: 7ff99000 Unfrozen
16 Id: 384.720 Suspend: 1 Teb: 7ff98000 Unfrozen
17 Id: 384.728 Suspend: 1 Teb: 7ffdc000 Unfrozen
18 Id: 384.730 Suspend: 1 Teb: 7ff97000 Unfrozen

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。