Rechercher sur arkzoyd.com

28 juillet 2008

Numéro de Patch RDA 4.12

Si vous voulez télécharger RDA 4.12 avec le numéro de patch est 7114647 ! Pour plus tard, il y a un produit nommé "Remote Diagnostics Agent OCM Bundle (rdaocm)" dans la liste des "Patches and Updates" de Metalink :
ftp updates.oracle.com
ftp> cd 7114647
ftp> ls
Jun 10 09:17 p7114647_4120_AIX.zip
Jun 10 09:17 p7114647_4120_AIX64-5L.zip
Jun 10 09:17 p7114647_4120_AIX64.zip
Jun 10 09:17 p7114647_4120_HP64.zip
Jun 10 09:17 p7114647_4120_HPUX-IA64.zip
Jun 10 09:17 p7114647_4120_LINUX.zip
Jun 10 09:17 p7114647_4120_Linux-IA64.zip
Jun 10 09:17 p7114647_4120_Linux-S390.zip
Jun 10 09:17 p7114647_4120_LinuxPower.zip
Jun 10 09:17 p7114647_4120_SOLARIS64.zip
Jun 10 09:17 p7114647_4120_Tru64.zip
Jun 10 09:17 p7114647_4120_WINNT.zip
Peu de nouveauté dans cette version, sinon un embryon de nouveau module qui adresse les problématiques de sécurité. On attend déjà RDA 4.13...

27 juillet 2008

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...

Oracle Streams B.A.-BA.

Il y a quelques jours, un post intitulée Migrer de 10g en 11g avec Zéro Indisponibilité et Streams, illustrait, sur ce blog, une utilisation d'Oracle Streams dans un cas particulier. Au vue des différents échanges sur le sujet, il semble utile de présenter un exemple plus simple que vous pourrez mettre en oeuvre en 30 minutes et qui donne une idée un peu plus précise de comment fonctionne Streams.

L'idée de l'exemple qui suit consiste à 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. L'intérêt d'un tel exemple réside surtout dans la simplicité de sa mise en oeuvre... mais passons aux choses concrètes.

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

Avant de paramétrer Oracle Streams, il faut réunir un certain nombre de conditions (Au moins pour la capture à partir des fichiers redo/archive log) ; Il faut que la base de données soit une version Enterprise Edition et en mode archivelog. En outre, il faut ajouter des informations supplémentaires dans les fichiers log pour permettre de capturer les clés primaires/uniques et ainsi appliquer les modifications sur la table répliquée. Il est possible de forcer la capture de ces informations pour une table uniquement ; Pour simplifier, nous allons activer ce "SUPPLEMENTAL LOG" pour toute la base de données. Exécutez le script ci-dessous à cette fin :
connect / as sysdba

alter database add supplemental log
data (primary key, unique index) columns;

select SUPPLEMENTAL_LOG_DATA_MIN,
SUPPLEMENTAL_LOG_DATA_PK,
SUPPLEMENTAL_LOG_DATA_UI
from gv$database;
D'autre part, il faut pouvoir reconstruire les modifications à partir des fichiers de redo et ce, même si les structures d'origine ont été modifiée dans l'intervalle par un ordre DDL. Streams s'appuie sur une copie minimale du dictionnaire de données au moment du démarrage de la capture stockée dans le Multi-Version Data Dictionary (MVDD). Il faut donc capturer les informations minimales et les enregistrer dans les fichiers de redo logs avec la commande ci-dessous :
var first_scn number;

SET SERVEROUTPUT ON
DECLARE
scn NUMBER;
BEGIN
DBMS_CAPTURE_ADM.BUILD(
first_scn => scn);
DBMS_OUTPUT.PUT_LINE('First SCN Value = ' || scn);
:first_scn := scn;
END;
/

