Disclaimer

Данный блог является моей личной точкой зрения и не обязательно отражает точку зрения Oracle.

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle

Поиск

Подписка

Использование Oracle Streams для репликации (часть 4)

04.04.2009 от aryndin99

Продолжение. Начало смотрите в предыдущих поста: часть 1, часть 2, часть 3.

В предыдущих трех частях мы:

  • кратко рассмотрели основные термины и концепции, связанные с использованием Oracle Streams
  • выполнили настройки, необходимые для начала работы (создание необходимых пользователей, database links и т.д.)
  • посмотрели, как настраивать репликацию средствами Database Control

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

Начиная с 11-ой версии СУБД Oracle поддерживает специальные макрокоманды для настройки репликации. Она значительно упростили жизнь администраторам. Теперь нет необходимости вручную создавать очереди, процессы сбора, передачи и применения.

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

Конифигурирование репликации с использованием пакета DBMS_STREAMS_ADM

Для упрощения конфигурации Oracle ввел в базе данных ряд простых процедур, осуществляющих детальную конфигурацию. Ниже в таблице список этих процедур:

 

MAINTAIN_GLOBAL Эта процедура конфигурирует Oracle Streams для репликации всех изменений на уровне базы данных. Запускается на базе, где будет выполняться сбор (capture).

Процесс-сборщик изменений никогда не будет собирать изменения в системных схемах: SYS, SYSTEM, or CTXSYS. Процедура MAINTAIN_GLOBAL не конфигурирует их репликацию.

MAINTAIN_SCHEMAS Эта процедура конфигурирует Oracle Streams для репликации всех изменений на уровне схемы пользователя. Запускается на базе, где будет выполняться сбор (capture).

У этой процедуры 2 вариант - параметр schema_names VARCHAR2 или DBMS_UTILITY.UNCL_ARRAY. Позволяет по-разному задавать список схем пользователей.

MAINTAIN_SIMPLE_TTS Это процедура клонирует табличное пространство из исходное базы в целевую. Затем включается Oracle для синхронизации табличных пространств.
MAINTAIN_TTS (замещает устаревшую MAINTAIN_TABLESPACES) От MAINTAIN_SIMPLE_TTS отличается тем, что может клонировать набор табличных пространств. Набор табличных пространств должен быть "автономным" (self-contained), т.е. не содержать объектов распределенных за пределы этого набора (например, секционированная таблица только частично находящаяся в этих табличных пространствах делает набор неавтономным).
MAINTAIN_TABLES Конфигурирует Oracle Streams для репликации изменений в наборе таблиц.

У этой процедуры 2 варианта - параметр table_names VARCHAR2 или DBMS_UTILITY.UNCL_ARRAY. Позволяет по-разному задавать список таблиц.

Для всех процедур характерны следующие особенности:

  • Процедуры автоматически исключает из репликации все объекты, которые не поддерживаются в Oracle Streams, добавляя отрицательные правила (negative rules) для каждого процесса, осуществляющего сборку и применение изменений. Для просмотра списка объектов, которые не могут быть реплицированы используйте представление DBA_STREAMS_UNSUPPORTED.
  • Если включен режим bi_directional, то во время работы процедуры в удаленной базе данных нельзя выполнять DDL и DML операции. Это ограничение не относится к базе-источнику.

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

Двусторонняя репликация без использования дампа для начальной синхронизации

0. Подключимся под пользователем STRMADMIN и создадим нового пользователя с нашей стандартной тестовой таблицей:

CREATE USER repl_bidirect_user IDENTIFIED BY oracle DEFAULT TABLESPACE repl_ts QUOTA UNLIMITED ON repl_ts;
CREATE TABLE repl_bidirect_user.employees TABLESPACE repl_ts AS SELECT * FROM hr.employees WHERE employee_id<111;
CREATE TABLE repl_bidirect_user.departments TABLESPACE repl_ts AS SELECT * FROM hr.departments;
ALTER TABLE repl_bidirect_user.employees ADD CONSTRAINT employee_id_pk PRIMARY KEY (employee_id);
ALTER TABLE repl_bidirect_user.departments ADD CONSTRAINT department_id_pk PRIMARY KEY (department_id);

На целевой базе нужно создать пользователя:

CREATE USER repl_bidirect_user IDENTIFIED BY oracle DEFAULT TABLESPACE repl_ts QUOTA UNLIMITED ON repl_ts;

