(Возврат на основную страницу)

 

Содержание номера за Март 2010 год

SQL Server

Март 2010 № 3 (111)

 

Editorial

Тони Дэвис Беспокойные драйверы

Фил Фактор Доброе слово об ODBC

Programming

Грегори А. Ларсен Эффективные приемы программирования на языке T-SQL

DB Design & Warehousing

Гэйл Шоу Помогите, моя база данных повреждена. В чем дело?

DB Design & Warehousing

Фабиано Аморим Оптимизация корреляции дат изнутри

 

Беспокойные драйверы

Тони Дэвис (Tony Davis)

Когда я только начинал заниматься компьютерными технологиями, в конце девяностых, Microsoft как раз потихоньку задвигала ODBC и начинала выставлять на первый план OLE­DB и ADO. Драйвер ODBC по­прежнему входил в состав комплекта Microsoft Windows MDAC, но его популярность была подмочена сложностью описания строк соединения и ненадежным и медленным доступом к данным. Microsoft была вынуждена оставить ODBC в комплекте, так как это был единственный способ подключиться ко всякого рода экзотическим источникам.

Большинство разработчиков для VB/ASP приняли ADO и OLEDB, так как им обещали более высокую производительность. Строки соединения не стали сильно проще, но разработчики упорно продвигались вперед. К счастью, теперешние разработчики под .NET получили в свое распоряжение ADO.NET, позволяющий подключаться к SQL Ser­ver через OLEDB, SQLClient или ODBC.

Однако, если вы работаете с неуправляемым (un­managed) кодом, дела обстоят хуже. С появлением SQL Server 2005 Microsoft решила не обновлять MDAC для поддержки нового функционала и типов данных. Вместо этого она ввела SQL Native client (SQLNCLI — собственный клиент), который предлагает сведенную воедино функциональность ODBC и OLEDB, размещенную в одной DLL и поддерживающую всю новую функциональность и все новые типы данных, — пользовательские типы, XML, varchar(max), snapshot isolation, Multiple Active Result Sets и так далее. Все старенькие неуправляемые приложения, которые использовали ADO /MDAC и не нуждались в новом функционале могут по­прежнему использовать MDAC, ныне торопливо переименованный в Windows DAC; или приложения требуется перевести с поддержкой SQL Server Native Client.

