Engellenen işlem raporunda boş engelleme işlemi


28

Extended Events kullanarak engellenmiş işlem raporları topluyorum ve bazı nedenlerden dolayı blocking-processdüğüm boş. Bu tam 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>

Bu hobt_id öğesinin ait olduğu dizin için dizin tanımı

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

Dahil olan hiçbir bölüm yok, bu tablo tanımıdır:

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

Veritabanının tamamındaki tabloların hiçbirinde tanımlanmış hiçbir tetikleyici veya yabancı anahtar yoktur.

Tam SQL Server derlemesi:

Microsoft SQL Server 2012 (SP3-CU4) (KB3165264) - 11.0.6540.0 (X64)
Haz 23 2016 17:45:11 Telif Hakkı (c) Microsoft Corporation Enterprise Edition: Windows NT 6.3’de Çekirdek Tabanlı Lisanslama (64 bit) (6.3 Yapı 14393:) (Hiper Yönetici)

Genişletilmiş olaylar, sadece engellenen işlem raporlarını günlüğe kaydetmek için oldukça basittir:

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

Veritabanı Okuma Taahhütlü Anlık İzolasyonunda yapılandırılmıştır ve maksimum paralellik derecesi 1 olarak ayarlanmıştır. Bu, sunucu yapılandırmasıdır:

+------------------------------------+-------+
|                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 |
+------------------------------------+-------+

Bir süre sunucu tarafı izlemesi çalıştırdım ve genişletilmiş olayları kullandığım gibi aynı boş düğümleri bir izleme dosyasında alıyorum.
Bu engellenen işlem raporu, Dynamics AX çalıştıran başka bir sunucuda sunucu tarafı izlemesi kullanılarak yakalandı, bu nedenle bu sunucuya veya yapıya özgü değil.

<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>

Bu raporlar için bir açıklaması olan var mı? Sorguyu engelleyen nedir?

Kilitler çok geçtikten sonra raporlara bakarsam ne olduğunu öğrenmenin bir yolu var mı?

Eklenmesi faydalı olabilecek bir şey, bu sorguların sp_cursorpreparevesp_cursorexecute

Şimdiye kadar onu yeniden üretemedim, rastgele ama çok sık oluyor gibi görünüyor.

Hepsi Dynamics AX ile ilgili birkaç durumda (farklı yapılarda) ve birkaç tablo / sorguda gerçekleşir.

O sırada arka planda meydana gelen herhangi bir dizin veya başka veritabanı bakım işi yoktur.

Cevapta srutzky tarafından verilen kodu kullanarak, bu engellenen süreç raporuyla ilgili bir miktar kayıt tutmayı başardım:

<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>

Bu, o zaman zarfında aynı kaynağın günlüğe kaydetme tablolarında bulunur: Karakter sınırı nedeniyle Gist

Diğer araştırmalar, rapordan hemen önce ve sonra boş bir engelleme işlemine sahip olduğumu ve aynı işlem için engelleme işlemi düğümlerine sahip olan raporları bulunduğunu gösteriyor:

<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 tarafından sağlanan yeni senaryo kullanılarak yeni veriler toplanmıştır. Maksimum direk uzunluğu nedeniyle github'a gönderilir .

Başlangıçta gönderilen veriler her ikisinde de oturum kimliğine sahip olmadığından, bazı yeni veriler tekrar github'da yayınlandı .

Github üzerindeki bağlantılar dahil olmak üzere yeni veriler

Yanıtlar:


6

Şu anda bu teoriyi test edemiyorum, ancak GitHub'a gönderilen en son yakalama verilerine dayanarak, size <process>düğümün boş olmasının sebebinin o anda çalışan bir istek gerektirdiğini söyleyebilirim (özniteliklerin çoğunda bulunur. sys.dm_exec_requestsdeğil de sys.dm_exec_sessions) ve bir anda çalışan isteği olmadan, nasıl bir yapıyor benzer, hiçbir ayrıntıyı rapor edemez INNER JOINarasında sys.dm_exec_requestsve sys.dm_exec_sessionsbir Oturum aktiftir ama hiçbir geçerli isteği nedeniyle boşta olduğu satırlarını dışarıda bırakır.

En üstteki veri kümesine bakarak ( monitorLoopdeğerler: 1748823, 1748824, 1748825 ve 1748827) aşağıdakileri görebiliriz:

  • idarasında blocked-process, her durumda aynı: process2552c1fc28 ve farklı tek özniteliktir waittime(anlaşılır).
  • nitelikleri blocking-processdüğümler hem farklılığını gösterir lastbatchstartedvelastbatchcompleted
  • nitelikleri blocking-processdüğümler göstermektedir için aynı değer spidvexactid