First SCN Value = 244468
La capture devra donc commencer avant la création de ces informations dans le redo log, d'où l'importance du first_scn lorsque vous créerez le process de capture. D'autre part, ces informations sont minimales et il vous faut également ajouter au MVDD, la définition des structures que vous voulez répliquer à l'aide des procédure prepare_xxx_instantiation du package dbms_capture_adm comme ci-dessous :
exec dbms_capture_adm.prepare_table_instantiation(-
table_name=>'demo.t1');

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 un process de capture


Vous allez maintenant aborder la création de votre configuration Streams proprement dites et commencer par créer un process de capture et ajoutez la table que vous voulez répliquer à ce process. Vous noterez dans ce qui suit, la valeur de first_scn inclut la capture du dictionnaire de données. Vous pouvez préciser le db_unique_name de la base de données (ou db_name si db_unique_name n'est pas utilisé) :

BEGIN
DBMS_CAPTURE_ADM.CREATE_CAPTURE(
queue_name => 'strmadmin.streams_queue',
capture_name => 'streams_capture',
rule_set_name => NULL,
source_database => 'BLACK',
use_database_link => false,
first_scn => 244468,
logfile_assignment => 'implicit');
END;
/

BEGIN
DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => 'demo.t1',
streams_type => 'capture',
streams_name => 'streams_capture',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => false,
include_tagged_lcr => true,
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_CAPTURE CAPTURE DEMO T1 DML T14


Etape 5 : Ajouter une règle de transformation au process de capture

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, nous allons copier la table demo.t1 dans copy.t1 :
begin
dbms_streams_adm.rename_schema(
rule_name => 't14' ,
from_schema_name => 'DEMO',
to_schema_name => 'COPY',
step_number => 0,
operation => 'add');
end;
/

Etape 6 : Créer un process d'apply

Un process d'apply doit également être créé. Celui-ci souscrit à la file d'attente utilisée pour stocker les modifications capturées et les applique sur la table copy.t1 :
connect strmadmin/strmadmin

Begin
DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => 'copy.t1',
streams_type => 'apply',
streams_name => 'streams_apply',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => true,
include_tagged_lcr => true,
source_database => 'BLACK',
inclusion_rule => true);
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
------------------------
246028

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

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 => 246028);
end;
/

Etape 8 : Démarrer un process d'apply

La suite est simple; Démarrez les process de capture et d'apply :
exec dbms_capture_adm.start_capture('streams_capture');
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 (3,'Text 3');

commit;

pause

select * from copy.t1;

Si Streams ne fonctionne pas, vous pouvez interroger DBA_CAPTURE, V$STREAMS_CAPTURE, DBA_APPLY, DBA_APPLY_ERROR, DBA_STREAMS_TABLE_RULES ou V$BUFFERED_QUEUES.

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_capture_adm.stop_capture('streams_capture');
exec dbms_apply_adm.stop_apply('streams_apply');

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

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

ASM et SPFILE

Si vous avez un spfile pour vos instances ASM, les commandes ALTER DISKGROUP MOUNT/DISMOUNT mettent à jour le paramètre asm_disgroups. Sinon, il faut que vous le modifiez dans le fichier init.ora. Alors dans le cas de RAC, mieux vaut un spfile non partagé qu'un fichier init.ora...

Créer une base de données avec CREATE DATABASE

Il y a quelques mois, un précédent post démontrait l'utilité de DBCA en mode silencieux pour créer une base de données en quelques minutes. Dans la foulée, Alex F. pointait que, si vous utilisez OMF avec une bases de données non-RAC, créer une base de données avec "CREATE DATABASE" est également extrêmement simple. Les 3 étapes qui suivent présentent comment...

Etape 1. Positionner l'environnement

Mettez à jour le fichier oratab et positionnez les variables d'environnement avec oraenv comme ci-dessous :
echo "BLACK:/u01/app/oracle/product/11.1.0/db_1:N" \
>> /etc/oratab

. oraenv

ORACLE_SID = [x] ? BLACK
The Oracle base for ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1 is /u01/app/oracle
Si votre base de données est 10g, assurez-vous que ORACLE_BASE est positionnée et créez les répertoire pour les fichiers de trace:
mkdir -p $ORACLE_BASE/admin/BLACK/adump
mkdir -p $ORACLE_BASE/admin/BLACK/bdump
mkdir -p $ORACLE_BASE/admin/BLACK/cdump
mkdir -p $ORACLE_BASE/admin/BLACK/udump
En 11g, cette dernière étape est inutile...

Etape 2. Créer un fichier spfile et un fichier de mode de passe

Si vous utilisez un fichier spfile, les paramètres sont mis à jour automatiquement par la commande CREATE DATABASE. Pour cette raison, commencez par créer un fichier init.ora comme ci-dessous et transformez le en spfile. Vous trouverez, les paramètres que vous devez positionner au minimum; db_create_file_dest définit la destination des fichiers OMF ; Vous préférerez utilisez sga_target plutot que memory_target si vous voulez utiliser les HugePages avec Linux :
cd $ORACLE_HOME/dbs
cat >initBLACK.ora <<EOF
processes=150
sga_target=350M
pga_aggregate_target=120M
db_name=BLACK
remote_login_passwordfile=exclusive
db_create_file_dest=/u01/app/oracle/oradata
EOF
Puis créez le SPFILE correspondant. Il est inutile de démarrer l'instance pour cela :
sqlplus / as sysdba

create spfile from pfile;

exit;
Enfin, créez un fichier de mots de passe :
orapwd  file=orapwBLACK password=change_on_install

Etape 3. Créer votre base de données

Cette dernière étape est rapide et vous ne configurerez que le minimum :
sqlplus / as sysdba

startup nomount

create database;

@?/rdbms/admin/catalog

@?/rdbms/admin/catproc
Et voilà, vous avez créé une base de données en 5 minutes aussi, reste à savoir pour en faire quoi...

20 juillet 2008

Streams 11g N'est PAS inclus dans Standard Edition

Il y a quelques semaines, je pointais dans ce blog le fait que le "Licensing Guide" a changé la description de Streams entre 10g et 11g, ce qui me laissait penser que vous pouviez utiliser la capture Streams en Standard Edition et SE1 à condition de la baser sur les archivelogs. En effet, d'après ces documents en 10g et 11g :
  • en 10g, la description est la suivante : SE1/SE: apply only
  • En 11g, la description est la suivante : SE1/SE: no capture from redo
J'avoue que j'ai été déçu de la suite avec ma base SE 11g:
exec dbms_capture_adm.prepare_schema_instantiation(-
schema_name=>'scott');

ERROR at line 1:
ORA-00439: feature not enabled: Streams Capture
ORA-06512: at "SYS.DBMS_LOGREP_UTIL", line 719
ORA-06512: at "SYS.DBMS_CAPTURE_ADM_INTERNAL", line 328
ORA-06512: at "SYS.DBMS_CAPTURE_ADM", line 372
ORA-06512: at line 1
Alors, j'ai effacé le post précédent pour éviter toute confusion, ouvert une SR et créé un 2e post que j'ai également effacé à la lumière de ce qui suit. J'ai également envoyé un mail au Product Manager de Streams, ce qui , au final, s'avère avoir été ma meilleure idée ; Oracle Streams serait bien disponible en version SE 11g :
The capture mechanism in 11g SE is Streams Synchronous Capture - a new feature in 11g. Redo-based capture is not available in the Standard Edition.
Alors voilà, j'avais encore compris de travers mais maintenant, vous savez de quoi il s'agit.

19 juillet 2008

Migrer de 10g en 11g avec Zéro Indisponibilité et Streams

Ou disons... Avec moins de 5 minutes d'indisponibilité ! Bien sur il y a quelques restrictions...

D'abord merci à Wilfrid qui a posé cette question sur un post précédent que j'ai malheureusement du effacer. Et, si vous voulez mettre en œuvre Streams pour un projet autre qu'une simple mise à jour de logiciel, je sais avec qui vous pouvez travailler !

