Имя: Пароль:
1C
 
Эскалация блокировок и ожидания на них
,
0 H A D G E H O G s
 
27.02.19
14:19
Дня доброго.
Есть таблица, с именем _InfoRg6219 и колонками
[_Fld6220RRef]
[_Fld6221]
[_Fld6222_TYPE]
[_Fld6222_RTRef]
[_Fld6222_RRRef]
[_Fld6223RRef]
[_Fld281]
содержащая 7 млн строк данных и 2 индекса:
Кластерный
[_Fld281]
[_Fld6220RRef]
[_Fld6221]
[_Fld6222_TYPE]
[_Fld6222_RTRef]
[_Fld6222_RRRef]
[_Fld6223RRef]

и некластерный:
[_Fld281]
[_Fld6222_TYPE]
[_Fld6222_RTRef]
[_Fld6222_RRRef]
[_Fld6220RRef]
[_Fld6221]
[_Fld6223RRef]

Из этой таблицы в 2 транзакциях, параллельно удаляются записи запросом вида:
DELETE FROM T1
FROM dbo._InfoRg6219 T1
WHERE (T1._Fld6222_TYPE = 0x08 AND T1._Fld6222_RTRef = 0x000016E5 AND T1._Fld6222_RRRef = P1) AND (T1._Fld281 = @P2)

План запроса прост, как палка и не менялся ни разу:
StmtText
--------
Clustered Index Delete(OBJECT:([DISTR_DE].[dbo].[_InfoRg6219].[_InfoRg6219_1] AS [T1]), OBJECT:([DISTR_DE].[dbo].[_InfoRg6219].[_InfoRg6219_2] AS [T1]), OBJECT:([DISTR_DE].[dbo].[_InfoRg6219].[_InfoRg6219_3] AS [T1]) WITH UNORDERED PREFETCH)
|--Index Seek(OBJECT:([DISTR_DE].[dbo].[_InfoRg6219].[_InfoRg6219_2] AS [T1]), SEEK:([T1].[_Fld281]=[@P2] AND [T1].[_Fld6222_TYPE]=0x08 AND [T1].[_Fld6222_RTRef]=0x000016E5 AND [T1].[_Fld6222_RRRef]=[P1]) ORDERED FORWARD)

Уровень изоляции транзакции - READ COMMITTED SNAPSHOT
В случае, если удаляется до 500 записей, транзакции выполняются параллельно, если записей больше 5000 - 2 транзакция ждет первую.
Во всех случаях - попадание в индекс есть, сколько строк к удалению - столько строк и прочитано в Index Seek.
В событии timeout lock Блокировка - IX на объекте _InfoRg6219
В профайлере найдена эскалация блокировки, что печально.

Я правильно понимаю, что никаких способов в SQL нет, чтобы отключить эскалацию. на таблицу, кроме как в запросе, который не поправить?

Кто игрался с флагами трассировки:
https://docs.microsoft.com/ru-ru/previous-versions/sql/sql-server-2005/ms188396(v=sql.90)
DBCC TRACEON (1221,-1);
DBCC TRACEON (1224,-1);

и параметром locks сервера SQL?

База высоконагруженная, 1300 пользователей, сцыкотно так сразу на живую хреначить.
1 H A D G E H O G s
 
27.02.19
14:22
Как вообще в 1С обстоит работа с модификациями данных с числом строк более 5000 в 1 транзакции? Неужели все сидят и курят?
2 H A D G E H O G s
 
27.02.19
14:28
Стопэ, увидел это в
https://its.1c.ru/db/metod8dev#content:5946:hdoc
3 mistеr
 
27.02.19
14:32
> База высоконагруженная, 1300 пользователей, сцыкотно так сразу на живую хреначить.

Из этих слов делаю вывод, что задача разовая, вызванная исключительно нетерпением начальства. В этом случае рекомендую просто потерпеть (и уговорить остальных).

Если же задача чистки регистра регулярная, то рекомендую уменьшить количество записей в транзакции. Проблема эскалации уйдет, а для ускорения можно будет добавить сеансов.

Обменять, так сказать, latency на throughput.
4 H A D G E H O G s
 
27.02.19
14:36
"Если же задача чистки регистра регулярная, то рекомендую уменьшить количество записей в транзакции. Проблема эскалации уйдет, а для ускорения можно будет добавить сеансов."

Этого сделать нельзя, это состояния марок алкоголя при проведении расходной накладной, они должны идти в 1 транзакции
5 H A D G E H O G s
 
27.02.19
14:37
Попробуем выправить флагами трассировки.
6 Вафель
 
27.02.19
14:38
можно еще поиграться порогм эксалации транзакции
7 H A D G E H O G s
 
27.02.19
14:40
(6) На продуктивном сервере?
На SQL.Ru пишут, что это может привести с экспотенциальному росту времени выполнения запросов.
8 Вафель
 