Öyleyse, engelleme işleminin Oturum Kimliği ve İşlem Kimliği, 4 farklı sorgu grubunda nasıl aynı olabilir? Kolay, açık bir işlem başlatıldı ve ardından bu partiler gerçekleştirildi. Bunlar ayrı partiler olduğundan, gönderilmeleri arasında zaman vardır, bu noktada mevcut bir istek yoktur, dolayısıyla gösterilecek işlem bilgisi yoktur (ancak oturum ve işlem hala oradadır).

Bu ek araştırma yapmak için, yararlı bilgiler yakalayabilir sys.dm_exec_requestsve sys.dm_tran_locks"Veritabanı" olarak ayarlayarak, bir SQL Server Agent "İşlem-SQL komut dosyası (T-SQL)" İş Adım aşağıdaki T-SQL yerleştirerek araştıracağınız bir kişi (bu durumda 6 kimliği olan kişi) ve bu işi her 10 saniyede bir çalıştırması için zamanlama. Aşağıdaki T-SQL, mevcut değilse aynı DB'de iki tablo oluşturacak ve herhangi bir istek kendini engelliyorsa veya engellenen bir Silme veya Güncelleme işlemi ise, "İstekler" tablosunu dolduracak . Herhangi bir istek bulunursa, şunları yakalamaya çalışır:

  • Engelleme sürecindeki Oturum ve İstek bilgileri (bu bölüm etkin bir İsteğin olduğunu varsaymaz, bu nedenle RIGHT JOINen azından Oturum bilgisini almak)
  • Engellenen ve (umarım) engelleme işlemleri için bağlantı bilgisi.
  • aynı oturum_kimliği için geçerli kilitler (yalnızca bu kilit bilginin yürütülmekte olan bu iki ifade arasındaki zaman içinde değişebileceğinden% 100 kesin olarak garanti edilmediğini aklınızda bulundurun ; yakalamaya değer). Bu bölüm şu anda yorumlanmıştır.

SQL Server Ajan T-SQL İş Adımı:

-- !! 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
                                     );
 */

Bir sorgu sekmesi açıp aşağıdakileri çalıştırarak bunu yeniden üretebilmeniz gerektiğini düşünüyorum:

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

Ardından, ikinci bir sorgu sekmesi açın ve aşağıdakileri yürütün:

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

PS Sadece belirtmek gerekirse, mantıklı olmayan tek şey, istek ve oturum bilgilerinin - dbo.tmpBlockingResearch_Requests- hala engelleme oturumu için hiçbir zaman satır içermemesidir . Yine de, tablo değişkeninin, her iki SessionID için kilitleri çektiği için engelleyici oturum kimliğine sahip olduğunu biliyorum. Bu, Müşteriden gelen "bağlantı" kapatıldıktan sonra İşlemin açık kalmasına izin verilen, ancak Bağlantı Havuzu Oluşturma nedeniyle bağlantının devam ettiği bir senaryoya işaret edebilir.


@TomV En yeni araştırma verilerini gözden geçirdim ve oldukça sağlam bir teoriye sahibim. Araştırma sorgularıma bir bölüm eklemek de dahil olmak üzere cevabımı güncellediğim için, lütfen iş adımım SQL'i yeni sorgularla değiştirin. çok fazla veri var). Sıfırdan başlamak için mevcut araştırma tablolarını kesmeyi / bırakmayı öneriyorum.
Solomon Rutzky

@TomV Tamam. Üstelik repro sorgumu SELECT yerine UPDATE olarak değiştirdim, böylece durumunuzu zaten daha iyi temsil etmeli. Ayrıca istek tablosundaki eksik satırlar hakkında bir not ekledim. Umarım yeni Connections tablosu, en azından engelleyen SessionID öğesinin devam ettiğini doğrular. (PS, yukarıdaki yorumlarımı temizlemeye başladım).
Solomon Rutzky,

İşin aktif. Reproyu test etmek ve gelecek hafta analiz etmek için biraz zamana ihtiyacım olacak
Tom V - Team Monica

Selam Solomon. Github'a 2 yeni örnek gönderildi. Ne yazık ki, sağlanan repro durumunu kullanarak boş bir engelleme işlemi BPR tetikleyemedim.
Tom V - Team Monica

Çok fazla zamanım olmadığı için çok hızlı bir görünüm aldı. Bağlantılar bilgisi engelleme oturumu kimliğinin hala etkin olduğunu gösteriyor ancak oturumlar tablosunda yok gibi görünüyor. Bunu daha sonra test edebilirim, ancak bağlantının havuzlandığını (bağlantı hala orada) ve komutlar arasında bağlantının kapalı olduğunu ancak bir işlemin açıkça açık olduğundan eminim (işlem_kimliği her zaman en son gördüğümüzle aynı olduğundan). Sonra daha yakından bakacağım ..
Solomon Rutzky

