Infrastructure at your Service

Introduction

Have you ever renamed your database?
When you cloned a DB, you probably started it with a new name and cloning (duplicating) with RMAN provided a new DBID, right?
So why should we need to rename a DB?

There may be several reasons:
due to changed company rules, you need to rename all your DBs
After a restore you need to run the DB with another name
After a snapshot clone, (see my recent blog) you want to run it with new name

First, I want to mention that all I found in the Internet was incomplete – even the Oracle® Database Utilities and MOS Doc Id 2258871.1. Incomplete regarding all the items that should be changed together with the DB-name or simply not working. Therefore, I write this article with the word “completely” at the end.

Starting point

We did a snapshot clone with our fancy new PureStorage.
The Oracle release and edition must be the same as on the source server, of course.
The oratab, spfile, etc are created and the $ORACLE_SID is set to T01A (the new SID will be changed to T01B).
Just to remember the commands – we did a snapshot and copied the volumes to the target server:

   purepgroup snap --suffix $SUFFIX ${SrcPG} --apply-retention
   purevol copy --force ${SrcPG}.$SUFFIX.$SrcVol1 $TgtVol1
   purevol copy --force ${SrcPG}.$SUFFIX.$SrcVol1 $TgtVol2
   purevol copy --force ${SrcPG}.$SUFFIX.$SrcVol1 $TgtVol3

Then we mounted the volumes and were already able to and start the DB – done 😊
But here the story starts…

1. Clean shutdown

First, before a rename, the DB needs a “clean” shutdown.
So simply startup and
while the DB is open, create a pfile and a script to rename all DB-files for later use
then shutdown the DB “immediate” (not “abort”).
Some blogs mention to backup the controlfile and/or switch the logfile, but this is not required.

2. The configuration files

The clone commands above “copied” the /u02/oradata containing the tablespace files
/u03/oradata containing redologs
/u90/fra containing backups

In your environment you may have more volumes. Feel free to adapt …

For a fresh clone, we will need as well the spfile and orapw from either the ADMIN- or ORACLE_HOME-directory and the sqlnet configuration files.
When you are doing frequent clones, you probably have these files already on your target server.

Note: From here on I will use “SRC” for the original, the source DB-name and
“TGT” for the new, the target DB-name.

 
Here in our example, we use:

$ADMIN = /u01/app/oracle/admin/$ORACLE_SID/pfile

for spfile and orapwd and

$TNS_ADMIN = /u01/app/oracle/network/admin

So, we need links to the files for both old-SID and new-SID and set the variable:

