Написано: 23.12.2022

2. CDBs и PDBs

Мультиконтейерная архитектура позволяет БД Oracle функционировать как многопользовательская контейнерная база данных (CDB).

Начиная с Oracle Database 21c, единственной поддерживаемой архитектурой является многопользовательская контейнерная база данных. В предыдущих выпусках Oracle поддерживала неконтейнерные базы данных (non-CDBS).

О контейнерах в CDB

Контейнер – это набор схем, объектов и связанных структур в БД контейнеров (CDB). Внутри CDB каждый контейнер имеет уникальный идентификатор и имя.

CDB включает в себя ноль, одну или множество созданных заказчиком подключаемых баз данных (PDB) и контейнеров приложений. PDB – это переносимая коллекция схем, объектов схемы и несхемных объектов, которая отображается клиенту Oracle Net как отдельная база данных. Контейнер приложения – это необязательный, созданный пользователем компонент CDB, который хранит данные и метаданные для одного или нескольких внутренних интерфейсов приложения. CDB включает в себя ноль или более контейнеров приложений.

На следующем рисунке представлены возможные контейнеры в CDB.

OraCon_Fig2-1

Каждый CDB имеет следующие контейнеры:

  • Ровно один корневой контейнер CDB (также называемый просто корнем)

Корневой CDB – это набор схем, объектов схемы и несхемных объектов, к которым принадлежат все PDB (см. “CDB и PDBS”). В корневом CDB хранятся метаданные, предоставленные Oracle, и общие пользователи. Примером метаданных является исходный код для пакетов PL/SQL, поставляемых Oracle. Общий пользователь – это пользователь БД, известный в каждом контейнере (см. “Общие учетные записи пользователей”). Корневой контейнер называется CDB$ROOT.

  • Ровно один системный контейнер

Системный контейнер включает в себя корневой CDB и все PDB в CDB. Таким образом, системный контейнер является логическим контейнером для самого CDB.

  • Ноль или более контейнеров приложений

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

  • Ноль или более созданных пользователем PDB

PDB содержит данные и код, необходимые для определенного набора функций (см. “PDBS”). Например, PDB может поддерживать определенное приложение, такое как приложение для управления персоналом или продажами. При создании CDB никаких PDB не существует. Вы добавляете PDB в соответствии с вашими бизнес-требованиями.

PDB принадлежит ровно нулю или одному контейнеру приложения. Если PDB принадлежит контейнеру приложения, то это PDB приложения. Например, PDB приложений cust1_pdb и cust2_pdb могут принадлежать контейнеру приложений saas_sales_ac, и в этом случае они не принадлежат никаким другим контейнерам приложений. Начальное приложение – это необязательный PDB приложения, который действует как созданный пользователем шаблон PDB, позволяющий быстро создавать новые PDB приложений.

  • Только один начальный PDB

Начальный PDB – это поставляемый системой шаблон, который CDB может использовать для создания новых PDB. Начальный PDB называется PDB$SEED. Нельзя добавлять или изменять объекты в PDB$SEED.

Пример 2-1 CDB без контейнеров приложений

В этом примере показан простой CDB с пятью контейнерами: системный контейнер (весь CDB), корневой CDB, начальный PDB (PDB$SEED) и два PDB. Каждая PDB имеет свое собственное специализированное приложение. Каждым PDB управляет другой администратор PDB. Общий пользователь существует во всем CDB с единым идентификатором. В этом примере обычный пользователь SYS может управлять корнем и каждой PDB. На физическом уровне этот CDB управляется одним или несколькими экземплярами БД и содержит набор файлов данных для каждой PDB и для самого CDB.

OraCon_Fig2-2

Пример 2-2 CDB с контейнером приложения

В этом варианте CDB содержит контейнер приложения с именем saas_sales_ac. В контейнере приложения PDB приложения cust1_pdb поддерживает приложение для одного клиента, а PDB приложения cust2_pdb поддерживает приложение для другого клиента. CDB также содержит PDB с именем hrpdb, который поддерживает приложение HR, но не принадлежит контейнеру приложений.