27.02.19
14:41
(7) ну сделай на тестовом стенде )))
9 Вафель
 
27.02.19
14:41
(7) у тебя на продуктиве эскалации постоянно идут?
10 H A D G E H O G s
 
27.02.19
14:44
(9) Ну когда ТТН с количеством марок в 3000 и больше. Это 3000 бутылок, это не так много на самом деле, их достаточно много.
11 Вафель
 
27.02.19
14:45
ну тогда сам решай, что выгоднее - ждать блокировки или тратить ресурсы на атомарные блокировки
12 mistеr
 
27.02.19
14:45
(4) А одним набором записей нельзя сделать?
13 Вафель
 
27.02.19
14:46
а еще можно напрямую в регистре через скл удалять
14 H A D G E H O G s
 
27.02.19
14:49
(13) А какая разница, вы задачу видели?
15 mistеr
 
27.02.19
14:50
Можно попробовать флаг 1224, выяснить дело в памяти или в количестве. 3000 и 5000 это не так много, памяти должно хватать. Кстати, может памяти скулю не хватает?
16 H A D G E H O G s
 
27.02.19
14:50
DELETE FROM T1
FROM dbo._InfoRg6219 T1
WHERE (T1._Fld6222_TYPE = 0x08 AND T1._Fld6222_RTRef = 0x000016E5 AND T1._Fld6222_RRRef = P1) AND (T1._Fld281 = @P2)

напишите это на SQL лучше
17 H A D G E H O G s
 
27.02.19
14:50
(15) На сервере 1Тб, занято SQL-ем где то 680-700 Гб.
18 Вафель
 
27.02.19
14:53
(14) в очередь, а потом скопом по всем параметрам сразу
19 H A D G E H O G s
 
27.02.19
14:54
(18) Не поняд
20 mistеr
 
27.02.19
14:55
(16) Легко. Скуль позволяет написать DELETE, в котором под условие попадут все 3000 марок. А вот 1С не позволяет.
21 H A D G E H O G s
 
27.02.19
14:57
(20) 1С позволяет. Вы читали (0) пост?
22 Вафель
 
27.02.19
14:57
(19) у тебя потоки отдельно что-то удаляют. а делегируй разделение на потоки мсскл. а 1с в 1 поток пусть делает
23 Вафель
 
27.02.19
14:57
или у тебя при отмене проведения - перепроведении докумена?
24 H A D G E H O G s
 
27.02.19
14:59
Анатолий, я не могу понять, что вы пишите.

У меня в ОбработкеПроведения() удаление записей регистрасведений.
Я не могу разбить это на отдельные транзакции в фоновыезадания, потому что это будут отдельные транзакции и если одна из них завершиться, а другая - нет - то все пойдет по звизде.
25 Вафель
 
27.02.19
15:01
(24) ну так надо было с этого начинать
26 H A D G E H O G s
 
27.02.19
15:01
Проверил на тестовом сервере
-T1211
-T1224
все хорошо
27 Вафель
 
27.02.19
15:03
отмени эскалацию только на этой таблице
ALTER TABLE mytable SET(LOCK_ESCALATION=DISABLE)
28 mistеr
 
27.02.19
15:03
(21) Может я чего-то не вижу, но в запросе (0) удаляется по одной записи.

P.S. По одной не в транзакции, а за одно выполнение запроса.
29 mistеr
 
27.02.19
15:04
(27) И получи тормоза в других неожиданных местах или нехватку памяти (хотя это вряд ли).
30 H A D G E H O G s
 
27.02.19
15:04
(28) В запросе (0) удаляется 5000 строк из 7 млн.
31 H A D G E H O G s
 
27.02.19
15:05
(27) До первой реструктуризации :-(
32 H A D G E H O G s
 
27.02.19
15:06
Пофиг
Есть флаги
Это рекомендует 1С
Вместо того, чтобы впилить Delete ***** with (LOCK_ESCALATION = DISABLE)
Ну или убрать эскалацию для большой таблицы
Или вывести параметр в конфигуратор

Значит они знают, что делают.
Я верю им.
33 mistеr
 
27.02.19
15:07
(30) То есть в 1С это набор записей из 5000 строк?
34 H A D G E H O G s
 
27.02.19
15:07
(33) Да
35 mistеr
 
27.02.19
15:09
(34) Тогда интересно, с какого фига эскалация на таблицу...
36 H A D G E H O G s
 
27.02.19
15:10
37 Вафель
 
27.02.19
15:11
(32) они индексы не могут сделать составные, а ты хочешь флаги в конфигураторе
38 mistеr
 
27.02.19
15:21
(36) А, значит 5000 где-то зашито...


Ну попробуй 1224 (без 1211).
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший