Twitter

oraenv++: an easy and powerful tool to set up your Oracle environment

I have never found a really good and portable way of setting up an Oracle/ASM environment. For sure, there is oraenv but it is based on oratab which is a static hardcoded text file and oraenv does not work well (at all ?) with RAC. Some tries to set up aliases to set up their environment but same, it is hardcoded, Oracle uses hardcoded env files in OCI, etc ... All of this works more and less well but it has always seemed a bit clumsy to me and during a recent email discussion I had with Osman, I decided to jump into that challenge to create something better, easier and more efficient than any of these tools and a fews days later was born oraenv++!

Key features

  • oraenv++ reads the environmental information from GI/CRS/Oracle Restart so no hardcoded configuration file is needed; sorry I cannot do anything if you do not have GI/CRS/Oracle Restart
  • oraenv++ sets the ORACLE_SID, ORACLE_HOME, ORACLE_BASE, PATH and can also set the ORACLE_PDB_SID environment variable to be able to directly connect to a PDB (from 18.8)
  • if you do not know the name of the database you want to set the env up, oraenv++ will show you a menu with a list of databases from your configuration to choose from
  • you can also grep and grep -v in the database list of your environment (regexp are supported)
  • GI storing the database names in lowercase regardless of their case, oraenv++ is not key sensitive regarding the database name nor the pattern(s) to grep/ungrep
  • oraenv++ has to be sourced (. oraenv++) and not executed (./oraenv++); I'll eventually write about the differences in my bash tips
  • I have tested it with GI 19c and I see no reason why it would not work from any GI 12c+ (including 21c+); not sure for GI 11g which should not be much around any more these days
  • I have been using oraenv++ for a little while now and I honestly find it











Examples

A first example to simply set up a database environment:
$ . oraenv++ prod12a
Database            : prod12a
ORACLE_HOME         : /u01/app/oracle/product/12.1.0.2/db_1
ORACLE_BASE         : /u01/app/oracle
ORACLE_SID          : PROD12A1
ORACLE_PDB_SID      :
sqlplus is          : /u01/app/oracle/product/12.1.0.2/db_1/bin/sqlplus
$
Here, we have set up the prod12a environememnt with the correct instance name running on the host you are connected to. If you do not want to see this output, you can make it silent:
$ . oraenv++ prod12a --silent
$
or
$ OPP_SILENT=True
$ . oraenv++ prod12a
$
If you do not specify a database name, oraenv++ will list all the databases which have an instance on this host from your GI configuration and show you a menu to choose from (let's go with 6 below):
$ . oraenv++
    Database    SID          ORACLE_HOME
-----------------------------------------------------------------
  1/ asm        +ASM1      /u01/app/19.11.0.0/grid
  2/ dev12a     DEV12A1    /u01/app/oracle/product/12.1.0.2/db_1
  3/ dev12b     DEV12B1    /u01/app/oracle/product/12.1.0.2/db_1
  4/ dev19a     DEV19A1    /u01/app/oracle/product/19.0.0.0/db_1
  5/ dev19b     DEV19B1    /u01/app/oracle/product/19.0.0.0/db_1
  6/ misc1      MISC11     /u01/app/oracle/product/12.1.0.2/db_1
  7/ misc2      MISC21     /u01/app/oracle/product/19.0.0.0/db_1
  8/ test       TEST1      /u01/app/oracle/product/11.2.0.4/db_1
  9/ prod12a    PROD12A1   /u01/app/oracle/product/12.1.0.2/db_1
 10/ prod12b    PROD12B1   /u01/app/oracle/product/12.1.0.2/db_1
 11/ prod19a    PROD19A1   /u01/app/oracle/product/19.0.0.0/db_1
 12/ prod19b    PROD19B1   /u01/app/oracle/product/19.0.0.0/db_1
-----------------------------------------------------------------
Which environment you want to set up ? (CTRL+C for exit)
6
Database            : misc1
ORACLE_HOME         : /u01/app/oracle/product/12.1.0.2/db_1
ORACLE_BASE         : /u01/app/oracle
ORACLE_SID          : MISC11
ORACLE_PDB_SID      :
sqlplus is          : /u01/app/oracle/product/12.1.0.2/db_1/bin/sqlplus
$
If you have many databases, you can narrow the selection down using --grep or --ungrep (acts as a grep -v); note that these 2 options allow mutiple comma separated pattern to be grepped/ungrepped; they also supports regexp -- this is far overkill but it is fun :)
$. oraenv++ --grep prod,dev --ungrep 12
     Database    SID          ORACLE_HOME
-----------------------------------------------------------------
  1/ dev19a     DEV19A1    /u01/app/oracle/product/19.0.0.0/db_1
  2/ dev19b     DEV19B1    /u01/app/oracle/product/19.0.0.0/db_1
  3/ prod19a    PROD19A1   /u01/app/oracle/product/19.0.0.0/db_1
  4/ prod19b    PROD19B1   /u01/app/oracle/product/19.0.0.0/db_1
-----------------------------------------------------------------
Which environment you want to set up ? (CTRL+C for exit)
This could also have been written (just to showcase a regexp :)):
$. oraenv++ --grep 19[ab]$
     Database    SID          ORACLE_HOME
-----------------------------------------------------------------
  1/ dev19a     DEV19A1    /u01/app/oracle/product/19.0.0.0/db_1
  2/ dev19b     DEV19B1    /u01/app/oracle/product/19.0.0.0/db_1
  3/ prod19a    PROD19A1   /u01/app/oracle/product/19.0.0.0/db_1
  4/ prod19b    PROD19B1   /u01/app/oracle/product/19.0.0.0/db_1
-----------------------------------------------------------------
Which environment you want to set up ? (CTRL+C for exit)
It indeed also works with ASM:
# . oraenv++ asm
Database            : asm
ORACLE_HOME         : /u01/app/19.11.0.0/grid
ORACLE_BASE         : /u01/app/oracle
ORACLE_SID          : +ASM1
ORACLE_PDB_SID      :
sqlplus is          : /u01/app/19.11.0.0/grid/bin/sqlplus
#
If you want to direct connect to a PDB, you can also specify one with the --pdb option which will set the ORACLE_PDB_SID variable and you could then directly connect to this PDB (this works from 18.8):
$ . oraenv++ dev19a --pdb MY_PDB
Database            : dev19a
ORACLE_HOME         : /u01/app/oracle/product/19.0.0.0/db_1
ORACLE_BASE         : /u01/app/oracle
ORACLE_SID          : DEV19A1
ORACLE_PDB_SID      : MYPDB
sqlplus is          : /u01/app/oracle/product/19.0.0.0/db_1/bin/sqlplus
$ sqlplus / as sysdba
SQL> show con_name
CON_NAME
----------------
MY_PDB

TODO / other features / Ideas

First of all, feel free to post down below or contact me if you have ideas or remarks.

On my end, one cool feature to implement in a next future would be to list the PDBs per CDB showing a menu to be able to choose from as we have hundreds of PDBs per CDB and we cannot really remember of all them then choosing from a list would be far easier. The thing here is that the PDBs are real GI resource from 21c only, they are listed in the services before 21c which I already use to show them in rac-status.sh. The thing is that crsctl is slow to query all the services when there are a lot of them so this would slow oraenv++
. Having said that, the direct connection to a PDB feature takes few seconds to get connected and ssh in any Cloud I have experienced are also slow verifying your credentials, billing you, etc ... and no one complains about it :)

Where to download ?

You can download oraenv++ from my public git repo or using the direct link to the source code from the Scripts menu on top of this page.

In case of issue/question, as usual, feel free to post a comment down below, contact me by email or linkedin chat.

Enjoy !

23 comments:

  1. A request: sometimes I perform an ssh to a database host, using a script I developed. If ssh to a RAC database, I will log on one of the RAC host instances, randomly.

    So, if for example the DB name is PROD, the SID would be PRODn, where n is a number from 1 to the max instance of PROD DB.

    I can directly setup env using ". oraenv++ PRODn". But I would love to be capable of perform a ". oraenv++ PROD", whatever the node I'm logged in...

    ReplyDelete
    Replies
    1. Hi,

      This is how it works, you just have to specify the database name, oraenv++ will look for the instance name of this database on the host it is and set up the environment accordingly.


      Delete
    2. Look at this example on a 6 nodes RAC:

      [root@exa01db03 ~]# dcli -g ~/dbs_group -l root ". oraenv++ asm" | grep ORACLE_SID
      exa01db03: ORACLE_SID : +ASM1
      exa01db04: ORACLE_SID : +ASM2
      exa01db09: ORACLE_SID : +ASM3
      exa01db10: ORACLE_SID : +ASM4
      exa01db11: ORACLE_SID : +ASM5
      exa01db12: ORACLE_SID : +ASM6
      [root@exa01db03 ~]#

      Delete
  2. Hi!
    In RAC, the script works fine.
    But it doesn't work with Oracle Restart (19c):
    "..[INFO] Found no DB/Instance, nothing to do !"

    ReplyDelete
    Replies
    1. Really, arghh, I have no Restart to test :/

      Could you please do:

      . oraenv++ -o fileforfred.txt

      And send me that file by email ? (my email is on top of the script and I'll check what is wrong)

      Thanks,

      Delete
  3. Set an alias for the correct opatch, and the appropriate PATH/LD_LIBRARY_PATH/PERL5LIB to run DBI scripts !

    ReplyDelete
  4. hello,
    got the error on OLR="/etc/oracle/olr.loc" not found
    does your script works on none cluster env ?
    regards JJ

    ReplyDelete
    Replies
    1. No, on non GI / Restart, I am afraid you have to rely on oraenv. This one reads the configuration from GI/Restart.

      Delete
  5. Hello

    Thanks a lot for your oraenv++ utility, for sharing it;
    What about license, can I use oraenv++ as is, or as base for my own script, without any conditions, or there is|are some condition(s)?
    I can't find license info at your oracle-scripts github-repo;

    Regards

    ReplyDelete
    Replies
    1. Hi,

      This is indeed something I have been thinking for a while; I will think about it realease it under a GPL licence so feel free to use it freely as much as you want.

      By the way, I have improved the performances significantly when listing all the databases in version 20211109 -- refresh it.

      Regards,

      Delete
    2. Hi,

      I made it GPLv3 so feel free to use it freely as much as you want.

      Regards,

      Delete
  6. to start with, love this script :-)

    Is it possible i discovered a small bug ? ;-)

    line 212
    export ORACLE_BASE=$(${ORACLE_HOME}/bin/orabase > /dev/null 2>&1)

    orabase is displaying the ORACLE_BASE, using the ORACLE_HOME.
    However output is redirected to /dev/null, so ORACLE_BASE is empty.

    [grid@xxxxx ~]$ . oraenv++ asm

    Database : asm
    ORACLE_HOME : /u01/app/19.14.0/grid
    ORACLE_BASE : <<------------------------- empty
    ORACLE_SID : +ASM1
    ORACLE_PDB_SID :
    sqlplus is : /u01/app/19.14.0/grid/bin/sqlplus

    ReplyDelete
    Replies
    1. So the below:
      export ORACLE_BASE=$(${ORACLE_HOME}/bin/orabase 2>/dev/null)

      Should fix the issue right ? Could you please test it and let me know? And I'll update the code accordingly.

      Thanks,

      Delete
    2. This is what i changed ( the numbers are the lines in vi )

      212 # 2022/04/19 export ORACLE_BASE=$(${ORACLE_HOME}/bin/orabase > /dev/null 2>&1)
      213 export ORACLE_BASE=$(${ORACLE_HOME}/bin/orabase )

      A question

      Do you think it's possible to add a '-list' option.
      To get an overview of what's on the node without having to ctrl-c, and offcourse no further action


      Delete
    3. Fixed !

      I don't get it, with no parameter oraenv++ will show you a list, correct ?

      Please send me an email if you want to discuss further on this.

      Delete
  7. i am getting below error in 19c
    [/tmp]
    oracle@******:abc1> . oraenv++
    -ksh: .[143]: local: not found [No such file or directory]

    Database SID ORACLE_HOME
    -ksh: .[132]: local: not found [No such file or directory]
    --
    1/ asm +ASM1 /grid/oracle/product/19
    2/ abc11 abc11 /oracle/product/1910
    -ksh: .[132]: local: not found [No such file or directory]

    ReplyDelete
  8. Thanks .. no issues after set to bash

    ReplyDelete
  9. Hi dear,

    First, congratulations for your work, the script is very useful.
    I would like to understand something, could you help me?

    In the environment where I am using oraenv++ I made a correction to an information in /etc/oratab, but this information does not reflect in oraenv++:

    oraenv++
    Database SID ORACLE_HOME
    -------------------------------------------------------------------
    1/ asm +ASM1 /u01/app/19.0.0.0/grid
    ...
    7/ sscp SSCP1 /u01/app/oracle/product/12.1.0.2/dbhome_8

    Updated oratab, with new path:

    SSCP:/u01/app/oracle/product/12.2.0/dbhome_10:N # line added by Agent
    SSCP1:/u01/app/oracle/product/12.2.0/dbhome_10:N # line added by Agent

    The oraenv++ continues to show the old info, why does not read this new info, friend?

    Please, where I can update this?

    Thank you.

    ReplyDelete
    Replies
    1. This is because the default oraenv is based on oratab that I wrote oraenv++ which is not based on oratab but on the cluster configuration. So you need to update your cluster configuration (srvctl) which is what you want to do as the cluster is what manages your databases resources (and not oratab) so it is important that these information are correct.

      Delete

OCI: Datapump between 23ai ADB and 19c ADB using database link

Now that we know how to manually create a 23ai ADB in OCI , that we also know how to create a database link between a 23ai ADB and a 19C AD...