OraCon_Fig2-3

В этом примере несколько администраторов баз данных управляют средой CDB:

  • Администратор CDB управляет самим CDB.

  • Администратор контейнера приложений управляет контейнером saas_sales_ac, включая установку и обновления приложений.

  • Администратор PDB приложения управляет двумя PDB в контейнере saas_sales_ac: cust1_pdb и cust2_pdb.

  • Администратор PDB управляет hrpdb.

Корневой и системный контейнер CDB

Корневой CDB, также называемый просто root, представляет собой набор схем, объектов схемы и несхемных объектов, к которым принадлежат все PDB.

Каждый CDB имеет один и только один корневой контейнер с именем CDB$ROOT. В корневом CDB хранятся системные метаданные, необходимые для управления PDB. Все PDB принадлежат корню. Системный контейнер – это корневой CDB и все PDB, принадлежащие этому корню.

Корневой CDB не хранит пользовательские данные. Oracle рекомендует не добавлять общие объекты в корневой CDB и не изменять схемы, предоставляемые Oracle в корневом CDB. Однако можно создать общих пользователей и роли для администрирования БДб. Обычный пользователь с необходимыми привилегиями может переключаться между контейнерами.

Oracle рекомендует AL32UTF8 для корневого набора символов. PDB с разными наборами символов могут находиться в одном и том же CDB без необходимости преобразования набора символов.

Пример 2-3 Все контейнеры в CDB

Следующий запрос, выданный пользователем с правами администратора, подключенным к корневому CDB, содержит список всех контейнеров в CDB (включая начальный и корневой CDB), упорядоченных по CON_ID.

COL NAME FORMAT A15
SELECT NAME, CON_ID, DBID, CON_UID, GUID 
FROM   V$CONTAINERS ORDER BY CON_ID;

NAME          CON_ID       DBID    CON_UID GUID
------------- ------ ---------- ---------- --------------------------------
CDB$ROOT           1 1895287725          1 2003321EDD4F60D6E0534E40E40A41C5
PDB$SEED           2 2795386505 2795386505 200AC90679F07B55E05396C0E40A23FE
SAAS_SALES_AC      3 1239646423 1239646423 200B4CE0A8DC1D24E05396C0E40AF8EE
SALESPDB           4 3692549634 3692549634 200B4928319C1BCCE05396C0E40A2432
HRPDB              5 3784483090 3784483090 200B4928319D1BCCE05396C0E40A2432

PDBs

PDB – это созданный пользователем набор схем, объектов и связанных структур, который логически отображается в клиентском приложении как отдельная БД.

Каждая PDB принадлежит SYS, независимо от того, какой пользователь создал PDB. SYS – это обычный пользователь в CDB, что означает, что этот пользователь имеет одинаковый идентификатор в корневом CDB и во всех существующих и будущих PDB в CDB.

Типы PDBs

Все PDB создаются пользователем с помощью инструкции CREATE PLUGGABLE DATABASE, за исключением PDB$SEED, которая поставляется Oracle.

Можно создавать следующие типы PDB.

pdb_types

Стандартный PDB

Этот тип PDB возникает в результате запуска CREATE PLUGGABLE DATABASE без указания PDB в качестве начального, прокси-PDB или корня приложения. Его возможности зависят от контейнера, в котором он создается:

  • PDB, подключенный к корневому CDB

Этот PDB принадлежит корневому CDB, а не контейнеру приложения. Этот тип PDB не может использовать общие объекты приложения. Смотрите раздел “Общие объекты приложения”.

  • PDB приложения

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

PDB приложения

Рассматривайте корень приложения как корневой контейнер для конкретного приложения. Он служит хранилищем для основного определения серверной части приложения, включая общие данные и метаданные. Чтобы создать корневой каталог приложения, подключитесь к корневому каталогу CDB и укажите предложение AS APPLICATION CONTAINER в инструкции CREATE PLUGGABLE DATABASE. Смотрите раздел “Корень приложения”.