ln -fs $ADMDIR/$ORACLE_SRC/pfile/orapw$ORACLE_SRC $ORACLE_HOME/dbs/orapw$ORACLE_SRC
ln -fs $ADMDIR/$ORACLE_TGT/pfile/orapw$ORACLE_TGT $ORACLE_HOME/dbs/orapw$ORACLE_TGT
ln -fs $ADMDIR/$ORACLE_SRC/pfile/spfile$ORACLE_SRC.ora $ORACLE_HOME/dbs/spfile$ORACLE_SRC.ora
ln -fs $ADMDIR/$ORACLE_TGT/pfile/spfile$ORACLE_TGT.ora $ORACLE_HOME/dbs/spfile$ORACLE_TGT.ora
export TNS_ADMIN=/u01/app/oracle/network/admin
/usr/bin/scp -pr [email protected]$SRCHOST:$ADMDIR/$ORACLE_SRC* $ADMDIR    (***)
/usr/bin/scp -pr [email protected]$SRCHOST:$TNS_ADMIN/*.ora $TNS_ADMIN

*** (if you do not want to copy a bulk load of *aud files, please modify the scp-command)

For completeness I would like to mention directories containing the $DB_UNIQUE_NAME like
/u01/app/oracle/admin/$DB_UNIQUE_NAME/xdb_wallet or 
/u01/app/oracle/diag/rdbms/$DB_UNIQUE_NAME/…
which are handled in my script.

3. DBNEWID

Now you can run the “main” command.

 nid target=/ dbname=$ORACLE_TGT

The output will tell you something about changed file names:

…
Control File /u02/oradata/T01A/control03T01A.dbf - modified
Datafile /u02/oradata/T01A/system01T01A.db - dbid changed, wrote new name
…
Instance shut down
Database name changed to T01B.
Modify parameter file and generate a new password file before restarting.
Database ID for database T01B changed to 2621333956.
All previous backups and archived redo logs for this database are unusable.
Database is not aware of previous backups and archived logs in Recovery Area.
Database has been shutdown, open database with RESETLOGS option.
Succesfully changed database name and ID.
DBNEWID - Completed succesfully.

Be aware – the file names were NOT changed. They are just registered in the controlfile.
And it tells us that all the archives and backups are obsolete.

4. Rename and adapt all and everything

Most blogs tell you ALTER SYSTEM SET DB_NAME=T01B; and start your DB  ⇒  😥

  • adapt the new pfile:
    in step 1 we have already created the new parameter-file with the adequate name:

    create pfile=’ $ADMDIR/$ORACLE_SRC/pfile/init$ORACLE_TGT.ora’ from spfile;

    on OS-level, we replace all SRC by TGT entries (not only the DB-name) and kick out all the heading lines:

    sed -i '/.archive_lag_target/,$!d' $ADMDIR/$ORACLE_SRC/pfile/init$ORACLE_TGT.ora
    sed -i "s/$ORACLE_SRC/$ORACLE_TGT/g" $ADMDIR/$ORACLE_SRC/pfile/init$ORACLE_TGT.ora
    sed -i "s/$SRCHOST/$TGTHOST/g" $ADMDIR/$ORACLE_SRC/pfile/init$ORACLE_TGT.ora
  • Create a new Password file:

    Since 12.2. the password must contain at least 8 characters and at least 1 special character.

    orapwd file=$ADMDIR/$ORACLE_SRC/pfile/orapw$ORACLE_TGT force=y password=Manager_19c entries=3
  • complete the oratab:
    echo "$ORACLE_TGT:$ORACLE_HOME:N" >> /etc/oratab
  • adapt the script to rename all DB-files:
    in step 1 we have already created the script to rename the DB-files. You probably know, that since 12c, we can move datafiles online. This would be resource intensive operation. Moving on OS-level is a “cheap” command – not even the inode will be changed.
    And renaming while the DB is in mount state, is as well a lightweight one.

    @script_rename.sql $ORACLE_SRC $ORACLE_TGT  ⇒  created script:  rename_db_files.sql

    We just need to remove the lines, containing the “old   1: …” and “new:   1: …”

    sed '/old/d;/new/d' -i rename_db_files.sql
  • rename the path/filenames on OS-level –we can modify path as well as filenames in one command. I love “sed”.

    (here $filesys1 and $filesys2 are our volumes, /u0*/oradata)

    cd $filsys1
     find . -type f -name "*$ORACLE_SRC*" | while read FN; do
       BFN=$(basename "$FN")
       NFN=$(echo ${BFN}|sed "s/$ORACLE_SRC/$ORACLE_TGT/g")
       mv "$BFN"  "$NFN"
     done
    #
     cd $filsys2
     find . -type f -name "*$ORACLE_SRC*" | while read FN; do
       BFN=$(basename "$FN")
       NFN=$(echo ${BFN}|sed "s/$ORACLE_SRC/$ORACLE_TGT/g")
       mv "$BFN"  "$NFN"
     done
  • adapt the SQL-net files
    replace all ORACLE_SID and Hostnames in listener.ora:

    cd $TNS_ADMIN
      sed -i "s/$SRCHOST/$TGTHOST/g"           $TNS_ADMIN/listener.ora
      sed -i "s/$ORACLE_SRC/$ORACLE_TGT/g"     $TNS_ADMIN/listener.ora

    adapt tnsnames.ora and append a tns-entry for the new DB: (I tend to leave the old one unchanged)

    SER=$(grep service_names $ADMDIR/$ORACLE_TGT/pfile/init$ORACLE_TGT.ora |awk -F\' '{print $2}')
     echo "############"    >> $TNS_ADMIN/tnsnames.ora
     echo "$ORACLE_TGT="    >> $TNS_ADMIN/tnsnames.ora
     echo " (DESCRIPTION="  >> $TNS_ADMIN/tnsnames.ora
     echo "   (ADDRESS=(PROTOCOL=TCP)(HOST=$TGTHOST)(PORT=1521)) "  >> $TNS_ADMIN/tnsnames.ora
     echo "   (CONNECT_DATA=(SERVICE_NAME=$SER))) "                 >> $TNS_ADMIN/tnsnames.ora
     echo “############”

    Restart the listener:

      lsnrctl stop
      lsnrctl start

clean up!   clean up!   clean up!

  • Clean and copy the “old” ADMIN-directory

    (I tend to leave the old one and remove it later)

    rm -f $ADMDIR/$ORACLE_SRC/adump/*.aud
     cd $ADMDIR
     ls -d $ORACLE_SRC* | while read FN; do
      BFN=$(basename "$FN")
      NFN=$(echo ${BFN}|sed "s/$ORACLE_SRC/$ORACLE_TGT/g")
      cp -ar "$BFN"  "$NFN"
      echo  "copied $BFN to  $NFN"
     done
  • clean the backups:
    whether your backups are in $FRA/$ORACLE_SID or in $FRA/$DB_UNIQUE_NAME, you can remove them all by:

    cd $FRA
     ls -d $ORACLE_SRC* | while read FN; do
      BFN=$(basename "$FN")
      NFN=$(echo ${BFN}|sed "s/$ORACLE_SRC/$ORACLE_TGT/g")
      if [ -d $BFN ]; then
       echo "delete old $BFN ..."
       rm -rf  ${BFN}
      fi
      mkdir  ${NFN}
     done
  • clean the DIAG-directory:
    you could simply remove the $ORACLE_BASE/diag/rdbms completely. If you have other DBs running on this machine, you do not want to delete all of them.

    find $ORACLE_BASE/diag/rdbms -name "${ORACLE_SRC,,}*" -exec rm -rf {} \;
    find $ORACLE_BASE/diag/rdbms -name "${ORACLE_TGT,,}*" -exec rm -rf {} \;
  • at last, you set the ORACLE_SID:
    export ORACLE_SID=$ORACLE_TGT

Finalize

  • Finally, you should be able to start the cloned DB with its new namee.
    sqlplus / as sysdba
    create spfile='$ADMDIR/$ORACLE_TGT/pfile/spfile$ORACLE_TGT.ora' from pfile='$ADMDIR/$ORACLE_TGT/pfile/init$ORACLE_TGT.ora';
    startup nomount;
    alter database mount;
    select name, dbid, created, open_mode  from V$DATABASE;

    rename all DB-files, including TEMP-files and redo-logs.

    @$PWD/rename_db_files.sql
    alter database open resetlogs;
    exit

do not forget to save your result and check all files and the FRA.

rman target /
BACKUP as compressed backupset DATABASE plus ARCHIVELOG delete all input;
exit

Remarks

  • These steps and code snippets cover the tasks for a standalone single instance DB.
  • In Data Guard environments you must be careful about renaming and moving files. The STANDBY_FILE_MANAGEMENT parameter determines how file changes on the primary server are applied to the standby server.
  • When using Oracle Managed Files (OMF), the command in script_rename.sql is even simpler. You do not specify “… rename ‘oldpath/filename’ TO ‘newpath/filename’” because Oracle knows where to put and how to name files. You simply specify: “… rename ‘oldpath/filename’”.
  • When working on a Container Database, run the NID command with the parameter
    PDB=[ALL | NONE] to change (or leave) all PDBs together with the container-DB.
    Funnily Oracle recommends that you use PDB=ALL, but PDB=NONE is the default. (See Database utilities.)
  • When using Global Database Names, double check the init$ORACLE_TGT.ora before creating a spfile.

2 Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Dieter Henig
Dieter Henig

Consultant