LATCH_EX очікує на ресурс METADATA_SEQUENCE_GENERATOR


11

У нас є процес, який формує звіт про інвентаризацію. На стороні клієнта процес розбиває настроювану кількість робочих потоків для створення фрагмента даних для звіту, який відповідає одному сховищу з багатьох (потенційно тисячі, як правило, десятки). Кожен робочий потік викликає веб-сервіс, який виконує збережену процедуру.

Процес бази даних для обробки кожного фрагмента збирає купу даних у # тимчасову таблицю. В кінці кожного фрагменту обробки дані записуються до постійної таблиці в tempdb. Нарешті, наприкінці процесу один потік на стороні клієнта запитує всі дані з постійної таблиці tempdb.

Чим більше користувачів, які працюють із цим звітом, тим повільніше він стає. Я проаналізував активність у базі даних. Одного разу я побачив 35 окремих запитів, всі заблоковані в один момент процесу. Усі ці SPID мали близько 50 мс очікування типу LATCH_EXресурсу METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8). Один SPID має цей ресурс, а всі інші блокують. Я не знайшов нічого про цей ресурс очікування у веб-пошуку.

У таблиці tempdb, яку ми використовуємо, є IDENTITY(1,1)стовпець. Чи очікують ці SPID-адреси в стовпці Ідентифікація? Які методи можна використати для зменшення чи усунення блокування?

Сервер є частиною кластера. На сервері працює 64-розрядна версія SQL Server 2012 Standard Edition SP1 для 64-розрядних Windows 2008 R2 Enterprise. Сервер має 64 ГБ оперативної пам’яті та 48 процесорів, але база даних може використовувати лише 16, оскільки це стандартне видання.

(Зауважте, що я не в захваті від дизайну використання постійної таблиці в tempdb для зберігання всіх цих даних. Зміна цього буде цікавою технічною та політичною проблемою, але я відкритий для пропозицій.)

ОНОВЛЕННЯ 23.04.2013

Ми відкрили справу підтримки з Microsoft. Я буду постійно оновлювати це питання, коли ми дізнаємось більше.

ОНОВЛЕННЯ 5.10.2013

Інженер підтримки SQL Server погодився, що очікування було викликано стовпцем Ідентифікатор. Видалення ідентичності усунуло очікування. Ми не могли дублювати проблему на SQL 2008 R2; це сталося лише в SQL 2012.


Чи фактично процес копіює дані з # Тимчасових таблиць у постійну таблицю, або на цьому кроці відбувається додаткова логіка перетворення?
Джон Сейгель

На кроці, якого він чекає, він копіює записи інвентаря одного магазину в постійну таблицю без перетворення. Ми могли працювати всередині постійної таблиці весь час, але я думаю, що програміст вирішив використовувати # Тимчасову таблицю як область утримування, щоб запобігти частому оновленню даних перетворюватися в блоки PAGE.
Пол Вільямс

Відповіді:


4

Якщо припустити, що ви можете виділити проблему з генеруванням значень ідентичності (спробуйте видалити цей стовпець як тест), я рекомендував би це:

  1. Вилучіть IDENTITYвластивість зі стовпця у підсумковій таблиці.
  2. Створюйте значення ідентичності у кожній з # тимчасових таблиць.
  3. Завантажуючи підсумкову таблицю, комбінуйте числовий ідентифікатор для конкретного магазину зі значеннями ідентичності з кроку 2.

Отже, якщо у вас є ідентифікатори зберігання 3 та 4, ви отримаєте кінцеві значення id таким чином:

3000000001
3000000002
3000000003
...
4000000001
4000000002
...

Або щось подібне до цього. Ви отримуєте ідею.

Це позбавить від необхідності серіалізувати IDENTITYпокоління, зберігаючи унікальність у кінцевому результаті.

Крім того, залежно від того, як працює процес, вставляйте остаточні обчислені значення id у # Тимчасові таблиці. Тоді ви зможете створити представлення, яке UNION ALLпоєднує їх, усуваючи необхідність взагалі копіювати дані.