Seed PDB

В отличие от стандартной PDB, seed PDB не предназначена для поддержки приложения. Скорее, seed PDB – это шаблон для создания PDB, поддерживающих приложения. Seed может быть любым из следующих:

  • Seed PDB, подключённый к корневому CDB (PDB$SEED)

Можно использовать этот шаблон, поставляемый системой, для создания новых PDB либо в контейнере приложения, либо в системном контейнере. Системный контейнер содержит ровно один seed-PDB. Нельзя удалить PDB$SEED, а также добавлять объекты в него или изменять объекты внутри него.

  • Seed PDB приложения

Для ускорения создания PDB приложений в контейнере приложений, можно создать необязательный seed-PDB приложения. Контейнер приложения содержит либо ноль, либо один seed-PDB приложения.

Для создания seed-PDB, нужно подключиться к контейнеру приложения и выполнить CREATE PLUGGABLE DATABASE ... AS SEED. Смотрите раздел “Seed приложения”.

Proxy PDB

Прокси-PDB – это PDB, который использует db-линк данных для ссылки на PDB в удаленном CDB. Когда вызываете инструкцию в прокси-PDB при открытом PDB, инструкция выполняется в указанной PDB.

Прокси-PDB нужно создать при подключении к корневому CDB или к корню приложения. Изменить или удалить прокси-PDB можно так же, как стандартный PDB.

Назначение PDBs

Для приложения, PDB является автономной, полностью функциональной БД Oracle. Можно объединить PDB в отдельную CDB для экономии за счет масштабирование, сохраняя при этом изоляцию между PDB.

Можно использовать PDB для достижения следующих конкретных целей:

  • Сохранения данных, специфичных для приложения

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

  • Перемещения данных в другой CDB

БД является “подключаемой”, потому что можно упаковать ее как автономную единицу, называемую отключенной PDB, а затем переместить ее в другой CDB.

  • Выполнения быстрых обновлений

Можно отключить PDB от CDB низкой версии БД Oracle, а затем подключить ее к CDB более высокой версии.

  • Быстрого копирования данных без потери доступности

Для тестирования и разработки можно клонировать PDB, пока она остается открытой, сохраняя клон в том же или другом CDB. При желании можно указать PDB в качестве обновляемого клонированного PDB. В качестве альтернативы, для копирования PDB можно использовать seed-PDB или пользовательское seed-приложения.

  • Для обращения к данным в другой CDB

Можно создать прокси-PDB, которая ссылается на другой PDB, либо в том же CDB, либо в отдельном CDB. Когда выдаются инструкции в прокси-PDB, они выполняются в удаленной PDB.

  • Для изоляции прав в PDB

Локальный или обычный пользователь с соответствующими привилегиями может предоставить права EXECUTE для объекта схемы для общего доступа в отдельной PDB.

Прокси-PDBs

Прокси-PDB ссылается на удаленную PDB, называемую ссылочной PDB.

Хотя инструкции SQL вызываются в прокси (ссылающемся) PDB, инструкции выполняются в ссылочном PDB. В этом отношении прокси-PDB в общих чертах аналогичен файлу символической ссылки в Linux.

Прокси-PDB предоставляют следующие преимущества:

  • Агрегирование данных из нескольких моделей приложений

Прокси-PDB позволяют создавать приложения, прозрачные для определения местоположения, которые могут агрегировать данные из нескольких источников. Эти источники могут находиться в одном центре обработки данных или распределены по разным центрам обработки данных.

  • Разрешают корню приложения в одном CDB распространять изменения приложения на другое корневое приложение

Предположим, что Cdb cdb_prod и cdb_test имеют одну и ту же модель приложения. Вы создаете прокси-PDB в контейнере приложения в cdb_prod, который ссылается на корень приложения в cdb_test. Когда вы запускаете сценарии установки и обновления в корне приложения в cdb_prod, БД Oracle передает эти инструкции в прокси-PDB, который, в свою очередь, отправляет их удаленно в корневом приложении в cdb_test. Таким образом, корень приложения в cdb_test становится точной копией корня приложения в cdb_prod.