1. Запустим процедуру DBMS_STREAMS_ADM.MAINTAIN_TABLES для настройки репликации

DECLARE
  tables DBMS_UTILITY.UNCL_ARRAY;
  BEGIN
    tables(1) := 'repl_bidirect_user.departments';
    tables(2) := 'repl_bidirect_user.employees';
    DBMS_STREAMS_ADM.MAINTAIN_TABLES(
      table_names                  => tables,
      source_directory_object      => NULL,
      destination_directory_object => NULL,
      source_database              => 'src.local',
      destination_database         => 'dest.local',      capture_name => 'bidirect_c',
      propagation_name => 'bidirect_p',
      apply_name => 'bidirect_a',
      perform_actions              => TRUE,
      bi_directional               => TRUE,
      include_ddl                  => TRUE,
      instantiation      => DBMS_STREAMS_ADM.INSTANTIATION_TABLE_NETWORK);
END;
/

2. Все. После завершения процедуры процессы настроены и репликация работает. Можно попытаться изменять данные в обоих базах и видеть результаты.

 

WARNING: обязательно задавайте имена capture_name, propagation_name и apply_name. С их отсутствием связан баг №7559768, вылившийся у меня вот в такой вот ужас

ERROR at line 1:

ORA-23616: Failure in executing block 21 for script 669763A80B9F30CCE040007F01005FB9 with

ORA-01422: exact fetch returns more than requested number of rows

ORA-06512: at "SYS.DBMS_RECO_SCRIPT_INVOK", line 130

ORA-06512: at "SYS.DBMS_STREAMS_RPC", line 468

ORA-06512: at "SYS.DBMS_RECOVERABLE_SCRIPT", line 576

ORA-06512: at "SYS.DBMS_RECOVERABLE_SCRIPT", line 599

ORA-06512: at "SYS.DBMS_STREAMS_MT", line 7755

ORA-06512: at "SYS.DBMS_STREAMS_ADM", line 2496

ORA-06512: at line 6

По поводу того, как выполнять troubleshooting я расскажу в следующих частях.

Репликация набора табличных пространств. 

0. Подключимся под пользователем STRMADMIN и создадим 2 табличных пространства. В первое мы положим табличку employees, во второе табличку departments. Между ними мы создадим связь в виде внешнего ключа.

CREATE TABLESPACE employees_tbs DATAFILE '/u01/app/oracle/oradata/src/employees_tbs.dbf'

  SIZE 25M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;

CREATE TABLESPACE departments_tbs DATAFILE '/u01/app/oracle/oradata/src/departments_tbs.dbf'

  SIZE 25M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;

CREATE USER repl_2ts_user IDENTIFIED BY oracle DEFAULT TABLESPACE employees_tbs

   QUOTA UNLIMITED ON employees_tbs

   QUOTA UNLIMITED ON departments_tbs;

CREATE TABLE repl_2ts_user.employees TABLESPACE employees_tbs AS SELECT * FROM hr.employees

WHERE department_id in (10,20,30,40);

CREATE TABLE repl_2ts_user.departments TABLESPACE departments_tbs AS SELECT * FROM hr.departments

WHERE department_id in (10,20,30,40); 
ALTER TABLE repl_2ts_user.employees ADD CONSTRAINT employee_id_pk PRIMARY KEY (employee_id);

ALTER TABLE repl_2ts_user.departments ADD CONSTRAINT department_id_pk PRIMARY KEY (department_id);

ALTER TABLE repl_2ts_user.employees ADD CONSTRAINT department_fk FOREIGN KEY (department_id) REFERENCES repl_2ts_user.departments(department_id);

На целевой базе нужно создать пользователя:

CREATE USER repl_2ts_user IDENTIFIED BY oracle DEFAULT TABLESPACE users;

1. Запустим процедуру DBMS_STREAMS_ADM.MAINTAIN_TTS для настройки репликации

DECLARE
  tablespaces DBMS_STREAMS_TABLESPACE_ADM.TABLESPACE_SET;
  BEGIN
    tablespaces(1) := 'employees_tbs';
    tablespaces(2) := 'departments_tbs';
    DBMS_STREAMS_ADM.MAINTAIN_TTS (
      tablespace_names             => tablespaces,
      source_directory_object      => 'SRC_DIR',
      destination_directory_object => 'DEST_DIR',
      source_database              => 'src.local',
      destination_database         => 'dest.local',      perform_actions => TRUE,             capture_name => 'two_tbs_c',
      propagation_name => 'BIDIRECT_P',
      apply_name => 'two_tbs_a',
      bi_directional               => FALSE,
      include_ddl                  => TRUE );
