Сервер Oracle: поточний стан, Oracle, Бази даних, статті

В.В. Сіколенко, Старший консультант, Oracle СНД
www.citforum.ru

Зміст

Зв’язаний зобов’язанням писати насамперед про те, що реально надається корпорацією Oracle зараз (У лютому 1997 року), а не передбачається в найближчому майбутньому, автор опинився в кілька скрутному становищі. Справа в тому, що поточної версії сервера Oracle – 7.3 – скоро виповниться вже рік (вона поставляється з кінця березня 1996 року). Наступна версія – восьма – як бачите передбачає зміну цифри вже не після крапки, а до неї, що – коли Ви маєте справу з Oracle – означає не просто поява нових удосконалень і опцій, а дійсно кардинальне оновлення програмного продукту. Усвідомлюючи відповідальність перед своїми користувачами за якість настільки відповідального програмного продукту, як сервер, корпорація Oracle спочатку запланувала тривалий цикл бета-тестування його восьмій версії (почався він у серпні 1996 року, а завершиться ймовірно влітку 1997го) із залученням великої кількості бета-тестерів (у тому числі і в Росії).

Як би там не було, а виходить, що розповідати доведеться про технології вже не самої “гарячої”, але в цьому є і своя перевага. По-перше, розгляд основ технології програмного продукту може дати куди більше значущою і корисної інформації, ніж розмова про самих новомодних віяння, від якого неминуче несе рекламним душком. А по-друге, я постараюся показати, що практично всі напрямки розвитку серверної технології, які отримали відображення в Oracle8, в тій чи іншій мірі вже закладені в Oracle 7.3, а отже користувачів Oracle не очікує перспектива прокинутися в один прекрасний ранок (а може бути і вечір) з необхідністю почати своє життя в світі СУБД з початку.


Oracle – це не тільки сервер БД.

А може бути навіть і не стільки. Одна з переваг Oracle в тому, що він ніколи не постачає свою технологію в “голом” вигляді, ставлячи користувача перед необхідністю шукати скільки прийнятний спосіб використання цієї технології. Перерахую лише основні напрямки програмних продуктів Oracle, не маючи можливості осягнути неосяжне, і розповісти про них скільки-небудь докладно.


Зважаючи – повторююся – неможливості висвітлити всі ці напрямки в одній статті, обмежимося розглядом тих нововведень, які з’явилися в поточній версії сервера 7.3, а заодно поговоримо про особливості сервера Oracle взагалі.


Загальні функціональні можливості.

Версія 7.3 сервера Oracle містить ряд функціональних нововведень, спрямованих як на розширення можливостей розробників додатків, так і на розвиток можливостей самої системи з обслуговування великого числа одночасних користувачів. Обговоримо спочатку останню тему (бо вона дуже важлива для розуміння технологічних особливостей СУБД), а потім, як водиться, перейдемо і до першої.


Блокування, моди ізоляції та інші нудні предмети

Заголовок розділу не випадковий, бо у багатьох одна лише згадка про перерахованих темах викликає нестримну позіхання. У цьому немає абсолютно нічого поганого (якщо звичайно позіхання не переходить плавно в наступний сон на робочому місці), бо, скажімо, розробник програм має право задатися питанням, навіщо власне йому потрібно розбиратися, а тим більше дбати про всю цю нудною внутрішньої кухні СУБД. На жаль, розібратися все-таки варто, бо будь-яка розрахована на багато користувачів СУБД в порівнянні з “персональної” містить досить багато підводних каменів, а відсутність адекватного врахування всіх цих факторів в додатку – особливо якщо воно працює не з Oracle, а з іншого СУБД – може привести до дуже неприємних сюрпризів.