Дякую за відповідь. Я погоджуюся, якщо це проблема, використовуючи який-небудь виготовлений ключ (або зовсім не ключ), це може виправити. Ми відкрили справу з Microsoft щодо цієї проблеми. Я опублікую результат тут і прийму вашу відповідь, якщо вони згодні, що це проблема.
Пол Вільямс

@Paul: Будь ласка, дайте мені знати; Мені так само цікаво. Як і ви, я не зміг знайти в Інтернеті нічого про цю засувку, але, безумовно, розумно, що це серіалізація ідентичності / послідовності. Незалежно від того, чи це вузьке місце, важко сказати, хоча, маючи 30+ ниток, які змагаються за значення, це здається ймовірним. Ви також можете спробувати скопіювати з кожної # тимчасової таблиці послідовно (а не паралельно), щоб побачити, чи це допомагає.
Джон Сейгель

2
Інженер SQL Server погодився, що це, ймовірно, IDENTITYстовпець. Ми зняли його з уже широкого кластерного індексу і повністю видалили стовпець. Це було не потрібно. Після цього ці очікування LATCH_EX минули. Ми не могли дублювати очікування на SQL 2008 R2. Проблема трапилась лише на SQL Server 2012.
Пол Вільямс

@Paul: Дякуємо за продовження. Дуже цікаво. Я здогадуюсь, що код, який генерує IDENTITYзначення, був переписаний для використання нового матеріалу генерації послідовностей, який був новим у 2012 році. На <2012 році ви можете побачити інший тип засувки, хоча якщо не було проблеми з парфумом, то, здається, був регресія в коді. У будь-якому випадку видалення IDENTITYстовпця - це найбезпечніше.
Джон Сейгель

Замість ідентичності ви можете спробувати використати "ПОСЛІДЖЕННЯ" (що є новим у SQL 2012)
Богдан Максим

7

(Оновлено лютий 2019 року)

Це стара публікація, в якій сказано, що мені нарешті вдалося переконати Microsoft у тому, що сам факт цього відбувається - це справді дефект.

Оновлення: MS підтвердила дефект та призначила йому помилку №12628722.

Я бачив цю публікацію минулого листопада 2018 року, коли ми стали страждати приблизно так само після того, як ми перейшли з сервера Sql Server 2005 до сервера Sql 2017. Таблиця рядків 3,3 мільйона, яка займала 10 секунд, щоб раптово вставити, раптом почала приймати 10 хвилин на таблицях із Identityстовпцями.

Виявляється, за цим стоїть два питання:

  1. Microsoft змінила поведінку в Sql Server 2014, щоб змусити групові вставки паралельно працювати - у попередніх версіях груповим вкладишам було надано серіалізований план.
  2. Після того, як паралельно працював на нашій 32-ядерній коробці, двигун проводив більше часу, коли сердечники фіксували один одного, ніж насправді виконували роботу.

Зайняли мене 4 тижні, але відразу після свят я отримав від Санти запізнілий подарунок - підтвердження того, що проблема справді була дефектом.

Є кілька можливих вирішень, які ми знайшли, поки це не буде виправлено:

  1. Використовуйте Option (MaxDop 1)в запиті, щоб повернути об'ємну вставку назад в серіалізований план.
  2. Маскуйте стовпець Identity, вкинувши його (наприклад Select Cast(MyIdentityColumn As Integer) As MyIdentityColumn)
    • це запобігає копіюванню властивості ідентичності під час використання SELECT...INTO
  3. Видаліть стовпець посвідчення, як описано вище.
  4. Змініть режим сумісності баз даних на Sql Server 2012 або нижче, щоб відновити серіалізований план.

Оновлення: виправлення MS, яке буде реалізовуватися, полягає у тому, щоб повернути такі типи вкладок до використання Serialized плану. Це заплановано на Sql Server 2017 CU14 (жодних новин про інші версії Sql Server - вибачте!). Коли буде реалізовано, слід слід включити Trace Flag 9492 або на рівні сервера, або через DBCC TraceOn .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.