Очистка кэша SQL Server и дисковый ввод-вывод

11

Мы заняты нагрузочным тестированием OLTP-системы, разработанной нами в .NET 4.0, и запускаем SQL Server 2008 R2 в задней части. Система использует очереди SQL Server Service Broker, которые очень производительны, но при обработке мы наблюдаем особую тенденцию.

SQL Server обрабатывает запросы с высокой скоростью в течение 1 минуты, после чего увеличивается ~ 20 секунд активности записи на диск. Следующий график иллюстрирует проблему.

Система SQL OLTP - счетчики производительности

Yellow = Transactions per second
Blue   = Total CPU usage
Red    = Sqlsrv Disk Write Bytes/s
Green  = Sqlsrv Disk Read Bytes/s

Во время устранения неполадок мы попробовали следующее без каких-либо существенных изменений в шаблоне:

  • Остановлен агент SQL Server.
  • Убил практически все остальные запущенные процессы (без A / V, SSMS, VS, Windows Explorer и т. Д.)
  • Удалены все остальные базы данных.
  • Отключены все таймеры разговоров (мы не используем триггеры).
  • Отошел от подхода, управляемого очередью сообщений, к простой / грубой схеме мониторинга таблиц.
  • Используются разные нагрузки от легких до тяжелых.
  • Исправлены все тупики.

Кажется, что SQL Server может создавать свой кэш и записывать его на диск через определенные промежутки времени, но я не могу найти ничего в Интернете, чтобы поддержать эту теорию.

Затем я планирую перенести решение в нашу специальную среду тестирования, чтобы посмотреть, смогу ли я воспроизвести проблему. Любая помощь в промежуточный период будет принята с благодарностью.

Обновление 1 В соответствии с запросом приведен график, включающий число контрольных точек страниц / сек , продолжительность жизни страниц и некоторые счетчики задержки диска.

Система SQL OLTP - Счетчики производительности - Контрольная точка

Похоже, что контрольная точка (голубая линия) является причиной снижения производительности (желтая линия), которую мы наблюдаем.

Задержка диска остается относительно постоянной во время обработки, и ожидаемый срок службы страницы не оказывает заметного влияния. Мы также скорректировали количество оперативной памяти, доступной для SQL Server, что также не имело большого эффекта. Изменение модели восстановления с SIMPLEна FULLтакже мало что изменило.

Обновление 2 Изменив «Интервал восстановления» следующим образом, нам удалось сократить интервал, через который возникают контрольные точки:

EXEC sp_configure 'show advanced options',1
GO 

RECONFIGURE
GO

EXEC sp_configure 'recovery interval', '30'
GO

RECONFIGURE 
GO

EXEC sp_configure 'show advanced options',0
GO
RECONFIGURE

Я не уверен, что это плохая практика, хотя?

Андре Хауптфляйш
источник
1
Добавьте счетчик контрольных точек страниц / сек. И снова протестируйте и покажите график. И в то время как ваши транзакции падают и записи увеличиваются - вы видите проблемы с производительностью? Я также добавил бы некоторые счетчики задержки диска - avg sec / read и avg sec / write
Майк Уолш,
И когда вы публикуете следующие графики, вы можете включить цифры. Этот график не показывает какого-либо масштаба.
Майк Уолш
5
И последнее (извините!) - сколько памяти на этом сервере? Можете ли вы добавить счетчик продолжительности жизни страницы? Можете ли вы описать физические настройки (память, настройки ввода-вывода, разбили ли вы файлы журналов и данных и т. Д.)
Майк Уолш,
2
В какой модели восстановления находится база данных? Это похоже на автоматическую проверку контрольных точек при заполнении журнала транзакций. Обратите внимание, что даже если база данных находится в FULLили BULK_LOGGED, она все равно SIMPLEбудет вести себя так, как если бы она находилась до полного резервного копирования.
Джон Зигель
2
Джон - Контрольная точка все равно будет происходить независимо от модели восстановления. Упрощенно: единственное различие заключается в том, что происходит с данными в журнале после контрольной точки в моделях восстановления. В полном случае она остается в журнале и требует резервного копирования. Проще говоря, он может быть усечен (или помечен для усечения .. повторного использования), но контрольная точка все еще должна быть.
Майк Уолш

Ответы:

11

Другие уже указали на виновника: SQL Server накапливает обновления в памяти (в пуле буферов) и только периодически сбрасывает их (в контрольных точках). Предлагаемые два варианта (-k и интервал контрольных точек) дополняют друг друга:

Но я не отвечал только, чтобы извергнуть прекрасные комментарии, которые вы получили далеко :)

К сожалению, вы видите очень типичное поведение обработки в очереди . Независимо от того, используете ли вы очереди Service Broker или выбираете использование таблиц в качестве очередей , система очень склонна к такому поведению. Это связано с тем, что обработка на основе очередей требует интенсивной записи, даже более интенсивной записи, чем обработка OLTP. Оба Епдиеие и вывод из примитивов операция записи и там почти нет операции чтения. Проще говоря, обработка очереди генерирует наибольшее количество записей (= большинство грязных страниц и большую часть журнала) по сравнению с любой другой рабочей нагрузкой, даже OLTP (т. Е. TPC-C, как рабочая нагрузка).

Очень важно, что записи рабочей нагрузки очереди следуют шаблону вставки / удаления: каждая вставленная строка очень быстро удаляется. Это важно отличать от шаблона «только добавление» рабочей нагрузки вставки (ETL). В основном вы кормите задачу по очистке призрака полноценной едой, и вы легко можете ее опередить. Подумайте, что это значит:

  • enqueue - вставка, это создаст грязную страницу
  • dequeue - это удаление, оно снова испачкает ту же страницу (может быть, повезет и поймает страницу до контрольной точки, поэтому она избежит двойного сброса, но только если повезет)
  • Призрачная очистка очистит страницу, сделав ее снова грязной

Да, это действительно означает, что вы можете в конечном итоге записать страницу три раза на диск, в трех разных запросах ввода-вывода, для каждого обрабатываемого сообщения (наихудший случай). И это также означает, что случайный ввод-вывод контрольных точек будет действительно случайным, так как точка записи страницы снова будет посещаться этими движущимися головками между двумя контрольными точками (по сравнению со многими рабочими нагрузками OLTP, как правило, группируются записи в некоторые «горячие точки», не очереди ...).

Таким образом, у вас есть эти три точки написания, гонка, чтобы снова и снова помечать одну и ту же страницу грязной. И это до того, как мы рассмотрим какие-либо разбиения страницы, какая обработка очереди также может быть склонна из-за порядка вставки ключей. Для сравнения, «типичные» рабочие нагрузки OLTP имеют гораздо более сбалансированное соотношение чтения / записи, а записи OLTP распределяются между вставками / обновлениями / удалениями, часто с обновлениями («изменениями статуса») и вставками, занимающими львиную долю. Записи обработки очереди исключительно вставляются / удаляются с определением 50/50.

Вот некоторые последствия:

  • Контрольно-пропускной пункт становится очень горячей проблемой (больше не сюрприз для вас)
  • Вы увидите сильную фрагментацию (сама по себе фрагментация не будет иметь большого значения, так как вы не собираетесь выполнять сканирование диапазона, но ваша эффективность ввода-вывода страдает, а очистка от призраков должна работать больше, замедляя ее еще больше)
  • Ваша пропускная способность случайного ввода-вывода в хранилище MDF станет для вас узким местом

Моя рекомендация состоит из 3 букв: S, S и D. Переместите MDF в хранилище, которое может обрабатывать быстрый случайный ввод-вывод. SSD. Fusion-IO, если у вас есть деньги. К сожалению, это один из тех симптомов, который не может быть решен с более дешевой оперативной памятью ...

Редактировать:

Как указывает Марк, у вас есть два логических диска, поддерживаемых одним физическим диском. Возможно, вы пытались следовать рекомендациям и разделить журнал на D: и данные на C: но, увы, безрезультатно, C и D - это один и тот же диск. Между контрольными точками вы достигаете последовательной пропускной способности, но как только контрольная точка запускается, головки дисков начинают двигаться, а пропускная способность вашего журнала падает, снижая пропускную способность всего приложения. Убедитесь, что вы разделили журнал БД, чтобы на него не влиял ввод-вывод данных (отдельный диск).

Ремус Русану
источник
2
Кстати, было бы интересно узнать, почему IO, управляемый контрольными точками, так сильно влияет на счетчики приложений. В идеале приложение должно пахать вперед, пока контрольная точка выполняет свою работу. Конечно, я предполагаю, что у вас нет общего пути доступа к хранилищам LDF и MDF (если вы это сделаете, то вы это заслужили ...). Возможно, у вас есть ненужные спорные моменты в приложении.
Ремус Русану
Очень красиво сделано, ответ Ремус.
Марк Стори-Смит
3
Глядя на перечисленные счетчики perfmon, я подозреваю, что вы можете быть правы в отношении данных и журналов, находящихся на одном диске или массиве.
Марк Стори-Смит
@ MarkStorey-Smith: Я думаю, что вы правы, OP имеет C:и D:логические диски, поддерживаемые одним и тем же физическим диском. Я сомневаюсь, что физический диск представляет собой батарею из 100 коротких полосатых шпинделей, так что это, вероятно, основная причина.
Ремус Русану
Да, этот тест был выполнен на моей локальной машине разработчика, которая имеет только один диск. Спасибо всем за помощь.
Андре Хауптфляйш