4

Engellenen işlemler kilit yükseltme nedeniyle ortaya çıkabilir.

Bu, Microsoft Destek makalesinde açıklanmıştır:

SQL Server'da kilit yükseltme nedeniyle oluşan engelleme sorunları nasıl çözülür

...
Kilit yükseltme, çoğu engelleme sorununa neden olmaz. Kilit yükseltme işleminin engelleme sorunlarıyla karşılaştığınız süre boyunca meydana gelip gelmediğini belirlemek için, Lock: Escalation olayını içeren bir SQL Profiler izlemesi başlatın. Herhangi bir Lock: Escalation olayı görmüyorsanız, sunucunuzda lock escalation oluşmaz ve bu makaledeki bilgiler sizin durumunuz için geçerli değildir.

Kilit yükseltme gerçekleşiyorsa, yükseltilmiş masa kilidinin diğer kullanıcıları engellediğini doğrulayın
...

Engellenen işlem olayından önce gerçekleşen kilit yükseltme olayları için Genişletilmiş Olayları (fiziksel dosya) kontrol edin .

açıklanması

Daha fazla ayrıntıya giren bir Microsoft Blog makalesi var:

SQL Server Kilidi Yükseltme ve Engelleme

...
2. Adım: Kilit Yükselişini ve Engellenen Süreç Raporu Olaylarını toplayın.

Eskalasyonu kilitle ve engellenen işlem raporu olayları, SQL Server tarafından otomatik olarak yakalanmaz. Bu olayların olup olmadığını bilmek için, SQL Server'a bunları kaydetmesini söylememiz gerekir. Ekibimiz bu bilgileri toplamak için Microsoft Dynamics için Performans Analizcisi aracını kullanıyor. Araç hakkında daha fazla bilgi ve bununla ilgili engelleme detaylarını nasıl toplayacağınızla ilgili olarak Rod Hansen tarafından bu yazıya göz atın. Sadece SQL Server Profiler'ı kullanmak istiyorsanız, toplamanız gereken olaylar aşağıda gösterilmiştir: ...

Kilit yükseltmeleri ve engellenen işlemleri yakaladıktan sonra, kilit yükseltmelerinin engellenen işlemlerin kök nedeni olup olmadığını belirlemeniz gerekir:

...
Adım 3: İzlemeyi SQL Server Profiler'da gözden geçirin.

Engellemenin kilit yükseltme ile ilgili olup olmadığını size söyleyecek iki ana gösterge vardır.

İlk önce, engellenen işlem raporu olaylarından hemen önce bir dizi kilit yükseltme olayını görürsünüz. Aşağıda, Microsoft Dynamics aracı için Performans Çözümleyicisi tarafından üretilen bir izden alınan bir örnek verilmiştir. Bu, izlemede aranacak bir şey, ancak bu tek başına kilit yükselişinin engellemeye neden olduğu anlamına gelmez. ...

ve Ötesi

Engellemenin aslında kilit yükseltme ile ilgili olduğunu doğrulamak için, engellenen işlem raporu ayrıntılarına bakmanız gerekir. TextData bölümünde waitresource'u arayın (aşağıdaki ekran görüntüsüne bakın). Eğer waitresource OBJECT ile başlıyorsa, bloke ifadenin devam etmeden önce serbest bırakılmak üzere bir masa seviyesinde kilit üzerinde beklediğini biliyoruz. Eğer waitresource OBJECT yerine KEY veya PAG ile başlıyorsa , kilit yükseltme bu spesifik blokta yer almaz . Kilit yükseltme, nerede başladığından bağımsız olarak her zaman kilidin kapsamını OJBECT'e yükseltir

Çözüm

(sadece yukarıda belirtilenler eşleşiyorsa)

Çözüm, görünüşe göre kilit yükselişini durduracak olan 1224 izleme bayrağını açmaktır:

SQL Server Kilidi Yükseltme ve Engelleme

Bu iki şeyi birlikte görüyorsanız, kilit yükselişinin engellenmeye yol açması oldukça iyi bir bahistir ve muhtemelen SQL Server izleme bayrağı 1224'ü uygulamaktan faydalanabilirsiniz.

Dynamics AX için SQL Server İzleme Bayrakları

İz bayrağı 1224, kilit sayısına bağlı olarak kilit yükselmesini devre dışı bırakır. Bu izleme bayrağının etkinleştirilmesi, bazı AX uygulamalarında gördüğüm bir şey olan kilit yükselişinden dolayı engelleme olasılığını azaltabilir. Bunun bir sorun haline geldiği en yaygın senaryo, Master Planning'in gün içerisinde çalıştırılması için bir gereksinim olduğunda

