|
Вся книга: Практика работы с Oracle: генерация, администрирование, репликация. И.К.Гаршин.
ISBN 5-901314-02-6 (рус.). УДК 004.42Oracle. ББК 32.973.26-018.2. Г21. В 1999-2000 г. программисты «Нефтегазсистемы» разработали и внедрили в большинство ОАО МН «Транснефти Информационную систему паспортизации магистральных нефтепроводов «СКУТОР». Сначала он был создан на базе MS Access, затем переведен на Oracle 8 с поддкржкой асинхронной репликации с помощью программы Oracle Multimaster. В книге подробно описан авторский опыт перевода и внедрения этой базы данных. |
Автор признателен руководителям и сотрудникам ЗАО «Нефтегазсистемы», начальникам и персоналу вычислительных центров региональных управлений ОАО «Транснефть», c чьей помощью был разработан и внедрен данный Oracle-проект.
Часть 2.
Репликация данных между серверами ORACLE
В этой части…
Глава 1. Механизмы репликации
Глава 2. Виды репликационных архитектур
Глава 3. Создание репликации БД по архитектуре с обновляемыми копиями
Глава 4. Особенности создания систем репликаций БД Oracle в различных сетевых ОС
Глава 5. Описание утилиты Oracle Replication Manager
Ч |
асть 2 предназначена для администраторов Oracle в организациях, использующих многоуровневую систему репликации. Здесь изложены подробная модель создания репликационного механизма, способы решения возникающих при этом проблем и основы администрирования такой системы. Вкратце описаны также особенности построения репликационного механизма в различных операционных системах (Novell Netware 5, MS Windows NT 4, Linux RedHat). Приводимые примеры скриптов перед использованием нуждаются в небольшой корректировке (имена пользователей, сервисов, пароли, пути и т.д.). Синтаксис большинства приводимых операций можно найти в разделах Oracle8 Database \ Oracle8 SQL Reference, Release 8.0 [8], и Oracle8 Database \ Oracle8 Replication, Release 8.0 [8].
Глава 1
В этой главе…
· Некорректируемые (read only) снимки
· Корректируемые (updatable) снимки
· Мультимастер
Снимки «только-для-чтения» (READ ONLY) являются копиями таблиц из другой схемы или БД, которые перечитываются через установленный интервал времени, т.е. периодически обновляются. Поэтому эти объекты будем называть некорректируемыми снимками, поскольку термин «необновляемые снимки», иногда используемый в переводной литературе, не точен – все снимки обновляются ( выполняется операция ALTER SNAPSHOT REFRESH …).
Для создания данного механизма репликации прежде всего в мастер-БД (т.е. в основной БД) на реплицируемые таблицы необходимо построить журналы снимков или «MLOG-и» (создание «эмлогов» по всем таблицам СИСТЕМЫ – в CLog.sql):
create snapshot log on TESTSNAP;
Затем в БД-копии выполняется создание снимка таблицы командой CREATE SNAPSHOT следующего вида:
create snapshot TESTSNAP01
refresh fast
next SYSDATE+1/288
start with SYSDATE
as select * from PLIMADRID.TESTSNAP@ORACLE;
Кроме того, снимки можно объединять в обновляемые группы (refresh groups) с тем, чтобы управлять периодичностью их обновления и разгрузить сетевой трафик. Для этого создается пользователь REPADMIN с правами на роли CONNECT, RESOURCE и DBA, а затем в его сессии используется DBMS-команда следующего вида:
begin
DBMS_REFRESH.MAKE(name => 'PLIPEKN0',
list => '',
next_date => trunc(SYSDATE,'DD')+1,
interval => 'trunc(SYSDATE,''DD'')+1',
implicit_destroy => TRUE,
rollback_seg => 'R10',
push_deferred_rpc => TRUE,
refresh_after_errors => FALSE);
end;
/
Далее выполняется добавление ранее созданного снимка в группу обновления:
begin
DBMS_REFRESH.ADD(name => 'PLIPEKN0',
list => 'BRANCH',
lax => TRUE);
end;
/
Для создания снимков по всем таблицам описываемой СИСТЕМЫ с их объединением в группы обновления можно использовать скрипт CRoSn.sql.
Удаление refresh-группы (вместе со снимками) выполняется DBMS-командой следующего вида (DrefGr.sql):
begin
DBMS_REPCAT.DROP_SNAPSHOT_REPGROUP(
gname => 'ORACLE4',
drop_contents => TRUE);
end;
/
Это наиболее простой способ создания копии БД. Его можно применять в главных офисах и управлениях, где важен доступ к просмотру информации и получение отчетов, а ввод данных не производится.
Для создания на БД-копии updatable snaphot-ов необходимо на основной БД создать журналы снимков, как и в случае с read only snaphot-ами (см. выше Часть 2, Глава 1: Некорректируемые (read only) снимки), для чего запустить скрипт CLogRep.sql (который отличается от CLog.sql отсутствием «логов» для нереплицируемых таблиц):
--drop snapshot log on BRANCH;
create snapshot log on BRANCH;
--start with 13 increment by 1 order nocache;
…
Затем в БД-копии создается snapshot-сайт (в дальнейшем – снап-сайт), заключающийся в создании и предоставлении прав администратору репликации REPADMIN, его регистрации как распространителя изменений, создании в его схеме и схеме SYSTEM связи dblink на основную БД и процессов периодической активизации этой связи (Sheduled Link) и очистки системных журналов. Аналогичный пользователь REPADMIN, но со своими правами, создается и в основной БД (см. скрипт CSnS.sql):
Листинг скрипта на создание snapshot-сайта
-- Connection to: SYSTEM@ORACLE.WORLD
-- 1. Creating user 'REPADMIN' at site ' ORACLE'
create user REPADMIN identified by REPADM;
-- 2a.Granting admin privileges to user 'REPADMIN' at site ' ORACLE'
begin
DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_SCHEMA(username => 'REPADMIN');
end;
/
-- 2b.Granting admin privileges to user 'REPADMIN' at site ' ORACLE'
grant comment any table to REPADMIN;
grant lock any table to REPADMIN;
-- 3. Registering user 'REPADMIN' as propagator at site 'ORACLE'
begin
DBMS_DEFER_SYS.REGISTER_PROPAGATOR(username => 'REPADMIN');
end;
/
-- ===========================================================
-- Connection to: SYSTEM@ULAN.WORLD
-- 1. Creating user 'REPADMIN' at site 'ULAN'
create user REPADMIN identified by REPADM;
-- 2a.Granting privileges to user 'REPADMIN'
-- (здесь отличие от мастер-сайта)
begin
DBMS_REPCAT_ADMIN.GRANT_SNAPADMIN_PROXY(username => 'REPADMIN');
end;
/
-- 2b.Granting privileges to user 'REPADMIN'
grant alter session to REPADMIN;
grant create cluster to REPADMIN;
grant create database link to REPADMIN;
grant create sequence to REPADMIN;
grant create session to REPADMIN;
grant create synonym to REPADMIN;
grant create table to REPADMIN;
grant create view to REPADMIN;
grant create procedure to REPADMIN;
grant create trigger to REPADMIN;
grant unlimited tablespace to REPADMIN;
grant create type to REPADMIN;
grant execute any procedure to REPADMIN;
grant create any trigger to REPADMIN;
grant create any procedure to REPADMIN;
grant select any table to REPADMIN;
-- ===========================================================
-- Connection to: SYSTEM@ORACLE.WORLD
-- 4. Creating link from ORACLE to ULAN
create public database link "ULAN.WORLD" using 'ULAN.WORLD';
-- Connection to: REPADMIN@ORACLE.WORLD
-- 5. Scheduling database link 'ULAN.WORLD'.
begin
DBMS_DEFER_SYS.SCHEDULE_PUSH(
destination => 'ULAN.WORLD',
interval => '/*1:Hr*/ SYSDATE + 1/24',
next_date => SYSDATE,
stop_on_error => FALSE,
delay_seconds => 0,
parallelism => 1);
end;
/
-- 6. Creating link from ORACLE to ULAN
create database link "ULAN.WORLD"
connect to "REPADMIN" identified by "REPADM";
-- 7. Scheduling purge at site 'ORACLE'
begin
DBMS_DEFER_SYS.SCHEDULE_PURGE(
next_date => SYSDATE,
interval => '/*1:Day*/ SYSDATE + 1',
delay_seconds => 0,
rollback_segment => '');
end;
/
Далее в БД-копии необходимо создать updatable-снимки (create snapshot … for update), последовательности генерации ключей для таблиц SNAP$_, а также с помощью DBMS-процедур создать refresh-группы, snapshot-группы (соответствующее каждой refresh-группе ), репликационные объекты и включить их в refresh-группы (CUpSn.sql):
Листинг скрипта на создание UPDATABLE-снимков
-- connect REPADMIN/REPADM@PLI_PEKIN
-------------------------------------------------------------------
prompt REFRESH GROUP PLIPEKN.PLIPEKN0
-- Создание refresh-группы
begin
DBMS_REFRESH.MAKE(name => 'PLIPEKN.PLIPEKN0',
list => '',
next_date => trunc(SYSDATE,'HH')+1/12,
interval => 'trunc(SYSDATE,''HH'')+1/12',
implicit_destroy => TRUE,
rollback_seg => 'R10',
push_deferred_rpc => TRUE,
refresh_after_errors => FALSE);
end;
/
-- Создание snapshot-группы
begin
DBMS_REPCAT.CREATE_SNAPSHOT_REPGROUP(
gname => 'PLIPEKN0',
master => 'PEKN',
propagation_mode => 'ASYNCHRONOUS');
end;
/
prompt PLIPEKN.BRANCH
create snapshot PLIPEKN.BRANCH refresh force
start with trunc(SYSDATE,'HH')+1/12
next trunc(SYSDATE,'HH')+1/12 for update as
select NAME, ID, CSCHEM, CORDATE, USERNAME
from PLIPEKN.BRANCH@PEKIN;
begin
DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT(
gname => 'PLIPEKN0',
sname => 'PLIPEKN',
oname => 'BRANCH',
type => 'SNAPSHOT',
ddl_text => '',
min_communication => TRUE);
end;
/
create sequence PLIPEKN.BRANCH_SEQ
start with 1000010 increment by 1 order nocache;
begin
DBMS_REFRESH.ADD(name => 'PLIPEKN.PLIPEKN0',
list => 'PLIPEKN.BRANCH',
lax => TRUE);
end;
/
Затем на таблицы SNAP$_ в БД-копии (созданные при создании снимков командой create snapshot) необходимо создать те же триггеры (вместе с функциями), какие существуют на соответствующих таблицах в основной БД (скрипт CTrgSnp.sql):
Листинг скрипта на создание триггеров на таблицы SNAP$_
prompt BRANCH_ID;
create or replace function BRANCH_ID(nAdm in number)
return number is nOPF number(12);
begin
select BRANCH_SEQ.nextval into nOPF from DUAL;
return nOPF;
exception
when NO_DATA_FOUND then
return NULL;
end BRANCH_ID;
/
prompt BRANCH_COR;
create or replace trigger BRANCH_COR
before insert or update on SNAP$_BRANCH
for each row
begin
if INSERTING and (nvl(:new.ID,0)=0) then
:new.ID:=BRANCH_ID(0);
end if;
:new.CORDATE:=SYSDATE;
:new.USERNAME:=USER;
end;
/
prompt BRANCH_LOG;
create or replace trigger BRANCH_LOG
after insert or update or delete on SNAP$_BRANCH
for each row
declare
N number(3);
K number(12);
begin
if INSERTING then
N:=1;
elsif UPDATING then
N:=2;
else
N:=3;
K:=:old.ID;
end if;
if N<>3 then
K:=:new.ID;
end if;
insert into
EDITIONS (TABNAME,TABKEY,ACTION)
values ('BRANCH',K,N);
end;
/
Для администрирования данного механизма можете воспользоваться скриптами для удаления снимков и последовательностей (DSnSq.sql), триггеров с функциями (DtrFnRep.sql) и др.:
Листинг фрагмента скрипта для удаления снимков
-- Удаление снимков
drop snapshot PRWEQUIP;
drop sequence PRWEQUIP_SEQ;
.
.
Листинг фрагмента скрипта на удаление таблиц и функций
-- Удаление триггеров реплицируемых таблиц с функциями
drop trigger PARWTANK_COR;
drop trigger PARWTANK_LOG;
.
.
Для создания системы Мультимастер необходимо создать главный мастер-сайт (master definition site, в дальнейшем – деф-сайт), создать мастер-группы, добавить в мастер-группы объекты (в простейшем случае - таблицы), определить для каждой таблицы методы разрешения конфликтов и добавить к мастер-группам сайты назначения (master destination site или master database, в дальнейшем – дест-сайт или мастер-БД). После выполнения этих действий автоматически создадутся дест-сайты с мастер-группами и объектами репликации на других БД Oracle.
A. Создание мастер-сайта заключается в следующем:
1. в создании в главной БД пользователя REPADMIN с правом на роль MASTERDEF (можно просто назначить роль DBA),
2. назначением основного пользователя в главной БД (являющегося владельцем ее таблиц) на права create any snapshot, alter any snapshot и роли CONNECT, RESOURCE
3. создании в других БД этой схемы,
4. создании в схеме REPADMIN dblink’ов на эти схемы;
5. регистрацией пользователя REPADMIN как propagator’а («проталкивателя» транзакций),
6. создании в его схеме процессов SHEDULE_PURGE (очистка)
7. и SHEDULE_PUSH (проталкивание) или, иначе – SHEDULED LINK (связь по расписанию).
Для создания мастер-сайта воспользуйтесь в ORM File/Setup Wizard… или запустите нижеприведенный скрипт CMs.sql, присоединившись к основной БД как SYSTEM. Этот скрипт создан с помощью ORM. В нем создается пользователь REPADMIN (которому затем даются права на роль MASTERDEF и другие привилегии), но не создаются связи (dblink) с другими базами, в результате чего процедура DBMS_DEFER_SYS.SCHEDULE_PUSH не создает задачи PUSH. :Поэтому можно либо включить DDL-команду создания dblink в этот скрипт перед созданием SHEDULED LINK (между 4 и 5 шагом), либо заранее создать REPADMIN с правами CONNECT, RESOURSE, DBA (так проще и надежнее, т.к. вся совокупность прав REPADMIN почти полностью покрывается ролью DBA) и dblink в его схеме, а затем запускать Wizard.
Листинг скрипта на создание мастер-сайта
-- 1. Creating user 'REPADMIN' at site 'PEKIN'
create user REPADMIN identified by REPADM;
/
-- 2. Granting admin privileges (роль MASTERDEF)
-- to user 'REPADMIN' at site 'PEKIN'
begin
DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_SCHEMA(username => 'REPADMIN');
end;
/
grant comment any table to REPADMIN;
grant lock any table to REPADMIN;
-- 3. Registering user 'REPADMIN' as propagator at site 'PEKIN'
begin
DBMS_DEFER_SYS.REGISTER_PROPAGATOR(username => 'REPADMIN');
end;
/
-- 4. Granting privileges to user 'REPADMIN'
grant execute any procedure to REPADMIN;
/
-- 5. Connection to: REPADMIN@PEKIN.WORLD
connect REPADMIN/REPADM@PEKIN.WORLD
/
-- Scheduling purge at site 'PEKIN'
begin
DBMS_DEFER_SYS.SCHEDULE_PURGE(
next_date => SYSDATE,
interval => '/*1:Day*/ SYSDATE + 1',
delay_seconds => 0,
rollback_segment => 'R10');
end;
/
-- 6. Creating scheduled link 'PLI_LOND'.
begin
DBMS_DEFER_SYS.SCHEDULE_PUSH(
destination => 'PLI_LOND',
next_date => SYSDATE,
interval => '/*10:Mins*/ SYSDATE + 10/(60*24)',
stop_on_error => FALSE,
delay_seconds => 0,
parallelism => 0);
end;
/
-- Connection to: SYSTEM@PEKIN.WORLD
connect SYSTEM/MANPEK@PEKIN.WORLD
/
-- 6. Granting privileges to user 'PLIPEKN'
grant alter session to PLIPEKN; -- (роль CONNECT)
grant create cluster to PLIPEKN; -- (роли CONNECT, RESOURCE)
grant create database link to PLIPEKN; -- (роль CONNECT)
grant create sequence to PLIPEKN; -- (роли CONNECT, RESOURCE)
grant create session to PLIPEKN; -- (роль CONNECT)
grant create synonym to PLIPEKN; -- (роль CONNECT)
grant create table to PLIPEKN; -- (роли CONNECT, RESOURCE)
grant create view to PLIPEKN; -- (роль CONNECT)
grant create procedure to PLIPEKN; -- (роль RESOURCE)
grant create trigger to PLIPEKN; -- (роль RESOURCE)
grant unlimited tablespace to PLIPEKN;
grant create type to PLIPEKN; -- (роль RESOURCE)
grant create any snapshot to PLIPEKN;
grant alter any snapshot to PLIPEKN;
/
-- 7. Те же права - пользователю REPADMIN
grant CONNECT, RESOURCE to REPADMIN;
grant unlimited tablespace to REPADMIN;
grant create any snapshot to REPADMIN;
grant alter any snapshot to REPADMIN;
/
B. Создание мастер-групп и включение в них объектов рекомендуется выполнять вместе с помощью скрипта CMGr__.sql:
Листинг скрипта на создание мастер-групп
-- Создание мастер-группы PLIPEKN0 --------------------------
begin
DBMS_REPCAT.CREATE_MASTER_REPGROUP(
gname => 'PLIPEKN0',
qualifier => '',
group_comment=> '');
end;
/
-- Включение в мастер-группу PLIPEKN0 таблицы BRANCH
begin
DBMS_REPCAT.CREATE_MASTER_REPOBJECT(
gname => 'PLIPEKN0',
type => 'TABLE',
oname => 'BRANCH',
sname => 'PLIPEKN',
use_existing_object => TRUE,
copy_rows => TRUE);
end;
/
-- Генерация репликационной поддержки для таблицы BRANCH
begin
DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT(
sname => 'PLIPEKN',
type => 'TABLE',
oname => 'BRANCH',
min_communication => TRUE);
end;
/
.
.
C. Определить для каждой таблицы методы разрешения конфликтов рекомендуется с помощью скрипта UpdRes.sql:
Листинг скрипта на добавление метода разрешения конфликтов к репликационной таблице
-- 1) creating column group 'DL'
begin
DBMS_REPCAT.DEFINE_COLUMN_GROUP(
sname => '"PLIPEKN"',
oname => '"BRANCH"',
column_group => '"DL"',
comment => '');
end;
/
-- 2) adding column(s) to column group 'DL'.
begin
DBMS_REPCAT.ADD_GROUPED_COLUMN(
sname => '"PLIPEKN"',
oname => '"BRANCH"',
column_group => '"DL"',
list_of_column_names =>
'NAME,ID,CSCHEM,CORDATE,USERNAME');
end;
/
-- 3) adding conflict resolution method 'Latest Timestamp'.
begin
DBMS_REPCAT.ADD_UPDATE_RESOLUTION(
sname => '"PLIPEKN"',
oname =>'"BRANCH"',
column_group => '"DL"',
sequence_no => 0 + 1,
method => 'Latest Timestamp',
parameter_column_name => '"CORDATE"');
end;
/
.
.
D. Добавлять к мастер-группам сайты назначения рекомендуется вручную с помощью ORM. (сначала надо добавить один сайт к каждой группе по очереди, затем приступать к добавлению другого сайта и т.д.). Пример API для добавления сайта к группе см. в скрипте AdDb.sql:
Листинг скрипта на добавление мастер-сайта к мастер-группе
-- adding master database 'PLI_ANTA' to master group 'PLIPEKN0'.
begin
DBMS_REPCAT.ADD_MASTER_DATABASE(
gname => '"PLIPEKN0"',
master => 'PLI_ANTA.WORLD',
use_existing_objects => TRUE,
copy_rows => TRUE,
propagation_mode => 'ASYNCHRONOUS');
end;
/
E. После выполнения вышеуказанных действий нужно перевести каждую группу в состояние NORMAL (активизировать мастер-группу с помощью операции Resume) – см. RAct.sql:
-- resuming replication on group 'PLIPEKN0'.
begin
DBMS_REPCAT.RESUME_MASTER_ACTIVITY(gname => 'PLIPEKN0');
end;
/