Oracle завжди славився – і заслужено – за свою здатність практично однаково ефективно обслуговувати будь-яку кількість одночасно працюючих користувачів (природно при наявності достатніх апаратних ресурсів сервера), не проявляючи схильність до вираженої (а тим більше стрибкоподібно) деградації продуктивності системи при збільшенні цього числа. Таке – треба сказати, зовсім не часте – властивість обумовлена цілим рядом архітектурних рішень, і не в останню чергу добре вивіреним механізмом блокувань. Oracle влаштований так, що в принципі – за винятком деяких дуже специфічних випадків – розробник додатків може не піклуватися про ефекти багато режиму роботи. Сервер сам забезпечує всі необхідні блокування (хоча звичайно дозволяє виконувати їх і “вручну”), причому здійснює їх завжди на мінімально можливому рівні: скажімо при зміні записи тільки цей запис і буде заблокована від змін іншими користувачами (до завершення транзакції). Такий принцип “безкомпромісно мінімального рівня блокувань “деколи піддається критиці за те, що він, як стверджується,” потребує великої кількості ресурсів для своєї реалізації “. Подібне твердження справедливе лише в тому випадку, коли блокування в системі реалізуються якимсь зовнішнім по відношенню до неї механізмом (якимось “менеджером блокувань”), які використовують свої внутрішні (а тому критичні щодо використання ресурсів) структури для обліку та управління всіма активними і потенційними блокуваннями. В Oracle ж необхідність забезпечення блокувань враховується вже в організації зберігання даних, а сам цей механізм є невід’ємною частиною ядра сервера, “переплітаючись” з усіма його внутрішніми алгоритмами.

Однак це ще далеко не все. Якщо роль блокувань при зміні даних більш-менш зрозуміла і не викликає зазвичай здивованих питань, то набагато складніше буває зрозуміти, яка ж ця роль, і чим чреваті пов’язані з нею ефекти при виконанні операцій читання.


Проблема моди ізоляції читання.

Насправді ця проблема існує, і зрозуміло, звідки вона береться: необхідно якось врахувати ефекти, пов’язані з тим, що поки один користувач читає дані, інший користувач (або інші користувачі) може ці дані змінювати. Стандарт ANSI SQL-92 описує вимоги до реалізації декількох т.зв. мод ізоляції операцій читання від виконуються одночасно з ним транзакцій. Вони варіюють від самої “слабкої” моди – т.зв. “Незафіксованого” (часто званого “брудним”) читання, при якому допускається зчитування даних незафіксованих транзакцій, до самої “сильною” – т.зв. “Повторюваного” читання, при якій гарантується повторюваність результату при повторенні операції в рамках транзакції* . Біда вся в тому, що сама наявність всіх цих різних мод ізоляції в стандарті SQL відображає аж ніяк не потреби користувачів (важко уявити собі, наприклад, розробника програми, зацікавленого в читанні даних чужих незафіксованих транзакцій – якщо тільки він не страждає такий особливою формою мазохізму), а різні ступені компромісу з можливостями розробників СУБД. Користувачів же хвилює (Або у всякому разі повинно хвилювати) зовсім інше: як уникнути тих неприємних ефектів, які можуть бути пов’язані з використанням всіх стандартних мод ізоляції, окрім самої “сильною” з них. Щоб не бути голослівним, розглянемо дуже простий приклад. Припустимо, в якійсь банківській системі є таблиця, що складається всього з двох полів:


РАХУНКУ

































Номер_счета


Сума

1

100000

2

100000

3

100000


.


.


.


.


.


.

99,998

100000

99,999

100000

100,000

100000


Припустимо, користувач запустив операцію підрахунку загальної суми грошей на всіх рахунках:


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”, причому знову-таки без використання блокувань! *


Функціональні нововведення

Якщо говорити про “зовні помітних” нововведення, то їх в 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.

Решта функціональні нововведення в Oracle7.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 в розподілених системах я не припускаю обговорювати в даній статті *, А ось обговорити особливості підтримки паралелізму в Oracle мені здається корисним (тим більше, що по не зовсім зрозумілих причин з цього питання в масової комп’ютерної пресі про Oracle часом дають – скажімо так – не цілком правильну інформацію, а із зустрічей з багатьма фахівцями я виніс враження, що вони часто мають про це і зовсім легендарне подання). Я втім не має наміру вдаватися в фундаментальні аспекти паралелізму в СУБД взагалі *, а спробую пояснити (і в якійсь мірі обгрунтувати) підхід розробників Oracle до даного питання.

Почну з констатації загальновідомого факту, що без використання паралелізму досягнення високих показників продуктивності СУБД неможливо. Розробники сервера Oracle доклали чимало зусиль для реалізації цієї істини на практиці, і не випадково Oracle володіє в даний момент абсолютними рекордами продуктивності як в OLTP-тестах TPC-C (причому цей рекорд тримається з квітня 1996 року), так і в DSS-тестах TPC-D (у варіанті з об’ємом даних 300 ГБ).*


Почнемо з короткою класифікації паралельних систем. Найбільш широко поширені симетрично-паралельні (SMP) системи, тобто такі, де процесори рівноправно використовують всі інші системні ресурси (Перш за все оперативну пам’ять і диски), які є загальними для них *. Кількість процесорів в таких системах, пропонованих на ринку, може доходити до 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 Option*


Поговоримо спочатку про паралелізм в режимі OLTP. Для його забезпечення в SMP-системах Oracle пропонує можливість використання багатопотокових поділюваних серверних процесів. Оскільки я вже давав характеристику даної можливості в статті [2], не буду повторюватися, а замість цього пропоную обговорити особливості підтримки OLTP на кластерах і MPP.

Для початку розберемося, що таке опція Oracle Parallel Server. Як я вже згадував, вона дозволяє декільком вузлам системи (фактично всім, що функціонує в даний момент часу) паралельно працювати з одного БД, що знаходиться на загальних дисках (в MPP-системі це будуть “віртуальні” загальні диски, підтримувані ОС). Користувальницькі сесії взаємодіють кожна зі своїм вузлом, але при цьому фактично працюють з одними і тими ж даними* Крім очевидної можливості використання повної потужності паралельної системи для роботи з БД, Oracle Parallel Server (OPS) дає ще одна важлива перевага: він забезпечує підвищену живучість БД. Справа в тому, що при виході з ладу одного з вузлів системи один з “залишилися в живих” автоматично виконує відновлення транзакцій збійного вузла, не переписаних з буфера у файли БД, так що для “Постраждалих” користувачів достатньо повторити операцію “з’єднання” з БД, щоб продовжити роботу на одному з решти вузлів.

Можна помітити, що в Oracle8 навіть ця операція буде не обов’язкова: нова версія сервера (ще раз нагадаю, що знаходиться в бета-тестуванні) дозволяє виконувати автоматичне перемикання сесій зі збійного вузла, так що наприклад перервані запити просто продовжують виконуватися після невеликої затримки.

Проте було б нечесно стверджувати, що при застосуванні OPS не виникає жодних проблем. Власне кажучи в порівнянні з SMP-системами виникає одна, але досить неприємна, проблема: синхронізація кешей в оперативній пам’яті вузлів. Справді, кожен вузол системи кешує дані БД у своїй оперативної пам’яті і може тримати їх там досить довгий час без переписування на диск. Якщо один з вузлів модифікував якусь запис БД, але не переписав її на диск, то при зверненні до тієї ж записи інший вузол не має права ні користуватися її копією в своїй пам’яті (вона вже не актуальна), ні навіть вважати її з диска. Для вирішення цієї проблеми вводяться т.зв. блокування паралельного кешу: при модифікації даних вузол паралельної системи як би вішає на них свій “замок”, так що будь-який інший вузол при зверненні до цих даних повинен спочатку “зняти замок”, що включає в себе передачу йому актуальних даних. Ясно, що якщо різні вузли будуть часто модифікувати одні і ті ж дані, то блокування паралельного кешу можуть помітно знизити продуктивність сервера в цілому.

На жаль дана проблема є принциповою, тобто від неї не можна повністю позбавитися ні за допомогою технічних хитрощів, ні за допомогою альтернативних рішень* . На щастя проблема не настільки страшна, як може здатися: у всякому разі зрозуміло, як можна з нею боротися. Якщо користувачі, що працюють з різними вузлами, рідко модифікують одні й ті ж записи, то та блокування паралельного кеша виникають рідко. Такий режим легко забезпечується, якщо, наприклад, на різні вузли сервера “призначаються” користувачі, які працюють з різними додатками, або працюють з даними різних відділів (відділень) та ін Програми, здійснюють “хаотичні” звернення до великої БД також мають слабку тенденцію до породження блокувань паралельного кеша. Тим не менш, розподіл користувачів між вузлами сервера повинно здійснюватися не навмання, а з урахуванням того, з якими даними і в якому режимі вони працюють *. Як би там не було, OPS вже досить давно і успішно використовується – особливо в інсталяціях, що вимагають підвищеної надійності системи. Не зайве зауважити, що і рекорд в тестах TPC-C поставлений з використанням OPS на кластері (Digital Alpha 8400)* . Звичайно рекорд рекордом, але для користувачів важливо знайти систему, що відповідає масштабам їх завдань. Треба сказати, що до останнього часу поняття “кластер” і “паралельний сервер” асоціювалися тільки з вельми потужними і дорогими конфігураціями апаратури. Частково це було пов’язано з реальними потребами ринку, а почасти з тим фактом, що підтримка кластерного режиму роботи вимагає досить значних системних ресурсів. Одним з перших пожирачів ресурсів є т.зв. менеджер розподілених блокувань (Distributed Locks Manager – DLM). Це програмна компонента (реалізована зазвичай у вигляді набору процесів), зазвичай поставляється фірмою-розробником ОС, завдання якої – управління доступом до ресурсів на рівні системи в цілому. Саме за допомогою DLM Oracle реалізує блокування паралельного кеша і взагалі синхронізацію роботи вузлів. Універсальність DLM в поєднанні з тим, що він є “зовнішньої складової” OPS, призводить до того, що загальна кількість блокувань паралельного кешу стає критичним ресурсом. Щоб знизити потребу в ньому, в Oracle 7.3 введено ряд удосконалень в управлінні виділенням цих блокувань, але для радикального вирішення проблеми безумовно потрібний інший підхід до реалізації DLM. Зокрема з цієї причини вже у версії 7.3 Oracle поступово переходить до реалізації DLM власними коштами в складі ядра сервера – остаточно цей процес буде завершений з виходом Oracle8. Як би там не було вже в найближчому (“весняному”) релізі 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)* .

Щоб завершити розмову про розбиття, хочу зазначити, що Oracle7 на жаль не включає в себе явною операції побудови статичних розділів таблиці (ця можливість вводиться в Oracle8), але в неявному вигляді це все ж можна зробити за допомогою імітації розділів окремими таблицями, об’єднаними в єдине уявлення за допомогою операції UNION ALL. При виконанні запитів до такого поданням оптимізатор Oracle7 трактує його саме як таблицю, розбиту на розділи, зокрема виконує виключення розділів, якщо це можливо (хоча – ще раз підкреслю – паралелізм з цими розділами жорстко не ув’язується)* .


Універсальний сервер Oracle ®

Я не випадково привів заголовок саме в такому вигляді: не так давно суд в США зажадав, щоб всі публічні згадки терміну “універсальний сервер” робилися саме в такому вигляді – з обов’язковим зазначенням логотипу фірми-виробника. З цим мабуть варто погодитися, бо навколо цього терміна в останній час було зламано чимало “маркетингових копій”, і різні фірми вкладають в нього різний зміст і – якщо хочете – різні технологічні стандарти. Я спробую пояснити, як трактує цей термін корпорація Oracle, потім коротко розповісти, які елементи “Універсального сервера Oracle” реалізовані у версії 7.3, потім зовсім вже трохи поговорити про те, що нового чекає користувачів в цьому плані в Oracle8.

Отже, що має на увазі корпорація Oracle, кажучи про універсальний сервері? Мова йде про три складових цього поняття.

Будь масштаб СУБД.
Oracle традиційно славиться як постачальник СУБД для великих інсталяцій, проте у зв’язку з цим існує (і активно підтримується конкурентами) також і думка про те, що для невеликих систем Oracle занадто важкоатлета, складний, доріг та ін Загалом-то це ніколи не було правдою, але особливо в останні кілька років Oracle прикладає чимало зусиль, щоб по всіх параметрах (включаючи ціни) утвердитися в якості основного постачальника у всіх сегментах ринку СУБД, починаючи з невеликих робочих груп. З 1994 року крім вже звичного “сервера масштаби підприємства” поставляються інші його варіанти: “сервер для робочих груп “(Workgroup server) і” персональний Oracle “(Personal Oracle) у двох редакціях – повній і” полегшеної “(Personal Oracle Lite). У цих продуктах особливий упор зроблений на їх відносну дешевизну, простоту установки і супроводу. При цьому всі варіанти сервера Oracle функціонально ідентичні за винятком деяких опцій (тільки в нинішній версії Personal Oracle Lite відсутня частина базової функціональності: він не підтримує багатокористувацькі схеми даних і процедурні розширення SQL).

Будь-який тип додатків.
Як я вже показував у попередніх розділах Oracle7 в однаковій мірі може бути оптимізовано і для OLTP-додатків, і для додатків DSS, причому їх цілком можна виконувати одночасно, не турбуючись про додаткові блокування, модах ізоляції та інших темах, здатних викликати головний біль у знайомих з ними на практиці фахівців при одному тільки їх згадуванні.*

Будь-який тип даних.
По цій темі поговоримо трохи докладніше, тим більше, що саме це питання найчастіше мусується, коли мова йде про той чи інший “універсальному сервері”.

По суті мова йде про розширення стандартного набору типів даних, характерного для РСУБД, а в перспективі про перехід до об’єктно-реляційної моделі СУБД*. В свою чергу ця задача може бути розділена на дві:


Oracle розвиває свій сервер в обох напрямках. У версії 7.3 вже підтримується кілька нових типів даних: неструктуровані тексти, просторові дані, відеодані. Власне кажучи, зберігати такі дані в БД і здійснювати до них доступ можна було і раніше: новизна в тому, що якщо раніше цей доступ здійснювався через самостійно працюють серверні процеси, і для роботи з ними потрібно використання спеціального інтерфейсу на рівні додатків, то тепер ця функціональність інтегрована в “базовий” сервер, так що, наприклад, можна виконати SQL-запит типу


SELECT ім’я, прізвище FROM Кандидати WHERE Парт_членство NOT IN (‘КПРФ’, ‘ЛДПР’) AND CONTAINS (Обіцянки, ‘Зниження податків & Підвищення дотацій’);

Як неважко здогадатися, в прикладі використовується таблиця “Кандидати”, в якій в одне з полів (BLOB-типу), назване “Обіцянки”, завантажені якісь тексти (які могли мати в оригіналі практично будь відомий формат). Після завантаження текст індексується спеціальним чином, так що навіть при дуже великому обсязі документів контекстний пошук здійснюється швидко. Така функціональність досягається при включення до сервер Oracle7 контекстної опції (Context Option)*.

Опція для роботи з просторовими даними (Spatial Data Option) фактично вводить тип даних “просторова точка” і операції над ним в СУБД, дозволяючи зберігати відповідні дані в таблицях оптимальним чином і на порядок (а часом і на два порядки) прискорювати виконання запитів, що містять порівняння по метриці (наприклад, “всі будинки, що знаходяться в радіусі 1 км від заданої точки” або “всі виміри, в яких комбінований показник температура-тиск виходить за заданий межа щодо оптимуму “).

Що стосується відеоданих, то відповідна їм опція – Video Option – єдина, “живе самостійним життям” по відношенню до сервера РСУБД (але не до БД!). Більш того, рекомендується конфігурація, в якій Video Server запускається на окремому комп’ютері від сервера БД. Пов’язано це з тим, що відтворення відеофрагментів в реальному часі (особливо по декількох каналах) – що саме і забезпечує Video Server – важко сумісне на сучасних масово вироблених комп’ютерах з функціонуванням сервера СУБД через чисто апаратних обмежень. Тим не менш додаток, що працює з Video Server, може здійснювати пошук відеофрагментів по описовим атрибутам і відтворення цих фрагментів – як єдину інтегровану операцію.

Щодо Web Option мабуть не зовсім правильно говорити про функціональні розширення сервера, оскільки по суті головне завдання опції – забезпечення інтерфейсу з Web Application Server і відповідно через нього з користувачами Intranet / Internet* .

Oracle OLAP Option навряд чи можна було розглядати як інтегровану компоненту сервера Oracle (продукти OLAP працюють з власним – багатовимірним – уявленням даних, збереженим окремо) до недавнього часу, коли за допомогою Access Manager з’явилася можливість встановлювати динамічний зв’язок багатовимірного куба OLAP з реляційними даними, стираючи тим самим грань між MOLAP і ROLAP (для аналітика, працює з додатками OLAP стало зовсім непомітно, чи працює він з попередньо сформованим багатовимірним кубом або з динамічним багатовимірним представленням реляційних даних).


Розвиток підходу в Oracle8.

На відміну від Oracle7 восьма версія сервера Oracle не просто надає розширений набір вбудованих типів даних, але і дозволяє конструювати нові типи даних зі специфікацією методів доступу до них. Це означає фактично, що розробники отримують в руки не просто систему для зберігання і обробки, скажімо, відеоданих (що зрозуміло потрібно далеко не в кожному додатку), а і інструмент, що дозволяє будувати структуровані типи даних, безпосередньо відображають сутність предметної області. Вплив цього фактора на можливості розробників можна мабуть порівняти з ефектом від переходу на реляційні СУБД на початку 80х років.

Oracle8 фактично спирається на новий стандарт SQL, що дозволяє описувати визначення нових типів об’єктів, що складаються з атрибутів (скалярних – тобто інших типів, множин об’єктів, посилань на об’єкти), і володіють асоційованими з ним методами. Будь колонка таблиці може бути будь-якого типу, підтримуються також вкладені таблиці і масиви об’єктів перемінної довжини * .

