Как время ожидания может быть выше времени на часах?

15

Когда я отслеживаю ожидания с помощью sp_BlitzFirst, я получаю следующую информацию:

<?ClickToSeeDetails -- 
For 20 seconds over the last 5 seconds, SQL Server was waiting on this 
particular bottleneck.


 -- ?>

Должно ли это звучать "20 раз за последние 5 секунд?" Нахождение было CLR_SEMAPHORE.

Роберт Райс
источник

Ответы:

24

Статистика без ожидания может (и чаще всего не будет) составлять больше, чем физическое время, затраченное на сам сервер.

Представьте себе ситуацию, когда 2 отдельных потока тратят одну и ту же секунду на ожидание какого-либо ресурса - у вас будет 2 секунды времени ожидания на 1 секунду времени.

Каждый поток имеет свои собственные ожидания - в сообщении сообщается, что 20 секунд времени ожидания для данного конкретного ресурса произошло за последние 5 секунд времени.

Или, другими словами, каждое ядро ​​может выполнять несколько запросов одновременно, и несколько ядер могут добавить еще больше ожиданий. Иными словами, устройство действительно имеет поток · секунды, а не секунды.

George.Palacios
источник
8

Также может быть полезно проработать пример. Рассмотрим три наиболее распространенных состояния для работника :

RUNNING = Работник в настоящее время работает либо без вытеснения, либо с вытеснением.

RUNNABLE = Рабочий готов к запуску в планировщике.

SUSPENDED = Работник в настоящее время приостановлен, ожидая события, чтобы отправить ему сигнал.

Работники с состоянием RUNNINGмогут генерировать время ожидания. Например, если рабочий должен запустить код в ОС, а не в SQLOS, он может ввести упреждающее или внешнее ожидание. В течение этого времени он будет выполнять код на связанном с ним процессоре, но все равно будет генерировать время ожидания.

Работники с состоянием RUNNABLEмогут генерировать время ожидания (насколько я знаю, они всегда). Если работнику сообщили, что ресурс доступен, он может накапливать время ожидания сигнала на основе последнего ожидания. Если рабочий исчерпал свой предыдущий квант 4 мс, он может накопить SOS_SCHEDULER_YIELDвремя ожидания.

Рабочие с состоянием SUSPENDED могут генерировать время ожидания. Рассмотрим работника, который ждет блокировки. Он будет генерировать время ожидания, пока не будет сообщено, что требуемый ресурс блокировки доступен. Некоторые отстраненные работники не генерируют время ожидания, в том числе не связанные с задачей.

Мой рабочий стол имеет четыре логических ядра, поэтому максимальное число рабочих по умолчанию составляет 512 . Это почти наверняка нецелесообразно, но на этой машине я могу теоретически генерировать 512 секунд времени ожидания в секунду, если мне удастся заставить каждого работника ждать чего-то одновременно. По мере увеличения числа основных / рабочих это число может стать еще выше.

Вы можете видеть более одной секунды ожидания в секунду, даже если вы не выполняете никаких запросов к SQL Server. На моей машине следующий запрос генерирует от 9 до 14 строк:

SELECT [state], last_wait_type, wait_started_ms_ticks
FROM sys.dm_os_workers
WHERE [state] IN ('SUSPENDED', 'RUNNABLE')
AND task_address IS NOT NULL
AND wait_started_ms_ticks <> 0
AND wait_started_ms_ticks >= start_quantum;

Я могу сделать снимок общего времени ожидания с момента последней перезагрузки сервера и сравнить его с новым общим итогом после десяти секунд ожидания:

DECLARE @start_wait_time_ms BIGINT;

SELECT @start_wait_time_ms = SUM(wait_time_ms)
FROM sys.dm_os_wait_stats
WHERE wait_type <> 'WAITFOR';

WAITFOR DELAY '00:00:10';

SELECT SUM(wait_time_ms) - @start_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type <> 'WAITFOR';

Иногда математика получается. В последний раз, когда я запускал его, дельта была 101339 мс. Другими словами, у меня было более 10 секунд ожидания в секунду только от системных задач.

Джо Оббиш
источник