अवरुद्ध प्रक्रिया रिपोर्ट में खाली ब्लॉकिंग प्रक्रिया


28

मैं विस्तारित घटनाओं का उपयोग करके अवरुद्ध प्रक्रिया रिपोर्ट एकत्र कर रहा हूं, और कुछ रिपोर्ट में किसी कारण के लिए blocking-processनोड खाली है। यह पूर्ण xml है:

<blocked-process-report monitorLoop="383674">
 <blocked-process>
  <process id="processa7bd5b868" taskpriority="0" logused="106108620" waitresource="KEY: 6:72057613454278656 (8a2f7bc2cd41)" waittime="25343" ownerId="1051989016" transactionname="user_transaction" lasttranstarted="2017-03-20T09:30:38.657" XDES="0x21f382d9c8" lockMode="X" schedulerid="7" kpid="15316" status="suspended" spid="252" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-03-20T09:39:15.853" lastbatchcompleted="2017-03-20T09:39:15.850" lastattention="1900-01-01T00:00:00.850" clientapp="Microsoft Dynamics AX" hostname="***" hostpid="1348" loginname="***" isolationlevel="read committed (2)" xactid="1051989016" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
   <executionStack>
    <frame line="1" stmtstart="40" sqlhandle="0x02000000f7def225b0edaecd8744b453ce09bdcff9b291f50000000000000000000000000000000000000000" />
    <frame line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" />
   </executionStack>
   <inputbuf>
(@P1 bigint,@P2 int)DELETE FROM DIMENSIONFOCUSUNPROCESSEDTRANSACTIONS WHERE ((PARTITION=5637144576) AND ((FOCUSDIMENSIONHIERARCHY=@P1) AND (STATE=@P2)))   </inputbuf>
  </process>
 </blocked-process>
 <blocking-process>
  <process />
 </blocking-process>
</blocked-process-report>

सूचकांक के लिए सूचकांक की परिभाषा इस hobt_id की है

