25 May 2009
SQL Server - Query distribuite in esecuzione senza mai terminare
Recentemente ho affrontato alcun problemi legati all'hang di query distribuite che utilizzano linked server, creati con provider di terze parti, per accedere a sorgenti dati diverse da Sql Server.
Di seguito sono descritte le attività eseguite per individuare la causa e come risolvere i problemi.
Problema
- In modalità casuale query utilizzanti linked server creati con provider di terze parti, rimangono in esecuzione senza mai terminare
- In alcuni casi, dopo il verificarsi della prima query in hang, tutte le successive query utilizzanti lo specifico Linked server, rimangono nello stesso stato di hang
- L'unica soluzione al problema consiste nel riavviare Sql Server
- L'esecuzione di una select sulla sysprocesses mostra lo SPID, avente in esecuzione la query, in stato di running con attesa su oledb
Dati da raccogliere
- Al fine di verificare l'effettiva attività rimasta in esecuzione all'interno di Sql server, catturare un mini dump o filtered dump del processo di Sql server
Di seguito il link su come utilizzare sqldumper per ottenere un filtered o mini dump
How to use the Sqldumper.exe utility to generate a dump file in SQL Server 2005
Mini-dump file that includes indirectly referenced memory
Sqldumper.exe ProcessID 0 0x0120:40
Filtered dump file
Sqldumper.exe ProcessID 0 0x8100
ProcessID, in questo specifico caso, è l'ID del processo di Sql server
- Salvare il risultato di una select * from master..sysprocesses, per individuare facilmente il Thread Id avente in esecuzione la query.
Analisi dei dati e Soluzione
- Installare i Debugging Tools for Windows
- Aprire windbg
start-->program files-->Debugging Tools for Windows—>windbg - Caricare i simboli pubblici
Con Windbg aperto, selezionare File -->Symbols file path
Inserire srv*c:\symbols*http://msdl.microsoft.com/download/symbols - Caricare il dump prodotto
Con Windbg aperto , selezionare File -->Open Crash Dump, selezionare il dump precedentemente prodotto - Individuare all'interno del dump il Thread ID avente in esecuzione la query
Da Windbg, eseguire il comando ~ per avere la lista dei numeri relativi ai Thread ID e Thread instance
0:000> ~
. 0 Id: 2304.1500 Suspend: 0 Teb: bffdf000 Unfrozen
1 Id: 2304.141c Suspend: 0 Teb: bffdb000 Unfrozen
2 Id: 2304.11f4 Suspend: 0 Teb: bffda000 Unfrozen
Convertire in esadecimale il valore presente nella colonna sysprocesses.kpid in corrispondenza dello SPID avente in esecuzione la query verso linked server, tale valore sarà il ThreadID.
Cercare il valore così ottenuto tra i Thread ID nella lista sopra visualizzata, tenendo conto che nella riga "
2 Id: 2304.11f4 Suspend: 0 Teb: bffda000 Unfrozen", 11f4
è il numero del Thread ID e 2 è numero del Thread Instance
Da notare che a causa del thread switching, il Thread ID potrebbe cambiare velocemente
Per capire la relazione tra Spid. kpid e Thread Instance consiglio il seguente documento
INFO: How to Correlate Spid, Kpid, and Thread Instance
- Posizionarsi sul thread eseguente la query tramite il comando
~~[ ThreadID]
Nel caso del dump da me analizzato, il numero del ThreadID era 1890
41 Id: 2304.1890 Suspend: 0 Teb: bff93000 Unfrozen
Per cui ho eseguito il comando ~~[1890]
0:000> ~~[1890]
. 41 Id: 2304.1890 Suspend: 0 Teb: bff93000 Unfrozen
Start: msvcr80!_endthreadex+0x61 (781329e1)
Priority: 0 Priority class: 32 Affinity: ff
- Visualizzare lo stack frame del thread tramite il comando k
0:041> k
# ChildEBP RetAddr
00 0f13d4b8 7739bf53 ntdll!KiFastSystemCallRet
01 0f13d4f0 7738965e user32!NtUserWaitMessage+0xc
02 0f13d518 7739f762 user32!InternalDialogBox+0xd0
03 0f13d7d8 7739f047 user32!SoftModalMessageBox+0x94b
04 0f13d928 7739eec9 user32!MessageBoxWorker+0x2ba
05 0f13d980 773d7d0d user32!MessageBoxTimeoutW+0x7a
06 0f13d9b4 773c42c8 user32!MessageBoxTimeoutA+0x9c
07 0f13d9d4 773c42a4 user32!MessageBoxExA+0x1b
08 0f13d9f0 0cb13f41 user32!MessageBoxA+0x45
09 0f13dad4 0cb180ac ThirdPartydriver!......
0a 0f13db68 0cb1b196 ThirdPartydriver!......
0b 0f13dbb4 0cb1b4e6 ThirdPartydriver!......
Dallo stack sopra riportato, possiamo capire come il driver di terze party, rinominato come ThirdPartydriver, ha eseguito internamente a Sql server una message box, motivo per cui, il thread non può proseguire l'attività.
Con buona probabilità, il driver di terze party ha eseguito una message box in seguito ad un problema interno o errore verificatosi, per cui per continuare l'analisi del problema sarà necessario contattare il produttore del driver.
Raffaella Canobbio
Support Escalation Engineer
Microsoft Enterprise SQL Support
Comment Notification
If you would like to receive an email when updates are made to this post, please register here
Subscribe to this post's comments using
Comment Policy: No HTML allowed. URIs and line breaks are converted automatically. Your e–mail address will not show up on any public page.