Сравнение и синхронизация связанных баз данных Oracle: таблицы и другие объекты

Как сравнить и синхронизировать таблицы в двух разных базах данных OracleДля сред репликации типичным является разделение таких объектов базы данных Oracle, как таблицы и индексы. Эти объекты известны как разделяемые объекты базы данных, поскольку несколько баз данных совестно используют их между собой. Разделяемые объекты базы данных обычно применяются материализованными представлениями и компонентами Oracle Streams, которые поддерживают копии одних и тех же таблиц и прочих объектов в нескольких базах данных. Среды репликации подобного рода стараются хранить общие объекты базы в разных местах в синхронизированном виде. Однако нередко происходит рассинхронизация таких объектов, и тогда таблица в отличающимся количеством строк и/или разными данными сравнивается c такой же таблицей в другой базе. Подобные расхождения данных, вызванные сетевыми проблемами, ошибками пользователей, изменениями в конфигурации, проблемами обновления материализованных представлений и т. д., могут помешать фиксации изменений в базе данных или успешной передаче их другим базам, которые связаны в общую среду репликации.

В Oracle Database 12c и 11g предусмотрен пакет DBMS_COMPARISON, который позволяет сравнивать объекты в различных базах. Если процесс сравнения показывает существенные расхождения между двумя базами данных, с помощью этого же пакета можно свести данные в обеих базах, так что они становятся идентичными. Сравнивать и сводить можно следующие типы объектов:

  • таблицы;
  • представления на одиночных таблицах;
  • материализованные представления;
  • синонимы перечисленных трех типов объектов.

Чуть позже будет приведен пример сравнения двух одноименных таблиц в разных базах данных, состоящих из одного и того же набора столбцов. Можно также сравнивать и разноименные таблицы, а также таблицы с разными столбцами, если только столбцы в двух таблицах будут одного и того же типа. Вдобавок можно сравнивать (и сводить) подмножества столбцов и строк вместо целых таблиц и материализованных представлений.

 

Сравнение данных на примере таблиц

В следующем примере мы сравним простой разделенный объект базы данных (таблицу employees), который принадлежит схеме пользователя HR. Чтобы наглядно продемонстрировать сведение данных, сначала мы изменим данные в трех строках разделенного объекта (таблице departments) удаленной базы данных. Затем с помощью пакета DBMS_COMPARE мы сравним две таблицы в двух базах, после чего воспользуемся им же для объединения отличий, чтобы две таблицы снова стали синхронизированными.

Единственное требование, которое должно быть удовлетворено при использовании пакета DBMS_COMPARE, состоит в том, чтобы сравниваемые таблицы имели, по крайней мере, один столбец, используемый в качестве индекса, по которому можно идентифицировать запись. Такой индексный столбец должен уникально идентифицировать каждую строку, участвующую в сравнении, в том смысле, что индекс должен быть либо первичным, либо уникальным ключом на столбце, не допускающем NULL-значения. В противном случае пакет не сможет сравнить два объекта. Таблица employee имеет столбец первичного ключа в обеих базах данных, так что здесь все в порядке.

1. Создадим связь первичной базы данных (or11) с вторичной базой (tenner). В примере в качестве владельца связи базы данных выступает пользователь system; это гарантирует наличие достаточных привилегий для выполнения процедур пакета DBMS_COMPARISON, а также для доступа и модификаций таблиц в обеих базах. Удаленная база данных называется tenner, поэтому так же мы назовем и ее связь из первичной базы данных or11

SQL> create database link tenner
connect to system identified by sammyy1
using 'tenner';
Database link created.
SQL>

Следующий шаг — получение расхождений между данными идентичных таблиц в двух базах данных.

2. Во вторичной базе проведем некоторые изменения в таблице hr.employees, чтобы данные отличались от данных той же таблицы из первичной базы:

SQL> delete from hr.employees where ename='MILLER';
1 row deleted.
SQL> update hr.employees set sal=10000 where ename='FORD';
1 row updated.
SQL> insert into hr.employees values
(9999,'ALAPATI','DBA',7792,'20-JUN-00',50000,10000,30);
1 row created.
SQL> commit;
Commit complete.
SQL> 

Обеспечив различие таблиц hr.employees в двух базах, можно запустить процедуру CREATE_COMPARISON для обнаружения этих различий.

3. Выполним сравнение таблицы hr.employees с одноименной таблицей второй базы, запустив процедуру CREATE_COMPARISON, как показано ниже:

SQL> begin
2 dbms_comparison.create_comparison(
3 comparison_name => 'compare1',
4 schema_name => 'hr',
5 object_name => 'employees',
6 dblink_name => 'tenner');
7* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> 

4. Выполним функцию COMPARE, чтобы посмотреть, нашла ли процедура CREATE_COMPARISON различия в двух таблицах:

SQL> declare
2 consistent boolean;
3 scan_info dbms_comparison.comparison_type;
4 begin
5 consistent := dbms_comparison.compare(
6 comparison_name => 'comp1',
7 scan_info => scan_info,
8 perform_row_dif => TRUE);
9 DBMS_OUTPUT.PUT_LINE('Scan ID: '||scan_info.scan_id);
10 IF consistent=TRUE THEN
11 DBMS_OUTPUT.PUT_LINE('No differences were found.');
12 ELSE 
13 DBMS_OUTPUT.PUT_LINE('Differences were found.');
14 end if;
15* end;
SQL> /
Scan ID: 4
Differences were found.
PL/SQL procedure successfully completed.
SQL>

