Среди основных направлений развития технологий работы с базами данных можно отметить следующие:

  • Создание мощных СУБД (конвергентных инфраструктур), одинаково эффективно работающих в разных средах (физический ЦОД предприятия пользователя; частное, публичное облако или гибридное облако; машина баз данных [1]; Cloud&Customer — фрагмент публичного облака, работающий в ЦОДе пользователя). Иначе говоря, современная база данных может работать и как СУБД, и как сервис.
  • Самоуправляемость, автономность и одновременное управление множеством СУБД с привлечением алгоритмов искусственного интеллекта.
  • Мультимодельность — поддержка в одной СУБД множества типов данных (таблицы, геинформация, текст, JSON, NoSQL, XML, Hadoop, Spark, мультимедиа и пр.) в условиях множественных нагрузок (OLTP, системы поддержки принятия решений, Интернет вещей, хранилища, блокчейн, «ключ-значение» и т. д.).
  • In-memory и использование векторных команд микропроцессоров.
  • Работа с энергонезависимой памятью.
  • Разделение базы данных между несколькими серверами (сегментирование, шардинг).
  • Кроме этого, естественно, продолжаются исследования по повышению надежности, производительности, безопасности, масштабируемости и управляемости СУБД.
  • Перечисленные тенденции нашли свое конкретное отражение в очередных версиях СУБД Oracle (19с и 20с).

Мультиарендность

Впервые мультиарендная архитектура, где один экземпляр СУБД управляет множеством подключаемых баз (Pluggable Database, PDB), появилась еще в версии 12.1 и быстро завоевала популярность пользователей [2]. Эта архитектура позволила снизить сложность сопровождения множества баз данных, повысив эффективность использования оборудования.

Для повышения надежности работы группы PDB для конкретной контейнерной базы данных (container database, CDB) можно сконфигурировать кластер (Real Application Clusters, RAC), закрепив отдельные PDB за его конкретными узлами для обеспечения изолированности и масштабируемости. Контейнеры позволяют просто делать клоны PDB, которые могут обновляться по мере обновления исходных PDB: вместо десяти обновлений для десяти баз данных достаточно обновить CDB — и все ее PDB автоматически обновятся до новой версии, а если этого не требуется, то можно перенести существующий вариант PDB в CDB новой версии. При этом метаинформация о PDB одной командой выгружается в xml-файл и загружается в другую CDB. Таким образом можно не только переместить PDB в другую CDB, но и делать в новой CDB клоны PDB, чтобы, например, всегда иметь свежую копию мастер-клона в новой CDB, открытую только для чтения, а изменять лишь новые клоны PDB. Это удобно для разработчиков приложений.

Разработчикам и тестировщикам часто требуется восстанавливать базу на определенный момент времени, что можно делать с помощью механизма ретроспективных запросов (flashback) либо с помощью нового механизма — карусели снапшотов (snapshot carousel). Если включен режим карусели, то СУБД будет автоматически ежедневно делать копию PDB и хранить ее в архивном файле (снапшоте). По умолчанию хранятся последние восемь снапшотов, из которых можно восстановить PDB на нужный момент времени.

Еще один интересный механизм мультиарендности — Application Container (AC). Если несколько PDB имеют одинаковые объекты (таблицы, процедуры, функции и т. д.), то их можно поместить в отдельную PDB, называемую AC. Все PDB, наследующие объекты этого контейнера, будут видеть эти объекты. Таким образом, исключается дублирование и упрощается сопровождение объектов — все изменения происходят в одной точке. Например, если разделяемым объектом является таблица, то возможны три варианта: хранить таблицу со всеми данными в AC, и тогда PDB будут видеть ее как таблицу, открытую для чтения; хранить таблицу и часть ее данных в АС, и тогда каждая PDB будет видеть эти данные в режиме чтения, но может иметь свою открытую для изменения часть этой таблицы; хранить только описание структуры таблицы в АС, и тогда каждая PDB будет иметь свой, скрытый от других, открытый для изменений вариант этой таблицы.

Все PDB изолированы и не видят друг друга, а администратор может управлять разделением ресурсов (память, процессоры, ввод-вывод, параллелизм) между базами. К примеру, с помощью механизма установки разрешенных операций (lockdown profiles) можно ограничить для PDB выполнение отдельных SQL-команд, запретить запуск некоторых потенциально опасных команд (например, системной команды alter system, влияющей на работоспособность базы), запретить выполнение команд операционной системы и даже запретить прямой доступ к этой PDB. Однако у серверных процессов ОС еще остается доступ к файлам базы и они могут читать либо модифицировать файлы чужих PDB, поэтому в версии 20с вводится механизм DB Nest. Все процессы ОС экземпляра СУБД Oracle делятся на две группы: фоновые и серверные, обслуживающие сессии и SQL отдельных пользователей, — механизм DB Nest запрещает серверным процессам конкретной PDB доступ к файлам, областям памяти других PDB и выполнение команд ОС. Это похоже на контейнеризацию в ОС: каждая PDB со своими серверными процессами и файлами работает в отдельном контейнере и изолирована от других PDB. Поскольку теперь с PDB можно работать как с обычной базой данных, у нее есть и традиционные средства настройки.

Мультиарендная архитектура доказала свои преимущества: на ней сегодня построены все автономные базы Oracle [3], и начиная с версии 20с поддерживается только эта архитектура. При необходимости можно по-прежнему иметь один экземпляр СУБД для каждой базы, создав CDB с одной PDB.

In-Memory

Работа в памяти (опция Database In-Memory) позволяет ускорить выполнение аналитических запросов. Для этого требуется задать размер кэша и указать таблицы, которые можно в него помещать. Сегодня используются два основных метода хранения данных: традиционный (построчный) и поколоночный. Аналитические запросы быстрее выполняются при поколоночном хранении, но обычные OLTP-запросы, требующие доступа к небольшому набору строк либо модифицирующие одну строку таблицы, работают в этом случае медленно. При построчном хранении OLTP работает быстро, но аналитика выполняется медленнее. Технология in-memory позволяет решить проблему эффективного выполнения смешанных запросов, включающих и OLTP, и аналитические запросы, и сложные вычисления, и т. д. Данные из базы хранятся на диске построчно, что позволяет применять традиционные механизмы хранения и ввода-вывода, а в оперативной памяти для заданных таблиц или их частей — хранить два представления их данных: построчное в буферном кэше и поколоночное в кэше in-memory (cм. рисунок).

Архитектура Oracle Database In-Memory

Когда в СУБД поступает новый запрос, SQL-оптимизатор определяет, как лучше его выполнить (на каком представлении данных), и строит соответствующий план выполнения запроса — работа аналитических запросов при этом может ускоряться на порядки. Это происходит не только за счет поколоночного представления данных и их кэширования в памяти, но и за счет того, что операции с колонками (векторами значений) СУБД Oracle выполняет с использованием векторных операций микропроцессора, позволяющих одной командой одного ядра процессора сразу выполнить, например, поиск значений в колонке. Более того, даже такие тяжелые и сложные операции, как объединение таблиц, могут быть преобразованы в набор векторных. В версии 20с появилась возможность выполнять и простые операции соединения с использованием векторных операций, In-memory Vector Join. Например, если нужно соединить таблицу «Продажи» и таблицу «Пункты продаж» по ключу «Код заказа», то значения колонок «Код заказа» этих таблиц загружаются в два векторных регистра и за один такт микропроцессора СУБД получает матрицу соответствия этих столбцов, что существенно ускоряет многие операции соединения, а также функции построения агрегированных отчетов.

Естественно, объем оперативной памяти ограничен, поэтому имеется утилита In-memory Advisor, анализирующая запросы и рекомендующая, какие именно таблицы и как следует поместить в кэш in-memory. Для экономии памяти кэшировать можно части таблиц (секции), не все колонки, а также сжимать данные. Начиная с версии 19с данные автоматически подкачиваются в кэш на место давно неиспользуемых, а в версии 20с, даже если только часть таблиц запроса хранится в кэше in-memory, а часть — в буферном кэше, СУБД будет использовать in-memory-алгоритмы.

В современных версиях СУБД Oracle Database технология in-memory используется не только для реляционных данных, но и для колонок с геоинформацией, текстом и JSON, а также при работе с внешними таблицами (external table).

«Побочный» эффект действия опции Database In-Memory — ускорение в два-три раза выполнения OLTP-запросов. Обычно для ускорения аналитических запросов строится множество дополнительных индексов для таблиц и каждое изменение данных таблицы вызывает также изменение всех этих индексов, что замедляет работу. В случае in-Memory можно удалить все эти дополнительные индексы и обеспечить ускорение OLTP-операций.

Существуют еще два типа приложений со специфическими запросами, которые также можно ускорить: таблицы «ключ-значение» и Интернет вещей, где требуется непрерывная вставка записей в таблицу (например, поток телеметрии с датчиков). Для этих приложений используются таблицы с расширенной памятью (memory optimized), для которых применяются специальные алгоритмы обработки. Если надо быстро извлекать данные из таблицы по ключу, то достаточно объявить такую таблицу как «Memoptimize for read» и задать для нее размер кэша. При этом таблица будет загружена в кэш при первом обращении к ней и в памяти для нее будет построен индекс. При запросе записи по ключу, СУБД, в обход традиционных механизмов, посмотрит этот индекс и сразу извлечет из памяти нужные строки. Такой алгоритм обеспечивает прямой доступ к ядру СУБД в обход SQL-уровня и позволяет в четыре раза ускорить выполнение запроса. Если требуется создать таблицу для работы с устройствами Интернета вещей, куда нужно быстро и непрерывно вставлять новые записи, то надо объявить эту таблицу как «Memoptimize for write». При добавлении записей в такую таблицу, строки вставляются в специальный буфер в памяти, а затем буферизованные данные пакетами пишутся на диск в фоновом режиме, что вдвое повышает производительность добавления записей.

Шардинг

Обычно таблица хранится в одной базе данных на одном сервере и ее обработкой занимаются либо сервер, либо группа узлов кластера RAC, однако если таблица слишком велика, а нагрузка очень большая и обработка отдельных частей таблицы допускает распараллеливание, то можно разрезать таблицу на части («шарды», от англ. shard — «осколок», «кусок») и разместить их на разных серверах. На каждом будет своя база, в которой будет находиться часть таблицы или часть группы связанных таблиц (семейство), и каждый сервер станет выполнять обработку своих шардов. Это позволяет осуществить горизонтальное масштабирование для высоконагруженных, распараллеливаемых задач, например поиска.

Механизм шардинга предполагает нарезку таблицы на части по ключу шардинга, который может явно указываться в SQL-запросах или при открытии сессии. Имеется координатор (шард-директор), по ключу определяющий, какому компьютеру передать обработку. Если же в запросе ключ не указан, то координатор выполняет запрос на всех шардах (кросс-шардинг). Все операции языка описания данных (Data Definition Language, DDL) с множеством узлов выполняются централизованно через координатор.

Достоинством шардинга является то, что новые узлы можно добавлять «на лету», увеличивая мощность системы и перенося в нее часть шардов (так называемый решардинг). Часть баз шардированного приложения может быть реализована в виде PDB или размещена в облаке. Таким образом, шардинг не только ускоряет обработку, но и повышает отказоустойчивость: выход узла из строя делает недоступной лишь часть данных.

В базе данных узла можно размещать не только часть одной таблицы, но и связанные по ключам части нескольких таблиц (семейство таблиц, table family tree) или несколько семейств. Кроме того, в эти базы для ускорения помещаются копии справочных таблиц и вся обработка выполняется на узле.

Начиная с версии 19с, в одной CDB могут быть PDB для шардов одной или разных шардированных баз данных. Если при работе с шардами в узлах для генерации уникальных значений используются последовательности (sequence), то можно обеспечить состояние, когда генерируемые значения будут уникальны как в шарде, так и для их группы. Для выбора способа разбиения базы на шарды применяется утилита Sharding Advisor.

Традиционно в СУБД используются два способа горизонтального масштабирования баз данных: RAC и шардинг. Первый работает с одной базой (или CDB) и распараллеливает обработку (процессоры и память), а второй делит одну базу на несколько (каждая со своими процессорами и памятью). Начиная с версии 18с предлагается еще один вариант — шардированный RAC (виртуальный шардинг). База данных при этом не разделяется на части, а остается единым целым, но данные делятся на виртуальные шарды и привязаны к узлам кластера RAC. Запросы с ключом шарда перенаправляются к узлам кластера, обслуживающим этот шард, что позволяет оптимизировать использование кэша базы и сократить пересылки блоков данных между узлами.

Энергонезависимая память

Согласно традиционной идеологии СУБД, данные обычно хранятся на дисках, а для обработки считываются в оперативную память и теряются после выключения сервера. В качестве промежуточного решения в Exadata между дисками и оперативной памятью размещалась флеш-память для хранения часто используемых данных, что, однако, по-прежнему намного медленнее, чем в оперативной памяти. Появление энергонезависимой памяти (Persistent Memory, PMEM) революционно поменяло ситуацию и неизбежно приведет к изменению архитектуры СУБД. Такая память дешевле оперативной, но по скорости близка к ней. В идеале можно всю базу поместить в PMEM и отказаться от дорогостоящих операций ввода-вывода, кэшей в памяти, подкачки блоков и т. д.

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

В Exadata реализовано четыре уровня хранения: диски («холодные» данные); Flash (кэширование «теплых» данных); PMEM (кэширование «горячих» данных); оперативная память. Обращение экземпляра СУБД к содержимому PMEM происходит не по стандартному протоколу RoCE (RDMA over Converged Ethernet), заменившему в свое время протокол RDMA Infiniband, а напрямую по протоколу RDMA (Remote Direct Memory Access), что исключает сетевой стек, стек ввода-вывода и на порядки снижает задержки. Кроме того, Exadata пишет журналы транзакций (redo log) на PMEM, что также ускоряет операции ввода-вывода.

Пользователи СУБД Oracle 20с, работающие на оборудовании, отличном от Exadata, также могут использовать PMEM, куда можно размещать журналы транзакций и файлы данных, причем SQL-запросы выполняются напрямую над данными файловой системы PMEM. Накладные расходы, связанные с использованием буферного кэша, здесь исключены, что позволяет ускорить выполнение важных запросов и повысить производительность.

Производительность и автономность

В каждой очередной версии СУБД Oracle обычно происходит оптимизация алгоритмов, повышается производительность выполнения некоторых операций, а также кода SQL и PL/SQL. Скорость обработки SQL-запроса зависит от плана его выполнения [4], который готовится оптимизатором запросов (Cost-Based Optimizer) на основе собранной статистики (количество записей, наличие индексов и т. д.). В случае устаревшей, неверной статистики план будет плохим, поэтому администраторы должны постоянно обновлять статистику. Однако сам процесс сбора статистики влияет на производительность, а в период между двумя ее сборами статистика снова неактуальна. Для решения этой проблемы предусмотрен механизм сбора статистики в реальном времени Real Time Statistic. Часть наиболее важной статистики («базовая статистика») хранится в оперативной памяти, автоматически обновляется при выполнении каждого оператора языка манипулирования данными (Data Manipulation Language, DML) и периодически сбрасывается на диск. Каждый новый запрос использует свежую статистику и выполняется по оптимальному плану.

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

Создание оптимального набора индексов — это искусство, которым владеет не каждый разработчик и администратор, поэтому требуется механизм автоматического создания индексов. Такой механизм состоит из шести шагов: захват — приложение периодически (каждые 15 минут) захватывает выполняемые SQL-запросы вместе с планами их выполнения с сопутствующей информацией и помещает в специальный репозиторий (Automatic SQL Tuning Set, ASTS); идентификация кандидатов — анализ вновь захваченных запросов с помощью алгоритмов искусственного интеллекта для выявления индексов, способных улучшить выполнение запросов; верификация — проверка влияния новых индексов на планы выполнения запросов; принятие решения — индекс, способный повысить производительность всех использующих его запросов, помечается как видимый для всех сессий и используется при построении планов запросов, а индекс, снижающий производительность всех запросов, удаляется, если же индекс ускоряет одну группу запросов, но замедляет другую, то он запрещается для использования запросами второй группы (они его не видят); онлайн-проверка — периодическое повторение работы по выявлению и построению новых автоматических индексов; мониторинг — проверка порядка использования автоматических индексов и удаление неиспользуемых индексов. Механизм автоматического построения индексов позволяет, при сохранении производительности приложения, использовать меньше индексов, чем при ручной настройке. Конечно, он требует дополнительных вычислительных ресурсов, поэтому при удалении всех индексов и выборе режима автоматического построения индексов нагрузка на процессоры вначале возрастет. Это допустимо на этапе первичной оптимизации, но лучше делать это на сервере с большим количеством процессоров, а затем, когда основной массив индексов построен, накладные расходы будут уже невелики.

Надежность

RAC, резервная база данных, шардинг, мультиарендность и автономность способны обеспечить уровень надежности базы 99,995 — это 30 минут простоев в год, однако для многих применений и этого может быть недостаточно. В очередных версиях СУБД Oracle появились новые средства повышения надежности.