1. Le principe

L'idée consiste à construire une seconde base de données comme décrit dans le schéma ci-dessous. La source et la destination doivent être des versions Enterprise Edition. La base clone est dans une version supérieure à la source. Cette architecture limite les interventions et la charge sur la base primaire au minimum:

Les 3 grandes phases du fonctionnement de l'architecture nécessitent de :
  1. Transmettre les fichiers d'archivelog du serveur primaire à celui abritant le clone et les enregistrer ces fichiers dans la base clone. Vous pouvez réaliser ces opérations manuellement ou en utilisant les capacités de transport des logs d'Oracle Enterprise Edition.
  2. Capturer les modifications du schéma applicatif au moyen d'un processus de capture Streams et de les publier dans une buffered queue Oracle Advanced Queuing
  3. Appliquer les modifications sur le schéma de la base clone.
Tous les détails, ou presque de cette implémentation sont dans la documentation qui suit :
Oracle® Streams Concepts and Administration
11g Release 1 (11.1)
B Online Database Upgrade with Oracle Streams

Nous allons simplement illustrer ce chapitre...

2. Un exemple simple

Alors disons pour commencer que vous avez une base de données, nommée BLACK en version 10.2. Il s'agit d'une base de données dont l'instance associée est nommée également BLACK ; pour cet exemple, il s'agit d'une base Oracle 10.2.0.4 sur Linux x86. Cette base a un schéma applicatif DEMO comme celui ci-dessous :
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 t_demo1 (id number primary key,
lib varchar2(10));

create table t_demo2 (id number,
lib varchar2(10));

create or replace type typ_demo3
as object(lib varchar2(100));
/

create table t_demo3 (id number primary key,
lib typ_demo3);

insert into demo.t_demo1
values (1,'data 1');

insert into demo.t_demo1
values (2,'data 2');

insert into demo.t_demo2
values (1,'data 1');

commit;

3. Quelques restrictions

Autant annoncer les mauvaises nouvelles d'abord ; Comme pour une logical Standby database, Streams ne permet pas de répliquer n'importe quelle structures :
  • Certain nombre de types, comme les SecureFiles, les "User Defined Types", les ROWID ou les Types Spatial ne peuvent pas être répliqués.
  • Certaines structures comme les files d'attentes AQ ne peuvent pas être répliquées.
  • Les tables répliquées doivent avoir au moins une clé primaire ou une clé unique.
  • Toutes les modifications doivent être stockées dans redo logs. En fait, il faudra activer des niveaux de log supplémentaires
Si votre base de données ne respecte pas ces points précédents, il vous faudra trouver un moyen de contourner votre problème, avec, par exemple des triggers. Vous noterez également que certaines structures ne nécessitent pas d'être répliquées :
  • Les Global Temporary Tables, évidemment !
  • Les Materialized Views
  • Les triggers devront généralement, mais aussi selon la logique qu'ils contiennent être désactivés
  • Les Jobs devront également le plus souvent être désactivés, sauf dans certains cas comme les rafraichissements des Materialized Views qui ceux-ci sont programmés.
  • Les valeurs utilisées des séquences ne sont pas répliquées
Ceci dit, passons à la pratique !

4. Préparer la base de données primaire

Pour pouvoir mettre en oeuvre Streams, il faut que votre base de données primaire soit en mode archivelogs. En outre, vous devrez sans doute ajouter un niveau de log supplémentaire :
alter database add supplemental log
data (primary key, unique index) columns;

select SUPPLEMENTAL_LOG_DATA_MIN,
SUPPLEMENTAL_LOG_DATA_PK,
SUPPLEMENTAL_LOG_DATA_UI
from gv$database;

Ensuite, vous devrez instancier la base clone. Utiliser une sauvegarde est, sans doute, la méthode la plus rapide. Vous pourriez alors utiliser une sauvegarde disque avec RMAN. Il suffit que vous ayez un répertoire avec le même nom sur les 2 serveurs primaire et clone (disons /backup) ; Ci-dessous, un exemple de sauvegarde RMAN ; notez le numéro de séquence du dernier fichier archivé pour commencer :
sqlplus / as sysdba

select thread#, max(sequence#) last_seq
from v$archived_log
group by thread#;

THREAD# LAST_SEQ
------- --------
1 2

exit

rman target /

configure controlfile autobackup
format for device type disk to '/oradata/backup/%F';

configure controlfile autobackup on;

configure channel device type disk
format '/oradata/backup/%U';

configure device type disk
backup type to compressed backupset parallelism 1;

show all;

backup database;

exit;
Il faut ensuite enregistrer le dictionaire de la base de données primaire dans les redo log et noter le SCN correspondant comme le premier SCN du process (first_scn) de la capture Streams :
sqlplus / as sysdba

SET SERVEROUTPUT ON
DECLARE
scn NUMBER;
BEGIN
DBMS_CAPTURE_ADM.BUILD(
first_scn => scn);
DBMS_OUTPUT.PUT_LINE('First SCN Value = ' || scn);
END;
/

First SCN Value = 497637
Une fois dictionnaire de la base primaire dans les redo log il faut indiquer les tables qui seront répliquées par Oracle Streams avec une des procédures dbms_capture_adm.prepare_xxx_instantiation comme ci-dessous :
exec dbms_capture_adm.prepare_schema_instantiation(-
schema_name=>'demo');
Si vous tentez d'exécuter cette procédure sur une base Standard Edition 10g ou 11g, vous obtenez le message qui suit:
BEGIN dbms_capture_adm.prepare_schema_instantiation(...
*
ERROR at line 1:
ORA-00439: feature not enabled: Streams Capture
ORA-06512: at "SYS.DBMS_LOGREP_UTIL", line 710
[...]
Il faudra archiver le dernier fichier de log pour s'assurer que le SCN de démarrage de l'apply soit postérieur à la construction du Multi Version Data Dictionary (MVDD) . Notez également le dernier fichier d'archive que vous sauvegarderez :

sqlplus / as sysdba

alter system archive log current;

col next_change# format 999999999999
select thread#, max(sequence#) last_seq, max(next_change#) instantiation_scn
from v$archived_log
group by thread#;

THREAD# LAST_SEQ INSTANTIATION_SCN
------- -------- -----------------
1 7 498370

exit

rman target /

backup archivelog from sequence 2;
Notez le derniers SCN du fichier d'archive que nous allons appliquer sur le clone. Ce SCN sera le SCN utilisé pour demarrer le processus d'apply. Enfin, partagez la sauvegarde avec le serveur clone par la méthode de votre choix (ftp, scp, nfs, bandes...) :
cd /backup

scp * oracle@clone-server:/backup

5. Préparer la base clone

Là aussi, vous avez le choix de la méthode. RMAN duplicate est une méthode simple et j'en ai déjà parlé dans d'autres circonstances. Pour l'implémenter :
  • Installez la même version d'Oracle que sur la base primaire
  • Créez un listener sur le serveur clone avec un enregistrement statique de l'instance pour permettre une connection à distance, même si l'instance n'est pas démarrée
  • Créez un fichier de mot de passe sur le serveur clone pour permettre la connexion à distance pour un utilisateur SYSDBA
  • Utilisez le fichier init.ora ou spfile de l'instance primaire pour créer et démarrer l'instance clone que nous appellerons WHITE pour cet exemple. Paramètrez log_file_name_convert et db_file_name_convert, si vous voulez changer la structure de répertoires de la base de données clone
  • Si vous êtes en 10g, créez l'arborescence d'aministration de votre base de données (adump, bdump, cdump, udump...) ainsi que les repertoires pour votre base de données et les fichiers d'archivelog
  • Créez un alias pour la base primaire et pour le clone dans les fichiers tnsnames.ora des 2 serveurs
Une fois l'ensemble des pré-réquis mis en place, lancez RMAN et la commande duplicate comme ci-dessous :
rman target sys@black auxiliary sys@white

startup clone nomount;

DUPLICATE TARGET DATABASE
TO WHITE nofilenamecheck
until sequence 8
open restricted;
Dans l'exemple qui précède, le numéro de séquence utilisé est le premier qui ne fait pas partie de la sauvegarde. "open restricted" permet de prévenir l'exécution des jobs que vous pouvez par conséquent stopper. N'oubliez pas de désactiver les triggers ! Vous pouvez ensuite ouvrir l'instance normalement :
sql 'alter system disable restricted session';
La base clone est créée.

6. Mettre à jour votre base de données

L'idée est d'appliquer un Patch Set sur la base clone ou de transformer votre schéma cible en fonction de vos besoins. Ces mises peuvent être effectuées la base clone sans impacter la base primaire; Par exemple, vous pouvez installer une Oracle 11g et lancer DBUA sur la base clone comme ci-dessous :
dbua -silent -sid WHITE
Vous appliquerez les changements enregistrés dans les redo logs de la base primaire dans les étapes qui suivent...

7. Créer les process de capture et d'apply sur la base clone

Avant de créer les process, il faut créer l'administrateur Streams, strmadmin, ainsi que la file d'attentes AQ qui sera utilisée par les process de capture et apply sur la base clone. Ci-dessous un exemple de comment réaliser ces opérations :
CREATE TABLESPACE streams_tbs
DATAFILE '/oradata/WHITE/streams_tbs.dbf'
SIZE 25M REUSE AUTOEXTEND ON MAXSIZE 256M;

CREATE USER strmadmin IDENTIFIED BY xxx
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;
/
Vous pouvez créer des fichiers de Standby redo log si vous voulez effectuer une capture "Real Time". Pour cela, vérifiez la taille des fichiers Redo Logs sur la base primaire :
select THREAD#, GROUP#, BYTES
from v$log
order by thread#, group#;

THREAD# GROUP# BYTES
------- ---------- ----------
1 1 52428800
1 2 52428800
1 3 52428800
Une fois que vous avez la taille des redo logs de la base primaire, vous pouvez créer des standby redo logs de la même taille sur la base clone :
alter database add standby logfile thread 1 group 21
('/oradata/WHITE/redo21_1.log') SIZE 52428800;
alter database add standby logfile thread 1 group 22
('/oradata/WHITE/redo22_1.log') SIZE 52428800;
alter database add standby logfile thread 1 group 23
('/oradata/WHITE/redo23_1.log') SIZE 52428800;
L'étape suivante consiste à créer le processus de capture et à ajouter une règle pour inclure tous les objets du schéma DEMO doivent être capturés.
BEGIN
DBMS_CAPTURE_ADM.CREATE_CAPTURE(
queue_name => 'strmadmin.streams_queue',
capture_name => 'streams_capture',
rule_set_name => NULL,
source_database => 'BLACK',
use_database_link => false,
first_scn => 497637,
logfile_assignment => 'implicit');
END;
/

BEGIN
DBMS_CAPTURE_ADM.SET_PARAMETER(
capture_name => 'streams_capture',
parameter => 'downstream_real_time_mine',
value => 'Y');
END;
/

BEGIN
DBMS_STREAMS_ADM.ADD_SCHEMA_RULES(
schema_name => 'demo',
streams_type => 'capture',
streams_name => 'streams_capture',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => true,
include_tagged_lcr => true,
source_database => 'BLACK',
inclusion_rule => true);
END;
/
Plusieurs objets du schéma demo de notre exemple ne peuvent pas etre capturés. On supposera qu'ils ne sont pas important ou pas modifiés dans cet exemple et il suffit de les exclure de la capture en ajoutant une règle négative :
-- Objets non supportés par Streams
select table_name
from dba_streams_unsupported
where owner='DEMO'
and auto_filtered='NO';

-- Vues matérialisées
select container_name
from dba_mviews
where owner='DEMO';

-- Objets sans UK/PK
select table_name
from dba_tables t
where owner='DEMO'
and table_name not in
(select table_name
from dba_constraints
where owner= t.owner
and constraint_type in ('P','U'));

-- Exclusion des tables non supportées par Streams
set serveroutput on
BEGIN
for i in 2..3 loop
dbms_output.put_line('T_DEMO'||to_char(i));
DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => 'demo.t_demo'||to_char(i),
streams_type => 'capture',
streams_name => 'streams_capture',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => true,
source_database => 'BLACK',
inclusion_rule => false);
end loop;
END;
/
La capture est paramétrée, vous pouvez ajouter le process d'apply ainsi que les règles d'inclusion et d'exclusion associées :
-- Create the Apply and add the DEMO schema
BEGIN
DBMS_STREAMS_ADM.ADD_SCHEMA_RULES(
schema_name => 'demo',
streams_type => 'apply',
streams_name => 'streams_apply',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => true,
include_tagged_lcr => true,
source_database => 'BLACK',
inclusion_rule => true);
END;
/

-- Exclusion des tables non supportées par Streams
set serveroutput on
BEGIN
for i in 2..3 loop
dbms_output.put_line('T_DEMO'||to_char(i));
DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => 'demo.t_demo'||to_char(i),
streams_type => 'apply',
streams_name => 'streams_apply',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => true,
source_database => 'BLACK',
inclusion_rule => false);
end loop;
END;
/
Enfin, il faut definir pour les objets cibles, le SCN qui correspond à leur instianciation à partir de la source, c'est à dire le SCN dans la colonne next_change# du dernier fichier archivelog appliqué lors de la commande RMAN DUPLICATE.
BEGIN
DBMS_APPLY_ADM.SET_SCHEMA_INSTANTIATION_SCN(
SOURCE_SCHEMA_NAME => 'demo',
SOURCE_DATABASE_NAME => 'BLACK',
INSTANTIATION_SCN => 498370);
END;
/

select *
from DBA_APPLY_INSTANTIATED_SCHEMAS;

BEGIN
for i in (select table_name
from dba_tables
where owner='DEMO')
loop
DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN(
SOURCE_OBJECT_NAME=>'demo.'||i.table_name,
SOURCE_DATABASE_NAME=>'BLACK',
INSTANTIATION_SCN=>498370);
end loop;
end;
/

select *
from DBA_APPLY_INSTANTIATED_OBJECTS;
8. Démarrer et superviser Streams

Utilisez dbms_capture_adm et dbms_apply_adm pour démarrer les process de capture et d'apply comme ci-dessous :
exec dbms_capture_adm.start_capture('streams_capture');

exec dbms_apply_adm.start_apply('streams_apply');

set lines 150
col capture_name format a16
col state format a70
col total_messages_captured format 999999999999
col apply_name format a16
select capture_name,
state,
total_messages_captured,
apply_name
from v$streams_capture;
9. Transférez et enregistrer les archivelogs de la base primaire à la base clone

Vous pouvez utiliser les capacités de transport des bases de données Enterprise Edition en parametrant la base de données primaire comme ci-dessous :
alter system
set log_archive_dest_2=
'service=WHITE lgwr async noregister valid_for=(online_logfiles,all_roles) db_unique_name=WHITE';

alter system set log_archive_dest_state_2=defer;

alter system switch logfile;

alter system set log_archive_dest_state_2=enable;

alter system switch logfile;
Supervisez ensuite la base clone et en particulier, vérifiez les fichiers alert.log, les process RFS, les process de capture et d'apply, les archivelogs enregistrés pour Streams et les Standby Redo logs :
select process, status, client_process, thread#, sequence#, blocks
from v$managed_standby
where process = 'RFS';

select capture_name,
state,
total_messages_captured,
apply_name
from v$streams_capture;

