Вопросы и ответы по SQL. Сжатие резервных копий, перенаправление клиентов при помощи зеркалирования баз данныхИсточник: oszone
Q Мы собираемся обновить большинство наших серверов до SQL Server 2008, и одна из функций, появления которых в производственной среде я жду с нетерпением, - сжатие резервных копий. Я знаю, что могу включить ее по умолчанию для всех баз данных на каждом сервере, но я также слышал, что, возможно, этого не стоит делать. Я не уверен, почему ее может быть нежелательно включать по умолчанию, поскольку кажется, что терять здесь нечего. Не могли бы вы помочь объяснить причины этого?
О. Ответом здесь будет мой неизменно любимый: все зависит от обстоятельств! Позвольте мне для объяснения привести некоторую базовую информацию. Ключевым моментом, который следует учесть, является степень сжатия, которую будет иметь каждая резервная копия базы данных, когда включено сжатие резервных копий. Степень сжатия при использовании любого алгоритма определяется тем, какие именно данные сжимаются. Случайные данные (мелкие целочисленные значения, например) буду сжиматься не слишком хорошо, так что возможную степень сжатия будет определять в основном содержимое таблиц и индексов в базе данных. Вот несколько примеров случаев, когда сжатие резервных копий может не дать высокой степени сжатия:
В случае, когда степень сжатия низка, проблема состоит не в самой низкой степени, а в том, что ресурсы ЦП, используемые для выполнения алгоритма сжатия, не приносят пользы. Вне зависимости от того, насколько хорошо можно сжать участок данных, ресурсы ЦП всегда используются для выполнения алгоритмов сжатия и распаковки. Это значит, что перед принятием решения о постоянном использовании сжатия для этой базы данных необходимо проверить, насколько хорошо каждая база данных сжимается в резервную копию. Иначе возможна бессмысленная трата ресурсов ЦП. Это и лежит в основе того, что вы слышали. Вкратце, если основная часть баз данных получит выгоды от сжатия резервных копий, имеет смысл включить сжатие резервных копий на уровне сервера и вручную изменить несколько задач резервного копирования, чтобы специально использовать параметр WITH NO_COMPRESSION. Как вариант, если основная часть баз данных не получит выгоды от сжатия резервных копий, имеет смысл отключить сжатие резервных копий на уровне сервера и вручную изменить несколько задач резервного копирования, чтобы специально использовать параметр WITH COMPRESSION. В. В прошлом году мы обновили наши базы данных, чтобы внести в них зеркалирование, позволяющее в случае сбоя перейти на зеркальную копию и продолжить работу. При разработке системы мы выполняли такие переходы для базы данных, и всё работало нормально. На прошлой неделе мы столкнулись с реальным сбоем, и переход базы данных произошел, но все транзакции приложения остановились, и приложение не подключилось к отказоустойчивому серверу. Как я могу установить SQL Server в будущем, чтобы он не сбрасывал подключения к приложениям в ходе перехода, чтобы транзакции могли продолжаться? О. Давайте разобьем ответ на две части: как приложения могут справляться с отказоустойчивостью и как управлять перенаправлением клиентов с помощью зеркалирования баз данных. Когда происходит переход при сбое с использованием любой из технологий высокой доступности, имеющихся в SQL Server, подключение клиента к потерпевшему сбой серверу сбрасывается, и все находившиеся в работе транзакции теряются. Перенос находящейся в пути транзакции между серверами невозможен (как в случае перехода при отказе, так и любом другом). В зависимости от применяемой технологии высокой доступности находящаяся в работе транзакция либо не будет существовать вообще на отказоустойчивом сервере, либо будет существовать как находящаяся в работе транзакция, но будет откатана обратно в качестве процесса восстановления работоспособности базы данных на отказоустойчивом сервере. Что касается зеркалирования баз данных, постоянно пересылающего записи журнала транзакций от основного сервера к зеркальному серверу, то обычно произойдет второе - находящиеся в работе транзакции откатываются в процессе восстановления работоспособности зеркальной базы данных на новом участнике безопасности. В силу этого имеются две вещи, которые приложение должно уметь делать корректно при работе на сервере с возможностью перехода на другой сервер при отказе:
Единственная технология высокой доступности здесь, которая не требует конкретно изменений на клиенте, чтобы позволить перенаправление клиентских подключений после перехода, - это отказоустойчивая кластеризация. Клиенты подключаются к имени виртуального сервера и прозрачно перенаправляются к активному узлу физического кластера. В случае технологий высокой доступности, таких, как доставка журналов и репликация, имя сервера отказоустойчивости отличается, а это значит, что после перехода на данный сервер необходимо перенаправление клиентских подключений вручную. Это перенаправление можно выполнить несколькими способами:
С помощью зеркалирования баз данных сработает любой из этих вариантов. Но зеркалирование баз данных также имеет встроенные возможности направления клиента. Строка подключения клиента может прямо указать имя зеркального сервера, к которому автоматически произойдет попытка подключения если оно невозможно к основному. Этот процесс известен как прямое перенаправление. Если строку подключения клиента невозможно изменить, то может быть возможно непрямое перенаправление, если потерпевший сбой сервер теперь работает как зеркальный сервер. Любое подключение к нему будет автоматически перенаправлено к новому участнику безопасности - но это сработает, только если зеркальный сервер функционирует. В техническом документе по SQL Server 2005 "Реализация отказоустойчивости приложений с помощью зеркалирования баз данных" эти варианты объяснены подробнее. В. Когда мы перешли на SQL Server 2005, мы переработали наши крупные таблицы, чтобы они разделялись на разделы образом, позволяющим воспользоваться пораздельным обслуживанием и механизмом скользящего окна. Это было описано в выпуске за август 2008 года ("Разделение, проверки согласованности и другое"). Но мы столкнулись с проблемой. Порой параллельные запросы приложения испытывают блокировку по всей таблице, даже когда запросы пытаются получить доступ к различным разделам. Я слышал, что в SQL Server 2008 данная проблема исправлена - не могли бы вы объяснить, как я могу остановить эту блокировку? Рис. 1. Изучение блокировок на таблице, поделенной на разделы О. Наблюдаемая проблема вызвана механизмом, именуемым укрупнением блокировок. SQL Server получает блокировки на данные, чтобы защитить их, пока запрос читает или записывает данные. Он может получать блокировки на целые таблицы, страницы файлов данных или отдельные строки таблиц/индексов, и каждая блокировка занимает небольшое пространство в памяти. Если запрос вызывает получение слишком большого числа блокировок, SQL Server может решить заменить все блокировки на строки или страницы в таблице единой блокировкой на всю таблицу (порог, где это происходит, составляет примерно 5000 блокировок, но точный алгоритм замысловат и настраиваем). Этот процесс называется укрупнением блокировок. В SQL Server 2005, если запрос А работает на одном разделе таблицы и вызывает получение достаточного числа блокировок, чтобы вызвать их укрупнение, вся таблица становится заблокированной. Это может предотвратить работу запроса Б на другом разделе той же таблицы. В силу этого, запрос Б блокируется, пока запрос А не завершит работу и не сбрасывает свои блокировки. В SQL Server 2008 механизм улучшения блокировок был улучшен, чтобы позволить таблице производить укрупнение блокировок на уровне разделов. В вышеприведенном примере это означает, что укрупнение блокировок, вызванное запросом А, приведет лишь к блокировке раздела, используемого запросом А, а не всей таблицы. Тогда запрос Б сможет работать на другом разделе, не подвергаясь блокировке. Запрос Б даже сможет сам вызвать укрупнение блокировок, которое заблокирует только раздел, на котором работает запрос Б, а не всю таблицу. Эту модель укрупнения блокировок можно установить, используя следующий синтаксис: ALTER TABLE MyTable SET (LOCK_ESCALATION = AUTO); GO Этот синтаксис указывает диспетчеру блокировок SQL Server использовать укрупнение блокировок на уровне разделов, если таблица разбита на них, и обычное укрупнение на уровне таблицы, если нет. Поведением по умолчанию является использование укрупнения блокировок на уровне таблицы. Устанавливать этот режим следует со осторожностью, поскольку в зависимости от поведения запросов он может привести к взаимоблокировкам. Например, если каждый из запросов А и Б вызывает укрупнение блокировок различных разделов в таблице, но затем пытается получить доступ к разделу, заблокированному другим, один из запросов будет прерван монитором взаимоблокировок. На рисунке показан пример запроса представления системного каталога sys.partitions (первый набор результатов) и динамического административного представления sys.dm_os_locks (второй набор результатов), чтобы изучить блокировки, удерживаемые для запросов на таблице, поделенной на разделы, где произошло укрупнение блокировок на уровне разделов. В данном случае существуют две исключительные блокировки уровне раздела (блокировки HOBT в выводе), но блокировки таблиц (блокировки OBJECT в выводе) не исключительны, так что несколько запросов смогут получать доступ к разделам, несмотря на укрупнение блокировок. Заметьте, что идентификаторы ресурсов для этих двух блокировок разделов совпадают с идентификаторами разделов для первых двух разделов таблицы в выводе для sys.partitions. Ранее в этом году поместил в блог пример сценария, показывающий, как работает эскалация блокировок на уровне раздела и потенциал для взаимоблокировок. В теме электронной документации по SQL Server 2008 под названием "Блокировка в механизме базы данных" содержится подробное разъяснение всех аспектов блокировок в SQL Server 2008. В. На одном из наших серверов возникли определенные проблемы с диском, содержащим журнал транзакций для базы данных, и база данных стала ненадежна. Последнее полное резервное копирование произошло пять недель назад, и восстановление всех резервных копий журнала также должно было занять слишком много времени. Проблема возникла во внерабочее время, так что мы восстановили испорченный журнал транзакций, чтобы избежать простоя. В определенных обстоятельствах это может вызвать проблемы. Но если ничто не получало доступ к данным, то я считаю, что все в порядке. Верно ли мы поступили? О. Вкратце ответ состоит в том, что о восстановлении журнала транзакций я мог бы задуматься, только если восстановление из резервных копий невозможно. Хотя вам и известны опасности восстановления журнала транзакций (читатели могут посмотреть запись в моем блоге "Крайние меры, применяемые в первую очередь...", чтобы узнать о них), факт того, что база данных стала ненадежной, означает то, что восстановление окончилось неудачей, - либо при восстановлении после сбоя, либо при откате транзакции. Это означает реальную возможность повреждения данных в базе данных. Хотя проблема и возникла в тихое время, подумали ли вы о запланированных и фоновых задачах? В момент повреждения журнала вполне могла работать задача обслуживания, восстанавливающая или реорганизующая кластеризованный индекс. Фоновая задача вполне могла вести фантомную очистку на страницах в куче или кластеризованном индексе. Любая из этих задач, для примера, могла вносить изменения в структуры кластеризованного индекса, которые в случае непроведения правильного отката привели бы к повреждениям в базе данных и возможным потерям данных. В общем, восстановление журнала транзакций всегда должно быть самой последней и крайней мерой в любом варианте аварийного восстановления из-за огромных возможностей для дальнейших повреждений и потери данных. Как минимум, на базе данных необходимо выполнить полный DBCC CHECKDB, чтобы проверить, нет ли повреждений. Далее необходимо изменить стратегию резервного копирования, чтобы иметь возможность выполнять своевременные восстановления, а не обращаться к радикальным мерам вроде восстановления журнала транзакций. Действия по разработке этой стратегии выходят за рамки данной статьи, но я планирую осветить эту тему в полноценной специальной статье в этом году. Так что оставайтесь с нами! |