END;
/

WARNING 1: для каждой пары баз данных может существовать только один передающий процесс (propagation), т.е. если ранее был создан процесс распространения с именем BIDIRECT_P, то его нужно использовать и в будущем. Если у нас появится третья база (скажем DEST2), то для нее может появиться свой процесс распространения.

WARNING 2: если процедура отработала без ошибок, все процессы работают нормально, но применение так и не происходит, то следует поглядеть на alert журналы на обоих базах. Я столкнулся с вот такой ошибкой на стороне целевой базы.

knllgobjinfo: MISSING Streams multi-version data dictionary!!!

knlldmm: gdbnm=SRC.LOCAL

knlldmm: objn=72415

knlldmm: objv=1

knlldmm: scn=1439397

See trace file for more information

Сообщение говорит о том, что на целевой базе отсутствует достаточная информация для репликации объектов и требуется на базе-источнике запустить процедуры *_INSTANTIATION:

  • DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION
  • DBMS_CAPTURE_ADM.PREPARE_SCHEMA_INSTANTIATION
  • DBMS_CAPTURE_ADM.PREPARE_GLOBAL_INSTANTIATION

2. Все. После завершения процедуры процессы настроены и репликация работает. Можно попытаться изменять данные в обоих базах и видеть результаты. Например вот так:

INSERT INTO repl_2ts_user.departments SELECT * FROM hr.departments

WHERE department_id in (120); 
INSERT INTO repl_2ts_user.employees SELECT * FROM hr.employees

WHERE department_id in (120);

COMMIT;

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

Итак, мы рассмотрели возможность репликации данных с использоватением DBMS_STREAMS_ADM.MAINTAIN_*. Эти процедуры позволяют очень легко настроить репликацию. Задачей этих процедур является генерация скрипта, который и выполнит начальную синхронизацию и настроит репликацию. Этот скрипт сохраняется в представлении dba_recoverable_script_blocks. С помощью этого представления можно производить troubleshooting возникших проблем, но это уже другая история для совсем другой части :) В скором времени, как появится немного времени я опубликую следующие 2-3 части.

До скорого! Оставайтесь на связи :)

Рубрики: Data Warehouse, Data Warehousing, Database, Streams | Комментарии (6) »

Комментарии (6)

  1. Alexey пишет:

    А можно ли в пределах одной базы настроить репликацию из одной схемы в другую?

  2. aryndin99 пишет:

    Да, это можно делать. Надо будет использовать трансформацию для того, чтобы задать новое имя таблицы или схемы. Скорее всего придется использовать не макропроцедуры (MAINTAIN_*), а более детальные (пакеты DBMS_CAPTURE_ADM, DBMS_APPLY_ADM и т.д.). Я напишу об этом, но чуть позже.

  3. Oracle Spatial, Mapviewer, Semantics и ГИС системы » Архив блога » Использование Oracle Streams для репликации (часть 5) пишет:

    [...] Oracle Streams для репликации (часть 5)Использование Oracle Streams для репликации (часть 4)Использование Oracle Streams для репликации (часть [...]

  4. Oracle Spatial, Mapviewer, Semantics и ГИС системы » Архив блога » Oracle Streams для репликации: troubleshooting (часть 6) пишет:

    [...] Oracle Streams для репликации (часть 5)Использование Oracle Streams для репликации (часть 4)Использование Oracle Streams для репликации (часть [...]

  5. Oracle Spatial, Mapviewer, Semantics и ГИС системы » Архив блога » Oracle Streams для репликации: расширенная настройка (часть 8) пишет:

    [...] (часть 6)Использование Oracle Streams для репликации (часть 5)Использование Oracle Streams для репликации (часть 4)Использование Oracle Streams для репликации (часть [...]

  6. aryndin99 пишет:

    О репликации в рамках одной базы данных я написал в 8-ой главе http://oraclegis.com/blog/?p=488

Оставить комментарий

Заметьте: Включена проверка комментариев. Нет смысла повторно отправлять комментарий.