Вопросы и ответы по SQL: Строки, превышающие размер страницы, разностные резервные копии и другое

OSzone.net » СУБД » MS SQL » Вопросы и ответы по SQL: Строки, превышающие размер страницы, разностные резервные копии и другое
Автор: Пол С. Рэндал
Иcточник: TechNet Magazine
Опубликована: 27.01.2009
В Я недавно обновил приложение для работы на SQL Server 2005. Среди того, чем я воспользовался, была возможность создавать строки большей длины, чем 8060 байт, что позволяет мне разрешить пользователям создавать более длинные поля данных без получения ошибки от SQL Server. Теперь, когда это приложение находится в рабочей среде, у нас возникают проблемы с производительностью для некоторых запросов поиска, которые работали нормально до этого изменения схемы. Я проверил фрагментацию различных индексов – все должно быть в порядке. Почему запросы на SQL Server 2005 работают медленно?

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

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

Именно этот механизм используется для хранения обычных столбцов бизнес-объектов (больших объектов), таких как XML, текст, изображения или данные типа varchar(max). Обратите внимание, что если схема таблицы содержит несколько столбцов различной длины, то нельзя гарантировать, что при превышении размера нескольких строк за пределы строки будет вытолкнут один и тот же столбец.

Этот механизм может создать проблему с производительностью. Запрос на получение столбца переменной длины от одной строки в таблице может требовать дополнительного ввода-вывода, если столбец был вытолкнут за пределы строки (для чтения в текстовой странице, содержащей находящееся за пределами строки местоположение значения). Если несколько столбцов имеют слишком большой размер, то производительность запроса на получение одного и того же столбца переменной длины из нескольких строк может быть непредсказуема в зависимости от того, сколько строк было вытолкнуто за пределы страницы.

В вашем случае запрос, выполняющий поиск в диапазоне или таблице для списка выбора, включающего в себя столбец переменной длины, страдает от низкой производительности в силу превышения размеров страницы строками и его влияния. Даже если индексы идеально фрагментированы, это не имеет значения: когда столбец переменной длины выталкивается за пределы страницы, то ранее экономный поиск, по сути, прерывается, поскольку для чтения текстовой страницы, содержащей вытолкнутое значение, нужен ввод-вывод произвольного доступа.

Строки, превышающие размер страницы, по-прежнему полезны в случае отдельных слишком длинных строк. Но если производительность запросов действительно важна, то этот компонент не следует использовать активно.


В Мы только что ввели зеркалирование баз данных между двумя отказоустойчивыми кластерами как способ достижения географического дублирования, более дешевого, чем репликация сети области хранения (SAN). Центры данных находятся в одном городе, поэтому мы можем использовать синхронное зеркалирование. Проблема заключается в том, что при переходе на другой ресурс в локальном кластере зеркалированная база данных переходит на удаленный кластер, что нежелательно. Как это предотвратить? Нужно, чтобы переход происходил только в случае недоступности локального кластера.

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

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

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

Второй способ – это изменение стандартного времени истечения зеркалирования базы данных. Это число происходящих раз в секунду проверок связи, на которые основное сервер должен не ответить, прежде чем он будет объявлен недоступным. Этот параметр именуется истечением времени партнера, и его значение по умолчанию – 10. Текущее значение истечения времени для базы данных можно найти, используя следующий код:

SELECT [mirroring_connection_timeout]
  FROM master.sys.database_mirroring
  WHERE [database_id] = DB_ID ('mydbname');
GO

Изменить его можно при помощи следующего кода:

ALTER DATABASE mydbname
  SET PARTNER TIMEOUT <timeoutvalue>;
GO

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


В В мою стратегию резервного копирования входит создание полных резервных копий и резервных копий журнала, но говорят, что для уменьшения времени восстановления к ней следует добавить разностные резервные копии. Я создаю полную резервную копию раз в неделю, а резервную копию журнала раз в час. Я попробовал добавить ежедневные разностные копии, но заметил, что разностные копии в конце недели приближаются по размеру к еженедельным полным резервным копиям. Мне казалось, что они записывают лишь изменения, подобно резервным копиям журнала. Я что-то упустил?

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

