Forcer le DBID et le DBName d’une base Oracle

Utilitaire DBNEWID

Avant l’introduction de l’utilitaire DBNEWID (nid) en 9i, il était impossible de modifier le DBID interne d’une instance. Quant à modifier le DBNAME de la base de données, cela passait nécessairement par la création d’un nouveau fichier de contrôle. L’arrivée de DBNEWID permet de modifier le DBID pour la première fois avec, ou non, son DBNAME.
Comme cas classique d’utilisation, rappelons que la modification du DBID est nécessaire lorsque vous souhaitez enregistrer dans le catalogue RMAN une base de données clonée à partir d’une première déjà connue. En effet, RMAN identifie les instances à l’aide du DBID, empêchant ainsi la gestion des 2 bases de données par le même catalogue. La génération d’une nouveau DBID pour la base clonée permet de passer outre cette restriction.

Forcer le DBID ?

Vous avez peut-être déjà tiqué sur la dernière phrase. DBNEWID permet de « générer un nouveau DBID » pour une base, et ce nouvel identifiant sera généré aléatoirement par Oracle sans que vous ayez la main dessus.
Mais qu’en est-il alors pour modifier le DBID avec un identifiant bien précis ?

J’en conviens : les cas où le besoin s’en fait sentir sont rares. Mais cela peut vous aider dans certaines situations problématiques.
nid ne permet pas de gérer ce besoin. Mais il existe pourtant une solution.

Etapes pour forcer un DBID (et éventuellement le DBNAME)

Monter l’instance

SQL> startup mount
ORACLE instance started.

Total System Global Area  881094656 bytes
Fixed Size                  2251288 bytes
Variable Size             713033192 bytes
Database Buffers          159383552 bytes
Redo Buffers                6426624 bytes
Database mounted.

Demander le nouveau DBID et le DBNAME

SQL> var old_name varchar2(20)
SQL> var old_dbid number
SQL> var new_name varchar2(20)
SQL> var new_dbid number

SQL> exec select name, dbid into :old_name,:old_dbid from v$database

PL/SQL procedure successfully completed.

SQL> print old_name
OLD_NAME
--------------------------------------------------------------------------------
DBMIG

SQL> print old_dbid

  OLD_DBID
--------------------------------------------------------------------------------
444855231

SQL> accept new_name prompt "Enter the new Database Name:"
Enter the new Database Name:DBMIG

SQL> accept new_dbid prompt "Enter the new Database ID:"
Enter the new Database ID:555966342

Demander le nouveau DBID et le DBNAME

SQL> exec :new_name:='&new_name'

PL/SQL procedure successfully completed.

SQL> exec :new_dbid:=&&new_dbid

PL/SQL procedure successfully completed.

SQL> set serveroutput on

SQL> exec dbms_output.put_line('Convert '||:old_name||  '('||to_char(:old_dbid)||') to '||:new_name|| '('||to_char(:new_dbid)||')')
Convert DBMIG(444855231) to DBMIG(555966342)

SQL> 
declare
  v_chgdbid   binary_integer;
  v_chgdbname binary_integer;
  v_skipped   binary_integer;
begin
  dbms_output.put_line('Convert '||:old_name||  '('||to_char(:old_dbid)||') to '||:new_name|| '('||to_char(:new_dbid)||')') ;
 
  dbms_backup_restore.nidbegin(:new_name, :old_name,:new_dbid,:old_dbid,0,0,10);
  dbms_backup_restore.nidprocesscf(v_chgdbid,v_chgdbname);
  dbms_output.put_line('ControlFile: ');
  dbms_output.put_line('  => Change Name:' ||to_char(v_chgdbname));
  dbms_output.put_line('  => Change DBID:' ||to_char(v_chgdbid));
 
  for i in (select file#,name from v$datafile)
  loop
     dbms_backup_restore.nidprocessdf(i.file#,0, v_skipped,v_chgdbid,v_chgdbname);
     dbms_output.put_line('DataFile: '||i.name);
     dbms_output.put_line('  => Skipped:'     ||to_char(v_skipped));
     dbms_output.put_line('  => Change Name:' ||to_char(v_chgdbname));
     dbms_output.put_line('  => Change DBID:' ||to_char(v_chgdbid));
  end loop;

  for i in (select file#,name from v$tempfile)
     loop
     dbms_backup_restore.nidprocessdf(i.file#,1, v_skipped,v_chgdbid,v_chgdbname);
     dbms_output.put_line('DataFile: '||i.name);
     dbms_output.put_line('  => Skipped:'     ||to_char(v_skipped));
     dbms_output.put_line('  => Change Name:' ||to_char(v_chgdbname));
     dbms_output.put_line('  => Change DBID:' ||to_char(v_chgdbid));
  end loop;
  dbms_backup_restore.nidend;
end;
/
Exemple de sortie
ControlFile:
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/system01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/undotbs01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/cwmlite01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/drsys01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/example01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/indx01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/odm01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/tools01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/users01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/xdb01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1
DataFile: /sauvegarde/MIGITEMA/oradata/dbmig/temp01.dbf
=> Skipped:0
=> Change Name:0
=> Change DBID:1

PL/SQL procedure successfully completed.

Redémarrage de l’instance

SQL> shutdown immediate;

ORA-01109: database not open


Database dismounted.
ORACLE instance shut down.

SQL> startup mount ;
ORACLE instance started.

Total System Global Area  881094656 bytes
Fixed Size                  2251288 bytes
Variable Size             713033192 bytes
Database Buffers          159383552 bytes
Redo Buffers                6426624 bytes
Database mounted.

SQL>  select name, dbid  from v$database ;

NAME            DBID
--------- ----------
DBMIG      555966342

Et hop ! Le tour est joué.