Cevap

Sonunda, kilit yükselişinin engellenen işlemlerin kök nedeni olduğu olabilir.


Alternatif Çözüm (işlem düğümü boş)

Bazı blocked_process_reports'ların daha ayrıntılı araştırılmasından sonra aşağıdaki alternatif açıklama yapılabilir.

Genişletilmiş Olaylar, o sırada başka herhangi bir işlemle ilgisi olmayan blocked_process_reports görüntülerini yakalar.

Ergo: Farklı bir nedenle engellenmeleri gerekiyor

SQL Server'ınızdaki sys.dm_os_wait_stats görünümünden bekleme türlerinden bir zaman dilimi yakalamanızı ve ölçümleriniz sırasında gerçekleşen sayıları karşılaştırmanızı öneririm. Paul Randall iyi bir senaryo var: Bana bekleme istatistiklerinizi gönderin, tavsiyemi alın ve karşılığında 30 günlük ücretsiz Pluralsight'ı alın

Komut dosyaları geçerli sayaçları yakalar, 23 saat bekler (değiştirilebilir), geçerli sayaçları yeniden alır ve size bekleme türlerinin en üst% 95'ini vermek için karşılaştırır. Bunu 1 saat boyunca deneyebilir ve XEL dosyasını kullanışlı hale getirebilirsiniz.

Depolama alanınızın yavaş yazıldığını söyleyen bir bekleme türü (örn. LCK_M_SH,…) bulabilirsiniz. Ya da başka bir ek yükünüz olduğunu (örneğin CX_PACKET_WAITS,….). Bir şey Güncellemelerinizi yavaşlatıyor. Daha sonra sys.dm_os_wait_stats'ın boş düğümlerle bloklanmış_process_reports ile ilgili olup olmadığını görebilirsiniz.

Engellenen bir SPID'nin aynı SPID tarafından engellendiği durumlar vardır:

SQL Server 2000 SP4'ü yükledikten sonra sysprocesses tablosundaki engellenen sütun, mandal beklemeleri için doldurulur

Bir SPID bir G / Ç sayfası mandalı beklerken, engellenen sütunun SPID'nin kendisini engellediğini kısaca bildirdiğini fark edebilirsiniz. Bu davranış, mandalların veri sayfalarındaki G / Ç işlemleri için kullanılmasının bir yan etkisidir. Bir iş parçacığı bir G / Ç isteği yayınladığında, G / Ç isteğini yayınlayan SPID sayfada bir mandal alır. Tüm SQL Server 2000 G / Ç işlemleri eşzamansızdır. Bu nedenle, G / Ç isteğini veren SPID, isteğin bitmesini beklemek zorunda kalırsa, SPID aynı sayfada başka bir mandal almaya çalışacaktır. Bu ikinci mandal, birinci mandal tarafından engellenir. Bu nedenle, engellenen sütun, SPID'nin kendisini engellediğini bildirir. G / Ç isteği tamamlandığında, ilk mandal serbest bırakılır. Ardından, ikinci mandal isteği verilir.

Alternatif Cevap

Bu, GÇ sorunlarınız olabileceğinin bir başka göstergesidir. Bu sorunlar "engellenen süreçler" ile sonuçlanır ancak ilgili bir yabancı SPID olmadan. Extended Events, süreci / SPID'yi ayrı bir düğümde rapor etmeyebilir.


Bu yanlış okuma olabilir, ancak bu bilgilerin sorunu olduğunu kanıtlamaz değil kilit yükseltme? Alıntılanan bir bölümden bahsetti "look at the blocked process report details."ve sorudaki en üstteki XML engellenen süreç raporu. Ardından, aynı alıntılanan bölümün dediği gibi "If waitresource starts with KEY or PAG instead of OBJECT, then lock escalation isn’t involved in that specific block.", bloke işlem raporu raporu XML gösteriliyor waitresource="KEY: 6:72057..... Demek ki buradaki "kilit yükseltme katılımı" demek.
Solomon Rutzky

Hayır, bunu yanlış okumadınız. Soruda verilen bölüm bu sunucuda bir konudur. Cevabım, yükselmeyi engelleme ve kilitleme nedeniyle oluşabilecek sorunlara küresel bir yaklaşım. Bazı önemli sorunları çözebilirseniz (OBJEK seviyesinin kilitlenmesi için blocked_process_reports), o zaman daha küçük olan sorunlar (diğer seviyelerde blocked_process_reports) kendiliğinden çözülebilir. İkinci bir alternatif cevap da eklememin nedeni budur.
John aka hot2use
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.