Nouveauté Streams 11g : La Capture Synchrone

La capture synchrone est une nouveauté d’Oracle 11g Streams qui s’appuie sur des triggers interne pour capturer des modifications. Elle est moins évoluée que la capture asynchrone basée sur LogMiner et les redo/archived logs. Par exemple, elle ne permet pas de propager les ordres DDL ou des LOB, elle utilise des files d’attentes persistantes…

Toutefois, la capture synchrone offre plusieurs avantages pour certains cas d’utilisation :

  • Elle peut fonctionner en mode noarchivelog
  • Elle est plus simple à mettre en oeuvre
  • Elle fonctionne avec les versions Standard Edition et Standard Edition One

Ce post, reprend le même cas d’utilisation que le post précédent qui présentait un exemple très simple de capture asynchrone avec cette fois une capture synchrone. Cet exemple consiste dons à répliquer et maintenir synchronisée la copie d’une table T1 dans un autre schéma de la même base de données.

Etape 1 : La table exemple

Pour commencer, il faut une table exemple. Le script ci-dessous crée le schéma DEMO et la table T1 que nous utiliserons dans la suite de cet exemple:

connect / as sysdba

create user demo
identified by demo
default tablespace users
temporary tablespace temp;

grant connect,resource to demo;

connect demo/demo

create table t1(
id number primary key,
text varchar2(80));

insert into t1(id, text)
values (1,'Text 1');

insert into t1(id, text)
values (2,'Text 2');

commit;

Etape 2 : Configurer la base de données

Contrairement à la capture asynchrone, la capture synchrone ne nécessite aucun paramétrage particulier de la base de données source. Il n’est pas nécessaire que la base de données soit en mode archivelog ni qu’aucun supplemental log soit défini. En outre, la capture synchrone ne s’appuie pas sur le Multi Version Data Dictionnary.

Etape 3 : Créer l’administrateur Oracle Streams

Pour créer les process et le règles associées à Streams, il faut créer un administrateur Streams pour votre base de données. Le script ci-dessous effectue les opérations associées et crée un tablespace (on suppose ici que les fichiers sont OMF), l’utilisateur, les privilèges et rôles associés ainsi qu’une file d’attente AQ qui sera utilisée par les process de capture et d’apply pour transporter les modifications :

connect / as sysdba

CREATE TABLESPACE streams_tbs
DATAFILE SIZE 25M
AUTOEXTEND ON MAXSIZE 256M;

CREATE USER strmadmin IDENTIFIED BY strmadmin
DEFAULT TABLESPACE streams_tbs
QUOTA UNLIMITED ON streams_tbs;

grant dba to strmadmin;

BEGIN
DBMS_STREAMS_ADM.SET_UP_QUEUE(
queue_table => 'strmadmin.streams_queue_table',
queue_name => 'strmadmin.streams_queue');
END;
/


Etape 4 : Créer le process d’apply

IMPORTANT :
Dans le cas de la capture synchrone il est indispensable de commencer par créer le process d’apply ; si vous n’effectuez pas cette opération, vous risquez lorsque vous mettrez à jour la table source, d’expérimenter l’erreur qui suit :

insert into demo.t1 values (5,’Text 5′)
*
ERROR at line 1:
ORA-26694: error while enqueueing into queue STRMADMIN.STREAMS_QUEUE
ORA-24033: no recipients for message

Vous allez donc créer dans un premier temps un process de capture en prenant soin de préciser, apply_captured => false pour indiquer que les messages qui seront utilisés sont persistants et n’utilisent pas de Buffered Queue; Ensuite ajoutez une règle pour appliquez les modifications de la table DEMO.T1 :

connect strmadmin/strmadmin

begin
dbms_apply_adm.create_apply(
queue_name => 'strmadmin.streams_queue',
apply_name => 'streams_apply',
apply_captured => false,
source_database => 'BLACK');
end;
/

