Автор: Paul Randal, CHECKDB From Every Angle: How long will CHECKDB take to run?
Это тема, о которой я уже писал в своём старом блоге, но на конференции SQL Connections она всплывала несколько раз, поэтому я хочу переопубликовать её для тех, кто только начал следить за моим блогом.
Есть только один момент, когда вы должны пытаться выяснить, сколько времени займёт выполнение CHECKDB, — при планировании регулярного обслуживания базы данных. Если вы столкнулись с повреждённой (или предположительно повреждённой) базой данных и только начинаете задумываться о том, сколько времени займёт выполнение CHECKDB, — вы допустили ошибку при планировании стратегии аварийного восстановления. Вы всегда должны знать, сколько времени (в среднем) занимает выполнение CHECKDB для вашей базы данных, чтобы:
- вы могли определить, не занимает ли конкретный запуск CHECKDB больше времени, чем обычно, — признак того, что он обнаружил некоторые повреждения;
- вы знали, сколько времени потребуется для получения результатов в ситуации аварийного восстановления.
На каждой конференции, которую я посещаю, кто-нибудь спрашивает меня, сколько времени займёт выполнение CHECKDB для их базы данных. Есть несколько способов ответить на этот вопрос:
- Бесполезный ответ: понятия не имею.
- Почти полезный ответ: сколько времени это заняло в прошлый раз и полностью ли одинаковы условия сейчас?
- Ответ, который я обычно даю: зависит от обстоятельств.
Многие люди сочли бы третий ответ в некоторой степени эквивалентным первому — бесполезным. Проблема в том, что существует множество факторов, влияющих на то, сколько времени займёт выполнение CHECKDB. Позвольте мне объяснить десять наиболее важных факторов, чтобы вы поняли, почему это на самом деле полезный ответ. Они перечислены не в порядке важности.
1) Размер базы данных
Довольно очевидно... CHECKDB должен прочитать каждую выделенную страницу в базе данных, поэтому чем больше база данных, тем больше времени потребуется на чтение всех страниц.
2) Конкурентная нагрузка ввода-вывода на сервере
На самом простом уровне, что делает CHECKDB? Он читает каждую выделенную страницу в базе данных. Это очень большой объём ввода-вывода. CHECKDB прилагает большие усилия, чтобы выполнять максимально эффективный ввод-вывод, считывая страницы базы данных в их физическом порядке с упреждающим чтением (readahead). Если на сервере нет конкурентной нагрузки ввода-вывода, то операции ввода-вывода будут настолько эффективны, насколько CHECKDB может их сделать. Однако добавление любого дополнительного ввода-вывода от SQL Server замедляет операции ввода-вывода CHECKDB. Если подсистема ввода-вывода уже находится на пределе своих возможностей из-за требований CHECKDB, любой дополнительный ввод-вывод снизит пропускную способность, доступную CHECKDB, — замедляя его.
3) Конкурентная активность ЦП на сервере
На следующем уровне простоты CHECKDB будет обрабатывать каждую прочитанную страницу тем или иным способом. В зависимости от различных указанных вами опций и схемы базы данных (подробности ниже) это будет использовать много ЦП — возможно, сервер будет загружен на 100% ЦП во время выполнения CHECKDB. Если на сервере есть какая-либо дополнительная нагрузка, она отнимет такты ЦП у CHECKDB и замедлит его.
По сути, пункты 2 и 3 говорят о том, что CHECKDB очень ресурсоёмок! Это, вероятно, одна из самых ресурсоёмких задач, которые вы можете попросить SQL Server выполнить, поэтому обычно рекомендуется не запускать его в часы пиковой нагрузки, так как вы не только заставите CHECKDB выполняться дольше, но и замедлите конкурентную нагрузку, возможно, до неприемлемого уровня.
4) Конкурентная активность обновлений в базе данных
CHECKDB получает согласованное представление базы данных из моментального снимка базы данных (database snapshot), который хранится на тех же дисковых томах, что и сама база данных. Если во время выполнения CHECKDB в базе данных происходит много изменений, изменённые страницы перемещаются в снимок, чтобы он оставался согласованным. Поскольку файлы снимка хранятся в том же месте, что и файлы базы данных, то чем больше конкурентных изменений в базе данных, тем больше прерываний эффективного ввода-вывода и тем медленнее работает CHECKDB.
5) Пропускная способность подсистемы ввода-вывода
Это просто. CHECKDB выполнит огромное количество операций ввода-вывода и может даже оказаться связанным с вводом-выводом (IO-bound), то есть ЦП будут периодически простаивать в ожидании завершения операций ввода-вывода, в зависимости от указанных опций и схемы базы данных. Это означает, что пропускная способность подсистемы ввода-вывода будет напрямую влиять на время выполнения CHECKDB. Итак, если у вас есть база данных объёмом 1 ТБ, а подсистема ввода-вывода может обеспечить только 100 МБ/сек, то только на чтение базы данных потребуется почти 3 часа (1 ТБ / 100 МБ / 3600 сек), и вы ничего не можете сделать, чтобы ускорить это, кроме как модернизировать подсистему ввода-вывода.
6) Количество ЦП (ядер обработки) на сервере
Это также включает в себя редакцию SQL Server, которая запущена. В Enterprise Edition CHECKDB может выполняться параллельно на всех ЦП в сервере (или на стольких, сколько решит процессор запросов, когда внутренние запросы CHECKDB компилируются). Параллельное выполнение может дать значительный прирост производительности CHECKDB и сократить время выполнения, при условии, что база данных также распределена по нескольким файлам (чтобы операции ввода-вывода могли быть распараллелены). Существует хитроумный алгоритм, который позволяет CHECKDB выполняться параллельно, и я объясню его подробно в отдельной статье.
С другой стороны, тот факт, что CHECKDB может выполняться параллельно в Enterprise Edition, может быть плох для некоторых сценариев, поэтому некоторые администраторы баз данных предпочитают принудительно делать CHECKDB однопоточным. SAP обычно рекомендует это для улучшения предсказуемости пользовательских запросов. Способ сделать это — включить документированный флаг трассировки 2528.
7) Скорость дисков, на которых размещена tempdb
Выполнение CHECKDB против очень большой базы данных (VLDB) использует много памяти для внутреннего состояния, и для VLDB потребность в памяти обычно превышает объём памяти, доступный SQL Server. В этом случае состояние выгружается в tempdb, поэтому производительность tempdb может быть критическим фактором производительности CHECKDB.
8) Сложность схемы базы данных
Это может оказать очень большое влияние на время выполнения CHECKDB, потому что это влияет на объём ЦП, который требуется CHECKDB. Например, самые дорогостоящие проверки, которые выполняет CHECKDB, — это проверки некластерных индексов. Ему нужно проверить, что каждая строка в некластерном индексе соответствует ровно одной строке в куче или кластерном индексе для таблицы, и что каждая строка кучи/кластерного индекса имеет ровно одну соответствующую строку в каждом некластерном индексе. Хотя для этого существует очень эффективный алгоритм, он всё равно занимает около 30% от общего ЦП, используемого CHECKDB!
Существует множество других проверок, которые выполняются только в том случае, если функции использовались в базе данных, — например, вычисление вычисляемых столбцов, связи между значениями LOB, хранящимися вне строки, Service Broker, XML-индексы, индексированные представления, — так что вы видите, что одних эмпирических факторов недостаточно для определения времени выполнения.
9) Какие параметры указаны
Это почти то же самое, что пункт 8, но с указанием различных параметров вы ограничиваете то, какие проверки CHECKDB фактически выполняет. Например, использование параметра WITH NOINDEX отключает проверки некластерных индексов, а использование параметра WITH PHYSICAL_ONLY отключает все логические проверки, что значительно сокращает время выполнения CHECKDB и делает его почти всегда связанным с вводом-выводом, а не с ЦП. Фактически, это наиболее распространённый параметр, который администраторы VLDB используют, чтобы сделать время выполнения CHECKDB управляемым.
Одна вещь, о которой следует знать: если вы указываете какие-либо параметры восстановления (repair options), CHECKDB всегда выполняется в однопоточном режиме, даже на многопроцессорном сервере с Enterprise Edition.
10) Количество и тип повреждений, существующих в базе данных
Опять же, это похоже на пункты 8 и 9. Если присутствуют какие-либо повреждения, могут быть запущены дополнительные проверки, чтобы попытаться выяснить более подробную информацию о повреждениях. Например, для проверок некластерных индексов алгоритм сильно настроен на случай отсутствия повреждений (подавляющее большинство случаев, учитывая миллионы запусков CHECKDB каждый день по всему миру). Когда обнаруживается повреждение некластерного индекса, необходимо использовать более глубокий алгоритм, чтобы точно определить, где находится повреждение, что включает повторное сканирование некоторых данных и, следовательно, занимает больше времени. Есть и несколько других подобных алгоритмов.
Резюме
Итак, вы видите, что нет простого ответа.

Комментариев нет:
Отправить комментарий