Що стосується методів доступу, то вони можуть бути визначені декількома способами. Простіший з них передбачає контроль ядра сервера за виконанням методу: це досягається, якщо методи реалізуються на PL / SQL (який також розширено для підтримки об’єктно-реляційних структур) або Java*. Оскільки PL / SQL практично не поступається за своєю функціональністю універсальним мов програмування, для переважної більшості складових типів даних таких можливостей буде достатньо. Якщо ж новий тип даних вимагає спеціальної обробки, не реалізованої стандартними засобами ядра СУБД (наприклад робота з мультимедійними даними, збереженими в BLOB-полях в БД), можна використовувати виклики зовнішніх процедур (call-outs), які можуть бути написані, наприклад, на мові C.

При використанні зовнішніх процедур виникає серйозна проблема організації їх взаємодії з ядром сервера. Найбільш спокуслива – на перший погляд – ідея включення їх безпосередньо в ядро ​​таїть в собі загрозу порушення стабільності цього ядра, оскільки воно виявляється незахищеним перед “чужим” кодом, і отже при будь-якому збої (або неправильному функціонуванні) стає практично неможливо визначити, стало це наслідком помилки в самому ядрі, або ж це “наведений” ефект від зовнішньої процедури* . Тому Oracle спочатку відмовився від такої ідеї і реалізує взаємодію ядра сервера з зовнішніми процедурами в захищеному режимі (тобто в різних адресних просторах). Для реалізації такої взаємодії і для доступу із зовнішніх процедур до даних БД потрібна наявність спеціального програмного інтерфейсу. Oracle в даному питанні пішов шляхом підтримки наявного стандарту інтерфейсу CORBA, дозволяючи таким чином оформляти розширення ядра сервера як т.зв. “Картриджі даних” (Data Cartridges), що входять в більш загальну архітектуру мережевих обчислень (Network Computing Architecture)* .

Для забезпечення поступової міграції додатків і даних в нову об’єктно-реляційну середу введені об’єктні представлення (object views), які дозволяють використовувати в нових програмах об’єктний інтерфейс, працюючи при цьому зі звичайними реляційними таблицями (таким чином зберігаючи працездатність старих додатків).


А що ще буде в Oracle8?

Власне про деякі нові можливості Oracle8 (розбиття таблиць і індексів, розширення можливостей паралельного сервера і паралельного виконання операцій, об’єктні розширення) я вже згадав. Цим список нововведень далеко не вичерпується. Перерахую лише деякі з решти. Нові можливості в адмініструванні – керовані сервером скиди та відновлення (власне кажучи це розширена інтеграція застосовувалася в Oracle7 утиліти Enterprise Backup), централізоване зберігання паролів (в Oracle7 досягалося при використанні Advanced Networking Option або при ідентифікації користувачів через ОС, що має відповідну функціональність), контроль за призначенням і старінням паролів (в Oracle7 – при ідентифікації користувачів через ОС). Нові режими взаємодії з сервером – підтримка черг пріоритетних повідомлень, які задають опис транзакції або її частини (ця функціональність речі може бути використана моніторами транзакцій), можливість мультиплексування сесій як на фізичних, так і на логічних каналах зв’язку. Фактичне зняття обмежень на кількість BLOB-колонок в таблицях, можливість їх тиражування. Можливість розбиття BLOB-полів і їх окремого зберігання (навіть поза БД). Розширення функціональних можливостей тиражування даних, введення програмного інтерфейсу тиражування, що дозволяє реалізувати підтримку реплікації з найрізноманітнішими системами зберігання даних. Підтримка таблиць, цілком збережених в індексах.

Ще раз підкреслю, що це далеко не повний список. Хочу лише звернути увагу, що більша частина нововведень виникла не на порожньому місці, а скоріше є розвиток тих рис, які вже містилися в тому чи іншому вигляді в Oracle7. Це не випадковість: Oracle гарантує сумісність версій сервера знизу вгору, при переході до Oracle8 користувачам навіть не буде потрібно перебудовувати свої БД.

Я дуже сподіваюся, що інформація, наведена у цій статті, буде корисна як тим, хто вже давно працює з сервером Oracle, так і тим, хто тільки знайомиться з цією системою.


Література


  1. Д.Девітт. Д.Грей Паралельні системи баз даних: майбутнє високоефективних баз даних. СУБД N2 1995 (переклад статті з CACM Vol.35 N6 1992)

  2. В.В.Сіколенко Підтримка розподілених систем в СУБД Oracle. СУБД N4 1996

  3. М.Т.Оззу, П.Валдуріз Розподілені та паралельні системи баз даних. СУБД N4 1996

Схожі статті:


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

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*