Функция compare использует Scan ID, равный 4, и печатает предложение “Differences were found” (Различия обнаружены).

Как сравнить и синхронизировать данные в разных в СУБД Oracle

5. Поскольку различия есть, можно запустить следующий запрос, использующий представления DBA_COMPARISON и DBA_COMPARISON_SCAN_SUMMARY, чтобы узнать, сколько различий было обнаружено при сравнении таблиц:

SQL> select c.owner,
2 c.comparision_name,
3 c.schema_name,
4 c.object_name,
5 s.current_diff_count
6 from dba_comparison , dba_comparison_scan_summary s
7 where c.comparison_name = s.comparison_name and
8 c.owner = s.owner and
9 s.scan_id = 1;
OWNER   COMP_NAME SCHEMA_NAME   OBJECT_NAME  CURRENT_DIF_COUNT
------- --------- ------------- ------------ -----------------
SYSTEM  COMP1     HR            EMPLOYEES                    3
SQL>

Столбец current_diff_count из DBA_COMPARISON_SCAN_SUMMARY показывает, что есть три строки, отличающиеся между таблицей hr.employees в базе данных or11 и таблицей hr.employees в базе данных tenner. Различие может быть обусловлено тем, что некоторая строка присутствует в одной базе, но отсутствует в другой, или же одна и та же строка в двух базах содержит разные данные.

 

Синхронизация  таблиц и других данных

Поскольку обнаружены расхождения между локальной и удаленной базами данных, необходимо синхронизировать таблицы hr.employees в двух базах, чтобы они содержали идентичные данные. Это делается с помощью процедуры CONVERGE из пакета DBMS_COMPARISON, как описано ниже.

1. Подключитесь к удаленной базе данных из локальной как пользователь system, который является владельцем ранее созданной связи базы данных:

$ sqlplus sytem/sammyy1@or11
SQL>

2. Выполните процедуру CONVERGE из пакета DBMS_COMPARISON для синхронизации данных между двумя базами:

SQL> declare
2 scan_info DBMS_COMPARISON.COMPARISON_TYPE;
3 begin
4 DBMS_COMPARISON.CONVERGE(
5 comparison_name => 'comp1',
6 scan_id => 4,
7 scan_info => scan_info,
8 converge_options => DBMS_COMPARISON.CMP_CONVERGE_LOCAL_WINS); 
9 DBMS_OUTPUT.PUT_LINE('Local Rows Merged:
'||scan_info.loc_rows_merged);
10 DBMS_OUTPUT.PUT_LINE('Remote Rows Merged:
'||scan_info.rmt_rows_merged);
11 DBMS_OUTPUT.PUT_LINE('Local Rows Deleted:
'||scan_info.loc_rows_deleted);
12 DBMS_OUTPUT.PUT_LINE('Remote Rows Deleted:
'||scan_info.rmt_rows_deleted);
13* end;
SQL> /
Local Rows Merged: 0
Remote Rows Merged: 2
Local Rows Deleted: 0
Remote Rows Deleted: 1
PL/SQL procedure successfully completed.
SQL>

В этом примере мы решили заменить данные таблицы hr.employees в удаленной базе данными из таблицы hr.employees локальной базы. Таким образом, в качестве опции сведения используется cmp_converge_local_wins, а это означает, что данные из локальной базы получат преимущество перед данными из удаленной базы. Однако можно было бы выбрать и обратный путь, указав cmp_converge_remote_wins — тогда данные таблицы из удаленной базы заменили бы данные таблицы локальной базы.

Процедура converge может модифицировать или удалить данные из одной базы данных, чтобы синхронизировать данные в обеих базах Oracle. Вывод, печатаемый после завершения процедуры converge, демонстрирует, что две строки в удаленной базы были слиты (merged), потому что они отличались от тех же строк в локальной базе. Слияние в данном случае означает, что строки локальной таблицы заменяют строки в удаленной таблице. Одна строка отражена в Remote Rows Deleted. Это строка, которая была найдена в удаленной базе данных, но отсутствовала в локальной. Поскольку мы решили, что данные удаленной базы должны совпадать с данными базы локальной, процедура converge удаляет строку из удаленной базы данных. Предполагая, что никаких других изменений во время синхронизации не произошло, теперь две таблицы в локальной и удаленной базах данных полностью синхронизированы.

Обратите внимание, что можно также сравнивать и сливать различные типы объектов двух баз данных. Например, можно сравнить и слить таблицу в одной базе с материализованным представлением в другой.

Вас заинтересует / Intresting for you:

Поддерживаемые Oracle типы дан...
Поддерживаемые Oracle типы дан... 9536 просмотров Валерий Павлюков Wed, 24 Oct 2018, 08:00:37
Видеокурс по администрированию...
Видеокурс по администрированию... 10719 просмотров Илья Дергунов Mon, 14 May 2018, 05:08:47
Обновление до Oracle Database ...
Обновление до Oracle Database ... 7857 просмотров Илья Дергунов Tue, 21 Nov 2017, 13:18:05
Создание базы данных Oracle
Создание базы данных Oracle 34421 просмотров Александров Попков Wed, 14 Nov 2018, 12:44:39
Войдите чтобы комментировать