Sunday, 25 November 2012

Immuning code from SQL INJECTION Attacks (Part 1)

There are various methods of how the plsql coders write their code to avoid sql injection attacks, and here we will see some methods and tips of how we can really protect the code..

Native dynamic SQL code what i feel is actually little easy to read and write than the code that uses the DBMS_SQL package, and runs much faster specially when it can be optimized by the compiler. But thats not the point of our discussion, the point is that SQL injection is a pretty famous attack and we can avoid this with strict adherence to some basic coding practices....

Assuming that you know the concepts of dynamic sql and then bind arguments, and what oracle says you must use dynamic SQL and not only this using bind arguments protects us against SQL injection attacks. Using bind arguments also enables cursor sharing, and thus improves application performance.

If an interface is not available to an attacker, it is clearly not available to be abused. Thus the first, and arguably most important, line of defense is to reduce the exposed interfaces to only those absolutely required.

Be alert of the following rights :=

Use Definer's Right: When you want to provide users unrestricted access to a table or tables via a subprogram, create the subprogram with definer's right.

Use Invoker's Right: When the purpose of the subprogram is to perform a parameterized, but powerful, operation by using the privileges of the user that invokes it, create the subprogram with invoker's right. Using invoker's rights helps to limit the privileges, and thereby, minimize the security exposure. However, it is not sufficient as the sole measure for eliminating SQL injection vulnerabilities.

Invoker's rights helps to minimize the security exposure

For the following procedure if you give execute privilege to HR user lets say, HR user would only be able to change the password of any user including the user SYS only if he has the ALTER USER system privilege.

create or replace procedure change_password (p_username varchar2 default null,p_new_password varchar2 default null)
is
v_sql_stmt varchar2(500);
begin
v_sql_stmt := 'ALTER USER '||p_username||' IDENTIFIED BY '||p_new_password;
execute immediate v_sql_stmt;
end change_password;
/

How bind arguments should be used ? Basically complete protected code from sql injection attack can be achieved only through elimination of input string concatenation in dynamic SQL, so 1 should avoid input string concatenation and use bind arguments be it automatically through static SQL or explicitly through dynamic SQL statements. A basic code of how bind arguments are used is below :=

create or replace procedure sum_it_up
    ( a number, b number, c number)
    is
    begin
    dbms_output.put_line(a+b+c);
    end;
   /


  DECLARE
   x NUMBER := 2;
   y NUMBER := 5;
   plsql_block VARCHAR2(100);
  BEGIN
   plsql_block := 'BEGIN sum_it_up(:g, :g, :h); END;';
   EXECUTE IMMEDIATE plsql_block USING x, y;
 END;
 /

How to reduce the actual attack, below we will see how the code is not immune in the first go and then how the code is immune in the following 2 cases ( PROCEDURE GET_CODE), below is the table of citizens where humas have their social security number which is the most private number and shall be hidden or protected :=

SQL> create table citizens (fname varchar2(20),lname varchar2(20), s_security_num number);

Table created.

SQL> insert into citizens values ('karan','dodwal',10034007);

1 row created.

SQL> insert into citizens values ('ram','singh',10059991);

1 row created.

SQL> commit;

Commit complete.

--FIRST ORDER ATTACK

Now look how it is vulnuerable in the following code

create or replace procedure get_code (p_fname varchar2 default null)
is
type c is ref cursor;
cv c;
vcode citizens.s_security_num%type;
v_stmt varchar2(300);
begin
v_stmt := 'select s_security_num from citizens where fname='''||p_fname||'''';
dbms_output.put_line('sql query : '||v_stmt);
open cv for v_stmt;
loop
fetch cv into vcode;
exit when cv%notfound;
dbms_output.put_line('code is '||vcode);
end loop;
close cv;
exception when others then
dbms_output.put_line(sqlerrm);
dbms_output.put_line('sql query '||v_stmt);
end;
/

Social security number of only ram is printed in the following output

SQL> exec get_code('ram');
sql query : select s_security_num from citizens where fname='ram'
code is 10059991

PL/SQL procedure successfully completed.

But look below how the Social security number of KARAN is also printed without even knowing RAM or KARAN, just by dummy ''X''

SQL>  exec get_code('x'' union select s_security_num from citizens where ''x''=''x');
sql query : select s_security_num from t1 where fname='x' union select
s_security_num from t1 where 'x'='x'
code is 10034007
code is 10059991

ISNT IT REALLY BAD...

--PROTECTION

--Now see how it isnt vulnuerable in the following code because here we are avoiding the use of dynamic SQL with concatenated input values

create or replace procedure get_code (p_fname varchar2)
is
begin
for i in (select s_security_num from citizens where fname=p_fname)
 loop
dbms_output.put_line(i.s_security_num);
end loop;
end;
/

Social security number of only ram is printed in the following output

SQL> exec get_code('ram');
10059991

PL/SQL procedure successfully completed.

But look below how neither of Social security numbers are printed and attacker is defeated clearly

SQL>  exec get_code('x'' union select s_security_num from citizens where ''x''=''x');

PL/SQL procedure successfully completed.

In my subsequent posts i will share with you other protection mechanisms, but for the time being i wish you all happy thanks giving and also do note the following practices to observe when you secure the Oracle database:

1) Encrypt sensitive data so that it cannot be viewed.
 
2) Evaluate all PUBLIC privileges and revoke them where possible.

3) Do not widely grant EXECUTE ANY PROCEDURE.

4) Avoid granting privileges WITH ADMIN option.

5) Ensure that application users are granted minimum privileges by default. Make privileges configurable if necessary.

6) Do not allow wide access to any standard Oracle packages that can operate on the operating system. These packages include:
        UTL_HTTP, UTL_SMTP, UTL_TCP, DBMS_PIPE, UTL_MAIL, and UTL_FTP

7) Certain Oracle packages such as UTL_FILE and DBMS_LOB are governed by the privilege model of the Oracle DIRECTORY object. Protect Oracle DIRECTORY objects.

8) Lock the database default accounts and expire the default passwords.

9) Remove example scripts and programs from the Oracle directory.

10) Run the database listener as a nonprivileged user.

11) Ensure that password management is active.

12) Enforce password management. Apply basic password management rules, such as password length, history, and complexity, to all user passwords. Mandate that all the users change their passwords regularly.

13) Lock and expire the default user accounts and change the default user password.

Wednesday, 27 June 2012

Solution for connection time taking long in oracle

I was at the client side back in november 2011 and repeatingly the same month i got few queries, client was complaining that some times the connection to database take time and give time out error , how i can check this problem in database . so to begin with i looked at the contents of SQLNET.INBOUND_CONNECT_TIMEOUT parameter in sqlnet.ora file, in addition to that this is what was there in sqlnet.ora - NAMES.DIRECTORY_PATH= (TNSNAMES).

Getting more details i saw some parameter values and and process parameter is 1500 fore each node :=

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
java_max_sessionspace_size           integer     0
java_soft_sessionspace_limit         integer     0
license_max_sessions                 integer     0
license_sessions_warning             integer     0
logmnr_max_persistent_sessions       integer     1
session_cached_cursors               integer     20
session_max_open_files               integer     10
sessions                             integer     49
shared_server_sessions               integer

Sometimes what happens is that if you have a shared connection, and the instance has a dispatcher parameter set higher than needed, connection time is affected inversely(sometimes on the order of minutes). I faced such a problem in a big database and it was actually solved by reducing the max_dispatchers parameter. Moreover if you see above in the client's system the value for sessions parameter seems to be very low. Normally its calculated as Sessions = (1.1 * PROCESSES) + 5

Just to explain the above SQLNET.INBOUND_CONNECT_TIMEOUT parameter in details, we use it to specify the time, in seconds, for a client to connect with the database server and provide the necessary authentication information.

If the client fails to establish a connection and complete authentication in the time specified, then the database server terminates the connection. In addition, the database server logs the IP address of the client and an ORA-12170: TNS:Connect timeout occurred error message to the sqlnet.log file. The client receives either an ORA-12547: TNS:lost contact or an ORA-12637: Packet receive failed error message.

The default value of this parameter is appropriate for typical usage scenarios. However, if you need to explicitly set a different value, Oracle recommends setting this parameter in combination with the INBOUND_CONNECT_TIMEOUT_listener_name parameter in the listener.ora file. When specifying the values for these parameters, note the following 2 recommendations:

1) Set both parameters to an initial low value.

2) Set the value of the INBOUND_CONNECT_TIMEOUT_listener_name parameter to a lower value than the SQLNET.INBOUND_CONNECT_TIMEOUT parameter.

For example, you can set INBOUND_CONNECT_TIMEOUT_listener_name to 2 seconds and SQLNET.INBOUND_CONNECT_TIMEOUT parameter to 3 seconds. If clients are unable to complete connections within the specified time due to system or network delays that are normal for the particular environment, then increment the time as needed... Have a nice day




Saturday, 25 February 2012

Difference between a child cursor and a parent cursor?



For basic information every sql statement in library cache has a parent cursor , it has a handle which is used to search hash value in library cache hash chains for the cursor handle. Mostly it points to its child cursors which are created due to optimizer mismatch and offcourse if semantics are different but the syntax is same. Check them in v$SQL_SHARED_CURSOR why childrens are not being shared.

Every cursor (aka sql statements)  gets two cursors in the library cache. One parent and one child cursor. This is the implementation for cursor multi versioning.

Each child cursor is also comprised of a handle and an object. The child object is comprised of two heaps numbered 0 and 6. Heap 0 contains all the identifying information for a particular version of the SQL statement and heap 6 contains the execution plan. This distinction between parent and child cursors is maintained even when there is only one version of each SQL statement.

The parent cursor contains the SQL statement text only, but no execution plan. Execution plans are found in child cursors. Child cursors are also called versions. 

Let us consider a case: A SQL statement was executed first time, then it would get a parent and child. If the same sql statement was executed again (with no change to the body of SQL keeping the same hash_value ), with a different non-shareable attributes, then a new child cursor will be added to this parent cursor. As you can see, you can have many child cursors associated with a parent cursor. Non-shareable attributed includes : such as different optimizer_mode, different session parameters etc.

In the absence of adaptive cursor sharing you would see lot of child cursors getting created if cursor_sharing was set to similar, for each unique value in the presence of histogram because of data skew after bind variable value peeking. Even if the plan is same you would see a unique child cursor for a distinct value. Even the length of the bind can cause a new child cursor to be created.

I did a following test on my laptop running 11G R2 on Rhel 5 on VM

SQL>create table karan (id number)

Table created.

SQL> select * from karan;

no rows selected

SQL> select sql_id, sql_text, child_number,optimizer_mode,
plan_hash_value from v$sql where sql_text like 'select * from kar%';

SQL_ID
-------------
SQL_TEXT
----------------------------------------------------------------------------------------------------
CHILD_NUMBER OPTIMIZER_ PLAN_HASH_VALUE
------------ ---------- ---------------
c99yw1xkb4f1u
select * from karan
           0 ALL_ROWS        1357081020


SQL> col SQL_TEXT format a40
SQL> /

SQL_ID        SQL_TEXT                                 CHILD_NUMBER OPTIMIZER_ PLAN_HASH_VALUE
------------- ---------------------------------------- ------------ ---------- ---------------
c99yw1xkb4f1u select * from karan                                  0 ALL_ROWS        1357081020


SQL> select sql_id, sql_text, child_number,optimizer_mode,plan_hash_value from v$sql where sql_text like 'select * from kar%'

SQL_ID        SQL_TEXT                                 CHILD_NUMBER OPTIMIZER_ PLAN_HASH_VALUE
------------- ---------------------------------------- ------------ ---------- ---------------
c99yw1xkb4f1u select * from kar                                  0 ALL_ROWS        1357081020

SQL> show  parameter optimizer_mode

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_mode                       string      ALL_ROWS

SQL> alter session set optimizer_mode=first_rows;

Session altered.

SQL> select * from karan;

no rows selected

SQL> select sql_id, sql_text, child_number,optimizer_mode,plan_hash_value from v$sql where sql_text like 'select * from kar%'
  2  ;

SQL_ID        SQL_TEXT                                 CHILD_NUMBER OPTIMIZER_ PLAN_HASH_VALUE
------------- ---------------------------------------- ------------ ---------- ---------------
c99yw1xkb4f1u select * from karan                                  0 ALL_ROWS        1357081020
c99yw1xkb4f1u select * from karan                                  1 FIRST_ROWS      1357081020


SQL> select id+1 from karan;

no rows selected

SQL> select sql_id, sql_text, child_number,optimizer_mode,plan_hash_value from v$sql where sql_text like 'select id+1 from kar%';

SQL_ID        SQL_TEXT                                 CHILD_NUMBER OPTIMIZER_ PLAN_HASH_VALUE
------------- ---------------------------------------- ------------ ---------- ---------------
0nxtnbrbf48rc select id+1 from karan                               0 FIRST_ROWS      1357081020

SQL> select id+1 from karan;

no rows selected

SQL> select sql_id, sql_text, child_number,optimizer_mode,plan_hash_value from v$sql where sql_text like 'select id+1 from kar%';

SQL_ID        SQL_TEXT                                 CHILD_NUMBER OPTIMIZER_ PLAN_HASH_VALUE
------------- ---------------------------------------- ------------ ---------- ---------------
0nxtnbrbf48rc select id+1 from karan                               0 FIRST_ROWS      1357081020

Saturday, 10 December 2011

RAC DBA ESSENTIALS For Starters


Oracle clusterware is a portable cluster infrastructure that provides High Availability(HA) to RAC databases and other applications. Here a cluster is a collection of two or more nodes where they share a common pool of storage used by Oracle clusterware system files (OCR and Voting disk), a common network interconnect, and a common operating system.

VOTING DISK

The primary purpose of voting disk is to help in situations where private network communication fail. So the voting disk is used to communicate the node state information used to determine which nodes will go offline.

OCR

The Oracle Cluster Registry (OCR) file is also a key component of oracle clusterware. It maintains information about high availability components in your cluster, such as the voting file is essentially used by Cluster synchronization services daemon for node-cluster node list , cluster database instance to node mapping, and CRS application resource profiles (such as services, Virtual interconnect protocol addresses and so on). This file is maintained by administrative tools such as SRVCTL. Its size is around 100 MB.

Oracle Clusterware Run-Time View

On UNIX, oracle clusterware stack is run from entries in /etc/inittab with respawn. Here is a basic description of each process :

Cluster Synchronization Service Daemon (OCSSD) : This process runs in both vendor clusterware and nonvendor clusterware environments. It integrates with existing vendor clusterware, when present. OCSSD's primary job is internode hea;th monitoring, primarily using the network interconnect as well as voting disks, and database/ASM instance endpoint discovery via group services. OCSSD runs as oracle user, and failure exit causes machine reboot to prevent data corruption in the event of a split brain.

Process Monitor Daemon (OPROCD) = This process is spawned in any nonvendor clusterware environment. If OPROCD detects problems, it kills a node. And yes it runs as root. This daemon is used to detect hardware and driver freezes on the machine. If a machine was frozen long enough for the other nodes to evict it from the cluster, it needs to kill itself to prevent any I/O from being reissued to the disk after the rest of the cluster has remastered locks.

Cluster ready services daemon (CRSD) : This process is the engine for High Availability operations.It manages Oracle clusterware registered applications and starts, stops, check and fails them over via special action scripts. CRSD spawns dedicated process called RACGIMON that monitor the health of the database and ASM instances and host various feature threads such as Fast Application Notification (FAN). One RACGIMON process is spawned for each instance. CRSD maintains configuration profiles as well as resource statuses in OCR (Oracle Cluster Registry). It runs as root and restarted automatically on failure. In addition, CRSD can spawn temporary children to execute particular actions such as : racgeut (execute under time), racgmd (Manage database), racgchsn (Change service Name), racgons (to add/remove ONS configuration to OCR), racgvip: to start/stop/check instance virtual IP.

Event management daemon (EVMD): This process forwards cluster events when things happen. It spawns a permanent child evmlogger that, on demand , spawns children such as racgevtf to invoke callouts. It runs as oracle, and is restarted automatically on failure.

NOTE :- The RACG infrastructure is used to deploy the oracle database in highly available clustered enviroment. This infrastructure in mainly implemented using the racgwrap script that invokes the racgmain program. It is used by CRS to execute actions for all node-centric resources as well as to proxy actions for all instance-centric resources to RACGIMON. Basically, this infrastructure is responsible for managing all ora.* resources.


GCS

Global Cache Service processes (GCS) are processes that, when spawned by Oracle, copy blocks directly from the holding instance's buffer cache and send a read consistent copy of the block to the requesting foreground process on the requesting instance to be placed into the buffer cache. GCS rolls back any uncommitted transactions for any blocks that are being requested for consistent read by the remote instance.

RAC software provides for up to 10 GCS processes (0 thru 9), depending on the amount of messaging traffic. However, there is, by default, one GCS process per pair of CPU. In general, the number of GCS processes varies depending on the amount of messaging traffic amongst nodes in the cluster. Note: Global Cache Services (GCS) were called Lock Manager Services (LMS) in Oracle Parallel Server (OPS).


Oracle 10g added a new initialization parameter called gcs_server_processes. This parameter allows you to set the number of GCS processes that are started to handle interconnect traffic. The default is 2, but can be increased on a per node basis if required.


CGS

Cluster Group Services (CGS) is a background process that monitors the entire cluster to manage global resources. By constantly probing the other instances, it checks and manages instance deaths and the associated recovery for GCS. When a node joins or leaves the cluster, it handles reconfiguration of locks and resources. In particular, CGS handles the part of recovery associated with global resources. Note: Cluster Group Services was called Lock Manager Monitor in OPS.

GES

Global Enqueue Service Daemon is a background agent process that manages requests for resources to control access to blocks and global enqueues. It manages lock manager service requests for GCS resources and sends them to a service queue to be handled by the GCS process. The GES process also handles global deadlock detection and remote resource requests (remote resource requests are requests originating from another instance).

LCK

The Lock Process (LCK) manages non-cache fusion resource requests such as library and row cache requests and lock requests that are

local to the server. LCK manages instance resource requests and cross-instance call operations for shared resources. It builds a list of invalid lock elements and validates lock elements during recovery. Because the LMS process handles the primary function of lock management, only a single LCK process exists in each instance. There is only one LCK process per instance in RAC.

DIAG

The Diagnosability Daemon (DIAG) background process monitors the health of the instance and captures diagnostic data about process failures within instances. The operation of this daemon is automated and updates an alert log file to record the activity that it performs.

Oracle 11g Processes

In addition, Oracle 11g added the following new processes:

ACMS: The Atomic Controlfile to Memory Service (ACMS) process insures SGA memory updates are updated on all nodes or none.

GTX: The Global Transaction Process supports XA transactions within RAC.

RMS: The RAC Management Process creates resources that allow new database instances to be added to the cluster.

RSM: The remote slave monitor creates slave processes for processes running on other RAC instances within the cluster.

Wednesday, 23 November 2011

Actual use of Active Session History (ASH)

Active Session History (ASH) was introduced in Oracle 10g. It samples the activity of each active1 database session every second. The data is held in a buffer in memory in the database. The design goal is to keep about an hour (your mileage will vary).
If a session is not active it will not be sampled. The in-memory buffer is exposed via a view called v$active_session_history. But yes if you want inactive sessions also to be sampled you can set the parameter _ash_enable_all = TRUE.

When an AWR snapshot is taken, 1 row in 10 from the ASH buffer is copied down into the AWR repository. It can also be flushed to disk between snapshots when the buffer reaches 66% full, so there is no missed data.The data is stored in WRH$_ACTIVE_SESSION_HISTORY and it is exposed via dba_hist_active_sess_history.

The main components of the ASH are
- 2 background procresses, MMON and MMNL,
- a rolling buffer, which sits in the SGA fixed area and holds the historical statistical information of active sessions

ASH is enabled by default, but before you rush off to use it, be aware that it is a licenced feature. It is part of the Diagnostic Pack, so you have to pay for it. I don’t like that either, but that’s how it is.

The ASH will auto-configure itself to try and hold at least one-hour worth of instance activity without wasting too much value SGA space and will never be bigger than 5% of SGA_TARGET or 5% of SHARED_POOL (if AutoSGA is not used)". ASH memory represents 2MB of memory per CPU, ASH cannot exceed 5% of shared pool and 5% of SGA_TARGET.

Comparison of ASH with SQL TRACE

ASH and SQL*Trace are not the same thing, but both are valuable tools for finding out about where processes spend time. SQL*Trace (or event 10046 as we used to call it) has been my weapon of choice for solving performance issues for a very long time, and it is extremely effective, and there is still a place for it.

There are difficulties with using SQL trace, especially in a production environment.

Firstly, it does have a run time overhead. You could afford to trace a single process, but you certainly couldn’t trace the entire database.

1) You have to work with trace in a reactive way. You will probably not already be tracing a process when you experience a performance problem, so you need to run the process again and reproduce the poor performance with trace.

2) Trace will tell you if a session is blocked waiting on a lock. However, it will not tell you who is blocking you. ASH will do this (although there are limitations).

3) A trace file records everything that happens in a session, whereas ASH data samples the session every seconds. Short-lived events will be missed, so the data has to be handled statistically.

4) There are problems with both approaches if you have the kind of application where you have lots of different SQL statements because the application uses literal values rather than bind variables (and cursor sharing is EXACT).

5) Oracle’s TKPROF trace file profiler cannot aggregate these statements, but I have found another called ORASRP  www.oracledba.ru/orasrp) that can. With ASH, you will see different SQL_IDs, but it can be effective to group statements with the same execution plan.

6) You may have trouble finding the SQL text in the SGA (or via the DBMS_XPLAN package) because it has already been aged out of the library cache. You may have similar problems with historical ASH data because the statement had been aged out when the AWR snapshot was taken.

7) A trace file, with STATISTICS_LEVEL set to ALL, will give you timings for each operation in the execution plan. So, you can see where in the execution plan the time was spent. ASH will only tell you how long the whole statement takes to execute, and how long was spent on which wait event.

Application Instrumentation

Oracle has provided a package called DBMS_APPLICATION_INFO since at least Oracle 8. This allows you to set two attributes; MODULE and ACTION for a session. That value then appears in v$session, and can be very useful to help you identify what database sessions relate to what part of an application. These values are then also captured by ASH. I cannot over-emphasise the importantance of this instrumentation when analysing performance issues. Without sensible values in these columns all you have is the program
name. You will probably struggle to identify ASH data for the sessions which are of interest. These values are not set by default. Instead DBAs are dependent on developers to include them in their code. For example, Oracle E-Business Suite has built this into the application.

Following query fetchs top sqls spent more on cpu/wait/io. (Thanks to Kyle Hailey for this script):

select
ash.SQL_ID ,
sum(decode(ash.session_state,'ON CPU',1,0)) "CPU",
sum(decode(ash.session_state,'WAITING',1,0)) -
sum(decode(ash.session_state,'WAITING', decode(en.wait_class, 'User I/O',1,0),0)) "WAIT" ,
sum(decode(ash.session_state,'WAITING', decode(en.wait_class, 'User I/O',1,0),0)) "IO" ,
sum(decode(ash.session_state,'ON CPU',1,1)) "TOTAL"
from v$active_session_history ash,v$event_name en
where SQL_ID is not NULL and en.event#=ash.event#

Tuesday, 22 November 2011

I/O Calibration Workaround

The I/O calibration feature of Oracle Database enables you to assess the performance of the storage subsystem, and determine whether I/O performance problems are caused by the database or the storage subsystem. Unlike other external I/O calibration tools that issue I/Os sequentially, the I/O calibration feature of Oracle Database issues I/Os randomly using Oracle data files to access the storage media, producing results that more closely match the actual performance of the database.

Oracle Database also provides Orion, an I/O calibration tool. Orion is a tool for predicting the performance of an Oracle database without having to install Oracle or create a database. Unlike other I/O calibration tools, Oracle Orion is expressly designed for simulating Oracle database I/O workloads using the same I/O software stack as Oracle. Orion can also simulate the effect of striping performed by Oracle Automatic Storage Management.

Prerequisites of I/O calibration :=
1) The user must be granted the SYSDBA privilege
2) timed_statistics must be set to TRUE
3) Asynchronous I/O must be enabled
4) When using file systems, asynchronous I/O can be enabled by setting the FILESYSTEMIO_OPTIONS initialization parameter to SETALL.
5) Ensure that asynchronous I/O is enabled for data files by running the following query:
SELECT NAME,ASYNCH_IO FROM V$DATAFILE F,V$IOSTAT_FILE I WHERE  F.FILE#=I.FILE_NO AND FILETYPE_NAME='Data File';

SOME OVERVIEW OF ORION TOOL

Oracle Orion is a tool for predicting the performance of an Oracle database without having to install Oracle or create a database. Unlike other I/O calibration tools, Oracle Orion is expressly designed for simulating Oracle database I/O workloads using the same I/O software stack as Oracle. Orion can also simulate the effect of striping performed by Oracle Automatic Storage Management.

Orion Test Targets

You can use Orion to test any disk-based character device that supports asynchronous I/O. Orion has been tested on the following types of targets:
1) DAS (direct-attached) storage: You can use Orion to test the performance of one or more local disks, volumes, or files on the local host.
2) SAN (storage-area network) storage: Orion can be run on any host that has all or parts of the SAN storage mapped as character devices. The devices can correspond to striped or un-striped volumes exported by the storage array(s), or individual disks, or one or more whole arrays.
3) NAS (network-attached storage): You can use Orion to test the performance on data files on NAS storage. In general, the performance results on NAS storage are dependent on the I/O patterns with which the data files have been created and updated. Therefore, you should initialize the data files appropriately before running Orion.

For each type of workload , Orion can run tests using different I/O loads to measure performance metrics such as MBPS, IOPS, and I/O latency. Load is expressed in terms of the number of outstanding asynchronous I/Os. Internally, for each such load level, the Orion software keeps issuing I/O requests as fast as they complete to maintain the I/O load at that level. For random workloads, using either large or small sized I/Os, the load level is the number of outstanding I/Os. For large sequential workloads, the load level is a combination of the number of sequential streams and the number of outstanding I/Os per stream. Testing a given workload at a range of load levels can help you understand how performance is affected by load.

Note the following when you use Orion:
1) Run Orion when the storage is idle (or pretty close to idle). Orion calibrates the performance of the storage based on the I/O load it generates; Orion is not able to properly assess the performance if non-Orion I/O workloads run simultaneously.
2) If a database has been created on the storage, the storage can alternatively be calibrated using the PL/SQL routine dbms_resource_manager.calibrate_io().








Thursday, 26 May 2011

ORACLE CURSORS BASICS


An SQL cursor is nothing but an area in user session memory which contains data about a specific statement. An SQL cursor actually has 2 parts.. The first heap which contains library cache metadata and second heap which is a larger heap contains executable representation of the cursor (usually called SQLAREA). Each heap is comprised of one or more chunks of memory.

SQL AREA can be thought of as a handle which points to a private sql area in UGA and the further pointing to the shared SQL area. All SQL cursors are allocated in 4K chunks. The bigger the cursor the more 4K chunks are allocated. An open cursor has already been parsed and the cursor handle is in library cache.

If the cursor is not in shared pool obviosuly it has to be reconstructed (hard parse) which requires a shared pool and library cache latch. A soft parse is preferable to a hard parse because the database skips the optimization and row source generation steps, proceeding straight to execution.

To reduce the mount of latching in your database DBA's configure a session cursor cache which contains instantiation of shared child cursors (closed session cursors) so that repeatable statements can reuse these cursors. You can store the reusable cursors in this session cursor cache. And the parameter session_cached_Cursors is independent of open_cursors. That means you can keep it higher than open_cursors because session cursors are not cached in open state. In 11G R2 default value of open_cursor is 300 and for session_Cached_cursors is 50

When the statement is in library cache, the associated cursor for the statement is placed on a hash chain. All these cursor handles are in shared pool inside hash chains. The parsing procedure actually has the following workings :=

1) find and execute an open cursor
2) Find a closed cursor in session cursor cache
3) search the hash chains for a soft parse
4) Construct the cursor (hard parse)

A Cursor is a handle to a specific PRIVATE SQL AREA. PRIVATE SQL AREA which is in the UGA keeps information about a parsed sql statement and session specific information for processing. When a statement is executed the process uses private sql area to store bind variable values, query execution work area and so on...
A Shared SQL area is different from private sql area. The shared sql area is in library cache containing execution plans in the SGA.

In the context of PL/SQL, the following is a notion of cursors

STATIC CURSORS

Static cursors are normal cursors like (explicit and implicit). For explicit cursors...A cursor is a mechanism by which you can assign a name to a "select statement" and manipulate the information within that SQL statement. A programmer can open, fetch data, close and check attributes of this kind of cursor.

Implicit cursors are more fast and they have less coding effort. And this one will never raise INVALID_CURSOR error and it cannot be opened outside the statement.

DYNAMIC CURSORS

Ref CURSORS created only when it is opened. A REF CURSOR is basically a data type.  A variable created based on such a data type is generally called a cursor variable.  A cursor variable can be associated with different queries at run-time.  The primary advantage of using cursor variables is their capability to pass result sets between sub programs (like stored procedures, functions, packages etc....)