Связанный обязательством писать прежде всего о том, что реально предоставляется корпорацией Oracle сейчас (в феврале 1997 года), а не предполагается в ближайшем будущем, автор оказался в несколько затруднительном положении. Дело в том, что текущей версии сервера Oracle - 7.3 - скоро исполнится уже год (она поставляется с конца марта 1996 года). Следующая версия - восьмая - как видите предполагает смену цифры уже не после точки, а до нее, что - когда Вы имеете дело с Oracle - означает не просто появление новых усовершенствований и опций, а действительно кардинальное обновление программного продукта. Сознавая ответственность перед своими пользователями за качество столь ответственного программного продукта, как сервер, корпорация Oracle изначально запланировала длительный цикл бета-тестирования его восьмой версии (начался он в августе 1996 года, а завершится предположительно летом 1997-го) с привлечением большого количества бета-тестеров (в том числе и в России).
Как бы то ни было, а получается, что рассказывать придется о технологии уже не самой "горячей", но в этом есть и свое преимущество. Во-первых, рассмотрение основ технологии программного продукта может дать куда больше значимой и полезной информации, нежели разговор о самых новомодных веяниях, от которого неизбежно несет рекламным душком. А во-вторых, я постараюсь показать, что практически все направления развития серверной технологии, получившие отражение в Oracle 8, в той или иной степени уже заложены в Oracle 7.3, а следовательно, пользователей Oracle не ожидает перспектива проснуться в одно прекрасное утро (а может быть, и вечер) с необходимостью начать свою жизнь в мире СУБД с начала.
Oracle - это не только сервер БД
А может быть, даже и не столько. Одно из преимуществ Oracle в том, что он никогда не поставляет свою технологию в "голом" виде, ставя пользователя перед необходимостью искать сколько-нибудь приемлемый способ использования этой технологии. Перечислю лишь основные направления программных продуктов Oracle, не имея возможности объять необъятное, и рассказать о них сколько-нибудь подробно.
Средства оперативного анализа данных - OLAP
Обе упомянутые группы программных продуктов поддерживают разработку приложений не только для традиционной уже двухзвенной схемы "клиент-сервер", но и для трехзвенной, включающей сервер приложений, в качестве которого выступает Oracle Web Applications Server. Другой вариант трехзвенной архитектуры предоставляет использование "мобильных агентов":
Oracle Mobile Agents, которые позволяют приложениям осуществлять доступ к серверу БД по линиям связи невысокой пропускной способности и надежности.
Предлагается большой набор различных приложений, начиная от Oracle Interoffice (корпоративная электронная почта, многопользовательский календарь, хранение и управление документами, документооборот) и "свежих" ориентированных на Intranet приложений (электронная коммерция и др.) до уже хорошо известных, но набравших всерьез силу в последние годы Oracle Applications, составляющих сегодня основную конкуренцию для такой системы, как SAP R/3 (которая, впрочем, сама осуществила в 1996 году 79% своих инcталляций с использованием сервера Oracle).
Ввиду - повторяюсь - невозможности осветить все эти направления в одной статье, ограничимся рассмотрением тех новшеств, которые появились в текущей версии сервера 7.3, а заодно поговорим об особенностях сервера Oracle вообще.
Общие функциональные возможности
Версия 7.3 сервера Oracle содержит ряд функциональных новшеств, направленных как на расширение возможностей разработчиков приложений, так и на развитие возможностей самой системы по обслуживанию большого числа одновременных пользователей. Обсудим сначала последнюю тему (ибо она весьма важна для понимания технологических особенностей СУБД), а потом - как водится - перейдем и к первой.
Блокировки, моды изоляции и прочие скучные предметы
Заголовок раздела не случаен, ибо у многих одно лишь упоминание о перечисленных темах вызывает неудержимую зевоту. В этом нет ровным счетом ничего предосудительного (если, конечно, зевота не переходит плавно в последующий сон на рабочем месте), ибо, скажем, разработчик приложений имеет право задаться вопросом: зачем, собственно, ему нужно разбираться, а тем более заботиться обо всей этой нудной внутренней кухне СУБД. К сожалению, разобраться все-таки стоит, ибо любая многопользовательская СУБД по сравнению с "персональной" содержит достаточно много подводных камней, а отсутствие адекватного учета всех этих факторов в приложении - особенно если оно работает не с Oracle, а с другой СУБД - может привести к весьма неприятным сюрпризам.
Oracle всегда славился - и заслуженно - своей способностью практически одинаково эффективно обслуживать любое количество одновременно работающих пользователей (естественно, при наличии достаточных аппаратных ресурсов сервера), не проявляя склонности к выраженной (а тем более скачкообразной) деградации производительности системы при увеличении этого числа. Такое - надо сказать, совсем не частое - свойство обусловлено целым рядом архитектурных решений, и не в последнюю очередь хорошо выверенным механизмом блокировок. Oracle устроен так, что в принципе - за исключением некоторых весьма специфических случаев - разработчик приложений может не заботиться об эффектах многопользовательского режима работы. Сервер сам обеспечивает все необходимые блокировки (хотя, конечно, позволяет выпонять их и "вручную"), причем осуществляет их всегда на минимально возможном уровне: скажем при изменении записи только эта запись и будет заблокирована от изменений другими пользователями (до завершения транзакции). Такой принцип "бескомпромиссно минимального уровня блокировок" порой подвергается критике за то, что он, как утверждается, "требует большого количества ресурсов для своей реализации". Подобное утверждение справедливо лишь в том случае, когда блокировки в системе реализуются неким внешним по отношению к ней механизмом (неким "менеджером блокировок"), использующим свои внутренние (а потому критичные по использованию ресурсов) структуры для учета и управления всеми активными и потенциальными блокировками. В Oracle же необходимость обеспечения блокировок учитывается уже в организации хранения данных, а сам этот механизм является неотъемлемой частью ядра сервера, "переплетаясь" со всеми его внутренними алгоритмами.
Однако это еще далеко не все. Если роль блокировок при изменении данных более или менее понятна и не вызывает обычно недоуменных вопросов, то гораздо сложнее бывает понять, какова же эта роль, и чем чреваты связанные с ней эффекты при выполнении операций чтения.
Проблема моды изоляции чтения
В действительности эта проблема существует, и понятно, откуда она берется: необходимо как-то учесть эффекты, связанные с тем, что пока один пользователь читает данные, другой пользователь (или другие пользователи) может эти данные изменять. Стандарт ANSI SQL-92 описывает требования к реализации нескольких т. наз. мод изоляции операций чтения от выполняющихся одновременно с ним транзакций. Они варьируют от самой "слабой" моды - т. наз. "незафиксированного" (часто называемого "грязным") чтения, при котором допускается считывание данных незафиксированных транзакций, до самой "сильной" - т. наз. "повторяемого" чтения, при котором гарантируется повторяемость результата при повторении операции в рамках транзакции1). Беда в том, что само наличие всех этих различных мод изоляции в стандарте SQL отражает отнюдь не потребности пользователей (трудно представить себе, например, разработчика приложения, заинтересованного в чтении данных чужих незафиксированных транзакций - если только он не страдает особой формой мазохизма), а различные степени компромисса с возможностями разработчиков СУБД. Пользователей же волнует (или во всяком случае должно волновать) совсем другое: как избежать тех неприятных эффектов, которые могут быть связаны с использованием всех стандарных мод изоляции, кроме самой "сильной" из них. Чтобы не быть голословным, рассмотрим очень простой пример.
Допустим, в некоей банковской системе есть таблица, состоящая всего из двух полей:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Предположим, пользователь запустил операцию подсчета общей суммы денег на всех счетах:
select sum(Сумма) from СЧЕТА;
В любой СУБД такая операция выполняется путем последователного перебора всех записей таблицы с подсчетом тебуемой суммы. Пусть теперь другой пользователь одновременно с выполнением этого отчета (то есть после его начала, но до его завершения) проводит простую транзакцию, переводящую 50000 с одного счета на другой:
update СЧЕТА set Сумма = Сумма - 50000 where Номер_счета = 1; update СЧЕТА set Сумма = Сумма + 50000 where Номер_счета = 100000; commit;.
Нетрудно заметить, что данная транзакция не изменяет общей суммы на счетах, но если отчет выполняется в любой стандартной моде изоляции, отличной от "повторямого" чтения, он неизбежно выдаст результат на 50000 больший! Причина в том, что с первого счета будет считана старая сумма, с последнего же - новая. Если при этом используется устанавливаемая по умолчанию в большинстве СУБД мода изоляции "завершенное чтение" (гарантирующая считывание данных только завершенных транзакций), то это только усугубит ситуацию: даже если транзакция не успеет завершиться до конца выполнения отчета, последний попросту остановится и будет ждать ее завершения, поскольку реализуется данная мода именно с помощью такой блокировки. Наличие указанных блокировок может привести и к еще более неприятным последствиям, если подключить третьего пользователя: нетрудно изменить пример так, что система попросту войдет в "клинч": пользователи окажутся в состоянии взаимного ожидания.
Если все моды изоляции, кроме "повторяемого чтения", столь опасны, то спрашивается: зачем они вообще допускаются? Дело в том, что при традиционном подходе реализация всех этих мод изоляции достигается с помощью блокировок того или иного уровня, причем чем "сильнее" мода изоляции, тем обременительнее блокировки: неблокирующим является лишь "грязное" чтение, а в случае "повторяемого чтения" на время выполнения отчета блокируются все записи, которые им могут быть считаны - т.е. фактически СУБД может почти потерять свои многопользовательские свойства!
А как же ведет себя Oracle?
Oracle решает проблему нетрадиционным путем. Если посмотреть внимательно на приведенный выше пример, то можно заметить, что "повторяемое" чтение в действительности избыточно для достижения правильного результата, поскольку проблема состоит не в том, что операцию чтения надо обязательно повторить с получением одинакового результата, а в том, что при однократном чтении данные оказываются не согласованными по времени. Если указанную согласованность обеспечить, то и задача будет решена! В этом собственно и состоит сущность моды изоляции "согласованное чтение", реализуемой сервером Oracle: любая операция чтения в Oracle выдает пользователю данные только тех транзакций, которые были завершены к моменту начала операции (и, естественно, не выдает данных незавершенных транзакций). Пользователь получает как бы "срез" данных БД на момент начала чтения. Такой режим работы называют еще "многоверсионным" чтением, ибо каждый пользователь видит как бы свою версию БД. Однако все это было бы не очень оправдано, если бы не тот замечательный факт, что Oracle реализует "согласованное чтение" без использования блокировок вообще. Операция чтения в Oracle никогда не блокируется и никогда не блокирует других. Не вдаваясь в обсуждение того, как Oracle добивается такого результата (если очень коротко, то в случае необходимости выполняется "реконструкция" данных с помощью т. наз. "сегмента отката" - замечательный пример того, как одна и та же структура с СУБД позволяет "убивать сразу несколько зайцев"), отметим, что данный режим работы является среди коммерческих СУБД уникальным.
Ну а как же быть с фантомами?
Казалось бы, какие тут еще могут быть проблемы, требующие усовершенствований? Проблема, однако, все-таки есть - вернее, она была до выхода версии 7.3. Дело в том, что мода "согласованного чтения" не совпадает ни с одной из мод изоляции, принятых в стандарте SQL-92. Она "сильнее" (и следовательно покрывает) все моды, кроме "повторяемого чтения", но она "слабее" последней. Действительно, при повторе операции в моде "согласованного чтения" можно получить совсем другой результат, ибо изменится момент времени, по которому синхронизуется "срез" данных. Oracle, правда, предоставлял (и, естественно, предоставляет) возможность объединять несколько операций чтения в т. наз. read-only транзакцию, синхронизуя их при этом к одному моменту времени. Однако для произвольных (т. е. включающих операции изменения данных) транзакций проблема повторяемых чтений (ее еще называют проблемой фантомов, ибо при, казалось бы, одинаковых действиях получается разный результат) оставалась. Собственно, значение этой проблемы вряд ли стоит преувеличивать, ибо достаточно трудно придумать осмысленный пример транзакции, меняющей данные в БД, в которой требовалось бы повторять одну и ту же операцию чтения несколько раз, да к тому же обязательно с одним и тем же результатом. Однако стандарт есть стандарт - в отношении мод изоляции он явно неудачен и справедливо подвергается критике. Причина тут, видимо, в том, что определяющими оказались не "запросы потребителя", а "диктат производителя". Хорошо еще, что стандарт не требует от СУБД обязательной реализации всех мод изоляции в буквальной форме, а лишь устанавливает минимальный уровень требований к ним. В принципе, конечно, придумать приложение, работающее в моде "повторяемого чтения", можно, и такое требование включено в ряд спецификаций (в частности, в спецификацию теста TPC-C). Oracle, конечно, всегда мог обеспечить реализацию данной моды изоляции, но - увы - с использованием блокировок таблиц (это в свое время препятствовало выполнению корпорацией Oracle тестов TPC-C). В версии 7.3 положение изменилось: теперь Oracle позволяет в явном виде установить моду изоляции "repeatable read", причем опять-таки без использования блокировок!2)
Функциональные новшества
Если говорить о "внешне заметных" нововведениях, то их в Oracle 7.3 появилось несколько. Во-первых, впервые появилась возможность читать и писать поля таблиц типа Long по частям (на уровне Oracle Call Interface), что безусловно полезно, ибо размер таких полей может доходить до 2 Гбайт. Во-вторых, расширился набор типов представлений (views), для которых допускается их непосредственная модификация. Если раньше они могли базироваться только на одной таблице, то теперь можно выполнять операции Insert и Update над представлениями, построенными на нескольких базовых таблицах с использованием простых соединений (естественно, с ограничениями, гарантирующими однозначную интерпретацию данных операций в отношении базовых таблиц). В-третьих, появился ряд новшеств в языке PL/SQL (процедурном расширении SQL), самое заметное из которых - поддержка таблиц, хранимых в памяти сервера. Например, если в БД есть таблица emp, то можно описать новый тип данных, соответствующий ее определению:
TYPE emp_table_type IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER;
Затем можно определить таблицу данного типа, хранимую в памяти:
emp_table emp_table_type;
и использовать ее в качестве своего рода буфера при работе с таблицей emp.
Остальные функциональные нововведения в Oracle 7.3 не столь существенны, поэтому обсуждать их в данной статье, пожалуй, не стоит.
Новые алгоритмы обработки запросов
Выполнение SQL-запроса - особенно имеющего сложную структуру - обычно распадается на несколько взаимосвязанных операций. Само это разбиение, а тем более выбор методов выполнения операций, как правило, допускают множество альтернативных решений. Выбор оптимальной их комбинации - задача оптимизатора, который на основании как характера запроса, так и имеющейся информации о задействованных таблицах и индексах, наличии тех или иных системных ресурсов (кстати, в Oracle 7.3 расширен набор видов предоставляемой оптимизатору информации: теперь он может учитывать частотные гистограммы индексируемых полей) строит т. наз. оценку стоимости разных вариантов решения. В принципе, пользователь может не особенно заботиться о том, как именно выполняется его запрос, но при настройке системы этот вопрос часто встает, тем более, что Oracle позволяет "помогать" оптимизатору (все-таки практика показывает, что при принятии неформальных решений опытный специалист часто оказывается эффективнее даже самых "умных" программ). Поэтому небезынтересно бывает представлять, какие именно алгоритмы применяются при работе с данными, каковы их достоинства и недостатки.
Помимо "джентльменского" набора более или менее универсальных методов существует также целый ряд более узкоспециализированных, т. е. таких, которые очень хорошо работают в некоторых ситуациях, но могут быть совсем неэффективными (или даже неприменимыми) в других. Несмотря на такой недостаток, применение этих методов может дать очень заметный эффект, особенно при выполнении сложных запросов над большими объемами данных, что характерно для систем поддержки принятия решений (DSS) - или, как сейчас стало модно говорить, для хранилищ данных. Другое дело, что ни один из методов не является панацеей, а стало быть система должна уметь использовать как можно большее их число.
В Oracle 7.3 введен целый ряд таких специализированных алгоритмов. Перечислим их без подробного рассмотрения (иначе статья достигнет уже совсем неприличных размеров).
Системное администрирование
Выход версии Oracle 7.3 ознаменовался также серьезным новшеством в области администрирования СУБД. До этого основным средством администратора являлся Server Manager - программный продукт с графическим интерфейсом, но ориентированный на управление одной БД (в случае нескольких БД приходилось использовать несколько сессий), не имевший удобных средств графического мониторинга системы и не позволявший непосредственно управлять удаленными заданиями, требовавшими привлечения системных команд и ресурсов, не находящихся под контролем СУБД Oracle.
Указанный пробел в общем-то неплохо заполнялся достаточно многочисленными программными продуктами третьих фирм, специализирующихся именно на средствах администрирования. Однако обеспечение единообразного администрирования распределенных систем стало настолько актуальной задачей, что полагаться полностью в этом вопросе на третьи фирмы стало сопряжено с неоправданным бизнес-риском для такой крупной корпорации, как Oracle.
Эти соображения стимулировали развитие новой стратегии корпорации в области средств администрирования сервера БД. В комплекте с сервером версии 7.3 (в вариантах Workgroup и Enterprise) поставляется Oracle Enterprise Manager. В состав этого программного продукта входит набор утилит управления, интегрированных в единую консоль администратора. Через специальный связной процесс - Communication Deamon - эта консоль может взаимодействовать с т. наз. интеллектуальными агентами - специальными процессами, функционирующими на компьютерах-серверах, обеспечивающими возможность удаленного управления (впрочем, агент требуется только для выполнения удаленных заданий и контроля за событиями - все основные административные функции реализуются через непосредственную связь консоли с сервером БД).
Все управляемые компоненты - БД, серверы (узлы), процессы - отображаются на консоли в т. наз. навигаторе объектов, позволяющем быстро находить требуемый объект и детализировать представление его структуры до нужного уровня. Непосредственно административные функции выполняются с помощью явного или неявного вызова соответствующих утилит. Для выполнения некоторых действий (перенос пользователя из одной БД в другую, присвоение новой роли пользователю и др.) достаточно "буксировки" мышкой.
Принципиально новой особенностью Enterprise Manager по сравнению с более ранними аналогичными продуктами Oracle является возможность определения и управления выполнением удаленных заданий, реализация которых выходит за рамки возможностей самой СУБД (сбросы, команды ОС и т. п.), а также возможность заставить систему саму извещать администратора о возникших (или даже предполагаемых) проблемах с помощью механизма событий.
Задания могут выполняться по заданному расписанию, причем непосредственный контроль за этим осуществляется локально интеллектуальным агентом, так что в принципе постоянная поддержка связи консоли с сервером не требуется (хотя для того, чтобы изменить задание или время его выполнения, необходимо, чтобы "агент вышел на связь"). Помимо использования набора стандартных типов заданий и их комбинаций "продвинутый" администратор может определять принципиально новые, исользуя системно-независимый язык TCL (Task Control Language). Фактически и "стандартные" типы заданий строятся с применением "шаблонов" на этом языке, тексты которых можно использовать в качестве образцов. Интерпретация TCL в конкретной ОС того или иного сервера осуществляется соответствующим интеллектуальным агентом, что делает управление СУБД почти не зависящим от платформы сервера (а таких платформ Oracle поддерживает, как известно, более 80). Например, при выполнении определенного задания сразу над группой объектов (а такая возможность есть) - скажем, при одновременном сбросе всех трех региональных БД - оно будет выполнено правильно даже если один из серверов работает под управлением Unix, другой - Windows NT, а третий - Novell Netware.
Набор возможных регистрируемых событий варьирует от самых простых (но важных!) типа запуска и останова сервера БД до достаточно "тонких" типа превышения частоты обращений к диску заданного администратором порога. События регистрируются интеллектуальными агентами и передаются на консоль администратора (точнее, на те из консолей, которые "интересуются" данным событием), а если потребуется, сообщение о событии может быть послано администратору по электронной почте или даже на пейджер.
Еще одной важной особенностью Oracle Enterprise Manager является то, что он имеет открытые интерфейсы на всех своих уровнях, что открывает возможность наращивания его функциональности за счет добавления новых административных утилит, управляющих процессов и пр. Эта возможность прежде всего ориентирована на фирмы, являющиеся поставщиками средств администрирования, но ею могут воспользоваться и сами пользователи СУБД.
Отдельного упоминания заслуживают поставляемые Oracle утилиты, входящие в т. наз. Performance Package. В него входят: утилита мониторинга системы (несколько десятков стандартных динамических диаграмм плюс возможность определять свои собственные); утилита, показывающая в наглядной форме физическое расположение объектов БД в файлах данных и позволяющая выполнять оптимизирующие операции (дефрагментацию); утилита, показывающая информацию о сессиях, потребляющих наибольшее количество ресурсов (есть возможность сортировки сессий по различным параметрам, для любой из выбранных сессий можно легко "спуститься" по лестнице детализации информации о ней вплоть до используемых курсоров и планов выполнения соответствующих им запросов). Наконец, есть еще две утилиты, стоящие несколько особняком. Это Oracle Trace - управляемая событиями трассировка - и Oracle Expert - экспертная система, проводящя анализ структуры, параметров и функционирования СУБД и генерирующая рекомендации (а также готовые административные скрипты) для ее оптимизирующей настройки.
Поддержка параллельных систем
Одно из общепризнанных достоинств сервера Oracle - его высокая степень масштабируемости: как горизонтальной, так и вертикальной. Возможности работы сервера Oracle в распределенных системах я не предполагаю обсуждать в данной статье3), а вот обсудить особенности поддержки параллелизма в Oracle мне кажется полезным (тем более, что по не совсем понятным причинам по этому вопросу в массовой компьютерной прессе об Oracle порой дают - скажем так - не вполне правильную информацию, а из встреч со многими специалистами я вынес впечатление, что они часто имеют об этом и вовсе смутное представление). Я, впрочем, не намерен вдаваться в фундаментальные аспекты параллелизма в СУБД вообще4), а попытаюсь объяснить (и в какой-то мере обосновать) подход разработчиков Oracle к данному вопросу.
Начну с констатации общеизвестного факта, что без использования параллелизма достижение высоких показателей производительности СУБД невозможно. Разработчики сервера Oracle приложили немало усилий для реализации этой истины на практике, и не случайно Oracle владеет в настоящий момент абсолютными рекордами производительности как в OLTP-тестах TPC-C (причем этот рекорд держится с апреля 1996 года), так и в DSS-тестах TPC-D (в варианте с объемом данных 300 Гбайт)5).
Начнем с краткой классификации параллельных систем. Наиболее широко распространены симметрично-параллельные (SMP) системы, т. е. такие, где процессоры равноправно используют все остальные системные ресурсы (прежде всего оперативную память и диски), являющиеся общими для них6). Количество процессоров в таких системах, предлагаемых на рынке, может доходить до 64. Для SMP-систем часто еще употребляют определение "система с полным разделением ресурсов" (shared-everything system). Следующий тип параллельной архитектуры - кластер: в нем узлы, имеющие свою собственную оперативную память (а возможно и собственные диски), через специальный контроллер имеют доступ к общим дискам ("система с разделяемыми дисками" - shared-disks system). Как правило, каждый из узлов кластера представляет собой SMP-систему, а количество узлов в кластерах, предлагаемых на рынке, доходит до 8. Наконец, третий тип архитектуры - массивно-параллельный (MPP). В ней узлы живут практически независимой жизнью, но между ними каким-то образом реализуется очень быстрая связь. Количество узлов в такой системе вполне может достигать ста и больше. Безусловно, чтобы называться массивно-параллельной система должна в той или иной степени обеспечивать взаимодействие и совместное пользование ресурсами для своих узлов, тем не менее к системам с данной архитектурой часто применяют определение "система без разделения ресурсов" (shared-nothing system).
В свою очередь, говоря о параллелизме в СУБД, подразумевают два разных его аспекта: параллелизм при выполнении потока операций (что актуально для OLTP-приложений) и параллелизм при выполнении отдельных операций (что актуально для DSS-приложений и соответственно хранилищ данных).
Сервер Oracle в любой конфигурации поддерживает параллелизм при выполнении потока операций (он архитектурно спроектирован под это) в SMP-архитектуре, для параллельного выполнения отдельных запросов требуется установка Parallel Query Option. Для кластеров и MPP-систем Oracle предлагает архитектуру, позволяющую всем узлам этих систем параллельно осуществлять доступ к одной БД: чтобы добиться этого, достаточно установить Parallel Server Option7).
Поговорим сначала о параллелизме в режиме OLTP. Для его обеспечения в SMP-системах Oracle предлагает возможность использования многопотоковых разделяемых серверных процессов. Поскольку я уже давал характеристику данной возможности в статье [2], не буду повторяться, а вместо этого предлагаю обсудить особенности поддержки OLTP на кластерах и MPP.
Для начала разберемся, что такое опция Oracle Parallel Server. Как я уже упоминал, она позволяет нескольким узлам системы (фактически всем, функционирующим в данный момент времени) параллельно работать с одной БД, находящейся на общих дисках (в MPP-системе это будут "виртуальные" общие диски, поддерживаемые ОС). Пользовательские сессии взаимодействуют каждая со своим узлом, но при этом фактически работают с одними и теми же данными8). Помимо очевидной возможности использования полной мощности параллельной системы для работы с БД, Oracle Parallel Server (OPS) дает еще одно важное преимущество: он обеспечивает повышенную живучесть БД. Дело в том, что при выходе из строя одного из узлов системы один из "оставшихся в живых" автоматически выполняет восстановление транзакций сбойного узла, не переписанных из буфера в файлы БД, так что для "пострадавших" пользователей достаточно повторить операцию "соединения" с БД, чтобы продолжить работу на одном из оставшихся узлов.
Можно заметить, что в Oracle8 даже эта операция будет не обязательна: новая версия сервера (еще раз напомню, находящаяся в бета-тестировании) позволяет выполнять автоматическое переключение сессий со сбойного узла, так что, например, прерванные запросы попросту продолжают выполняться после небольшой задержки.
Однако было бы нечестно утверждать, что при применении OPS не возникает никаких проблем. Собственно говоря, по сравнению с SMP-системами возникает одна - но достаточно неприятная - проблема: синхронизация кэшей в оперативной памяти узлов. В самом деле, каждый узел системы кэширует данные БД в своей оперативной памяти и может держать их там достаточно долгое время без переписывания на диск. Если один из узлов модифицировал некую запись БД, но не переписал ее на диск, то при обращении к той же записи другой узел не имеет права ни пользоваться ее копией в своей памяти (она уже не актуальна), ни даже считать ее с диска. Для разрешения этой проблемы вводятся т. наз. блокировки параллельного кэша: при модификации данных узел параллельной системы как бы вешает на них свой "замок", так что любой другой узел при обращении к этим данным должен сначала "снять замок", что включает в себя передачу ему актуальных данных. Ясно, что если различные узлы будут часто модифицировать одни и те же данные, то блокировки параллельного кэша могут заметно снизить производительность сервера в целом.
К сожалению, данная проблема является принципиальной, т. е. от нее нельзя полностью избавиться ни с помощью технических ухищрений, ни с помощью альтернативных решений9). К счастью. проблема не столь страшна, как может показаться: во всяком случае, понятно, как можно с нею бороться. Если пользователи, работающие с разными узлами, редко модифицируют одни и те же записи, то и блокировки параллельного кэша возникают редко. Такой режим легко обеспечивается, если, например, на разные узлы сервера "назначаются" пользователи, работающие с разными приложениями, или работающие с данными различных отделов (филиалов) и пр. Приложения, осуществляющие "хаотичные" обращения к большой БД, также имеют слабую тенденцию к порождению блокировок параллельного кэша. Тем не менее, распределение пользователей между узлами сервера должно осуществляться не наобум, а с учетом того, с какими данными и в каком режиме они работают10). Как бы то ни было, OPS уже достаточно давно и успешно используется - особенно в инсталляциях, требующих повышенной надежности системы. Нелишне заметить, что и рекорд в тестах TPC-C поставлен с использованием OPS на кластере (Digital Alpha 8400)11). Конечно, рекорд рекордом, но для пользователей важно найти систему, отвечающую масштабам их задач. Надо сказать, что до последнего времени понятия "кластер" и "параллельный сервер" ассоциировались только с весьма мощными и дорогостоящими конфигурациями аппаратуры. Отчасти это было связано с реальными потребностями рынка, а отчасти с тем фактом, что поддержка кластерного режима работы требует весьма значительных системных ресурсов. Одним из первых пожирателей ресурсов является т. наз. менеджер распределенных блокировок (Distributed Locks Manager - DLM). Это программный компонент (реализованный обычно в виде набора процессов), обычно поставляемый фирмой-разработчиком ОС, задача которого - управление доступом к разделяемым ресурсам на уровне системы в целом. Именно с помощью DLM Oracle реализует блокировки параллельного кэша и вообще синхронизацию работы узлов. Универсальность DLM в сочетании с тем, что он является "внешней составляющей" OPS, приводит к тому, что общее количество блокировок параллельного кэша становится критичным ресурсом. Чтобы снизить потребность в нем, в Oracle 7.3 введен ряд усовершенствований в управлении выделением этих блокировок, но для радикального решения проблемы безусловно требовался другой подход к реализации DLM. В частности, по этой причине уже в версии 7.3 Oracle постепенно переходит к реализации DLM собственными средствами в составе ядра сервера - окончательно этот процесс будет завершен с выходом Oracle 8. Как бы то ни было, уже в ближайшем ("весеннем") релизе Oracle 7.3.3 ожидается поставка параллельного сервера для кластеров, функционирующих под управлением таких "легковесных" ОС, как SCO UnixWare и Windows NT (последняя - как для платформы Intel, так и для DEC Alpha).
Теперь поговорим о параллелизме при выполнении отдельных операций (прежде всего запросов, ибо это наиболее важно для задач типа DSS). Как всегда, оптимизатор выбирает один из возможных алгоритмов выполнения запросов (при этом важно, что в Oracle он с самого начала при оценке стоимости того или иного решения учитывает заданную для данного запроса степень параллелизма), затем каждый шаг алгоритма разбивается на несколько параллельных потоков. Координатор выполнения запроса запускает нужное число процессов (при этом используются все наличные процессоры - включая различные узлы кластера или MPP-системы) и обеспечивает как внутриоперационный (параллельные потоки внутри шага алгоритма), так и межоперационный параллелизм. В список операций, подлежащих распараллеливанию, помимо просмотра таблиц включены также все алгоритмы соединения (и т. наз. "антисоединения" - конструкции типа NOT IN) таблиц, сортировки, операции агрегирования (SUM, AVG, GROUP BY и пр.), вложенные подзапросы, объединения (UNION, UNION ALL) и некоторые другие. Кроме того, возможно параллельное выполнение таких операций, как создание таблицы по результатам запроса (CREATE TABLE AS SELECT), загрузка данных, сброс и восстановление БД, выполнение операций тиражирования данных. В Oracle8 к этому списку добавятся операции INSERT, UPDATE и DELETE.
Одним из наиболее фундаментальных вопросов, которые приходится решать при реализации параллельного выполнения запросов, является выбор метода распределения данных между параллельными потоками при выполнении таких операций, как полный просмотр таблиц. Самым простым (и исторически реализованным первым - фирмой Tandem) методом является "привязка" параллелизма к статическому разбиению нужных таблиц на разделы, проводимому по правилу, заданному администратором системы. Этот метод и до сих пор является краеугольным камнем параллелизма в ряде СУБД.
В принципе, в самой идее разбиения таблиц на разделы безусловно есть серьезные положительные стороны, особенно когда это разбиение осуществляется на основе диапазонов значений содержательных параметров либо функций от них. Тогда, во-первых, может быть облегчена работа администратора БД в случае, когда таблица содержит большой объем данных (например, если разбить таблицу фактических продаж по месяцам, то можно выполнять сбросы только последнего раздела таблицы), во-вторых, становится возможным т. наз. исключение разделов при выполнении запросов, содержащих условие на параметр разбиения (скажем, в вышеупомянутом примере, если требуется посчитать общий объем продаж с начала текущего года, то разделы, относящиеся к более ранним датам, можно не рассматривать).
Однако когда параллелизм в выполнении запросов ставится в зависимость от статичного разбиения таблиц, это приводит к ряду проблем. Дело в том, что для достижения оптимального параллелизма в этом случае требуется (по очевидным причинам), чтобы данные были распределены по разделам равномерно. В принципе этого нетрудно добиться, если, скажем, помещать каждую новую запись в новый раздел по циклическому алгоритму (round-robin). Но в этом случае, как нетрудно заметить, полностью теряются указанные выше два преимущества. И наоборот, если выполнять разбиение по содержательному критерию, то весьма часто получается, что данные распределяются по разделам неравномерно, что неизбежно приводит к тому, что, закончив свою работу, параллельные процессы ждут "отстающего товарища", которому не повезло с разделом. Если речь идет об устоявшихся (т. е. фактически не обновляемых) данных и о конкретном запросе с небольшими вариациями, то практически всегда можно найти некий компромиссный вариант разбиения, убивающий обоих зайцев, но в реальных системах типа DSS запросы как правило носят нерегламентированный характер (ad-hoc), а данные - опять-таки как правило - периодически обновляются. Все это как минимум приводит к серьезной административной работе, связанной с перестройкой разделов (что становится попросту обязательным, если требуется сменить степень параллелизма), но даже это не гарантирует оптимального параллельного выполнения запросов.
Такие соображения побудили разработчиков Oracle7 отказаться от принципа "статичного" параллелизма и реализовать алгоритм т. наз. динамического разбиения таблиц при параллельном выполнении запросов. Упрощенно его суть в том, что таблица логически "разбивается" непосредственно при выполнении запроса в соответствии с заданной степенью параллелизма. Это не означает, впрочем, что она попросту делится на равные части произвольным образом - все гораздо изощреннее. Дело в том, что скорость обработки одного и того же объема данных в разных разделах может быть различна в зависимости как от характера запроса, так и от того, на каких физических устройствах располагается динамический раздел, да и от других порой трудно предсказуемых причин. Поэтому таблица делится реально на число разделов гораздо большее, чем степень параллелизма (и разделы эти бывают различного размера), а их назначение параллельным процессам регулируется динамически в зависимости от того, с какой скоростью они справляются с уже порученной работой.
Надо сказать, что алгоритм динамического разбиения таблиц весьма непрост, и было бы нечестно утверждать, что в нем с самого начала все было сделано самым оптимальным образом. Однако одно из самых важных преимуществ этого алгоритма в его гибкости, поэтому в него постоянно вносились усовершенствования на основании накопленного опыта эксплуатации в реальных инсталляциях, в результате чего от релиза к релизу Oracle7 добивался все более оптимальных характеристик параллелизма в выполнении запросов. К примеру, в релизе 7.3 основные усовершенствования были связаны с поддержкой MPP-архитектур. Дело в том, что в них диски не равноценны по скорости доступа для каждого из узлов системы (к "своим" дискам доступ осуществляется быстрее, чем к "чужим"), поэтому и динамические разделы стали выделяться параллельным процессам преимущественно на локальных для соответствующих узлов дисках (преимущественно - опять-таки потому, что, завершив свою "локальную" работу, процесс не прекращает деятельность, а начинает помогать "отстающим").
Как бы то ни было, сейчас можно с уверенностью констатировать, что метод динамического разбиения таблиц оправдал себя, позволив при минимальной дополнительной нагрузке на администратора БД добиться, тем не менее, практически оптимального распраллеливания выполнения запросов. Высокая масштабируемость Oracle в параллельном выполнении запросов на системах с различной архитектурой иллюстрируется также и тем фактом, что Oracle 7.3 сумел показать рекордные параметры в TPC-D тесте (в варианте с объемом данных 300 Гбайт) как среди MPP-систем (на IBM SP/2), так и среди SMP-систем (на Sun Enterprise Server 10000)12).
Чтобы завершить разговор о разбиениях, хочу отметить, что Oracle 7, к сожалению, не включает в себя явной операции построения статических разделов таблицы (эта возможность вводится в Oracle 8), но в неявном виде это тем не менее можно сделать с помощью имитации разделов отдельными таблицами, объединенными в единое представление с помощью операции UNION ALL. При выполнении запросов к такому представлению оптимизатор Oracle7 трактует его именно как таблицу, разбитую на разделы, в частности выполняет исключение разделов, если это возможно (хотя - еще раз подчеркну - параллелизм с этими разделами жестко не увязывается)13).
Универсальный сервер Oracle(r)
Я не случайно привел заголовок именно в таком виде: не так давно суд в США потребовал, чтобы все публичные упоминания темина "унивесальный сервер" делались именно в таком виде - с обязательным указанием логотипа фирмы-производителя. С этим, пожалуй, стоит согласиться, ибо вокруг данного термина в последнее время было сломано немало "маркетинговых копий", и различные фирмы вкладывают в него различный смысл и - если хотите - различные технологические стандарты. Я попробую объяснить, как трактует данный термин корпорация Oracle, затем кратко рассказать, какие элементы "Универсального сервера Oracle" реализованы в версии 7.3, затем совсем уж немного поговорить о том, что нового ждет пользователей в этом плане в Oracle 8.
Итак, что подразумевает корпорация Oracle, говоря об универсальном сервере? Речь идет о трех составляющих этого понятия.
Любой масштаб СУБД
Oracle традиционно славится как поставщик СУБД для крупных инсталляций, однако в связи с этим бытует (и активно поддерживается конкурентами) также и мнение о том, что для небольших систем Oracle слишком тяжеловесен, сложен, дорог и пр. В общем-то, это никогда не было правдой, но в особенности в последние несколько лет: Oracle прикладывает немало усилий, чтобы по всем параметрам (включая цены) утвердиться в качестве основного поставщика во всех сегментах рынка СУБД, начиная с небольших рабочих групп. С 1994 года помимо уже привычного "сервера масштаба предприятия" поставляются другие его варианты: "сервер для рабочих групп" (Workgroup server) и "персональный Oracle" (Personal Oracle) в двух редакциях - полной и "облегченной" (Personal Oracle Lite). В этих продуктах особый упор сделан на их относительную дешевизну, простоту установки и сопровождения. При этом все варианты сервера Oracle функционально идентичны, за исключением некоторых опций (только в нынешней версии Personal Oracle Lite отсутствует часть базовой функциональности: он не поддерживает многопользовательские схемы данных и процедурные расширения SQL).
Любой тип приложений
Как я уже показывал в предыдущих разделах, Oracle 7 в одинаковой степени может быть оптимизирован и для OLTP-приложений, и для приложений DSS, причем их вполне можно исполнять одновременно, не беспокоясь о дополнительных блокировках, модах изоляции и прочих темах, способных вызвать головную боль у знакомых с ними на практике специалистов при одном только их упоминании14).
Любой тип данных
По этой теме поговорим чуть подробнее, тем более что именно этот вопрос чаще всего муссируется, когда речь идет о том или ином "универсальном сервере".
В сущности, речь идет о расширении стандартного набора типов данных, характерного для РСУБД, а в перспективе о переходе к объектно-реляционной модели СУБД15). В свою очередь, эта задача может быть разделена на две:
Oracle развивает свой сервер в обоих направлениях. В версии 7.3 уже поддерживается несколько новых типов данных: неструктурированные тексты, пространственные данные, видеоданные. Собственно говоря, хранить такие данные в БД и осуществлять к ним доступ можно было и раньше: новизна в том, что если раньше этот доступ осуществлялся через самостоятельно работающие серверные процессы, и для работы с ними требовалось использование специального интерфейса на уровне приложений, то теперь данная функциональность интегрирована в "базовый" сервер, так что, к примеру, можно выполнить SQL-запрос типа
SELECT имя, фамилия FROM Кандидаты
WHERE Парт_членство NOT IN ('КПРФ', 'ЛДПР')
AND CONTAINS ( Обещания, 'Снижение налогов & Повышение дотаций');
Как нетрудно догадаться, в примере используется таблица "Кандидаты", в которой в одно из полей (BLOB-типа), названное "Обещания", загружены некие тексты (которые могли иметь в оригинале практически любой известный формат). После загрузки текст индексируется специальным образом, так что даже при очень большом объеме документов контекстный поиск осуществляется быстро. Такая функциональность достигается при включении в сервер Oracle7 контекстной опции (Context Option)16).
Опция для работы с пространственными данными (Spatial Data Option) фактически вводит тип данных "пространственная точка" и операции над ним в СУБД, позволяя хранить соответствующие данные в таблицах оптиальным образом и на порядок (а порой и на два) ускорять выполнение запросов, содержащих сравнения по метрике (например, "все дома, находящиеся в радиусе 1 км от заданной точки" или "все замеры, в которых комбинированный показатель температура-давление выходит за заданный предел относительно оптимума").
Что касается видеоданных, то соответствующая им опция - Video Option - единственная, "живущая самостоятельной жизнью" по отношению к серверу РСУБД (но не к БД!). Более того, рекомендуется конфигурация, в которой Video Server запускается на отдельном компьютере от сервера БД. Связано это с тем, что воспроизведение видеофрагментов в реальном времени (особенно по нескольким каналам) - что как раз и обеспечивает Video Server - трудно совместимо на современных массово производимых компьютерах с функционированием сервера СУБД из-за чисто аппаратных ограничений. Тем не менее приложение, работающее с Video Server, может осуществлять поиск видеофрагментов по описательным атрибутам и воспроизведение этих фрагментов - как единую интегрированную операцию.
Относительно Web Option, пожалуй, не совсем правильно говорить о функциональных расширениях сервера, поскольку, в сущности, главная задача опции - обеспечение интерфейса с Web Application Server и соответственно через него с пользователями Intranet/Internet17).
Oracle OLAP Option едва ли можно было рассматривать как интегрированную компоненту сервера Oracle (продукты OLAP работают с собственным - многомерным - представлением данных, хранимым отдельно) до недавнего времени, когда с помощью Access Manager появилась возможность устанавливать динамическую связь многомерного куба OLAP с реляционными данными, стирая тем самым грань между MOLAP и ROLAP (для аналитика, работающего с приложениями OLAP, стало совершенно незаметно, работает ли он с предварительно сформированным многомерным кубом или с динамическим многомерным представлением реляционных данных).
Развитие подхода в Oracle 8
В отличие от Oracle 7 восьмая версия сервера Oracle не просто предоставляет расширенный набор встроенных типов данных, но и позволяет конструировать новые типы данных со спецификацией методов доступа к ним. Это означает фактически, что разработчики получают в руки не просто систему для хранения и обработки, скажем, видеоданных (что, понятно, нужно далеко не в каждом приложении), а и инструмент, позволяющий строить структурированные типы данных, непосредственно отображающие сущности предметной области. Влияние этого фактора на возможности разработчиков можно, пожалуй, сравнить с эффектом от перехода на реляционные СУБД в начале 80-х годов.
Oracle8 фактически опирается на новый стандарт SQL, позволяющий описывать определения новых типов объектов, состоящих из атрибутов (скалярных - т. е. других типов, множеств объектов, ссылок на объекты), и обладающих ассоциированными с ним методами. Любая колонка таблицы может быть любого типа, поддерживаются также вложенные таблицы и массивы объектов переменной длины18).
Что касается методов доступа, то они могут быть определены несколькими способами. Более простой из них предполагает контроль ядра сервера за выполнением метода: это достигается, если методы реализуются на PL/SQL (который также расширен для поддержки объектно-реляционных структур) или Java19). Поскольку PL/SQL практически не уступает по своей функциональности универсальным языкам программирования, для подавляющего большинства составных типов данных таких возможностей будет достаточно. Если же новый тип данных требует специальной обработки, не реализуемой стандартными средствами ядра СУБД (к примеру, работа с мультимедийными данными, хранимыми в BLOB-полях в БД), можно использовать вызовы внешних процедур (call-outs), которые могут быть написаны, допустим, на языке C.
При использовании внешних процедур возникает серьезная проблема организации их взаимодействия с ядром сервера. Наиболее соблазнительная - на первый взгляд - идея включения их непосредственно в ядро таит в себе угрозу нарушения стабильности этого ядра, поскольку оно оказывается незащищенным перед "чужим" кодом, и, следовательно, при любом сбое (или неправильном функционировании) становится практически невозможно определить, явилось ли это следствием ошибки в самом ядре, или же это "наведенный" эффект от внешней процедуры20). Поэтому Oracle изначально отказался от такой идеи и реализует взаимодействие ядра сервера с внешними процедурами в защищенном режиме (т. е. в различных адресных пространствах). Для реализации такого взаимодействия и для доступа из внешних процедур к данным БД требуется наличие специального программного интерфейса. Oracle в данном вопросе пошел по пути поддержки имеющегося стандарта интерфейса Corba, позволяя т.о. оформлять расширения ядра сервера как т. наз. "картриджи данных" (Data Cartridges), входящие в более общую архитектуру сетевых вычислений (Network Computing Architecture)21).
Для обеспечения постепенной миграции приложений и данных в новую объектно-реляционную среду введены объектные представления (object views), которые позволяют использовать в новых приложениях объектный интерфейс, работая при этом с обычными реляционными таблицами (т. о. сохраняя работоспособность старых приложений).
А что еще будет в Oracle 8?
Собственно, о некоторых новых возможностях Oracle 8 (разбиение таблиц и индексов, расширение возможностей параллельного сервера и параллельного выполнения операций, объектные расширения) я уже упомянул. Этим список новшеств далеко не исчерпывается. Перечислю лишь некоторые из оставшихся. Новые возможности в администрировании - управляемые сервером сбросы и восстановления (собственно говоря, это расширенная интеграция применявшейся в Oracle 7 утилиты Enterprise Backup), централизованное хранение паролей (в Oracle 7 достигалось при использовании Advanced Networking Option или при идентификации пользователей через ОС, имеющую соответствующую функциональность), контроль за назначением и устареванием паролей (в Oracle7 - при идентификации пользователей через ОС). Новые режимы взаимодействия с сервером - поддержка очередей приоритетных сообщений, задающих описание транзакции или ее части (эта функциональность, кстати, может быть использована мониторами транзакций), возможность мультиплексирования сессий как на физических, так и на логических каналах связи. Фактическое снятие ограничений на количество BLOB-колонок в таблицах, возможность их тиражирования. Возможность разбиения BLOB-полей и их отдельного хранения (даже вне БД). Расширение функциональных возможностей тиражирования данных, введение программного интерфейса тиражирования, позволяющего реализовать поддержку репликации с самыми разнообразными системами хранения данных. Поддержка таблиц, целиком хранимых в индексах.
Еще раз подчеркну, что это далеко не полный список. Хочу лишь обратить внимание, что большая часть новшеств возникла не на пустом месте, а скорее представляет собой развитие тех черт, которые уже содержались в том или ином виде в Oracle7. Это не случайность: Oracle гарантирует совместимость версий сервера снизу вверх, при переходе к Oracle8 пользователям даже не потребуется перестраивать свои БД.
Я очень надеюсь, что информация, приведенная в данной статье, будет полезна как тем, кто уже давно работает с сервером Oracle, так и тем кто только знакомится с этой системой.
Литература
1. Д. Девитт. Д. Грей. Параллельные системы баз данных: будущее высокоэффективных баз данных. - СУБД # 2, 1995 (перевод статьи из CACM Vol. 35 # 6, 1992).
2. В.В. Сиколенко. Поддержка распределенных систем в СУБД Oracle. - СУБД # 4, 1996
3. М.Т. Оззу, П. Валдуриз. Распределенные и параллельные системы баз данных. - СУБД # 4, 1996.
1) Автор считает, что подробное обсуждение всех этих мод изоляции в данной статье неуместно: вместо этого он предлагает обратиться к соответствующей литературе.
2) Не следует, конечно, полагать при этом, что блокировки при выполнении чтения в Oracle вообще никогда не используются: другое дело, что они применяются тогда, когда это обусловлено потребностями приложения, а не СУБД. Например, если вы, считав запись, намерены затем модифицировать ее, и хотите, чтобы, пока вы соберетесь это делать, вас не опередил с аналогичной операцией кто-то другой (в противном случае вы получите соответствующее сообщение об ошибке), можно выполнить операцию "Select for update", которая наложит на запись т. наз. разделяемую блокировку. Конфликты в результате "скрытой" модификации другими пользователями тех записей, на которые "претендуете" вы, возможны также в рамках "сериализуемых" (работающих в моде "повторяемого чтения") транзакций, когда они реализуются без блокировок, но Oracle автоматически обнаруживает эти конфликты и выполняет откат транзакций. Другими словами - если пояснить ситуацию на примере - оператор, продающий билеты на самолет, может выполнить запрос на наличие свободных мест, а затем, при попытке продать билет на одно из них, получить сообщение, что эту операцию успел раньше выполнить другой оператор, но Oracle никак не позволит дважды продать билет на одно и то же место (если, конечно, это не явится следствием ошибки в приложении).
3) Желающим предлагаю посмотреть мою статью [2] в "СУБД" # 4 за 1996 год.
4) Опять-таки отсылаю читателей к "СУБД" # 4 1996 к интересной статье [3], предупреждаю только, что это перевод статьи, написанной несколько лет назад, поэтому все приводимые там данные о фактической реализации параллелизма в той или иной системе очень далеки от сегодняшней реальности.
5) Я очень далек от того, чтобы на основании этих фактов утверждать, что Oracle - самая быстрая СУБД в мире, или нечто подобное. В сущности, степень масштабируемости СУБД - один из немногих параметров, о которых реально позволяют судить результаты TPC-тестов. Что касается "производительности СУБД вообще", то для специалиста сама постановка такого вопроса бессмысленна вне контекста, т. е. режима использования, уровня загрузки системы, требований к ней и пр. В этом плане, к сожалению, спецификации TPC позволяют выполнять тесты в контекстах, далеких от реальной жизни. Например, результат TPC-C практически ничего не говорит о том, какова будет производительность СУБД в действительно многопользовательском (больше 5 рабочих станций) режиме, не запрещается использование приемов типа отключения записи в журнальные файлы (на практике это означало бы невосстановимую потерю данных даже при самом незначительном сбое системы - к чести Oracle могу заметить, что он подобные фокусы принципиально не допускает, кроме случаев выполнения заведомо восстановимых операций: CREATE TABLE AS SELECT, загрузки данных из текстовых файлов). В качестве образного сравнения рискну предложить такое: представьте, что вам посоветовали бы судить о потребительских качествах различных марок автомобилей на основании их испытаний на абсолютно ровной и прямой трассе, причем когда используются специальные форсированные модели, с которых к тому же разрешается снять все вплоть до тормозов. Впрочем, вряд ли стоит предъявлять претензии в TPC-тестам: они ведь изначально задумывались как средство независимой оценки степени пригодности тех или иных платформ (прежде всего аппаратных) для их использования в неких типовых задачах СУБД. Затем уж с легкой руки отделов маркетинга фирм-производителей СУБД значение TPC-результатов было раздуто до неприличия. Увы - в конечном счете и Oracle был в определенной степени втянут в эти игры (хотя, безусловно, не он был их инициатором). Остается лишь пожалеть, что альтернативных независимых и общепризнанных тестов для СУБД не существует. Впрочем, я очень прошу рассматривать данную сноску как выражение личного мнения автора, а никак не в качестве официальной позиции корпорации Oracle.
6) В принципе существуют более специфичные архитектуры, которые по-своему интересны, например с неравноправным доступом к памяти (NUMA), но для краткости мы не будем сейчас рассматривать особенности работы Oracle с ними.
7) Здесь я хочу указать на два достаточно распространенных заблуждения относительно сервера Oracle. Первое состоит в том, что параллелизм будто бы не присущ ему внутренне, а достигается за счет неких внешних "примочек" (под которыми подразумевают указанные опции). Как видите, наиболее часто требуемый вид параллелизма вообще не требует никаких опций, опции же - это отнюдь не "примочки": их установка означает выбор соответствующего варианта сборки ядра сервера, а выделение их связано как раз с тем, что соответствующие виды параллелизма требуются на практике далеко не во всех инсталляциях. Второе заблуждение - увы, встречающееся в журналах - состоит в том, что для параллельной работы сервера Oracle требуется Parallel Server Option. Как видите, эта опция нужна лишь при работе с кластерами и MPP, да и то только в режиме параллельного доступа к одной БД с разных узлов.
8) В принципе в "безсессионном" режиме работы - например при использовании мониторов транзакций - можно не "привязывать" пользователей к узлам системы и реализовать т. о. динамическую балансировку их загрузки, но, как я покажу ниже, к данной возможности следует относиться с известной осторожностью.
9) Собственно альтернативное решение предлагается только одно: разделить физически БД между узлами, чтобы они не могли напрямую обращаться к "чужим" данным. Как нетрудно увидеть, этот подход ликвидирует блокировки параллельного кэша в чистом виде, но заменяет их на необходимость пересылки данных между узлами даже при чтении, а если транзакция затрагивает данные нескольких узлов, то требуется и вовсе дорогостоящий протокол ее двухфазного завершения.
10) Ясно, что проблема блокировок параллельного кэша не возникает вовсе, если доступ к БД осуществляется преимущественно на чтение, или если данные четко "делятся" между узлами сервера. В последнем случае нет больших проблем и у подхода с физическим разделением данных, но тогда это разделение является жестко заданным, параллельный же сервер допускает гораздо большую гибкость.
11) Я намеренно не привожу достигнутый результат, ибо дело в общем-то не в абсолютной цифре (она в большей степени характеризует мощность использованного сервера), а в том, что был достигнут почти тот же "коэффициент масштабируемости" (удельная производительность на процессор), что и в другом тесте на той же модели сервера, но не в кластерной, а в "чистой" SMP-конфигурации, имеющей соответственно вчетверо меньше процессоров.
12) Как и в случае теста TPC-C, хочу предостеречь от трактовки результатов TPC-D в качестве исчерпывающей характеристики пригодности той или иной системы для какой-либо конкретной инсталляции хранилища данных. Если же говорить о тестах вообще, то хочу отметить, что выбор метода динамического разбиения таблиц требовал определенного "маркетингового мужества", ибо применение более сложного и изощренного алгоритма давало серверу Oracle7 высокую степень адаптивности, необходимую для реально работающих систем, но ставило Oracle в невыгодное положение по сравнению с конкурентами при проведении показательных тестов, когда была возможность тщательной "ручной" настройки структуры БД под конкретные данные и конкретные запросы.
13) Я уж не говорю о том, что для разбиения таблицы на физические разделы, располагающиеся на разных дисках, существует даже несколько способов.
14) Это не означает впрочем, что оба режима будут одинаково оптимальны при одном и том же выборе параметров системы. Безусловно, по крайней мере часть параметров требуют разного подхода при их оптимизации для OLTP- и DSS-систем. По этой причине поддержка "смешанного" режима обязательно сопряжена с некоторым компромиссом, и не следует трактовать приведенное утверждение как рекомендацию совмещать оперативную систему с хранилищем данных. Более разумно на практике говорить о том, что, скажем, если основной режим системы - OLTP, то совсем не обязательно дожидаться ночной паузы в работе, чтобы выполнить на ней сложный - но срочный - отчет, и Oracle гарантирует, во-первых, корректность результатов отчета, во-вторых, что его выполнение не повлияет сколько-нибудь заметно на работу пользователей.
15) В сущности, все, что предлагается сейчас в данном направлении, вряд ли может претендовать на название "объектно-реляционная СУБД" в полной мере. С точки зрения специалиста гораздо правильнее говорить о введении абстрактных типов данных в РСУБД, хотя некоторые черты классов и наследования их свойств, характерные именно для объектно-ориентированного программирования, присутствуют.
16) Возможностиэтой опции, вообще говоря, гораздо шире простого контекстного поиска: этотпоиск может осуществляться по нечетким критериям, по созвучию, специальныеутилиты могут проводить смысловой анализ документов с выделением ключевыхслов, автоматическим построением тезаурусов и аннотаций и пр. К сожалению,все эти возможности полностью реализуются в нынешней версии программногопродукта только для англоязычных текстов.
17) Хотя, с другой стороны, Web-опция фактически обеспечивает хранение на сервере программ, динамически формирующих Web-страницы, так что расширение функциональности налицо - другое дело, что достигается оно с помощью стандартных средств ядра системы.
18) Сколько-нибудь подробное рассмотрение объектно-реляционных свойств Oracle 8 требует отдельной статьи: здесь я лишь привожу их далеко не полный перечень.
19) Поддержка Java ядром сервера скорее всего будет отсутствовать в первом релизе Oracle 8.
20) Собственно говоря, проблема не в том, что окажется "лучше написано" или "лучше протестировано" - как известно, любой тест может доказать наличие ошибок, но никак не их отсутствие - а в том, что, не обладая исходным кодом "внешнего включения" в ядро своей системы, фирма едва ли может до конца решить проблему ее технической поддержки.
21) Здесь придется упомянуть еще одну - пожалуй самую свежую - легенду об Oracle, которая, возможно, появилась вследствие неверной трактовки информационных сообщений о поддержке сервером Oracle8 стандарта Corba при взаимодействи с картриджами данных. Состоит она в том, что Oracle8 якобы "работает с объектами через Corba" и что, следовательно, данные объектов хранятся вне БД, а взаимодействие с ними осуществляется через "архитектуру среднего уровня". В принципе, возможность взаимодействия сервера с удаленными картриджами действительно будет реализована (скорее всего, не в первом релизе Oracle8), но мнение о том, что именно такой механизм является основным для расширения сервера Oracle8, не имеет ничего общего с действительностью. Сервер Oracle берет на себя хранение всех данных и большую часть функций, относящихся к ним (защита, поддержка транзакций, сбросы и восстановления, блокировки и пр.), картридж данных должен лишь реализовать конкретное наполнение методов доступа, указать способ индексирования, сортировки, оптимизации запросов и т. п. Интерфейс картриджа с ядром сервера реализуется через межпроцессное взаимодействие, а Corba - лишь средство описания этого интерфейса.