Непохоже, чтобы собственный клиент оказался более мощным или надежным по сравнению с MDAC, который имел тенденцию время от времени «заваливать» приложение после установки очередного пакета обновлений Windows. К сожалению, смельчаки, оставившие MDAC в пользу the native client в погоне за новым функционалом SQL вступили на минное поле («Обновление приложения с переходом от компонентов MDAC к собственному клиенту SQL Server», http://msdn.microsoft.com/ru­ru/library/ms131035.aspx). В то время как MDAC более или менее терпимо относился к нечеткому соблюдению спецификаций (как, например, именование параметра с символа “@”), native client ведет себя бескомпромиссно и выдает ошибку. Нашлось также множество мелких отличий в поведении — описании строк соединения, обработки ошибок соединений, предупреждений и сообщений об ошибках и даже в базовых вещах обработки транзакций. И ведь нельзя сказать, чтобы новый функционал поддерживался в полном объеме. Да собственный клиент поддерживает тип xml и запросы FOR XML …но это и все. Больше ничего из XML арсенала не поддерживается. Для этого придется использовать SQLXML.

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

Вместо этого новые драйверы приходят и уходят, вместе с ними появляются и исчезают новые стандарты доступа к данным, такие как LINQ и EF, в результате, разработчики парализованы обилием выбора и не в состоянии даже нормально обновить свои приложения, чтобы поддержать функционал последней версии СУБД.

Доброе слово об ODBC

Фил Фактор (Phil Factor)

Я бы хотел сказать доброе слово в адрес одного из незаслуженно забытых столпов технологии доступа к данным от MicrosoftODBC. Даже если вы надежно закуклились в среде .NET, это так приятно время от времени получить доступ к широкому спектру источников данных, таких как Clipper, Ingres, Lotus Notes, ADABAS или LDAP с использованием Call­Level интерфейса, являющегося международным SQL стандартом. Он позволяет использовать один и тот же код для доступа к такой экзотике как IBM i5/OS, Linux, системы на базе Mac OS X или к SQL Server из приложения, работающего под Linux. ODBC — быстр.

В конце концов, самый быстрый способ завести данные в SQL Server — это BCP, которая использует ODBC. (через специализированный BCP API). Там, где LINQ только обещает универсальный доступ через посредство провайдеров, ODBC обеспечивает требуемое в течение уже многих лет.

В глубине ADO.NET и SQL Native Clientпо­прежнему лежит великая система на базе ODBC 3.51, если она нужна вам. Каждая копия Windows включала этот функционал. Почему нет?

«Не начинай все сначала, Фил, — слышу я ваши мысли. — А что там насчет проклятия мало понятных строк соединения ODBC? Что там такого уж хорошего в части поддержки стандарта SQL? Почему ни один из драйверов для доступа к настольным БД (Desktop Database Driver) никогда не работал стабильно?»

«OK. Можно прикрыться от строк соединения. Я видел приложения, которые вполне успешно этого добивались; А эти жуткие сообщения от Jet? Хотя поддержка SQL Server для ODBC выполнена великолепно, драйверы от Microsoft кроме драйвера для SQL Server всегда были плохи. Третьи фирмы вышли на рынок с богатым набором прекрасных драйверов, но драйверы от Microsoft для поддержки настольных БД едва поддерживали минимальный SQL синтаксис. Поддержка ODBC представлена на трех уровнях: minimum, Core и Extended. Если у нас есть драйверы, обеспечивающие хотя бы уровень Core, мы считаем себя счастливыми. Драйверы Microsoft для настольных БД едва поддерживали минимальную грамматику».

Я недавно я открыл свой надежный, зачитанный том «ODBC 2.0 Programmers Reference and SDK» 1992 года издания. Это было великолепное чтение. Даже с высоты прошедших лет все выглядело очень стройно, архитектура была подозрительно близка к тому, что описывается для LINQ. Получить метаданные для ODBC источника? Нет проблем! Даже ограничения? Конечно. Расширенный драйвер предоставляет мощный интерфейс для доступа к данным и развитый API. А как насчет аппаратно независимого диалекта SQL? Да, все тут.

Много можно сказать в пользу ODBC как средства решения многочисленных проблем доступа к данным, которые встают перед нами сегодня. Конечно, многие драйверы необходимо расширить для получения доступа к новым типам данных; да, они не предоставляют полной информации о схеме данных для сложного приложения. Инструменты, которые работают с БД только через ODBC, не смогут конкурировать с теми, что берут сведения напрямую из БД. Но это все проблемы, вполне поддающиеся решению. С ODBC/JDBC мы близки к созданию эффективного универсального стандарта доступа к разнообразным данным на разных платформах и приложениях. Это кажется достойной целью.

Историю интерфейсов доступа к данным Microsoft, рассказанную архитектором Майком Пиццо, см. здесь: http://blogs.msdn.com/data/archive/2006/12/05/data-access-api-of-the-day-part-i.aspx.

Эффективные приемы программирования на языке T-SQL

Не используйте скалярные функции в списке столбцов или в предложениях WHERE

Грегори А. Ларсен (Gregory A. Larsen)

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

Типы функций

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

Я не уверен, известно ли уже большинству из вас, что такое скалярная функция. Но просто на тот случай, если вы этого не знаете, я приведу ее определение, чтобы мы с вами говорили на одном языке. Скалярная функция — это функция, которая возвращает единственное значение.

Не забывайте о том, что не все скалярные функции создаются одинаково. Некоторые скалярные функции ссылаются на данные в таблицах, тогда как другие этого не делают. В этой статье мы будем говорить о скалярных функциях, которые получают входные параметры, а затем используют эти параметры, чтобы считать какие­то данные из базы данных, и вернуть значение обратно, в предложение языка T­SQL, откуда была вызвана функция.

Помогите, моя база данных повреждена.
В чем дело?

Гэйл Шоу (Gail Shaw)

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

Как выявить повреждение

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

SQL Server detected a logical consistency-based I/O error: incorrect checksum (expected: 0xfdff74c9;
actual: 0xfdff74cb). It occurred during a read of page (1:69965) in database ID 13 at offset
0x0000002229a000 in file 'D:\Develop\Databases\Broken1.mdf'.
Attempt to fetch logical page 1:69965 in database 13 failed. It belongs to allocation unit
72057594049069056 not to 281474980642816.

(SQL Server обнаружил логическую ошибку ввода-вывода, связанную с согласованностью: неправильная контрольная сумма (ожидаемое значение: 0xfdff74c9;
фактическое значение: 0xfdff74cb). Ошибка произошла во время чтения страницы (1:69965) в базе данных с идентификатором 13 по смещению 0x0000002229a000
в файле 'D:\Develop\Databases\Broken1.mdf'.
Попытка извлечь логическую страницу 1:69965 в базе данных 13 не удалась. Страница принадлежит единице размещения 72057594049069056, а не 281474980642816.)

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

Я не собираюсь рассматривать случай, когда база данных находится в состоянии SUSPECT (подозрительная). Рассмотрение возможных причин, по которым БД берется «под подозрение», методов выявления этих причин и различных средств их устранения само по себе может послужить темой для статьи, если не для целой книги.

Что делать при повреждении базы данных

•    Не паниковать.

•    Не отсоединять базу данных.

•    Не перезапускать SQL Server.

•    Не бросаться немедленно исправлять ошибки.

•    Выполнить проверку целостности.

•    Заняться анализом первопричин.

Не паниковать

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

Не отсоединять базу данных

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

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

Не перезапускать SQL Server

Аналогично отсоединению БД, перезапуск службы SQL не приведет к исправлению повреждения, если оно есть.

Так же как и отсоединение базы данных, перезапуск этой службы может ухудшить ситуацию. Если SQL Server сталкивается с повреждением во время выполнения перезапуска­восстановления базы данных, эта БД будет помечена как SUSPECT (подозрительная), т. е. потенциально имеющая повреждения, что существенно затруднит любые необходимые исправления.

Не бросаться немедленно исправлять ошибки

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

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

Выполнить проверку целостности

Чтобы выбрать метод устранения повреждения, необходимо располагать подробной информацией о том, что именно повреждено. Единственным способом получения такой информации является выполнение инструкции CheckDB с опцией All_ErrorMsgs (в версии 2005 SP3, выполнение инструкции CheckDB с опцией All_ErrorMsgs предусмотрено по умолчанию, и явно указывать эту опцию не надо; ее также не надо указывать в версии SQL 2008).

Кроме того, использование опции No_Infomsgs обеспечит удаление всей информации о количестве строк и страниц в таблице: для устранения повреждения эта информация не нужна. (При проверке целостности следует выполнять команду DBCC Checkdb в консоли с выводом результатов в файл. В среде SQL Server Management Studio максимальное число возвращаемых сообщений об ошибках равно 1000. — Прим. ред.)

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

Анализ первопричин

Устранить повреждение — это только часть работы. Если не выяснена его первопричина, повреждение может возникнуть снова. Обычно, самой распространенной причиной повреждения являются проблемы, связанные с подсистемой ввода­вывода. Другими возможными причинами являются неправильно функционирующие фильтрующие драйверы (например, антивирусы), вмешательство человека или ошибка в SQL­коде.

Дальнейшие шаги

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

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

Если кто­либо сталкивается с ошибкой, которая здесь не описана, см. последний раздел в этой статье «Получение помощи».

Неверные метаданные о дисковом пространстве

Msg 2508, Level 16, State 3, Line 1

The In-row data RSVD page count for object "Broken1", index ID 0, partition ID 76911687695381, alloc unit ID 76911687695381 (type In-row data) is incorrect. Run DBCC UPDATEUSAGE.

(Ошибка 2508, степень серьезности 16, состояние 3, строка 1. Неверный подсчет страниц RSVD для объекта «Broken1», идентификатор индекса 0, идентификатор секции 76911687695381, идентификатор единицы размещения 76911687695381(тип «данные в строке» [In-row data]). Выполните команду DBCC UPDATEUSAGE.)

Эта ошибка указывает на то, что страница содержит некорректное значение для зарезервированного пространства. В версии SQL 2000 допускались некорректные, и даже отрицательные, значения счетчиков строк и страниц для таблицы или индекса. Инструкция CheckDB их не отслеживала. В версии SQL 2005 эти счетчики должны иметь правильные значения, и инструкция CheckDB выдает предупреждение, когда сталкивается с таким сценарием.

Данная проблема не является серьезной, и ее решение тривиально. Как сказано в сообщении, выполните инструкцию DBCC UPDATEUSAGE применительно к проблемной базе данных, и предупреждения исчезнут. Неверные значения счетчиков чаще всего встречаются в тех базах данных, для которых было выполнено обновление с версии SQL 2000, по причинам, названным выше, и эта проблема не должна возникать в базах данных, созданных в версиях SQL 2005 и SQL 2008.

Msg 8914, Level 16, State 1, Line 1
 Incorrect PFS free space information for page (1:26839) in object ID 181575685, index ID 1, partition ID 293374720802816, alloc unit ID 76911687695381 (type LOB data). Expected value
0_PCT_FULL, actual value 100_PCT_FULL.

(Ошибка 8914, степень серьезности 16, состояние 1, строка 1
Неверные сведения о свободном месте PFS для страницы (1:26839) в объекте c идентификатором 181575685, идентификатор индекса 1, идентификатор секции 293374720802816, идентификатор единицы размещения 76911687695381 (тип «данные LOB»). Ожидаемое значение 0_PCT_FULL, фактическое значение: 100_PCT_FULL.)

Эта ошибка указывает на то, что страница PFS (свободное место на страницах), которая используется для отслеживания заполнения страниц, содержит некорректные значения. Подобно предыдущей, эта ошибка не является серьезной. Алгоритм, который используется для ее выявления в версии SQL 2000, не всегда точен. Хотя для устранения повреждения в данном случае необходимо выполнить инструкцию CheckDB с уровнем исправления Repair_Allow_Data_Loss, на самом деле, если нет никаких других ошибок, никакие данные удалены не будут.

Повреждены только некластеризованные индексы

Если все ошибки, выявленные в результате выполнения инструкции checkDB, относятся к индексам с идентификаторами (ID), значение которых равно или больше 2, значит, все повреждения находятся в некластеризованных индексах. Поскольку данные в некластеризованном индексе являются избыточными, такие повреждения можно исправить без потери данных.

Если все ошибки, которые были обнаружены при выполнении инструкции CheckDB, возникли в некластеризованных индексах, рекомендованный уровень исправления — Repair_Rebuild.

Msg 8941, Level 16, State 1, Line 1
 Table error: Object ID 181575685, index ID 4, page (3:224866). Test (sorted [i].offset >= PAGEHEADSIZE) failed. Slot 159, offset 0x1 is invalid.

(Ошибка 8941, степень серьезности 16, состояние 1, строка 1
Ошибка в таблице: идентификатор объекта 181575685, идентификатор индекса 4, страница (3:224866). Тест (sorted [i].offset >= PAGEHEADSIZE) не выполнен. Недопустимый слот 159, смещение 0х1.)

Msg 8942, Level 16, State 1, Line 1
 Table error: Object ID 181575685, index ID 4, page (3:224866). Test (sorted[i].offset >= max) failed. Slot 0, offset 0x9f overlaps with the prior row.

(Ошибка 8942, степень серьезности 16, состояние 1, строка 1
Ошибка в таблице: идентификатор объекта 181575685, идентификатор индекса 4, страница (3:224866). Тест (sorted[i].offset >= max) не выполнен. Слот 0, смещение 0x9f перекрывается с предыдущей строкой.)

Это только примеры: возможных ошибок намного больше.

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

Именно это, главным образом, и делается при выполнении инструкции CheckDB с уровнем исправления repair_rebuild, однако, для исправления необходимо, чтобы база данных находилась в однопользовательском режиме. Таким образом, лучше, как правило, перестроить индексы вручную, поскольку база данных может продолжать работу в оперативном режиме и использоваться, пока выполняется повторное создание поврежденных индексов.

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

Повреждены страницы LOB

Msg 8964, Level 16, State 1, Line 1
 Table error: Object ID 181575685, index ID 1, partition ID 72057594145669120, alloc unit ID 72057594087800832 (type LOB data). The off-row data node at page (1:2444050), slot 0, text ID 901891555328 is not referenced.

(Ошибка 8964, степень серьезности 16, состояние 1, строка 1
Ошибка в таблице: идентификатор объекта 181575685, идентификатор индекса 1, идентификатор секции 72057594145669120, идентификатор единицы распределения 72057594087800832 (тип данные LOB). Отсутствует ссылка на узел внестрочных данных на странице (1:2444050), слот 0, идентификатор текста 901891555328.)

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

Если в результате проверки с помощью инструкции CheckDB не было выявлено никаких других ошибок, тогда при выполнении этой инструкции с уровнем исправления Allow_Data_Loss проблемные страницы LOB просто будут освобождены. Поскольку строк данных, которым принадлежат эти большие объекты, не существует, освобождение страниц LOB не приведет к дальнейшей потере данных.

Ошибки правильности данных

Msg 2570, Sev 16, State 3, Line 17
 Page (1:1103587), slot 24 in object ID 34, index ID 1, partition ID 281474978938880, alloc unit ID 281474978938880 (type "In-row data"). Column "modified" value is out of range for data type "datetime". Update column to a legal value
.

(Ошибка 2570, степень серьезности 16, состояние 3, строка 17
Страница (1:1103587), область памяти 24, идентификатор объекта 34, идентификатор индекса 1, идентификатор секции 281474978938880, идентификатор единицы размещения 281474978938880 (тип "In-row"). Значение столбца "modified" выходит за пределы допустимого диапазона для типа данных "datetime". Замените значение столбца на допустимое.)

Ошибка правильности данных указывает на присутствие в столбце значения, выходящего за пределы допустимого диапазона значений для данного столбца. Это может быть значение типа datetime, в котором число минут, истекших после полуночи, превысило 1440, строка в кодировке Unicode, в которой количество байтов не кратно 2, или значение, вещественное или с плавающей запятой, с неверным количеством знаков после запятой.

По умолчанию такие ошибки не выявляются в базах данных, для которых было выполнено обновление с версии SQL 2000 или младше. Инструкция CheckDB с опцией DATA_PURITY должна быть один раз успешно выполнена до обновления.

Исправление таких ошибок при выполнении инструкции CheckDB не предусмотрено. Эта инструкция «не знает», какие значения надо поместить в столбец, чтобы заменить недопустимые значения. Исправить ошибки неправильных данных довольно легко, но это делается вручную. Неверные значения следует ежегодно обновлять какими­то имеющими смысл значениями. Главная проблема — найти «плохие» строки. Необходимые для этого шаги подробно описаны вот в этой статье из базы знаний Microsoft: http://support.microsoft.com/kb/923247.

Повреждены кластеризованный индекс или куча

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

Если какие­либо ошибки, выявленные при выполнении инструкции CheckDB, находятся в листовых страницах кластеризованного индекса, рекомендуемый уровень исправления — Repair_Allow_Data_Loss.

Server: Msg 8976, Level 16, State 1, Line 2
 Table error: Object ID 181575685, index ID 1, partition ID 76911687695381, alloc unit ID 76911687695381 (type In-row data). Page (1:22417) was not seen in the scan although its parent (1:479) and previous (1:715544) refer to it.

(Сервер: ошибка 8976, степень серьезности 16, состояние 1, строка 2
Ошибка в таблице: идентификатор объекта 181575685, идентификатор индекса 1, идентификатор секции 76911687695381, идентификатор единицы распределения 76911687695381 (тип In-row). Страница (1:22417) не видна при просмотре, хотя на нее ссылаются родительская (1:479) и предыдущая (1:715544) страницы. Проверьте наличие предыдущих ошибок.)

Server: Msg 8939, Level 16, State 1, Line 2
 Table error: Object ID 181575685, index ID 0, page (1:168576). Test (m_freeData >= PAGEHEADSIZE && m_freeData <= (UINT)PAGESIZE - m_slotCnt * sizeof (Slot)) failed. Values are
44 and 8028.

(Сервер: ошибка 8939, степень серьезности 16, состояние 1, строка 2
Ошибка в таблице: идентификатор объекта 181575685, идентификатор индекса 0, страница (1:168576). Тест (m_freeData >= PAGEHEADSIZE && m_freeData <= (UINT)PAGESIZE - m_slotCnt * sizeof (Slot)) не выполнен. Значения: 44 и 8028.)

Это только примеры; ошибок из этой группы гораздо больше. Следует обратить внимание на то, что значение упомянутого в сообщении идентификатора индекса 0 или 1. Если какая­либо из ошибок, возвращенных инструкцией CheckDB, имеет идентификатор индекса 0 или 1, значит, есть повреждения в основных таблицах.

Такого рода повреждения относятся к числу исправимых, но исправление подразумевает потерю строк или целых страниц. Если при выполнении инструкции CheckDB для исправления повреждений удаляются данные, то внешние ключи проверяться не будут, и не будет обеспечено срабатывание триггеров. Просто будут освобождены строки или страницы. Это может привести к нарушениям целостности данных (дочерние записи без «родителя») и, в конечном итоге, к логическим противоречиям в базе данных (строки некластеризованного индекса или страницы LOB, которые больше не ссылаются на строку). Раз так, выполнять исправление в данном случае не рекомендуется.

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

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

Возможно, в случае кластеризованного индекса удастся определить, что именно будет удалено при выполнении инструкции CheckDB.

См. вот эту запись в блоге: http://sqlskills.com/BLOGS/PAUL/post/CHECKDB-From-Every-Angle-Using-DBCC-PAGE-to-find-what-repair-will-delete.aspx.

Повреждены метаданные

Msg 3853, Level 16, State 1, Line 1
 Attribute (object_id=181575685) of row (object_id=181575685,column_id=1) in sys.columns does not have a matching row (object_id=181575685) in sys.objects.

(Ошибка 3853, степень серьезности 16, состояние 1, строка 1
Атрибут (object_id=181575685) строки (object_id=181575685,column_id=1) в sys.columns не имеет совпадающей строки (object_id=181575685) в sys.objects.)

Ошибки такого рода обычно встречаются в базах данных, обновленных с версии SQL 2000, когда кто­то обновил собственно системные таблицы.

Ни в одной из версий SQL Server не обеспечивается принудительное использование механизма внешних ключей применительно к системным таблицам, поэтому в версии SQL 2000 вполне возможно удалить строку из таблицы sysobjects (например, таблицу) и при этом сохранить в таблицах syscolumns и sysindexes строки, ссылающиеся на удаленную строку.

В версии SQL 2000, выполнение инструкции Check­DB не обеспечивает проверки системного каталога, поэтому такого рода проблемы часто остаются совершенно незамеченными. В версии SQL 2005, при выполнении инструкции CheckDB осуществляется проверка согласованности системного каталога, и таким образом эти ошибки могут быть выявлены.

Исправить ошибки повреждения метаданных непросто. Выполнение инструкции CheckDB не обеспечивает их исправления, поскольку единственный способ исправить такие ошибки — это удалить записи из системных таблиц, что может привести к потере основных данных. Если есть резервная копия базы данных, полученная до того, как было выполнено обновление до версии SQL 2005, и это обновление было выполнено совсем недавно, тогда можно восстановить такую резервную копию в версии SQL 2000, исправить в этой версии системные таблицы, и после этого повторить обновление базы данных.

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

http://www.sqlskills.com/BLOGS/PAUL/post/TechEd-Demo-Using-the-SQL-2005-Dedicated-Admin-Connection-to-fix-Msg-8992-corrupt-system-tables.aspx

Другое решение — сгенерировать сценарии для всех объектов базы данных и экспортировать все данные. Создать новую базу данных, воссоздать в ней объекты и загрузить данные.

Обычно рекомендуется второй вариант.

Неустранимые повреждения

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

Если чистой резервной копии нет, тогда остается единственный вариант — сгенерировать сценарии для объектов базы данных и экспортировать доступные данные. Вполне вероятно, что из­за наличия повреждений доступны будут не все данные, и скорее всего, не для всех объектов удастся получить сценарии без ошибок.

Повреждены системные таблицы

Msg 7985, Level 16, State 2, Line 1
 System table pre-checks: Object ID 4. Could not read and latch page (1:358) with latch type SH.
 Check statement terminated due to unrepairable error.

(Ошибка 7985, Степень серьезности 16, Состояние 2, Строка 1. Предварительная проверка системных таблиц: объект с идентификатором ID 4. Не удалось прочитать и заблокировать кратковременной блокировкой типа SH страницу (1:358). Инструкция проверки прервана из-за неустранимой ошибки.)

Msg 8921, Level 16, State 1, Line 1
 Check terminated. A failure was detected while collecting facts. Possibly tempdb out of space or a system table is inconsistent.

(Ошибка 8921, степень серьезности 16, состояние 1, строка 1. Проверка прервана. В процессе сбора фактов была обнаружена ошибка. Возможно, нехватка пространства для базы данных tempdb, или несогласованность системной таблицы.)

При выполнении инструкция CheckDB полагается на несколько критичных системных таблиц, чтобы получить представление о том, что должно находиться в базе данных. Если оказываются поврежденными именно эти системные таблицы, тогда инструкция CheckDB не может получить информацию о том, что собой представляет база данных, и даже не в состоянии проанализировать такую БД, не говоря уже о ее восстановлении.

Повреждены страницы распределения

Msg 8946, Level 16, State 12, Line 1
 Table error: Allocation page (1:2264640) has invalid PFS_PAGE page header values. Type is 0. Check type, alloc unit ID and page ID on the page.

(Ошибка 8946, степень серьезности 16, Состояние 12, строка 1
Ошибка в таблице: на странице размещения (1:2264640)  имеются недопустимые значения заголовка страницы PFS_PAGE. Тип - 0. Проверьте тип, идентификатор единицы размещения и идентификатор страницы, используемые для этой страницы.)

Msg 8998, Level 16, State 2, Line 1
 Page errors on the GAM, SGAM, or PFS pages prevent allocation integrity checks in database ID 13 pages from (1:2264640) to (1:2272727)

(Ошибка 8998, Степень серьезности 16, Состояние 2, Строка 1
Ошибки страниц на страницах GAM, SGAM или PFS блокируют проверку целостности размещения в базе данных с идентификатором ID 13 на страницах с (1:2264640) по (1:2272727)).

В этом случае в базе данных повреждены одна или несколько страниц распределения. Страницы распределения используются для обозначения того, какие страницы и экстенты в БД распределены, а какие — свободны. Выполнение инструкция CheckDB не обеспечит исправление поврежденных страниц распределения, поскольку в отсутствие таких страниц исключительно трудно определить, какие экстенты распределены, а какие — нет. Удаление страницы распределения — это не вариант решения, поскольку в результате оказались бы потерянными до 4 Гб данных.

Получение помощи

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

Помощь может быть оказана в разных формах. Если есть главный администратор БД, спросите совета у него. Если у вас есть наставник, обратитесь к наставнику. Задайте вопрос на форуме: на этом, на форумах или в новостных группах Microsoft, или на любом другом форуме по вашему выбору. Только знайте, что не всякий совет, который дается на форуме, является хорошим советом. Фактически, там время от времени публикуются явно опасные предложения.

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

Заключение

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

Оптимизация корреляции дат изнутри

Фабиано Аморим (Fabiano Amorim)

Умело представив нам в своей предыдущей статье такую возможность оптимизатора запросов, как корреляция дат, Фабиано рассматривает работу этой малоизвестной возможности изнутри, чтобы дать исчерпывающее объяснение того, как функционирует механизм корреляции дат.

В своей последней статье я объяснил, как работает параметр Date_Correlation_Optimization, и показал, что мы можем добиться значительного прироста производительности при выполнении запросов, если используем этот параметр надлежащим образом. На этот раз мы глубже проанализируем эту новую возможность, и заглянем «за кулисы», чтобы посмотреть, как она работает, и какую логику использует оптимизатор запросов для выявления корреляции между двумя столбцами типа datetime. Первый вопрос, на который нам надо ответить:

Что делает оптимизатор SQL Server, чтобы обнаружить значения, которые используются в качестве фильтра в запросе (точнее говоря, в качестве фильтра для столбца Data_Entrega)?

--------------------------------- Дополнительные материалы ------------------------------

все загрузки можно сделать с одной страницы LINK {https://www.idera.com/Action/ProcOrder.aspx?CartID=102410&PurchaseType=DLNow}

нужно только справа отметить соответствующие продукты

=====================================================

 

SQL compliance manager v3.1

 

SQL compliance manager is a comprehensive auditing solution that tells you who did what, when and how on your SQL Servers. SQL compliance manager helps you ensure compliance with regulatory and data security requirements such as Sarbanes-Oxley, GLBA, HIPAA, PCI DSS, and Basel II by providing customizable, low-impact auditing, alerting and reporting on virtually all activity across multiple SQL servers. SQL compliance manager also includes powerful self-auditing features to alert you of any changes to data collection settings or attempts to tamper with the audit data repository.

 

---

 

SQL defrag manager v2.5

 

 

SQL defrag manager is the only SQL Server defragmentation solution in the industry that automates the time-consuming process of pinpointing fragmentation "hot spots" and takes action to defragment automatically, or on demand.

---

 

SQL secure v2.5

 

 

SQLsecure analyzes permissions data from SQL Server and Active Directory as well as the file system and registry to show who has access to what database objects and how access is granted. SQL secure also monitors changes made to access rights so that unapproved changes can be easily identified and fixed. Additionally, SQLsecure evaluates key security settings within SQL Server and provides proactive recommendations to improve server security.

 

(Возврат на основную страницу)

 

Hosted by uCoz