select apply_name, status, error_number, error_message
from dba_apply;

select consumer_name, source_database, thread#, sequence#
from dba_registered_archived_log
order by consumer_name, thread#, sequence#;

select thread#, group#, dbid, sequence#, bytes, status
from v$standby_log
order by thread#, group#;
10. Tester la configuration

Outre le fait que la configuration n'ait pas d'erreur, vérifiez que les données modifiées sont bien propagées sur la base clone. Pour cela, modifiez des données sur la source. Vous pouvez également créer une table comme ci-dessous sur la base primaire :
create table demo.streams_healthcheck(
id number primary key,
last_update date);

insert into demo.streams_healthcheck (id, last_update)
values (1,sysdate);

commit;

alter session set nls_date_format='DD/MM/YYYY HH24:MI:SS';

select last_update
from demo.streams_healthcheck
where id=1;

11. Basculer la base clone en production

Déjà la fin de l'histoire :
  1. Arrêtez votre application
  2. Mettez à jour une données dans une table test et validez qu'elle est appliquée dans la base production
  3. Effectuez les derniers changements nécessaires dans la base clone (Activez les triggers, changez les séquences,...)
  4. Démarrez l'application sur votre base clone en 11g qui est maintenant la base de production.
C'est finalement assez simple et si vous avez un script fiable pour la dernière étape, l'indisponibilité peut être de l'ordre de quelques minutes ou même moins. En outre Streams vous permet aussi, pourquoi pas, de transformer le schéma sur la base clone pour permettre la mise à jour d'une application dans la foulée. Vous pouvez aussi utiliser une réplication bi-directionnelle et ainsi disposer d'un plan de retour arrière même si vous decouvrer un problème après plusieurs heures.

Bonne chance pour votre projet et si vous voulez un coup de main, pensez à nous !

12 juillet 2008

Changer le prompt "SQL>" de SQL*Plus

Voici un mini post plus pour moi que pour vous pour garder la commande qui permet de changer le prompt de SQL*Plus et ainsi éviter quelques erreurs. C'est largement inspiré d'un post de blog d'Eddie Awad et vous pouvez ajouter cette commande dans $ORACLE_HOME/sqlplus/admin/glogin.sql pour l'oublier :
column user_sid new_value sql_prompt

select lower(user) || '@' || instance_name user_sid
from v$instance;

set sqlprompt '&sql_prompt> '
Rassurez-vous, vous aurez bientôt un post qui, j'en suis sur, vous intéressera beaucoup plus si vous êtes fan d'Oracle.

03 juillet 2008

De retour en France le 1er août

C'est officiel : je reviens aux affaires en France le 1er août 2008 au matin !

Si vous avez des projets Oracle... entrez en contact dès à présent en laissant un commentaire sur ce post ; je ne le publierai pas. Si vous ne voyez pas l'intérêt de travailler ensemble, restez simplement branché au blog via le flux RSS, ça devrait s'animer de nouveau bientôt, si j'ai un peu de temps :-).

D'ici là continuez à suivre la série en cours sur les installations en mode silencieux d'Oracle :
  1. Installation des bases de donnees 10.2 et 11.1
  2. Patchs et upgrade d'Oracle 10.2 et 11.1
  3. Clone des logiciels et bases de données
  4. Installation d'Oracle RAC 10.2
  5. Ajout d'un noeud à un cluster RAC 10.2
  6. Suppression d'un noeud d'un cluster RAC 10.2
  7. Installation d'Oracle RAC 11.1
  8. Ajout d'un noeud à un cluster RAC 11.1
  9. Suppression d'un noeud d'un cluster RAC 11.1
  10. Une tonne d'autres chose à savoir à propos des installations en mode "silent".
Il y en aura encore 5 ce mois de Juillet ! Et qui sait, il en y aura peut-être d'autres parmi mes posts sur le blog en anglais de Pythian ! Au plaisir de ce revoir ou de se voir, j'espère.