Для создания прокси-PDB, выполните команду CREATE PLUGGABLE DATABASE с предложением AS PROXY FROM, где в предложении FROM указывается имя ссылочной PDB и db-линк. Инструкция создания копирует только файлы данных, принадлежащие табличным пространствам SYSTEM и SYSAUX.

Пример 2-4 Создание прокси-PDB

В этом примере подключаются к контейнеру saas_sales_ac в локальном продуктивном CDB. Общий пользователь sales_admin создает прокси-PDB с именем sales_sync_pdb. Этот PDB приложения ссылается на корневой каталог приложения с именем saas_sales_test_ac в CDB удаленной разработки, к которому он обращается с помощью ссылки на базу данных cdb_dev_rem. Когда происходит обновление приложения в saas_sales_ac в продуктивной БД, обновление автоматически распространяется на корневое приложение saas_sales_test_ac в удаленном CDB.

CONNECT sales_admin@saas_sales_ac
Password: ***********

CREATE PLUGGABLE DATABASE sales_sync_pdb AS PROXY FROM saas_sales_test_ac@cdb_dev_rem;

Имена для PDBs

Контейнеры в CDB совместно используют одно и то же пространство имен, что означает, что они должны иметь уникальные имена в этом пространстве имен.

Имена для следующих контейнеров не должны конфликтовать в пределах одного и того же CDB:

  • корневой CDB
  • PDB, подключенные к корневому CDB
  • Корневые приложения
  • PDB приложений

Например, если один и тот же CDB содержит контейнеры приложений saas_sales_ac и saas_sales_test_ac, то два PDB приложения, оба с именем cust1, не могут одновременно находиться в обоих контейнерах. Правила пространства имен также запрещают создание PDB с именем cust1pdb в корне CDB и PDB с именем cust1pdb в корне приложения.

Имена для PDB и корневых контейнеров приложений должны соответствовать тем же правилам, что и имена сетевых служб. Более того, поскольку PDB или корневой каталог приложения имеют службу со своим собственным именем, имя контейнера должно быть уникальным для всех CDB, чьи службы доступны через определенный прослушиватель. Первый символ имени контейнера, созданного пользователем, должен быть буквенно-цифровым, остальные символы должны быть либо буквенно-цифровыми, либо подчеркиванием (_). Поскольку имена служб не чувствительны к регистру, имена контейнеров не чувствительны к регистру и пишутся в верхнем регистре, даже если они указаны с использованием идентификаторов с разделителями.

DB-линки между PDBs.

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

Рисунок 2-4 DB-линки между PDB

На этом рисунке, администратор PDB подключен к PDB с именем hrpdb1. По умолчанию, во время этого сеанса пользователя c##dba не может запросить таблицу emp2 в hrpdb2 без указания ссылки на базу данных.

OraCon_Fig2-4

Исключения из этого правила включают:

  • Общий объект, подключенный к данным, которому доступны все PDB приложения, содержащие ссылку на данные, указывающие на этот объект. Например, контейнер приложения saas_sales_ac может содержать у себя таблицу usa_zipcodes, связанную с данными. В этом случае, общий пользователь c##dba может подключиться к PDB приложения в этом контейнере, а затем сделать запрос к usa_zipcodes, даже если фактическая таблица находится в корне приложения. В этом случае ссылка на базу данных не требуется.

  • Предложение CONTAINERS() в SQL, выданное из корневого CDB или корневого приложения. Используя это предложение, вы можете запрашивать данные во всех PDB, подключенных к корню контейнера.

При создании прокси-PDB, нужно указать имя db-линка в предложении FROM команды CREATE PLUGGABLE DATABASE ... AS PROXY. Если прокси-PDB и ссылочный PDB, находятся в разных CDB, то db-линк должен быть определен в корневом CDB, который будет содержать прокси-PDB. Db-линк должен подключаться либо к удаленному ссылочному PDB, либо к корню удаленного CDB.