begin
dbms_streams_adm.add_table_rules(
table_name => 'demo.t1',
streams_type => 'apply',
streams_name => 'streams_apply',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => false,
include_tagged_lcr => false,
source_database => 'BLACK',
inclusion_rule => true);
end;
/

set lines 120
col streams_name format a16
col streams_type format a9
col table_owner format a10
col table_name format a15
col rule_type format a8
col rule_name format a15

select STREAMS_NAME,
STREAMS_TYPE,
TABLE_OWNER,
TABLE_NAME,
RULE_TYPE,
RULE_NAME
from DBA_STREAMS_TABLE_RULES;

STREAMS_NAME STREAMS_T TABLE_OWNE TABLE_NAME RULE_TYP RULE_NAME
---------------- --------- ---------- --------------- -------- ---------------
STREAMS_APPLY APPLY DEMO T1 DML T128

Etape 5 : Ajouter une règle de transformation au process d’apply

Dans cet exemple, vous utilisez la même base de données pour la source et la destination de la réplication Streams et la table source et destination ne peuvent pas être la même. Par conséquent, vous devez ajouter une règle de transformation. Dans le script qui suit, vous ajouterez une règle de transformation au process d’apply pour transformer DEMO en COPY :

begin
dbms_streams_adm.rename_schema(
rule_name => 't128' ,
from_schema_name => 'DEMO',
to_schema_name => 'COPY',
step_number => 0,
operation => 'add');
end;
/

Etape 6 : Créer le process de capture

Vous pouvez alors créer le process de capture. Il est important de noter que dans le cas d’une capture synchone, ce process est forcement actif et ne peut pas être arrêté :

connect strmadmin/strmadmin

BEGIN
DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => 'demo.t1',
streams_type => 'sync_capture',
streams_name => 'sync_capture',
queue_name => 'strmadmin.streams_queue');
END;
/

Etape 7 : Instancier la table

Cette opération consiste à créer la table copy.t1, copie de demo.t1 par la méthode de votre choix et à indiquer le SCN d’instanciation de cette table au process d’apply qui ne commencer à appliquer les modifications capturée sur la table source qu’à partir de ce SCN. Dans le script qui suit, la table copy.t1 est instanciée grâce la la fonctionnalité de flashback query:

connect / as sysdba

create user copy
identified by copy
default tablespace users
temporary tablespace temp;

grant connect,resource to copy;

create table copy.t1(
id number primary key,
text varchar2(80));

select dbms_flashback.get_system_change_number
from dual;

GET_SYSTEM_CHANGE_NUMBER
------------------------
285959

insert into copy.t1
(select * from demo.t1 as of scn 285959);

commit;

Une fois la table instanciée, la procédure set_table_instantiation_scn du package dbms_apply_adm definit
le premier SCN d’apply :

begin
dbms_apply_adm.set_table_instantiation_scn(
source_object_name => 'demo.t1',
source_database_name => 'BLACK',
instantiation_scn => 285959);
end;
/

Etape 8 : Démarrer un process d’apply

La suite est simple; Démarrez les process d’apply :

exec dbms_apply_adm.start_apply('streams_apply');

Etape 9 : Tester Streams

Et effectuez un test du fonctionnement d’Oracle Streams

insert into demo.t1(id, text)
values (5,'Text 5');

commit;

pause

select * from copy.t1;

Si Streams ne fonctionne pas, vous pouvez interroger DBA_SYNC_CAPTURE_TABLES, DBA_APPLY, DBA_APPLY_ERROR, DBA_STREAMS_TABLE_RULES ou la table qui supporte la file d’attente Streams.

Etape 10 : Arrêter et Supprimer la configuration Streams

Que votre test soit concluant ou que vous vouliez nettoyer votre configuration pour recommencer, voici comment supprimer les process de capture, d’apply et toutes les règles associées :

exec dbms_apply_adm.stop_apply('streams_apply');

exec dbms_capture_adm.drop_capture('sync_capture',true);
exec dbms_apply_adm.drop_apply('streams_apply',true);

Et bien sur, vous pouvez aussi supprimer les tables et utilisateurs…