Showing posts with label Oracle 11g R2. Show all posts
Showing posts with label Oracle 11g R2. Show all posts

Friday, August 12, 2011

Confused SRVCTL in Oracle 11g R2

OS: RHEL 5.5 64-bit

DB: Oracle Database 11gR2

Grid: Oracle Clusterware 11gR2

A database “adverten” is running on a Linux (64-bit) box. This database happens to be a two-node Oracle RAC database. The instance names of this database are “adverten1” and ““adverten2” respectively on the two nodes.

I ran the RACcheck tool but unfortunately it does not list this database. However other databases running on this server are listed.

Below is the excerpt from “raccheck” tool:

List of running databases registered in OCR

1. clonedb

2. frisdb

3. All

4. None

Believe me; the instance is there and running.

 
[oracle@node1 raccheck]$ ps -ef|grep pmon
grid      8585     1  0 Aug06 ?        00:00:17 asm_pmon_+ASM1
oracle   12351  8299  0 22:16 pts/7    00:00:00 grep pmon
oracle   21959     1  0 Aug09 ?        00:00:31 ora_pmon_clonedb1
oracle   24222     1  0 Aug09 ?        00:00:19 ora_pmon_adverten1
oracle   29006     1  0 Aug07 ?        00:00:32 ora_pmon_frisdb1
[oracle@node1 raccheck]$

It’s time to debug “raccheck” tool.

“is_rdbms_installed_crs ()” procedure of the “raccheck” script is of our interest for now and below are the statements from where it is actually fetching database names.

It grabs the list of databases using the following:

       $CRS/bin/srvctl config database > $db_list_fil

And checks for database status using the following:

 
crs_db_status=$($CRS/bin/srvctl status database -d $db_list|grep -i $loc	alnode|grep -ic "is running")

Okay, running the first command manually lists my database:

 
[grid@node1 ~]$ $CRS_HOME/bin/srvctl config database
advertence
clonedb
frisdb
[grid@node1 ~]$

If you notice, the database name listed above is “advertence” (10 letter word). The database name from V$DATABASE view is “adjudica” (8 letter word), also instances use “adverten”.

 
SQL> select name from v$database;

NAME
---------
ADJUDICA

SQL>

However, the second command could not locate the database instances:

[grid@node1 ~]$ $CRS_HOME/bin/srvctl status database -d advertence
Instance adverten1 is not running on node node1
Instance adverten2 is not running on node node2
[grid@node1 ~]$

Of course “adverten” is not registered resource. So the following will fail:

 
[grid@abis19 ~]$ $CRS_HOME/bin/srvctl status database -d adverten
PRCD-1120 : The resource for database adverten could not be found.
PRCR-1001 : Resource ora. adverten.db does not exist
[grid@abis19 ~]$

This is the reason “raccheck” is not able to list this database.

What might have happened is the question that needs to be answered.

At the time of database creation, “advertence” was keyed in as the database name. But Oracle created a database by trimming it to 8 characters and reserving 1 character for instance number. But for some reason “advertence” database resource was registered.

Apparently, the “ora. advertence.db” resource registered with the cluster is in “OFFLINE” state.

 
[grid@node1 ~]$ crs_stat  ora. advertence.db
NAME=ora. advertence.db
TYPE=ora.database.type
TARGET=OFFLINE
STATE=OFFLINE

[grid@node1 ~]$

It’s all messy here, but things are working.

I will have to create a Service Request with Oracle Support to resolve this issue for this client of mine.

Wednesday, March 16, 2011

Transpose Rows to Columns

In the old Oracle 8i days, transposing rows to columns was not straight forward. As Oracle Developer (working on Oracle Developer 2000), I remember writing a query using MAX and DECODE functions to transpose rows into columns for my previous employer. My efforts were applauded as this query replaced the old database stored procedure (function). Thanks to Tom Kyte for his wonderful asktom.oracle.com site.

Here’s a sample function which was then in use:

SQL> create or replace function test_func(p_deptno in emp.deptno%type)
  2    return varchar2 is
  3    cursor emp_cur is
  4       select deptno, ename
  5         from emp
  6        where deptno = nvl(p_deptno, deptno)
  7        order by ename;
  8    l_ename varchar2(500);
  9  begin
 10    for emp_rec in emp_cur loop
 11      l_ename := l_ename ||','|| emp_rec.ename;
 12    end loop;
 13    return(substr(l_ename, 2));
 14  end;
 15  /

Function created.

SQL>
SQL> column new_col format a50
SQL>
SQL>
SQL> select test_func(10) new_col from dual;

NEW_COL
--------------------------------------------------
CLARK,KING,MILLER

SQL> select test_func(20) new_col from dual;

NEW_COL
--------------------------------------------------
ADAMS,FORD,JONES,SCOTT,SMITH

SQL> select test_func(30) new_col from dual;

NEW_COL
--------------------------------------------------
ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

SQL>
SQL> select deptno, test_func(deptno) new_col
  2    from (select distinct deptno from emp)
  3    order by deptno;

    DEPTNO NEW_COL
---------- -----------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

SQL>
SQL>

I stumbled upon Analytic Functions that were introduced with Oracle 8i and came up with the following query:

SQL> select deptno, rtrim(new_col, ',') new_col
  2    from (select deptno,
  3                 max(decode ( rn , 1, ename || ',')) ||
  4                 max(decode ( rn , 2, ename || ',')) ||
  5                 max(decode ( rn , 3, ename || ',')) ||
  6                 max(decode ( rn , 4, ename || ',')) ||
  7                 max(decode ( rn , 5, ename || ',')) ||
  8                 max(decode ( rn , 6, ename )) new_col
  9            from (select ename, deptno,
 10                         row_number() over ( partition by deptno
 11                                             order by rownum) rn
 12                    from emp)
 13            group by deptno)
 14  order by deptno;

    DEPTNO NEW_COL
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 SMITH,JONES,SCOTT,ADAMS,FORD
        30 ALLEN,WARD,MARTIN,BLAKE,TURNER,JAMES

SQL>

The major drawback of the above query is the limitation of number of values it can display for the ENAME column. If a new employee joins department number “30” then this query has to be modified. This query was well suited for the environment where it was written as the number of values was known and were limited.

Then came Oracle 9i introducing SYS_CONNECT_BY_PATH function. The above limitations are overcome using this new function. It is capable of transposing “n” number of rows into columns. The same query can now be rewritten as:

SQL>
SQL> select deptno,
  2         max(substr(sys_connect_by_path (ename, ','),2)) new_col
  3   from (select deptno, ename,
  4                row_number() over (partition by deptno
  5                                    order by ename) rno
  6          from emp)
  7  start with rno = 1
  8  connect by rno = prior rno + 1
  9      and prior deptno = deptno
 10  group by deptno
 11  order by deptno;

    DEPTNO NEW_COL
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

SQL>

Well, so far so good. But Oracle 11g introduced LISTAGG function. This function makes life very easy. The query looks very simple, no hierarchies, no connect by ….

Here’s the new query:

SQL> 
SQL> select deptno,
  2         listagg(ename, ',') within group 
  3            (order by ename) new_col
  4    from emp
  5  group by deptno
  6  order by deptno;

    DEPTNO NEW_COL
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

SQL>

Isn’t it simple? Over the years Oracle has introduced tons of new features (like the one discussed here) that make life simple and at the same time making the code more performant.

The question is "are we really using these features efficiently?"

Saturday, November 27, 2010

Oracle Database 11g R2: Interactive Quick Reference

Oracle has released "Interactive Quick Reference" for DBA's and Developer's to better understand Oracle Database architecture. It includes

1) List of DBA Views,

2) Database Architecture Diagram, and

3) List of all Database Background Processes by category.

Click here to read more about it and click here to download it.