- PVSM.RU - https://www.pvsm.ru -

Настройка двухсторонней синхронизации БД Oracle (Oracle Streams)

Настройка двухсторонней синхронизации БД Oracle (Oracle Streams)

Что делать, если нет дисковой полки под RAC, а синхронизацию БД Oracle в реальном времени обеспечить нужно? Настроить потоки данных Oracle (Oracle Streams)!

Про потоки данных написано много. Например, здесь [1], здесь [2] и здесь [3], в том числе и в официальной документации [4]. В данной статье описан вариант настроек без использования redo-логов, работающий для редакций Oracle Standard Edition One и Oracle Standard Edition 11gR2 (лицензия на Enterprise позволяет провести настройку проще, прямо в Enterprise Manager Console, см. ограничения [5]).

Итак, стремимся к автоматическому перехвату DML операций во всех таблицах схемы HR и синхронизации данных в обе стороны:

Настройка двухсторонней синхронизации БД Oracle (Oracle Streams)

  1. Настройка системных параметров БД:
    sqlplus / as sysdba
    ALTER SYSTEM SET global_names        = true scope= both;
    ALTER SYSTEM SET shared_pool_size    = 256M scope= both;
    ALTER SYSTEM SET streams_pool_size   = 256M scope= both;
    ALTER SYSTEM SET java_pool_size      = 100M scope= both;
    ALTER SYSTEM SET parallel_max_servers= 10   scope= both;
    
  2. Настройка Oracle Net Services
    tnsnames.ora:

    ORCLA =
      (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = host_a)(PORT = 1521))
        (CONNECT_DATA =
          (SERVER = DEDICATED)
          (SERVICE_NAME = orcla.local)
        )
      )
    ORCLB =
      (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = host_b)(PORT = 1521))
        (CONNECT_DATA =
          (SERVER = DEDICATED)
          (SERVICE_NAME = orclb.local)
        )
      )
    

  3. Создание табличного пространства администратора Streams:
    mkdir C:Oracleapporadatastrems
    sqlplus / as sysdba
    -- Создать табличное пространство
    CREATE TABLESPACE streams_tbs DATAFILE 'C:Oracleapporadatastremsstreams_tbs.dbf'
    	SIZE 25M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
    
  4. Cоздание администратора streams с привилегиями Oracle Streams:
    sqlplus / as sysdba
    -- создать администратора Streams
    CREATE USER strmadmin IDENTIFIED BY "<пароль>"
    	DEFAULT TABLESPACE streams_tbs
    	QUOTA UNLIMITED ON streams_tbs;
    -- права на подключение
    GRANT CONNECT TO strmadmin;
    GRANT DBA TO strmadmin;
    BEGIN
    -- привилегии администратора Streams
    	DBMS_STREAMS_AUTH.GRANT_ADMIN_PRIVILEGE(
    	grantee          => 'strmadmin',
    	grant_privileges => TRUE);
    END;
    /
    execute MGMT_USER.MAKE_EM_USER('STRMADMIN');
    
  5. Создание связей баз данных (database links):
    sqlplus strmadmin@orcla
    CREATE DATABASE LINK orclb CONNECT TO strmadmin
    	IDENTIFIED BY "<пароль>"
    	USING 'orclb';
    sqlplus strmadmin@orclb
    CREATE DATABASE LINK orcla CONNECT TO strmadmin
    	IDENTIFIED BY "<пароль>"
    	USING 'orcla';
    -- просмотреть связи базы данных
    SELECT * FROM ALL_DB_LINKS;
    -- протестировать связь базы данных
    SELECT * FROM DUAL@ORCLB;
    SELECT * FROM TAB@ORCLB;
    
  6. Создание очередей Streams, которые будут использоваться для хранения изменений в БД:
    sqlplus strmadmin@orcla
    begin
    -- Создание очередей (4 ANYDATA queues at each database)
    	dbms_streams_adm.set_up_queue@orcla(
    		queue_table=> 'strmadmin.apply_queue_table_a',
    		queue_name => 'strmadmin.apply_queue_a',
    		queue_user => 'strmadmin');
    	
    	dbms_streams_adm.set_up_queue@orcla(
    		queue_table=> 'strmadmin.capture_queue_table_a',
    		queue_name => 'strmadmin.capture_queue_a',
    		queue_user => 'strmadmin');
    	
    	dbms_streams_adm.set_up_queue@orclb(
    		queue_table=> 'strmadmin.apply_queue_table_b',
    		queue_name => 'strmadmin.apply_queue_b',
    		queue_user => 'strmadmin');
    	
    	dbms_streams_adm.set_up_queue@orclb(
    		queue_table=> 'strmadmin.capture_queue_table_b',
    		queue_name => 'strmadmin.capture_queue_b',
    		queue_user => 'strmadmin');
    end;
    /
    
  7. Создание процессов применения (Apply process):
    sqlplus strmadmin@orcla
    begin
    -- Создание процессов применения 
    	dbms_apply_adm.create_apply@orcla(
    		queue_name     => 'strmadmin.apply_queue_a',
    		apply_name     => 'apply_a',
    		source_database=> 'orclb',
    		apply_captured => false);
    
    	dbms_apply_adm.create_apply@orclb(
    		queue_name     => 'strmadmin.apply_queue_b',
    		apply_name     => 'apply_b',
    		source_database=> 'orcla',
    		apply_captured => false);
    end;
    /
    
  8. Настройка дополнительных параметров применения (подробнее [6]):
    sqlplus strmadmin@orcla
    begin
    -- не выключать процесс при возникновении ошибки
    	dbms_apply_adm.set_parameter@orcla(
    		apply_name  => 'apply_a',
    		parameter   => 'disable_on_error',
    		value       => 'n');
    	dbms_apply_adm.set_parameter@orclb(
    		apply_name  => 'apply_b',
    		parameter   => 'disable_on_error',
    		value       => 'n');
    
    -- проводить сравнение только по первичному ключу
    	dbms_apply_adm.set_parameter@orcla(
    		apply_name  => 'apply_a',
    		parameter   => 'compare_key_only',
    		value       => 'y');
    	dbms_apply_adm.set_parameter@orclb(
    		apply_name  => 'apply_b',
    		parameter   => 'compare_key_only',
    		value       => 'y');
    end;
    /
    
  9. Создание процессов синхронного сбора изменений таблиц (Synchronous capture):
    sqlplus strmadmin@orcla
    SET SERVEROUTPUT ON
    DECLARE
    	V_SN VARCHAR2(255);
            -- получить список всех таблиц схемы
    	CURSOR GET_TABLES_CUR IS
    		SELECT table_name
    		FROM all_tables
    		WHERE owner = '<название схемы синхронизируемой БД>'
    		ORDER BY table_name;
    BEGIN
      DBMS_OUTPUT.ENABLE;
      -- название схемы
      V_SN := '<название схемы синхронизируемой БД>';
      FOR V_GT IN GET_TABLES_CUR LOOP
    -- Создание синхронного сбора изменений всех таблиц схемы (Synchronous capture)
    	dbms_streams_adm.add_table_rules@orcla(
    		table_name     => V_SN || '.' || V_GT.table_name,
    		streams_type   => 'sync_capture',
    		streams_name   => 'sca' || V_GT.table_name,
    		queue_name     => 'strmadmin.capture_queue_a',
    		include_dml    => true,
    		include_ddl    => false,
    		source_database=> 'orcla');
    	dbms_streams_adm.add_table_rules@orclb(
    		table_name     => V_SN || '.' || V_GT.table_name,
    		streams_type   => 'sync_capture',
    		streams_name   => 'scb' || V_GT.table_name,
    		queue_name     => 'strmadmin.capture_queue_b',
    		include_dml    => true,
    		include_ddl    => false,
    		source_database=> 'orclb');  
      END LOOP;
      COMMIT;
    END;
    /
    
  10. Процесс передачи изменений (Propagation process):
    sqlplus strmadmin@orcla
    SET SERVEROUTPUT ON
    DECLARE
    	V_SN VARCHAR2(255);
    	CURSOR GET_TABLES_CUR IS
    		SELECT table_name
    		FROM all_tables
    		WHERE owner = '<название схемы синхронизируемой БД>'
    		ORDER BY table_name;
    BEGIN
      DBMS_OUTPUT.ENABLE;
      -- название схемы
      V_SN := '<название схемы синхронизируемой БД>';
      FOR V_GT IN GET_TABLES_CUR LOOP
    	-- Настройка передачи изменений
    	  dbms_streams_adm.add_table_propagation_rules@orcla(
    		table_name              => V_SN || '.' || V_GT.table_name,
    		streams_name            => 'prop_a',
    		source_queue_name       => 'strmadmin.capture_queue_a',
    		destination_queue_name  => 'strmadmin.apply_queue_b@orclb',
    		source_database         => 'orcla',
    		queue_to_queue          => true);
    	  dbms_streams_adm.add_table_propagation_rules@orclb(
    		table_name              => V_SN || '.' || V_GT.table_name,
    		streams_name            => 'prop_b',
    		source_queue_name       => 'strmadmin.capture_queue_b',
    		destination_queue_name  => 'strmadmin.apply_queue_a@orcla',
    		source_database         => 'orclb',
    		queue_to_queue          => true);
      END LOOP;
      COMMIT;
    END;
    /
    
  11. Первоначальная синхронизация таблиц (если необходимо):
    -- удаление таблиц
    drop table "repl_user"."<имя удаляемой таблицы>"@orclb cascade constraints;
    -- создать ссылку на каталог на БД «b»
    create or replace directory b_dir as 'c:oracleapporadata';
    -- получить SCN на БД «a»
    select owner, directory_name, directory_path from all_directories;
    -- синхронизация таблицы по сети
    select dbms_flashback.get_system_change_number@orcla() from dual;
    impdp strmadmin/<пароль>@orclb directory=b_dir network_link=orcla tables=<название схемы синхронизируемой БД>.<имя таблицы> flashback_scn=2025750
    
  12. Установка контрольных точек (необходимо для начала отчета перехвата изменений):
    sqlplus strmadmin@orcla
    SET SERVEROUTPUT ON
    DECLARE
    	V_SN VARCHAR2(255);
    	CURSOR GET_TABLES_CUR IS
    		SELECT table_name
    		FROM all_tables
    		WHERE owner = '<название схемы синхронизируемой БД>'
    		ORDER BY table_name;
    	iscn_a  number; 
    	iscn_b  number;    
    BEGIN
      DBMS_OUTPUT.ENABLE;
      -- название схемы
      V_SN := '<название схемы синхронизируемой БД>';
    	  iscn_a := dbms_flashback.get_system_change_number@orcla();
    	  iscn_b := dbms_flashback.get_system_change_number@orclb();
    	  FOR V_GT IN GET_TABLES_CUR LOOP
    	-- Установка SCN для таблиц
    	  dbms_apply_adm.set_table_instantiation_scn@orcla(
    		source_object_name    => V_SN || '.' || V_GT.table_name,
    		source_database_name  => 'orclb',
    		instantiation_scn     => iscn_b);
    	  dbms_apply_adm.set_table_instantiation_scn@orclb(
    		source_object_name    => V_SN || '.' || V_GT.table_name,
    		source_database_name  => 'orcla',
    		instantiation_scn     => iscn_a);
      END LOOP;
      COMMIT;
    END;
    /
    
  13. Запуск процессов применения и передачи:
    sqlplus strmadmin@orcla
    begin
    -- остановить все процессы
    	dbms_apply_adm.stop_apply@orcla(
    		apply_name      => 'apply_a');
    	dbms_propagation_adm.stop_propagation@orcla(
    		propagation_name=> 'prop_a',
    		force           => false);
    	dbms_apply_adm.stop_apply@orclb(
    		apply_name      => 'apply_b');
    	dbms_propagation_adm.stop_propagation@orclb(
    		propagation_name=> 'prop_b',
    		force           => false);
    -- запустить все процессы
    	dbms_apply_adm.start_apply@orcla(
    		apply_name      => 'apply_a');
    	dbms_propagation_adm.start_propagation@orcla(
    		propagation_name=> 'prop_a');
    	dbms_apply_adm.start_apply@orclb(
    		apply_name      => 'apply_b');
    	dbms_propagation_adm.start_propagation@orclb(
    		propagation_name=> 'prop_b');
    end;
    /
    
  14. Настройка завершена.
  15. Описание по отработке исключений приведено в «Troubleshooting Streams Apply Errors ORA-1403, ORA-26787 or ORA-26786,Conflict Resolution (Doc ID 265201.1)» и в «Streams Conflict Resolution (Doc ID 230049.1)»

Автор: enkidu

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/oracle/70527

Ссылки в тексте:

[1] здесь: http://habrahabr.ru/post/123569/

[2] здесь: http://citforum.ru/database/oracle/streams_simple/

[3] здесь: http://www.oraclegis.com/blog/?p=501

[4] официальной документации: http://docs.oracle.com/cd/B28359_01/server.111/b28324/tdpii_repcont.htm#TDPII080

[5] ограничения: http://docs.oracle.com/cd/E11882_01/license.112/e47877/editions.htm#DBLIC116

[6] подробнее: http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_apply.htm#ARPLS300

[7] Источник: http://habrahabr.ru/post/238521/