CREATE UNIQUE CLUSTERED INDEX [I_7402FOCUSDIMENSIONHIERARCHYIDX] ON [dbo].[DIMENSIONFOCUSUNPROCESSEDTRANSACTIONS]
(
    [PARTITION] ASC,
    [FOCUSDIMENSIONHIERARCHY] ASC,
    [STATE] ASC,
    [GENERALJOURNALENTRY] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

इसमें कोई विभाजन शामिल नहीं है, यह तालिका परिभाषा है:

CREATE TABLE [dbo].[DIMENSIONFOCUSUNPROCESSEDTRANSACTIONS](
    [FOCUSDIMENSIONHIERARCHY] [bigint] NOT NULL DEFAULT ((0)),
    [GENERALJOURNALENTRY] [bigint] NOT NULL DEFAULT ((0)),
    [STATE] [int] NOT NULL DEFAULT ((0)),
    [RECVERSION] [int] NOT NULL DEFAULT ((1)),
    [PARTITION] [bigint] NOT NULL DEFAULT ((5637144576.)),
    [RECID] [bigint] NOT NULL,
 CONSTRAINT [I_7402RECID] PRIMARY KEY NONCLUSTERED 
(
    [RECID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[DIMENSIONFOCUSUNPROCESSEDTRANSACTIONS]  WITH CHECK ADD CHECK  (([RECID]<>(0)))
GO

पूरे डेटाबेस में किसी भी टेबल पर कोई ट्रिगर या विदेशी कुंजी परिभाषित नहीं हैं।

सटीक SQL सर्वर बिल्ड है:

Microsoft SQL Server 2012 (SP3-CU4) (KB3165264) - 11.0.6540.0 (X64)
जून 23 2016 17:45:11 कॉपीराइट (c) Microsoft Corporation एंटरप्राइज़ संस्करण: Windows NT 6.3 के लिए कोर-आधारित लाइसेंसिंग (64-बिट) 14393 बनाएँ:) (हाइपरविजर)

विस्तारित घटनाएं काफी सरल हैं, बस अवरुद्ध प्रक्रिया रिपोर्ट लॉगिंग कर रहे हैं:

CREATE EVENT SESSION [Dynperf_Blocking_Data] ON SERVER 
ADD EVENT sqlserver.blocked_process_report(
    ACTION(package0.collect_system_time,sqlserver.client_hostname,sqlserver.context_info)),
ADD EVENT sqlserver.lock_escalation(
    ACTION(package0.collect_system_time,sqlserver.client_hostname,sqlserver.context_info)),
ADD EVENT sqlserver.xml_deadlock_report(
    ACTION(package0.collect_system_time,sqlserver.client_hostname,sqlserver.context_info)) 
ADD TARGET package0.event_file(SET filename=N'F:\SQLTrace\Dynamics_Blocking.xel',max_file_size=(100),max_rollover_files=(10))
WITH (MAX_MEMORY=32768 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=PER_NODE,TRACK_CAUSALITY=ON,STARTUP_STATE=ON)
GO

डेटाबेस पढ़ा हुआ स्नैपशॉट अलगाव में कॉन्फ़िगर किया गया है, और समानता की अधिकतम डिग्री 1 पर सेट है। यह सर्वर कॉन्फ़िगरेशन है:

+------------------------------------+-------+
|                name                | value |
+------------------------------------+-------+
| access check cache bucket count    |     0 |
| access check cache quota           |     0 |
| Ad Hoc Distributed Queries         |     0 |
| affinity I/O mask                  |     0 |
| affinity mask                      |     0 |
| affinity64 I/O mask                |     0 |
| affinity64 mask                    |     0 |
| Agent XPs                          |     1 |
| allow updates                      |     0 |
| backup compression default         |     1 |
| blocked process threshold (s)      |     2 |
| c2 audit mode                      |     0 |
| clr enabled                        |     0 |
| common criteria compliance enabled |     0 |
| contained database authentication  |     0 |
| cost threshold for parallelism     |     5 |
| cross db ownership chaining        |     0 |
| cursor threshold                   |    -1 |
| Database Mail XPs                  |     1 |
| default full-text language         |  1033 |
| default language                   |     0 |
| default trace enabled              |     1 |
| disallow results from triggers     |     0 |
| EKM provider enabled               |     0 |
| filestream access level            |     0 |
| fill factor (%)                    |     0 |
| ft crawl bandwidth (max)           |   100 |
| ft crawl bandwidth (min)           |     0 |
| ft notify bandwidth (max)          |   100 |
| ft notify bandwidth (min)          |     0 |
| index create memory (KB)           |     0 |
| in-doubt xact resolution           |     0 |
| lightweight pooling                |     0 |
| locks                              |     0 |
| max degree of parallelism          |     1 |
| max full-text crawl range          |     4 |
| max server memory (MB)             | 65536 |
| max text repl size (B)             | 65536 |
| max worker threads                 |     0 |
| media retention                    |     0 |
| min memory per query (KB)          |  1024 |
| min server memory (MB)             |     0 |
| nested triggers                    |     1 |
| network packet size (B)            |  4096 |
| Ole Automation Procedures          |     0 |
| open objects                       |     0 |
| optimize for ad hoc workloads      |     1 |
| PH timeout (s)                     |    60 |
| precompute rank                    |     0 |
| priority boost                     |     0 |
| query governor cost limit          |     0 |
| query wait (s)                     |    -1 |
| recovery interval (min)            |     0 |
| remote access                      |     1 |
| remote admin connections           |     0 |
| remote login timeout (s)           |    10 |
| remote proc trans                  |     0 |
| remote query timeout (s)           |   600 |
| Replication XPs                    |     0 |
| scan for startup procs             |     1 |
| server trigger recursion           |     1 |
| set working set size               |     0 |
| show advanced options              |     1 |
| SMO and DMO XPs                    |     1 |
| transform noise words              |     0 |
| two digit year cutoff              |  2049 |
| user connections                   |     0 |
| user options                       |     0 |
| xp_cmdshell                        |     0 |
+------------------------------------+-------+

मैंने थोड़ी देर के लिए सर्वर साइड ट्रेस चलाया और मुझे ट्रेस फ़ाइल में उतने ही खाली नोड्स मिले जितने मैं विस्तारित घटनाओं का उपयोग करते हैं।
इस ब्लॉक की गई रिपोर्ट को एक सर्वर साइड ट्रेस का उपयोग करके दूसरे सर्वर पर भी Dynamics AX चलाकर कैप्चर किया गया था, इसलिए यह इस सर्वर या बिल्ड के लिए विशिष्ट नहीं है।

<blocked-process-report monitorLoop="1327922">
 <blocked-process>
  <process id="processbd9839848" taskpriority="0" logused="1044668" waitresource="KEY: 5:72057597098328064 (1d7966fe609a)" waittime="316928" ownerId="3415555263" transactionname="user_transaction" lasttranstarted="2017-03-27T07:59:29.290" XDES="0x1c1c0c3b0" lockMode="U" schedulerid="3" kpid="25236" status="suspended" spid="165" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-03-27T07:59:47.873" lastbatchcompleted="2017-03-27T07:59:47.873" lastattention="2017-03-27T07:58:01.490" clientapp="Microsoft Dynamics AX" hostname="***" hostpid="11072" loginname="***" isolationlevel="read committed (2)" xactid="3415555263" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
   <executionStack>
    <frame line="1" stmtstart="236" stmtend="676" sqlhandle="0x020000004d6830193d42a167edd195c201f40bb772e9ece20000000000000000000000000000000000000000"/>
   </executionStack>
   <inputbuf>
(@P1 numeric(32,16),@P2 int,@P3 bigint,@P4 nvarchar(5),@P5 nvarchar(36),@P6 int,@P7 numeric(32,16),@P8 bigint,@P9 int)UPDATE PRODCALCTRANS SET REALCOSTAMOUNT=@P1,RECVERSION=@P2 WHERE (((((((PARTITION=@P3) AND (DATAAREAID=@P4)) AND (COLLECTREFPRODID=@P5)) AND (COLLECTREFLEVEL=@P6)) AND (LINENUM=@P7)) AND (RECID=@P8)) AND (RECVERSION=@P9))   </inputbuf>
  </process>
 </blocked-process>
 <blocking-process>
  <process/>
 </blocking-process>
</blocked-process-report>

क्या किसी के पास इन रिपोर्टों के लिए स्पष्टीकरण है? क्वेरी को क्या रोक रहा है?

क्या यह पता लगाने का कोई तरीका है कि अगर ताले लंबे समय तक चले जाने के बाद मैं रिपोर्ट देख रहा हूं तो क्या हो रहा है?

एक चीज जो जोड़ने के लिए उपयोगी हो सकती है, वह यह है कि इन प्रश्नों को चलाया जाता है sp_cursorprepareऔरsp_cursorexecute

अब तक मैं इसे पुन: पेश करने में सक्षम नहीं हुआ, ऐसा लगता है कि यादृच्छिक रूप से लेकिन बहुत बार होता है।

यह कई उदाहरणों (विभिन्न बिल्डों के) और कई तालिकाओं / प्रश्नों पर होता है, जो सभी Dynamics AX से संबंधित हैं।

उस समय पृष्ठभूमि में कोई अनुक्रमणिका या अन्य डेटाबेस रखरखाव कार्य नहीं होते हैं।

Srutzky द्वारा उत्तर में दिए गए कोड का उपयोग करके मैं इस अवरुद्ध प्रक्रिया रिपोर्ट से संबंधित कुछ लॉगिंग को कैप्चर करने में सक्षम था:

<blocked-process-report monitorLoop="1621637">
 <blocked-process>
  <process id="processd06909c28" taskpriority="0" logused="0" waitresource="KEY: 5:72057597585719296 (d2d87c26d920)" waittime="78785" ownerId="4436575948" transactionname="user_transaction" lasttranstarted="2017-04-13T07:39:17.590" XDES="0x3219d034e0" lockMode="U" schedulerid="3" kpid="133792" status="suspended" spid="106" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-04-13T07:39:17.657" lastbatchcompleted="2017-04-13T07:39:17.657" lastattention="1900-01-01T00:00:00.657" clientapp="Microsoft Dynamics AX" hostname="****" hostpid="11800" loginname="****" isolationlevel="read committed (2)" xactid="4436575948" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
   <executionStack>
    <frame line="1" stmtstart="72" stmtend="256" sqlhandle="0x0200000076a6a92ab1256af09321b056ab243f187342f9960000000000000000000000000000000000000000"/>
    <frame line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"/>
   </executionStack>
   <inputbuf>
(@P1 int,@P2 int,@P3 bigint,@P4 int)UPDATE PRODROUTEJOB SET JOBSTATUS=@P1,RECVERSION=@P2 WHERE ((RECID=@P3) AND (RECVERSION=@P4))   </inputbuf>
  </process>
 </blocked-process>
 <blocking-process>
  <process/>
 </blocking-process>
</blocked-process-report>

यह उस समय के आसपास समान संसाधन के लिए लॉगिंग टेबल में पाया जाता है: चरित्र की सीमा के कारण जिस्ट

आगे की जांच से पता चलता है कि खाली ब्लॉकिंग प्रक्रिया वाली रिपोर्ट के ठीक पहले और बाद में मेरे पास उसी रिसोर्सिड के लिए रिपोर्ट है जिसमें ब्लॉकिंग प्रक्रिया नोड्स हैं:

<blocked-process-report monitorLoop="1621636">
 <blocked-process>
  <process id="processd06909c28" taskpriority="0" logused="0" waitresource="KEY: 5:72057597585719296 (d2d87c26d920)" waittime="73765" ownerId="4436575948" transactionname="user_transaction" lasttranstarted="2017-04-13T07:39:17.590" XDES="0x3219d034e0" lockMode="U" schedulerid="3" kpid="133792" status="suspended" spid="106" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-04-13T07:39:17.657" lastbatchcompleted="2017-04-13T07:39:17.657" lastattention="1900-01-01T00:00:00.657" clientapp="Microsoft Dynamics AX" hostname="***" hostpid="11800" loginname="***" isolationlevel="read committed (2)" xactid="4436575948" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
   <executionStack>
    <frame line="1" stmtstart="72" stmtend="256" sqlhandle="0x0200000076a6a92ab1256af09321b056ab243f187342f9960000000000000000000000000000000000000000"/>
    <frame line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"/>
   </executionStack>
   <inputbuf>
(@P1 int,@P2 int,@P3 bigint,@P4 int)UPDATE PRODROUTEJOB SET JOBSTATUS=@P1,RECVERSION=@P2 WHERE ((RECID=@P3) AND (RECVERSION=@P4))   </inputbuf>
  </process>
 </blocked-process>
 <blocking-process>
  <process status="sleeping" spid="105" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2017-04-13T07:40:31.417" lastbatchcompleted="2017-04-13T07:40:31.423" lastattention="1900-01-01T00:00:00.423" clientapp="Microsoft Dynamics AX" hostname="**" hostpid="11800" loginname="**" isolationlevel="read committed (2)" xactid="4436165115" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
   <executionStack/>
   <inputbuf>
(@P1 bigint,@P2 nvarchar(5),@P3 bigint,@P4 bigint,@P5 nvarchar(11),@P6 int,@P7 nvarchar(21),@P8 datetime2)SELECT T1.REGDATETIME,T1.REGDATETIMETZID,T1.WORKERPILOT,T1.WORKER,T1.WRKCTRIDPILOT,T1.REGTYPE,T1.PROFILEDATE,T1.JOBID,T1.JOBIDABS,T1.MATCHRECIDSTARTSTOP,T1.JOBACTIVE,T1.RESNO,T1.STARTITEMS,T1.GOODITEMS,T1.SCRAPITEMS,T1.FINISHEDCODE,T1.TMPGOODITEMS,T1.TMPSCRAPITEMS,T1.SYSMRPUPDATEREQUEST,T1.ERROR,T1.ERRORTXT,T1.TMPSTARTITEMS,T1.AUTOSTAMP,T1.ERRORSPECIFICATION,T1.COSTCATEGORY,T1.ONCALLACTIVITY,T1.TERMINALID,T1.PDSCWGOODITEMS,T1.PDSCWSCRAPITEMS,T1.PDSCWSTARTITEMS,T1.RETAILTERMINALID,T1.MODIFIEDDATETIME,T1.RECVERSION,T1.PARTITION,T1.RECID FROM JMGTERMREG T1 WHERE (((PARTITION=@P1) AND (DATAAREAID=@P2)) AND (((((WORKER=@P3) OR ((WORKER=@P4) AND (WRKCTRIDPILOT=@P5))) AND (REGTYPE=@P6)) AND (JOBID=@P7)) AND (REGDATETIME&gt;=@P8))) ORDER BY T1.REGDATETIME   </inputbuf>
  </process>
 </blocking-process>
</blocked-process-report>

Srutzky द्वारा प्रदान की गई नई स्क्रिप्ट का उपयोग करके नए डेटा एकत्र किए गए हैं। यह पोस्ट की अधिकतम लंबाई के कारण गिथब पर पोस्ट किया गया है

चूंकि मूल रूप से पोस्ट किए गए डेटा में दोनों सत्र आईडी नहीं है इसलिए कुछ नए डेटा को फिर से जीथब पर पोस्ट किया गया है

नए डेटा सहित जीथब पर कनेक्शन

जवाबों:


6

मैं फिलहाल इस सिद्धांत का परीक्षण नहीं कर सकता, लेकिन GitHub पर पोस्ट किए गए सबसे हाल ही के कैप्चर किए गए डेटा के आधार पर , मैं कहूंगा कि आपका <process>नोड खाली होने का कारण यह है कि इसके लिए वर्तमान में चल रहे अनुरोध की आवश्यकता है (कई विशेषताएँ इसमें पाई गई हैं sys.dm_exec_requestsऔर नहीं में sys.dm_exec_sessions) और वर्तमान में चल रहे अनुरोध के बिना, यह किसी भी विवरण को रिपोर्ट नहीं कर सकता है कि कैसे एक INNER JOINबीच में कर रहा है sys.dm_exec_requestsऔर sys.dm_exec_sessionsउन पंक्तियों को बाहर कर देगा जहां एक सत्र सक्रिय है, लेकिन बिना किसी वर्तमान अनुरोध के कारण निष्क्रिय है।

डेटा के शीर्ष सेट को देखते हुए ( monitorLoopमान: 1748823, 1748824, 1748825, और 1748827) हम निम्नलिखित देख सकते हैं:

  • idके blocked-processप्रत्येक मामले में एक ही है: process2552c1fc28 , और केवल विशेषता है कि अलग है waittime(जाहिर है)।
  • blocking-processनोड्स की विशेषताएं दोनों lastbatchstartedऔर में अंतर दिखाती हैंlastbatchcompleted
  • blocking-processनोड्स की विशेषताएं इसके लिए समान मान दिखाती हैं spidऔरxactid

तो, ब्लॉकिंग प्रक्रिया का सत्र और लेन-देन 4 अलग-अलग क्वेरी बैचों में समान कैसे हो सकता है? आसान, एक स्पष्ट लेनदेन शुरू किया गया था और फिर इन बैचों को निष्पादित किया गया था। और क्योंकि ये अलग-अलग बैच हैं, उनके बीच समय दिया जा रहा है, जिस बिंदु पर कोई वर्तमान अनुरोध नहीं है, इसलिए दिखाने के लिए कोई प्रक्रिया जानकारी नहीं है (लेकिन सत्र और लेनदेन अभी भी हैं)।

आदेश में इस में अतिरिक्त अनुसंधान करने के लिए है, तो आप से उपयोगी जानकारी पर कब्जा कर सकते हैं sys.dm_exec_requestsऔर sys.dm_tran_locksएक एसक्यूएल सर्वर एजेंट "लेन-देन-SQL स्क्रिप्ट (T-SQL)" नौकरी चरण में निम्नलिखित T-SQL रखकर, "डेटाबेस" होने के लिए की स्थापना आप जिस पर शोध कर रहे हैं (इस मामले में वह 6 की आईडी वाला है), और इस कार्य को हर 10 सेकंड में चलाने के लिए शेड्यूल कर रहा है। नीचे दी गई टी-एसक्यूएल उसी डीबी में दो तालिकाओं का निर्माण करेगी यदि वे मौजूद नहीं हैं और फिर "अनुरोध" तालिका को पॉपुलेट करेंगे यदि कोई अनुरोध या तो खुद को अवरुद्ध कर रहा है, या यदि वह डिलीट या अपडेट ऑपरेशन है जिसे अवरुद्ध किया जा रहा है । यदि कोई अनुरोध पाया जाता है, तो वह पकड़ने की कोशिश करेगा:

  • अवरुद्ध प्रक्रिया पर सत्र और अनुरोध की जानकारी (यह हिस्सा यह नहीं मानता है कि एक सक्रिय अनुरोध है, इसलिए RIGHT JOINकम से कम सत्र निर्देश प्राप्त करें)
  • अवरुद्ध और (उम्मीद है) अवरुद्ध प्रक्रियाओं के लिए कनेक्शन जानकारी।
  • उन समान सत्र_ के लिए वर्तमान ताले (बस ध्यान रखें कि लॉक जानकारी 100% सटीक होने की गारंटी नहीं है क्योंकि यह जानकारी उन दो बयानों को निष्पादित करने के बीच के समय में बदल सकती है; फिर भी, जानकारी पर्याप्त रूप से पर्याप्त है। मूल्य पर कब्जा करना)। वर्तमान में इस अनुभाग में टिप्पणी की गई है।

SQL सर्वर एजेंट T-SQL कार्य चरण:

-- !! Remember to set the "Database" for the T-SQL Job Step to
--    the DB that has database_id = 6 !!
SET NOCOUNT ON;
IF (OBJECT_ID(N'dbo.tmpBlockingResearch_Requests') IS NULL)
BEGIN
  -- Create requests capture table
  SELECT SYSDATETIME() AS [CaptureTime], req.*,
         ses.login_time, ses.[host_name], ses.[program_name], ses.host_process_id,
         ses.client_version, ses.client_interface_name, ses.security_id,
         ses.login_name, ses.nt_domain, ses.nt_user_name, ses.memory_usage,
         ses.total_scheduled_time, ses.endpoint_id, ses.last_request_start_time,
         ses.last_request_end_time, ses.is_user_process, ses.original_security_id,
         ses.original_login_name, ses.last_successful_logon, ses.last_unsuccessful_logon,
         ses.unsuccessful_logons, ses.authenticating_database_id
  INTO   dbo.tmpBlockingResearch_Requests
  FROM   sys.dm_exec_requests req
  INNER JOIN sys.dm_exec_sessions ses
          ON ses.[session_id] = req.[session_id]
  WHERE  1 = 0;
END;

IF (OBJECT_ID(N'dbo.tmpBlockingResearch_Connections') IS NULL)
BEGIN
  -- Create connections capture table
  SELECT SYSDATETIME() AS [CaptureTime], con.*
  INTO   dbo.tmpBlockingResearch_Connections
  FROM   sys.dm_exec_connections con
  WHERE  1 = 0;
END;

IF (OBJECT_ID(N'dbo.tmpBlockingResearch_Locks') IS NULL)
BEGIN
  -- Create locks capture table
  SELECT SYSDATETIME() AS [CaptureTime], loc.*
  INTO   dbo.tmpBlockingResearch_Locks
  FROM   sys.dm_tran_locks loc
  WHERE  1 = 0;
END;
---------------------------------
DECLARE @SessionIDs TABLE (SessionID SMALLINT NOT NULL,
                           BlockingSessionID SMALLINT NOT NULL);

INSERT INTO dbo.tmpBlockingResearch_Requests
OUTPUT inserted.[session_id], inserted.[blocking_session_id]
INTO   @SessionIDs ([SessionID], [BlockingSessionID])
  SELECT SYSDATETIME() AS [CaptureTime], req.*,
         ses.login_time, ses.[host_name], ses.[program_name], ses.host_process_id,
         ses.client_version, ses.client_interface_name, ses.security_id,
         ses.login_name, ses.nt_domain, ses.nt_user_name, ses.memory_usage,
         ses.total_scheduled_time, ses.endpoint_id, ses.last_request_start_time,
         ses.last_request_end_time, ses.is_user_process, ses.original_security_id,
         ses.original_login_name, ses.last_successful_logon, ses.last_unsuccessful_logon,
         ses.unsuccessful_logons, ses.authenticating_database_id
  FROM   sys.dm_exec_requests req
  INNER JOIN sys.dm_exec_sessions ses
          ON ses.[session_id] = req.[session_id]
  WHERE ses.[is_user_process] = 1
  AND   req.[database_id] = DB_ID()
  AND   (
          req.blocking_session_id IN (req.[session_id], -2, -3, -4)
    OR   (req.[command] IN (N'DELETE', N'UPDATE') AND req.[blocking_session_id] > 0)
        );

-- Get at least session info, if not also request info, on blocking process
INSERT INTO dbo.tmpBlockingResearch_Requests
  SELECT SYSDATETIME() AS [CaptureTime], req.*,
         ses.login_time, ses.[host_name], ses.[program_name], ses.host_process_id,
         ses.client_version, ses.client_interface_name, ses.security_id,
         ses.login_name, ses.nt_domain, ses.nt_user_name, ses.memory_usage,
         ses.total_scheduled_time, ses.endpoint_id, ses.last_request_start_time,
         ses.last_request_end_time, ses.is_user_process, ses.original_security_id,
         ses.original_login_name, ses.last_successful_logon, ses.last_unsuccessful_logon,
         ses.unsuccessful_logons, ses.authenticating_database_id
  FROM   sys.dm_exec_requests req
  RIGHT JOIN sys.dm_exec_sessions ses
          ON ses.[session_id] = req.[session_id]
  WHERE ses.[session_id] IN (SELECT DISTINCT [BlockingSessionID] FROM @SessionIDs);

-- If any rows are captured this time, try to capture their connection info
INSERT INTO dbo.tmpBlockingResearch_Connections
  SELECT SYSDATETIME() AS [CaptureTime], con.*
  FROM   sys.dm_exec_connections con
  WHERE  con.[session_id] IN (
                              SELECT [SessionID]
                              FROM @SessionIDs
                              UNION -- No "ALL" so it does DISTINCT
                              SELECT [BlockingSessionID]
                              FROM @SessionIDs
                             );

/*
-- If any rows are captured this time, try to capture their lock info
INSERT INTO dbo.tmpBlockingResearch_Locks
  SELECT SYSDATETIME() AS [CaptureTime], loc.*
  FROM   sys.dm_tran_locks loc
  WHERE  loc.[request_session_id] IN (
                                      SELECT [SessionID]
                                      FROM @SessionIDs
                                      UNION -- No "ALL" so it does DISTINCT
                                      SELECT [BlockingSessionID]
                                      FROM @SessionIDs
                                     );
 */

मुझे लगता है कि आपको एक क्वेरी टैब खोलने और निम्नलिखित को निष्पादित करने में सक्षम होना चाहिए:

CREATE TABLE dbo.tmp (Col1 INT);
BEGIN TRAN;
INSERT INTO dbo.tmp (Col1) VALUES (1);

फिर, एक दूसरा क्वेरी टैब खोलें और निम्नलिखित पर अमल करें:

UPDATE dbo.tmp
SET    Col1 = 2
WHERE  Col1 = 1;

PS बस यह कहा गया है, केवल एक चीज जो समझ में नहीं आती है वह यह है कि अनुरोध और सत्र की जानकारी - dbo.tmpBlockingResearch_Requests- अभी भी अवरुद्ध सत्र के लिए पंक्तियों में कभी भी शामिल नहीं है। फिर भी मुझे पता है कि टेबल वेरिएबल में ब्लॉकिंग सेशन आईडी है, क्योंकि इसने दोनों सत्रों के लिए ताले में खींच लिया था। यह उस परिदृश्य की ओर इशारा कर सकता है जिसमें ग्राहक से "कनेक्शन" बंद होने के बाद लेन-देन को खुला रहने दिया जाता है, लेकिन कनेक्शन पूलिंग के कारण कनेक्शन अभी भी बना हुआ है।


@TomV मैंने नवीनतम अनुसंधान डेटा की समीक्षा की है और एक बहुत ठोस सिद्धांत है। मैंने अपने उत्तर को अपने शोध प्रश्नों में शामिल करने के साथ ही अपने उत्तर को भी अपडेट कर दिया है, इसलिए कृपया जॉब स्टेप SQL को यहां नए प्रश्नों के साथ बदलें (मैंने "लॉक" क्वेरी को भी टिप्पणी की थी क्योंकि हमें अभी उस डेटा की आवश्यकता नहीं है और यह बहुत सारा डेटा है)। मैं सुझाव देता हूं कि खरोंच से शुरू करने के लिए मौजूदा शोध तालिकाओं को काट / गिराया जाए।
सोलोमन रटज़की

@TomV ठीक है। और मैंने अपनी रीप्रो क्वेरी को अपडेट के बजाय एक अद्यतन के रूप में अद्यतन करने के लिए अपडेट किया है, इसलिए इसे आपकी स्थिति का और अधिक प्रतिनिधि होना चाहिए। मैंने अनुरोध तालिका में लापता पंक्तियों के बारे में अंत में एक नोट भी जोड़ा। उम्मीद है कि नई कनेक्शन तालिका कम से कम अवरुद्ध सत्र के निरंतर अस्तित्व की पुष्टि करेगी। (पीएस, मैंने ऊपर अपनी टिप्पणियों को साफ करना शुरू कर दिया)।
सोलोमन रटज़की

आपकी नौकरी सक्रिय है। मुझे रेप्रो का परीक्षण करने और अगले सप्ताह इसका विश्लेषण करने के लिए कुछ समय खोजने की आवश्यकता होगी
टॉम वी - टीम मोनिका

हाय सोलोमन। जीथब पर 2 नए उदाहरण पोस्ट किए गए हैं। दुर्भाग्य से मैं प्रदान किए गए रेप्रो केस का उपयोग करके एक खाली अवरोधक प्रक्रिया BPR को ट्रिगर नहीं कर सका।
टॉम वी - टीम मोनिका

बहुत जल्दी देखो, क्योंकि मेरे पास ज्यादा समय नहीं है। ऐसा लगता है कि कनेक्शन जानकारी ब्लॉकिंग सत्र आईडी को अभी भी सक्रिय दिखाती है लेकिन यह सत्र तालिका में नहीं है। मैं बाद में इसका परीक्षण कर सकता हूं, लेकिन मुझे पूरा यकीन है कि कनेक्शन पूलिंग (कनेक्शन अभी भी है) को इंगित करता है और कनेक्शन अभी तक आदेशों के बीच बंद हो रहा है लेकिन एक लेनदेन स्पष्ट रूप से खुला है (चूंकि लेन-देन_id हमेशा वैसा ही होता है जैसा हमने पिछली बार देखा था)। बाद में करीब से देखेंगे।
सोलोमन रटज़की

4

ब्लॉक किए गए लेनदेन लॉक एस्केलेशन के कारण हो सकते हैं।

यह Microsoft समर्थन आलेख में समझाया गया है:

SQL सर्वर में लॉक एस्केलेशन के कारण अवरुद्ध समस्याओं को कैसे हल करें

...
लॉक एस्केलेशन सबसे अवरुद्ध समस्याओं का कारण नहीं बनता है। यह निर्धारित करने के लिए कि क्या लॉक एस्केलेशन उस समय के आसपास हो रहा है जब आप अवरुद्ध समस्याओं का अनुभव करते हैं, एक SQL Profiler ट्रेस शुरू करें जिसमें लॉक: एस्केलेशन ईवेंट शामिल हो। यदि आपको कोई लॉक नहीं दिखता है: एस्केलेशन ईवेंट्स, लॉक एस्केलेशन आपके सर्वर पर नहीं हो रहा है और इस आलेख में जानकारी आपकी स्थिति पर लागू नहीं होती है।

यदि लॉक एस्केलेशन हो रहा है, तो सत्यापित करें कि एस्केलेटेड टेबल लॉक अन्य उपयोगकर्ताओं को अवरुद्ध कर रहा है
...

अवरोधित प्रक्रिया इवेंट से पहले हुई लॉक एस्केलेशन ईवेंट के लिए विस्तारित ईवेंट (भौतिक फ़ाइल) की जाँच करें ।

की व्याख्या

एक Microsoft ब्लॉग आलेख है जो आगे विस्तार में जाता है:

SQL सर्वर लॉक एस्केलेशन और ब्लॉकिंग

...
चरण 2: ताला वृद्धि और अवरुद्ध प्रक्रिया रिपोर्ट घटनाक्रम लीजिए।

लॉक एस्केलेशन और ब्लॉक की गई प्रक्रिया रिपोर्ट ईवेंट्स स्वचालित रूप से SQL सर्वर द्वारा कैप्चर नहीं किए जाते हैं। यह जानने के लिए कि क्या ये घटनाएँ हो रही हैं, हमें उन्हें रिकॉर्ड करने के लिए SQL सर्वर को बताने की आवश्यकता है। हमारी टीम उस जानकारी को इकट्ठा करने के लिए Microsoft डायनेमिक्स टूल के लिए प्रदर्शन विश्लेषक का उपयोग करती है। रॉड हेनन द्वारा टूल पर अधिक जानकारी और इसके साथ अवरुद्ध विवरण एकत्र करने का तरीका जानने के लिए इस पोस्ट को देखें। यदि आप SQL सर्वर प्रोफाइलर का उपयोग करना चाहते हैं, तो आपको जिन घटनाओं को एकत्र करने की आवश्यकता होगी, उन्हें नीचे दिखाया गया है: ...

यदि आपने लॉक एस्केलेशन और अवरुद्ध प्रक्रियाओं पर कब्जा कर लिया है, तो आपको यह निर्धारित करना होगा कि क्या लॉक एस्केलेशन अवरुद्ध प्रक्रियाओं का मूल कारण हैं:

...
चरण 3: SQL सर्वर प्रोफाइलर में ट्रेस की समीक्षा करें।

दो मुख्य संकेतक हैं जो आपको बताएंगे कि क्या ब्लॉक लॉक एस्केलेशन से संबंधित है।

सबसे पहले, आप अवरुद्ध प्रक्रिया रिपोर्ट घटनाओं के तुरंत पहले ताला वृद्धि घटनाओं की एक श्रृंखला देखते हैं। नीचे Microsoft Dynamics उपकरण के लिए प्रदर्शन विश्लेषक द्वारा निर्मित ट्रेस से लिया गया एक उदाहरण है। ट्रेस में देखने के लिए यह एक बात है, लेकिन इसका मतलब यह नहीं है कि लॉक एस्केलेशन अवरुद्ध होने का कारण है। ...

और आगे

यह सत्यापित करने के लिए कि ब्लॉकिंग वास्तव में लॉक एस्केलेशन से संबंधित है, आपको अवरुद्ध प्रक्रिया रिपोर्ट विवरण को देखने की आवश्यकता है। TextData सेक्शन में Waitresource की तलाश करें (नीचे स्क्रीनशॉट देखें)। अगर वेट्रेस सोर्स OBJECT से शुरू होता है, तो हमें पता है कि ब्लॉक किए गए स्टेटमेंट को आगे बढ़ने से पहले टेबल लेवल लॉक पर इंतज़ार किया जा सकता है। अगर वेट्रेस सोर्स OBJECT के बजाय KEY या PAG से शुरू होता है , तो उस विशिष्ट ब्लॉक में लॉक एस्केलेशन शामिल नहीं है । लॉक एस्केलेशन हमेशा एक लॉक के दायरे को OJBECT तक बढ़ा देगा जहां यह शुरू होता है

समाधान

(केवल उपर्युक्त मिलानों के अनुसार)

समाधान जाहिरा तौर पर ट्रेस ध्वज 1224 को चालू करने के लिए है जो ताला वृद्धि को बंद कर देगा:

SQL सर्वर लॉक एस्केलेशन और ब्लॉकिंग

यदि आप इन दोनों चीजों को एक साथ देखते हैं, तो यह एक बहुत अच्छी शर्त है कि ताला बढ़ने से अवरोध पैदा हो रहा है और आप शायद SQL Server ट्रेस ध्वज 1224 को लागू करने से लाभान्वित होंगे।

डायनेमिक्स AX के लिए SQL सर्वर ट्रेस फ्लैग्स

ट्रेस ध्वज 1224 ताले की संख्या के आधार पर लॉक एस्केलेशन को अक्षम करता है। इस ट्रेस ध्वज को सक्षम करने से लॉक एस्केलेशन के कारण अवरुद्ध होने की संभावना को कम किया जा सकता है- कुछ मैंने एक्सएक्स कार्यान्वयन की संख्या के साथ देखा है। सबसे आम परिदृश्य जहां यह एक मुद्दा बन जाता है जब दिन के दौरान चलने के लिए मास्टर प्लानिंग की आवश्यकता होती है

उत्तर

अंत में यह हो सकता है कि लॉक एस्केलेशन अवरुद्ध प्रक्रियाओं का मूल कारण है।


वैकल्पिक समाधान (प्रक्रिया नोड खाली)

कुछ अवरुद्ध_प्रणाली की आगे की जांच के बाद निम्नलिखित वैकल्पिक स्पष्टीकरण किया जा सकता है।

विस्तारित ईवेंट्स अवरुद्ध_प्रकार_प्रतिस्पर्धी कैप्चर कर रहे हैं जो उस समय किसी भी अन्य प्रक्रियाओं से संबंधित नहीं हैं।

एर्गो: उन्हें एक अलग कारण से अवरुद्ध किया जाना चाहिए

मेरा सुझाव है कि आप अपने SQL सर्वर पर sysinos_os_wait_stats दृश्य से प्रतीक्षा प्रकारों की समय सीमा पर कब्जा कर सकते हैं और अपने माप के दौरान हो रही ब्लॉक्ड_प्रोसेसर_पोर्ट्स के साथ संख्याओं को सहसंबंधित करेंगे। पॉल रान्डेल के पास एक अच्छी स्क्रिप्ट है: मुझे अपने प्रतीक्षा आँकड़े भेजें और मेरी सलाह लें और बदले में 30 दिनों की मुफ्त प्लुरलिटी प्राप्त करें

स्क्रिप्ट वर्तमान काउंटरों को कैप्चर करती है, 23hours की प्रतीक्षा करती है (संशोधित की जा सकती है), वर्तमान काउंटरों को फिर से हटा देती है और आपको शीर्ष 95% प्रतीक्षा प्रकार देने के लिए उनकी तुलना करती है। आप इसे 1 घंटे के लिए कह सकते हैं और XEL फ़ाइल को संभाल सकते हैं।

आपको एक प्रतीक्षा प्रकार (जैसे LCK_M_SH,…) मिल सकता है जो आपको बता रहा है कि लेखन में आपका भंडारण धीमा है। या आपके पास कुछ अन्य ओवरहेड (जैसे CX_PACKET_WAITS,…।) है। कुछ आपके अपडेट को धीमा कर रहा है। फिर आप देख सकते हैं कि क्या sysinos_os_wait_stats खाली नोड्स के साथ अवरुद्ध_प्रोसेसर_सपोर्ट्स से संबंधित है।

ऐसे मामले हैं जब एक अवरुद्ध SPID को उसी SPID द्वारा अवरुद्ध किया जा रहा है:

आप SQL Server 2000 SP4 को स्थापित करने के बाद latch प्रतीक्षा के लिए sysprocesses तालिका में अवरुद्ध स्तंभ आबाद है

जब एक SPID I / O पृष्ठ कुंडी के लिए प्रतीक्षा कर रहा है, तो आप देख सकते हैं कि अवरुद्ध स्तंभ संक्षेप में रिपोर्ट करता है कि SPID स्वयं को अवरुद्ध कर रहा है। यह व्यवहार उस तरीके का एक साइड इफेक्ट है, जो डेटा पेजों पर I / O संचालन के लिए उपयोग किया जाता है। जब कोई थ्रेड I / O अनुरोध जारी करता है, तो I / O अनुरोध जारी करने वाला SPID पृष्ठ पर एक कुंडी प्राप्त करता है। सभी SQL Server 2000 I / O ऑपरेशन अतुल्यकालिक हैं। इसलिए, यदि SPID ने I / O अनुरोध जारी किया है, तो SPID उसी पृष्ठ पर एक और कुंडी लगाने का प्रयास करेगा, जिसे समाप्त करने के लिए अनुरोध का इंतजार करना होगा। यह दूसरी कुंडी पहले कुंडी द्वारा अवरुद्ध है। इसलिए, अवरुद्ध स्तंभ रिपोर्ट करता है कि SPID खुद को अवरुद्ध कर रहा है। जब I / O अनुरोध पूरा हो जाता है, तो पहली कुंडी जारी की जाती है। फिर, दूसरा कुंडी अनुरोध प्रदान किया जाता है।

वैकल्पिक उत्तर

यह एक और संकेत है कि आप IO मुद्दे हो सकते हैं। इन मुद्दों के परिणामस्वरूप "अवरुद्ध प्रक्रियाएं" होती हैं, लेकिन संबंधित विदेशी एसपीआईडी ​​के बिना। विस्तारित ईवेंट अलग नोड में प्रक्रिया / SPID की रिपोर्ट नहीं कर सकते हैं।


मैं इसे गलत ठहरा सकता हूं, लेकिन क्या यह जानकारी साबित नहीं करती है कि मुद्दा लॉक एस्केलेशन नहीं है ? एक उद्धृत खंड कहता है "look at the blocked process report details.", और प्रश्न में सबसे ऊपर का XML अवरुद्ध प्रक्रिया रिपोर्ट है। अगला, वही उद्धृत अनुभाग कहता है "If waitresource starts with KEY or PAG instead of OBJECT, then lock escalation isn’t involved in that specific block.", और अवरुद्ध-प्रक्रिया-रिपोर्ट XML दिखाता है waitresource="KEY: 6:72057....। तो इसका मतलब है कि "लॉक एस्केलेशन शामिल नहीं है"।
सोलोमन रटज़की

नहीं, आप इसे गलत नहीं समझ रहे हैं। प्रश्न में प्रदान किया गया अनुभाग इस सर्वर पर एक समस्या है। मेरा जवाब उन मुद्दों के लिए एक वैश्विक दृष्टिकोण है जो अवरुद्ध और ताला वृद्धि के कारण हो सकता है। यदि आप कुछ प्रमुख मुद्दों (OBJECT लेवल लॉकिंग के लिए block_process_reports) को ठीक कर सकते हैं, तो छोटे मुद्दे (अन्य स्तरों पर block_process_reports) स्वयं को हल कर सकते हैं। यही कारण है कि मैंने एक दूसरा वैकल्पिक उत्तर भी जोड़ा है।
जॉन उर्फ ​​हॉट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.