Monday, January 18, 2010

VIP, Dataguard Broker & RAC

In a RAC environment if VIP isn't used for client connection, it will defeat the whole purpose of using VIPs which give fast notification when a node fails. If not have to wait until a TCP timeout occurs which could take a while.

In RAC if the default listener is on port of 1521, then DBCA will not automatically set
the LOCAL_LISTENER. However it will default to a connection string that refers to the physical host address (not virtual address).

Oracle 11.1.0.7 and above has a new dataguard broker parameter StaticConnectIdentifier StaticConnectIdentifier configurable instance-specific property specifies the connection identifier that the DGMGRL client will use when starting database instances. The default value for this is the concatenation of The ADDRESS attribute value of the listener that is specified for the LOCAL_LISTENER initialization parameter and the value for the SERVICE_NAME attribute will be set to a concatenation of db_unique_name_DGMGRL.db_domain.

Therefore if LOCAL_LISTENER is not set explicitly for VIP address it will use the physical host address. Could be observed with

DGMGRL> show instance "TBXA04B1" StaticConnectIdentifier
StaticConnectIdentifier =
'(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=hostname)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=TBXA04B_DGMGRL)(INSTANCE_NAME=TBXA04B1)(SERVER=DEDICATED)))'


Always better to explicitly set the LOCAL_LISTENER to VIP.

StaticConnectIdentifier is added to 11.1 with the patchset of 11.1.0.7. Documentation of it is available with 11.2

Thursday, December 17, 2009

upgrade 11g R1 to 11g R2 without DBUA

1. update the timezone file for ease, refere

2. then follow the same step as in 10g to 11g

3. Few modifications

instead of utlu111i.sql use utlu112i.sql,
utlu111s.sql use utlu112s.sql



Find out about the invalid views with
SELECT count(*) FROM dba_invalid_objects;
SELECT distinct object_name FROM dba_invalid_objects;

Wednesday, December 2, 2009

Result Cache for Ref Cursor returning PL/SQL codes

According to Oracle documentation if a PL/SQL SP is returning a ref cursor then result cache is not supported. But there's a way to circumvent with somewhat beneficial results.

Below is a package written for the HR sample schema

create or replace package emps_pkg as

type detail is ref cursor;

function getempdetails (options in INTEGER, departname in VARCHAR2, jobtitle in VARCHAR2) return detail;

end;
/


create or replace package body emps_pkg as

function getempdetails(options in INTEGER,departname in VARCHAR2, jobtitle in VARCHAR2) return detail is

employees detail;
main_query VARCHAR2(2000) := 'select /*+ result_cache */ e.* from employees e,departments d,jobs j
where e.department_id = d.department_id and j.job_id = e.job_id ';
begin
if options = 1 then
main_query := main_query ||'and d.department_name=:1';
open employees for main_query using departname;

return employees;

else
main_query := main_query ||'and j.job_title=:1';

open employees for main_query using jobtitle;

return employees;
end IF ;
end;
end;
/


Package body contains some dynamic sql (there's no real logic behind this package only to demonstrate the use of result cache) which is constructed with the result_cache hint.

execute the package code and observe the plan


select emps_pkg.getempdetails(2,'Purchasing','Purchasing Manager') from dual;
select * from table(dbms_xplan.display_cursor(null,null,'ALL'));

Plan hash value: 980169617

------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | RESULT CACHE | a68hth9dfygb5ddg0hr8hnty9b | | | | |
| 2 | NESTED LOOPS | | | | | |
| 3 | NESTED LOOPS | | 6 | 570 | 4 (0)| 00:00:01 |
|* 4 | TABLE ACCESS FULL | JOBS | 1 | 27 | 3 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | EMP_JOB_IX | 6 | | 0 (0)| |
|* 6 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 6 | 408 | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------


Recompile the package body without the result cache hint and observe the plan and it would be

Plan hash value: 980169617

-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 6 | 570 | 4 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | JOBS | 1 | 27 | 3 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | EMP_JOB_IX | 6 | | 0 (0)| |
|* 5 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 6 | 408 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------


The benefit comes from the fact the sql query inside the SP could use the result cache. But the overhead of executing the PL/SQL code is still there which I believe won't be present in "proper" result cached SPs.

Any changes to depending tables will make the cache invalid just like the expected behavior.