Скажу відразу , що моє запитання / проблема виглядає схожа на цю попередній, але так як я не впевнений , якщо причина або початкова інформація є таким же, я вирішив розмістити своє питання ще з деякими деталями.
Випуск під рукою:
- в чужу годину (наприкінці робочого дня) виробничий екземпляр починає поводитися нерівномірно:
- високий процесор для екземпляра (від базової лінії ~ 30% він збільшився приблизно вдвічі і все ще зростає)
- збільшена кількість транзакцій в секунду (хоча завантаження програми не побачило жодних змін)
- збільшена кількість непрацюючих сеансів
- дивні події блокування між сеансами, які ніколи не відображали такої поведінки (навіть читання невмілих сесій викликало блокування)
- Топ інтервалу, який чекав інтервалу, був засувкою без сторінки на 1-му місці, а замки посіли 2 місце
Початкове розслідування:
- використовуючи sp_whoIsActive, ми побачили, що запит, виконаний нашим інструментом моніторингу, вирішує запускати надзвичайно повільно і захоплювати багато процесора, чого раніше не було;
- рівень його ізоляції був прочитаний без підтвердження;
- ми подивилися на план, який ми побачили нерозумні цифри: StatementEstRows = "3.86846e + 010" з приблизно 150 ТБ передбачуваних даних, які потрібно повернути
- ми підозрювали, що причина монітора запитів була причиною, тому ми відключили цю функцію (ми також відкрили квиток у нашого постачальника, щоб перевірити, чи знають вони про будь-яку проблему)
- від тієї першої події це сталося ще кілька разів, і кожен раз, коли ми вбиваємо сеанс, все приходить у норму;
- ми розуміємо, що запит надзвичайно схожий на один із запитів, використовуваних MS в BOL для моніторингу магазину запитів - запити, які нещодавно регресували у виконанні (порівнюючи різні моменти часу)
- ми запускаємо один і той же запит вручну і спостерігаємо однакову поведінку (CPU використовується постійно зростаючим, збільшуючи очікування засувок, несподівані блокування .. тощо)
Запит провини:
Select qt.query_sql_text,
q.query_id,
qt.query_text_id,
rs1.runtime_stats_id AS runtime_stats_id_1,
interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time),
p1.plan_id AS plan_1,
rs1.avg_duration AS avg_duration_1,
rs2.avg_duration AS avg_duration_2,
p2.plan_id AS plan_2,
interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time),
rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt
Inner Join sys.query_store_query AS q
ON qt.query_text_id = q.query_text_id
Inner Join sys.query_store_plan AS p1
ON q.query_id = p1.query_id
Inner Join sys.query_store_runtime_stats AS rs1
ON p1.plan_id = rs1.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi1
ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id
Inner Join sys.query_store_plan AS p2
ON q.query_id = p2.query_id
Inner Join sys.query_store_runtime_stats AS rs2
ON p2.plan_id = rs2.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi2
ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
Where rsi1.start_time > DATEADD(hour, -48, GETUTCDATE())
AND rsi2.start_time > rsi1.start_time
AND p1.plan_id <> p2.plan_id
AND rs2.avg_duration > rs1.avg_duration * 2
Order By q.query_id, rsi1.start_time, rsi2.start_time
Налаштування та інформація:
- SQL Server 2016 SP1 CU4 Enterprise на кластері Windows Server 2012R2
- Магазин запитів увімкнено та налаштовано за замовчуванням (налаштування не змінено)
- база даних, імпортована з екземпляра SQL 2005 (і все ще на рівні сумісності 100)
Емпіричне спостереження:
- завдяки надзвичайно дурній статистиці ми взяли всі * plan_persist ** об’єкти, які використовуються в поганому оціночному плані (фактичного плану ще немає, тому що запит так і не завершився) та перевірили статистику, деякі з індексів, використаних у плані, не мали жодної статистики (DBCC SHOWSTATISTICS не повернув нічого, виберіть із sys.stats показав функцію NULL stats_date () для деяких індексів
Швидке і брудне рішення:
- вручну створити відсутні статистичні дані щодо системних об'єктів, пов’язаних із магазином запитів або
- змусити запуск запиту використовувати новий CE (traceflag) - який також створить / оновить необхідні статистичні дані або
- змінити рівень сумісності бази даних на 130 (так він за замовчуванням використовує новий CE)
Отже, моє справжнє питання було б:
Чому запит у магазині запитів може спричинити проблеми з роботою у всьому екземплярі? Ми знаходимося на території помилок із магазином запитів?
PS: За короткий час я завантажу декілька файлів (екрани друку, IO статистика та плани).
Файли додані на Dropbox .
План 1 - початковий нерозумний кошторисний план у виробництві
План 2 - фактичний план, старий СЕ, в тестовій середовищі (та ж поведінка, ті ж дурні статистики)
План 3 - фактичний план, новий CE, в тестовій середовищі