Когда блок (логическая группа из восьми непрерывных страниц файла данных) изменяется каким бы то ни было образом, он помечается на специальной странице битовой карты, обычно именуемой картой различий. Карта различий присутствует для каждых 4 ГБ каждого файла данных. При снятии разностной резервной копии подсистема резервного копирования проверяет все эти карты и копирует все изменившиеся блоки, но карты различий при этом не сбрасываются. Это значит, что если между последовательным созданием разностных копий изменились еще блоки, то более поздние копии будут больше. Карты различий сбрасываются лишь при создании полной резервной копии.

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

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

Это может потребовать восстановления массы резервных копий журнала, особенно если сбой произошел непосредственно перед следующим полным резервным копированием. (В наихудшем случае это будет означать необходимость восстанавливать 24 + 24 + 24 + 24 + 24 + 24 + 23 резервных копии журнала!) Добавление ежедневного разностного резервного копирования к этой стратегии меняет действия при восстановлении на приведенные ниже.

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

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


В У меня есть отказоустойчивый кластер из двух узлов. На каждом из узлов работает единственный экземпляр SQL Server 2005. Я следую обычному совету и устанавливаю каждый экземпляр на использование лишь 50% доступной памяти. Теперь у меня возникли проблемы, поскольку рабочая нагрузка на обоих экземплярах требует большего объема памяти для поддержания тех же уровней производительности. Если я устраню ограничение на память или сделаю его выше, то, наверное, столкнусь с проблемами при переходе одного из экземпляров на резервный ресурс и их одновременной работе на одном узле. Что вы могли бы порекомендовать?

О Я отвечу на этот вопрос для случая двух узлов и двух экземпляров, но все написанное ниже применимо и к случаям наличия иного числа экземпляров (N-1 отказоустойчивых кластеров с N узлами и N-1 экземплярами SQL Server на каждом).

Многие сталкиваются с высокой рабочей нагрузкой (поглощающей более 50% памяти сервера) на том и другом экземпляре и не принимают во внимание результаты работы на одном узле после перехода на резервный ресурс для рабочих нагрузок. Без специальной настройки распределение памяти между экземплярами может стать непропорциональным, так что одна из рабочих нагрузок будет работать нормально, а вторая еле продвигаться.

В случае SQL Server 2000 рекомендации заключаются в ограничении каждого экземпляра использованием не более чем 50% памяти узла кластера. Это вызвано тем, что диспетчер памяти в SQL Server 2000 не отвечает на требование памяти – если SQL Server поглощает, скажем, 80% памяти узла, он не отдаст ее обратно. В ситуации перехода на резервный ресурс это значит, что другому только что запустившемуся экземпляру будет доступно не более 20% памяти. В случае ограничения обоих экземпляров максимумом в 50% памяти узла, перешедшему экземпляру будут гарантированы эти 50%. Проблема в том, что рабочая нагрузка каждого из экземпляров также будет ограничена этими 50%.

В случае SQL Server 2005 (и SQL Server 2008) диспетчер памяти начинает отвечать на требование памяти, так что максимум в 50% больше не является адекватным. Но при отсутствии всяких ограничений два экземпляра, работающих на одном узле кластера могут давить друг на друга, пока не достигнуто непропорциональное распределение памяти.

Ответ заключается в установке минимального объема памяти для каждого экземпляра, чтобы они не могли отбирать друг у друга слишком много памяти. Распространенным параметром для случая двух узлов и двух экземпляров является выделение каждому из экземпляров минимум 40% памяти. Это означает, что когда каждый экземпляр работает на отдельном узле, он потребляет столько памяти, сколько хочет. В случае перехода на резервный ресурс каждому экземпляру гарантируется определенный объем памяти для сохранения установленного уровня производительности рабочей нагрузки, и небольшой объем оставляется для общего использования. Хотя это значит, что в случае перехода производительность обеих рабочих нагрузок упадет (как и ожидается), они не будут ограничены все время, когда каждый экземпляр работает на отдельном узле кластера.


Ссылка: http://www.oszone.net/8531/