Первоначально резервная база данных (Standby) применялась только для переключения на нее в случае сбоя основной, как бы догоняя ее. Затем появилась опция Active data Guard (ADG) открытия резервной базы на чтение, что позволило разгрузить основную, освободив ее от операций построения отчетов, аналитики и резервного копирования. Однако очень часто при построении большого сложного отчета требуется изменить данные в таблицах — например, записать диапазон дат, за которые строится отчет, или сохранить информацию о времени последнего построения отчета. Начиная с версии 19с это можно сделать и в резервной базе — standby-база c ADG открыта теперь для небольших изменений. Когда на резервной базе выполняется оператор Update, Delete или Insert, он автоматически перенаправляется на основную базу и выполняется, а изменения передаются на резервную. При этом поддерживается транзакционность: до момента фиксации транзакции изменения другим транзакциям не видны.

Еще один полезный новый механизм — синхронный откат (flashback) основной и резервной базы. При откате назад основной базы, резервная также автоматически откатывается. При большом объеме изменений на основной базе, поток изменений, передаваемый на резервную, тоже очень велик, что может затруднить формирование актуальной резервной базы и увеличить отставание резервной базы от основной. В новой версии предусмотрен механизм MIRA (Multi Instance Recovery Apply): если на основной и резервной системах работает RAC, то изменения от узла/узлов основной базы могут выполняться параллельно и для различных узлов резервной базы. При этом сохраняется порядок выполнения транзакций, но за счет распараллеливания нагрузки скорость синхронизации основной и резервной баз возрастает.

Большинство операций основной базы обычно записываются в журнал, передаются на резервную базу и там выполняются, однако журналирование замедляет работу, увеличивает накладные расходы, поэтому для некритичных операций администраторы отключают журналирование (режим nologging), что чревато рассинхронизацией объектов основной и резервной базы. Команда Validate/Recover Nologging Block позволяет выявить и синхронизировать рассинхронизированные объекты данных. Начиная с версии 18c поддерживается передача изменений при отключенном журналировании непосредственно по сети, без фазы записи изменений в журнал транзакций.

Oracle 20c

В версию 20с, кроме уже упомянутых, вошло еще несколько возможностей, отражающих тенденции развития современных СУБД.

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

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

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

В состав опции Advanced Analytics теперь входят средства создания, обучения, настройки и оценки моделей машинного обучения. Предоставляются библиотека таких моделей, средства их построения и настройки. Как правило, модели используют язык Pyton, однако выбор, построение и обучение таких моделей — сложная операция, требующая высокой квалификации в области машинного обучения, поэтому в новую версию включен компонент AutoML, позволяющий выбрать правильную и наиболее подходящую модель для конкретной задачи, настроить необходимые атрибуты (колонки таблицы) — входы для модели, а также выбрать параметры моделей.

***

Многие из рассмотренных возможностей пока уникальны для Oracle Database, но в ближайшем будущем они появятся и в других коммерческих СУБД. Полный перечень нововведений вместе c обсуждением основных тенденций в мире СУБД приведен на сайте mrivkin.narod.ru/oracle. Новая инициатива Oracle — Always Free — позволяет каждому желающему бесплатно получить две автономные базы для изучения возможностей новых версий и разработки приложений. Однако следует учесть, что некоторые возможности, такие как, например, автоматические индексы, онлайн-статистика и таблицы, оптимизированные для работы в памяти, требуют существенных вычислительных ресурсов, поэтому реализованы только на платформе Exadata.

Литература

1. Дмитрий Волков, Андрей Николаенко. На пути к «железным» СУБД // Открытые системы.СУБД.— 2019.— № 2. — С. 8–13. URL: www.osp.ru/os/2019/02/13054946/ (дата обращения: 21.05.2020).

2. Марк Ривкин, Игорь Мельников. СУБД для облаков // Открытые системы.СУБД.— 2013.— № 6. — С. 30–33. URL: www.osp.ru/os/2013/06/13036850/ (дата обращения: 21.05.2020).

3. Марк Ривкин. На пути к автономным базам данных // Открытые системы.СУБД.— 2018. — № 2. — С. 31–34. URL: www.osp.ru/os/2018/2/13054176/ (дата обращения: 21.05.2018).

4. Леонид Борчук. Стоимостные оптимизаторы для СУБД: вчера и сегодня // Открытые системы.СУБД. — 2016.— № 1. — С. 36–39. URL: https://www.osp.ru/os/2016/01/13048655/ (дата обращения: 22.05.2020).

Марк Ривкин (mark.rivkin@oracle.com) — директор по технологическому консалтингу, Oracle CIS (Москва).