Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 DeadLock  [new]
PaulWist
Member

Откуда:
Сообщений: 2299
Дано:

Microsoft SQL Server 2012 (SP4-GDR) (KB4583465) - 11.0.7507.2 (X64) Nov 1 2020 00:48:37 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)


Табличка (1.5 млн записей):

+
CREATE TABLE [dbo].[ART_PARAMS](
	[ART_ID] [int] NOT NULL,
	[CODE_INFOR_ERP] [varchar](47) NULL,
	[STATUS] [varchar](20) NULL,
	[ALTERN_D2] [varchar](47) NULL,
	[IZGOTOVITEL] [varchar](252) NULL,
 CONSTRAINT [PK_ART_PARAMS] PRIMARY KEY CLUSTERED 
(
	[ART_ID] 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].[ART_PARAMS]  WITH CHECK ADD  CONSTRAINT [FK_ARTPARAMS] FOREIGN KEY([ART_ID])
REFERENCES [dbo].[ARTICLES] ([ART_ID])
GO

ALTER TABLE [dbo].[ART_PARAMS] CHECK CONSTRAINT [FK_ARTPARAMS]
GO

CREATE NONCLUSTERED INDEX [ART_PARAMS_CODE_INFOR_ERP_NDX] ON [dbo].[ART_PARAMS]
(
	[CODE_INFOR_ERP] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO


Граф:

+
<deadlock>
<victim-list>
<victimProcess id="processd3f90d0c8" />
</victim-list>
<process-list>
<process id="processd3f90d0c8" taskpriority="0" logused="0" waitresource="PAGE: 5:1:66942918 " waittime="7999" ownerId="1926158621" transactionname="UPDATE" lasttranstarted="2021-11-23T14:00:09.610" XDES="0x6cb7343a8" lockMode="U" schedulerid="16" kpid="5140" status="suspended" spid="2474" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-11-23T14:00:04.163" lastbatchcompleted="2021-11-23T14:00:04.163" lastattention="1900-01-01T00:00:00.163" clientapp="SQLAgent - TSQL JobStep (Job 0x82306FD409770E46904B4506C3629CE4 : Step 2)" hostname="NEM-PDM-01" hostpid="5620" loginname="NEM\admin_sql_pdm" isolationlevel="read committed (2)" xactid="1926158621" currentdb="7" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="INTEGRATION.dbo.GAL_CREATE_CODEREQUEST_NEW_02D2" line="91" stmtstart="9180" stmtend="9596" sqlhandle="0x03000700e54db542359f110147ad000001000000000000000000000000000000000000000000000000000000">
UPDATE Search.dbo.ART_PARAMS SET STATUS='+' where STATUS='+++'
-- </frame>
<frame procname="adhoc" line="4" stmtstart="162" sqlhandle="0x01000700e9c23a2040c6b5ce0700000000000000000000000000000000000000000000000000000000000000">
exec GAL_CREATE_CODEREQUEST_NEW_02D2 </frame>
</executionStack>
<inputbuf>
exec GAL_CREATE_CODEREQUEST_NEW_02D2 </inputbuf>
</process>
<process id="processd3f064cf8" taskpriority="0" logused="100992" waitresource="PAGE: 5:1:66942916 " waittime="4952" ownerId="1926129050" transactionname="user_transaction" lasttranstarted="2021-11-23T13:59:57.573" XDES="0x416c396a8" lockMode="IU" schedulerid="11" kpid="7048" status="suspended" spid="695" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-11-23T14:00:12.757" lastbatchcompleted="2021-11-23T14:00:12.757" lastattention="1900-01-01T00:00:00.757" hostpid="468" loginname="sysdba" isolationlevel="read uncommitted (1)" xactid="1926129050" currentdb="5" lockTimeout="4294967295" clientoption1="32" clientoption2="16416">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="50" sqlhandle="0x02000000369e5a02b9522aaf10631005de1c1d05920e689f0000000000000000000000000000000000000000">
UPDATE [ART_PARAMS] set [CODE_INFOR_ERP] = @1 WHERE [ART_ID]=@2 </frame>
<frame procname="adhoc" line="1" sqlhandle="0x02000000e9418d387c53824cff658a37934691d223d11f440000000000000000000000000000000000000000">
UPDATE ART_PARAMS SET CODE_INFOR_ERP = 'D2122001.0.11.026671' WHERE ART_ID = 1171866 </frame>
</executionStack>
<inputbuf>
UPDATE ART_PARAMS SET CODE_INFOR_ERP = 'D2122001.0.11.026671' WHERE ART_ID = 1171866 </inputbuf>
</process>
</process-list>
<resource-list>
<pagelock fileid="1" pageid="66942918" dbid="5" subresource="FULL" objectname="search.dbo.ART_PARAMS" id="lockb863c9c80" mode="IX" associatedObjectId="72057597674586112">
<owner-list>
<owner id="processd3f064cf8" mode="IX" />
</owner-list>
<waiter-list>
<waiter id="processd3f90d0c8" mode="U" requestType="wait" />
</waiter-list>
</pagelock>
<pagelock fileid="1" pageid="66942916" dbid="5" subresource="FULL" objectname="search.dbo.ART_PARAMS" id="lock50d027f00" mode="U" associatedObjectId="72057597674586112">
<owner-list>
<owner id="processd3f90d0c8" mode="U" />
</owner-list>
<waiter-list>
<waiter id="processd3f064cf8" mode="IU" requestType="wait" />
</waiter-list>
</pagelock>
</resource-list>
</deadlock>


По графу (слева направо):

Процесс process id="processd3f90d0c8", spid="2474" выполняет сканирование "таблички" и обновление:

UPDATE Search.dbo.ART_PARAMS SET STATUS='+' where STATUS='+++'


на страницу PAGE: 5:1:66942916 получил mode="U", затребовал получение lockMode="U" на страницу PAGE: 5:1:66942918 - тут всё понятно!!!


Процесс process id="processd3f064cf8, spid="695" обновляет по первичному кластерному индексу одну запись:

UPDATE ART_PARAMS SET CODE_INFOR_ERP = 'D2122001.0.11.026671' WHERE ART_ID = 1171866


причём на страницу PAGE: 5:1:66942918 получил mode="IX" и затребовал на страницу PAGE: 5:1:66942916 получение lockMode="IU".

Как бы DeadLock налицо.

Вопрос: нафига process id="processd3f064cf8, spid="695" получил mode="IX" на страницу PAGE: 5:1:66942918 ведь он обновляет запись по кластерному индексу ???

К сообщению приложен файл (Deadlock2.xdl - 3Kb) cкачать
24 ноя 21, 10:09    [22400065]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 9155
PaulWist,

надо смотреть - что находится на этой странице. Иначе можно долго гадать :)
24 ноя 21, 10:46    [22400079]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
PaulWist
Member

Откуда:
Сообщений: 2299
Владислав Колосов,

Как посмотреть и что надо искать???
24 ноя 21, 10:52    [22400081]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
msLex
Member

Откуда:
Сообщений: 9542
PaulWist
Вопрос: нафига process id="processd3f064cf8, spid="695" получил mode="IX" на страницу PAGE: 5:1:66942918 ведь он обновляет запись по кластерному индексу ???



А вы знаете для чего нужны I(ntent) lock-и?

При наложении любой "обычной" блокировки, на все объекты большей гранулярности накладывают соответствующие Intent блокировки. Например, при X блокировки на ключ, накладываются IX блокировки на страницу и таблицы.

Нужно это для того, чтобы не было необходимости сравнивать блокировки разной гранулярности.


Пример

1-й процесс запустил массовое удаление записей, и SQL Engine "решил" не блокировать отдельные записи, а блокировать целиком страницы, т.е. накладывать X блокировки на PAGE

2-й процесс запустил изменение 1 записи по ключу, и хочет наложить X блокировку на KEY


Если бы не было Intent блокировок, 2-му процессу пришлось бы проверять наличие несовместимый блокировок всех уровней (PAGE, TABLE), а 1-му, помимо проверки верхних уровней (TABLE), нужно проверять все "подобъекты", т.е. нет ли несовместимых KEY блокировок на каждой записи на странице?

Что будет, если какой-то процесс захочет наложить блокировку на уровне терабайтной таблицы можно приставить.

Вместо этого, любой lock дублируется I lock на уровне выше, и все сравнения допустимости блокировок сводятся к проверки в рамках конкретного объекта.
24 ноя 21, 11:11    [22400090]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
PaulWist
Member

Откуда:
Сообщений: 2299
msLex


Пример

1-й процесс запустил массовое удаление записей, и SQL Engine "решил" не блокировать отдельные записи, а блокировать целиком страницы, т.е. накладывать X блокировки на PAGE

2-й процесс запустил изменение 1 записи по ключу, и хочет наложить X блокировку на KEY


Если бы не было Intent блокировок, 2-му процессу пришлось бы проверять наличие несовместимый блокировок всех уровней (PAGE, TABLE), а 1-му, помимо проверки верхних уровней (TABLE), нужно проверять все "подобъекты", т.е. нет ли несовместимых KEY блокировок на каждой записи на странице?

Что будет, если какой-то процесс захочет наложить блокировку на уровне терабайтной таблицы можно приставить.

Вместо этого, любой lock дублируется I lock на уровне выше, и все сравнения допустимости блокировок сводятся к проверки в рамках конкретного объекта.


ОК.

Давайте рассмотрим "Ваш пример" на конкретном, приведенном deadlock, первый процесс (тот который слева, отстреленный), обновляет сканируя таблицу, те идёт по листовому уровню кластерного индекса получая U блокировку и натыкается на страницу листового уровня, которую заблокировал IX второй процесс обновляющий по кластерному ключу.

По логике, второй процесс должен был наложить IX блокировку на таблицу, но не как не на листовую страницу.

Вот нафига, второму процессу блокировать две страницы листового уровня???
24 ноя 21, 11:39    [22400110]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
msLex
Member

Откуда:
Сообщений: 9542
PaulWist
msLex


Пример

1-й процесс запустил массовое удаление записей, и SQL Engine "решил" не блокировать отдельные записи, а блокировать целиком страницы, т.е. накладывать X блокировки на PAGE

2-й процесс запустил изменение 1 записи по ключу, и хочет наложить X блокировку на KEY


Если бы не было Intent блокировок, 2-му процессу пришлось бы проверять наличие несовместимый блокировок всех уровней (PAGE, TABLE), а 1-му, помимо проверки верхних уровней (TABLE), нужно проверять все "подобъекты", т.е. нет ли несовместимых KEY блокировок на каждой записи на странице?

Что будет, если какой-то процесс захочет наложить блокировку на уровне терабайтной таблицы можно приставить.

Вместо этого, любой lock дублируется I lock на уровне выше, и все сравнения допустимости блокировок сводятся к проверки в рамках конкретного объекта.


ОК.

Давайте рассмотрим "Ваш пример" на конкретном, приведенном deadlock, первый процесс (тот который слева, отстреленный), обновляет сканируя таблицу, те идёт по листовому уровню кластерного индекса получая U блокировку и натыкается на страницу листового уровня, которую заблокировал IX второй процесс обновляющий по кластерному ключу.

По логике, второй процесс должен был наложить IX блокировку на таблицу, но не как не на листовую страницу.

Вот нафига, второму процессу блокировать две страницы листового уровня???



кластерный и некластерный индекс
24 ноя 21, 12:49    [22400146]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
PaulWist
Member

Откуда:
Сообщений: 2299
msLex


кластерный и некластерный индекс


Ааа, Семён Семёныч (с) Брил. рука

Спасибо!!!
24 ноя 21, 13:27    [22400162]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1909
PaulWist,

только партиция одинаковая.

что показывает:
select object_name(object_id), object_id, index_id, partition_number from sys.partitions where partition_id = 72057597674586112


add:
да и в принципе можно заголовок страниц :
dbcc page (5, 1, 66942918, 0) with tableresults;
dbcc page (5, 1, 66942916, 0) with tableresults;


Сообщение было отредактировано: 24 ноя 21, 13:41
24 ноя 21, 13:34    [22400170]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
PaulWist
Member

Откуда:
Сообщений: 2299
felix_ff
PaulWist,

только партиция одинаковая.

что показывает:
select object_name(object_id), object_id, index_id, partition_number from sys.partitions where partition_id = 72057597674586112



object_name object_id index_idpartition_number
ART_PARAMS 1868689855 1 1


???

Сообщение было отредактировано: 24 ноя 21, 14:47
24 ноя 21, 14:46    [22400215]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1909
PaulWist,

предположу что у вас
страница 66942916 m_type=2
страница 66942918 m_type = 1
24 ноя 21, 15:03    [22400226]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
PaulWist
Member

Откуда:
Сообщений: 2299
felix_ff
PaulWist,

предположу что у вас
страница 66942916 m_type=2
страница 66942918 m_type = 1


Я тоже сначала так предположил, НО m_type = 1 для обоих страниц.

Картинка не пристёгивается :(

Сообщение было отредактировано: 24 ноя 21, 15:26
24 ноя 21, 15:19    [22400229]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
PaulWist
UPDATE ART_PARAMS SET CODE_INFOR_ERP = 'D2122001.0.11.026671' WHERE ART_ID = 1171866

Похоже, что в этой транзакции есть ранее еще такой же апдейт с ART_ID, большим 1171866
24 ноя 21, 16:27    [22400276]     Ответить | Цитировать Сообщить модератору
 Re: DeadLock  [new]
PaulWist
Member

Откуда:
Сообщений: 2299
invm

Похоже, что в этой транзакции есть ранее еще такой же апдейт с ART_ID, большим 1171866


Мда, другого логического объяснения пока не вижу.

Спасибо.
25 ноя 21, 07:58    [22400476]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить