Вход |  Регистрация

Все Тэги

Online-курс “Основы APM”: Неприятные сюрпризы от SQL сервера

18.11.2013400 просм.

Проблемы с TempDB

База данных TempDB доступна всем пользователям SQL Server для размещения временных объектов, здесь же SQL Server создает разнообразные внутренние объекты для сортировки, буферизации, модификации индексов. И здесь может образоваться узкое место, если какие-то процессы выйдут из-под контроля.

Разработчики и DBA стараются избежать потенциальных проблем, стараясь не использовать тяжелого кода при работе с TempDB. Но помимо кода, к замедлению работы могут привести и ошибки конфигурации. Самые распространенные из них:

  • Только один файл данных TempDB
  • Слишком много файлов данных TempDB (например, по одному на каждое из 40 ядер)
  • Несколько файлов данных TempDB, но разного размера или с неравномерным приростом

Почему все эти случаи являются проблемными? Ответ на этот вопрос слишком технический, чтобы объяснять его здесь. При желании можно почитать в интернете про SGAM и PFS, а краткая версия – так уж в SQL реализована работа с хранением данных.

Иногда советуют иметь по одному файлу TempDB на каждое ядро процессора. С этим советом стоит быть осторожными. Наличие большого количества больших временных таблиц или проведение множества операций, которые работают с TempDB (например, серьезные операции сортировки), может привести к тому, что цикличная работа с большим количеством файлов TempDB замедлит эти операции.

Избежать проблем с TempDB можно используя хорошо подобранное количество файлов данных, причем одинакового размера. Советуем начать с четырех файлов одинакового размера и с одинаковым уровнем авто-инкремента. После чего нужно постоянно мониторить уровень активности TempDB и следить за возможными конфликтами (например, отслеживать ожидания PAGELATCH на TempDB).

Причем нужен именно постоянный мониторинг. Приложения меняются и могут внезапно создавать более сильную нагрузку на TempDB. Меняется и SQL Server, и новый функционал может изменить работу с TempDB.

Раздутые таблицы

По мере заполнения таблиц, как только очередная страница достигает порога в 8Кб, SQL сервер ее разделяет на две. Разделение страниц – интенсивная в плане операций чтения и записи деятельность, и при этом образуется низкая плотность страниц и логическая фрагментация (логический порядок не совпадает с физическим). От этого страдают и индексы, в основном кластеризованные.

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

Чтобы избежать разделения страниц, часто играются с настройкой заполнения Fill Factor, которая определяет, насколько плотно SQL сервер упаковывает страницы данных при перестройке индексов. По умолчанию выставляется 100%, при этом сервер упаковывает как можно больше данных на одну страницу. Однако можно менять уровень заполнения для каждого индекса (лучше не трогать уровень всего сервера). Например, когда в таблице много полей инициализируются в Null и лишь позже заполняются, лучше выставить уровень заполнения пониже, например, 90%, чтобы иметь возможность делать эти обновления полей без излишнего разделения страниц.

То же самое можно делать, если ключ кластеризованного индекса не инкрементный (например, фамилия). Если только всех людей в эту таблицу не вносят изначально в алфавитном порядке, то вставки в индекс будут в произвольных местах, и уменьшение фактора заполнения поможет уменьшить фрагментацию.
При этом ставить уровень заполнения низким (например, 50%) тоже плохо: да, будет меньше разделения страниц, но будет использовано больше памяти в кэше и на дисках, дольше будут производиться бэкапы.

Заключение

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

Команда ALG DevOps Team будет благодарна за Ваши ответы на следующие вопросы:

ALG_DevOps_Team