Thursday, March 6, 2014

Formatted CRSCTL output for oracle 11gR2

Formatted CRSCTL output for oracle 11gR2:

crsctl status res |grep -v "^$"|awk -F "=" 'BEGIN {print " "} {printf("%s",NR%4 ? $2"|" : $2"\n")}'|sed -e 's/ *, /,/g' -e 's/, /,/g'|  awk -F "|" 'BEGIN { printf "%-40s%-35s%-20s%-50s\n","Resource Name","Resource Type","Target ","State" }{ split ($3,trg,",") split ($4,st,",")}{for (i in trg) {printf "%-40s%-35s%-20s%-50s\n",$1,$2,trg[i],st[i]}}'


Tuesday, February 4, 2014

ORA-01031 on CREATE MATERIALIZED VIEW

ORA-01031 on CREATE MATERIALIZED VIEW
I had a weird problem  today,
 I tried to create an Materialized view on an application user from sys user and faced ORA-01031 error.
When issuing a CREATE MATERIALIZED VIEW statement for a different schema (as DBA), one might encounter the following error:
SQL> CREATE MATERIALIZED VIEW rshankar.test_mv AS SELECT * FROM dual;
CREATE MATERIALIZED VIEW rshankar.test_mv AS SELECT * FROM dual
                                                         *
ERROR at line 1:
ORA-01031: insufficient privileges
For our setup let’s assume we have two users:
·         User SYS (has the DBA privilege and is used to setup the DB server)
·         User RSHANKAR (schema owner)
We want to use the SYS user to create the objects for the schema RSHANKAR. This is a standard approach to seperate the deployment user from the actual schema owner. So let’s create these two users and grant the privileges (DBA for the deployment user, CONNECT and RESOURCE for the schema owner):
SQL> CREATE USER RSHANKAR IDENTIFIED BY test123;

User created.

SQL> GRANT RESOURCE, CONNECT TO rshankar;

Grant succeeded.

SQL> ALTER USER rshankar QUOTA 100M ON users;

User altered.

SQL> GRANT CREATE MATERIALIZED VIEW TO rshankar;

Grant succeeded.
So far, so good. The user SYS  has all the privileges that come with the DBA role and the user RSHANKAR has a limited set of privileges due to the RESOURCE and CONNECT roles. In addition to those roles, we want to grant CREATE MATERIALIZED VIEW to our schema owner.
Now let’s see what happens when we try to issue the statement as the deployment user (SYS):
SQL> connect sys as sysdba
Enter password:
Connected.
SQL> CREATE MATERIALIZED VIEW rshankar.test_mv AS SELECT * FROM dual;
CREATE MATERIALIZED VIEW rshankar.test_mv AS SELECT * FROM dual
                                                         *
ERROR at line 1:
ORA-01031: insufficient privileges
SYS have the DBA privileges, so the problem must be that RSHANKAR does not have the correct privileges! So let’s try with the user RSHANKAR:
SQL> connect rshankar
Enter password:
Connected.
SQL> CREATE MATERIALIZED VIEW test_mv AS SELECT * FROM dual;

Materialized view created.
Now the confusion is complete. Why can I create the materialized view while connected as RSHANKAR, but not create the same view when connected as SYS? The user SYS has higher privileges than the user RSHANKAR, so that should not happen! It turns out that this is expected behaviour (MOS Doc 749112.1).
To solve the mystery, grant the CREATE TABLE privilege directly to the schema owner:
SQL> GRANT CREATE TABLE TO rshankar;

Grant succeeded.
Now the CREATE MATERIALIZED VIEW statement works as expected:
SQL> connect sys as sysdba
Enter password:
Connected.
SQL> CREATE MATERIALIZED VIEW rshankar.test_mv AS SELECT * FROM dual;

Materialized view created.


This solve my problem J

Friday, December 14, 2012


Oracle SQL TUNING ADVISOR

Oracle allows the optimizer to run in tuning mode where it can gather additional information and make recommendations about how specific statements can be tuned further.
In tuning mode the optimizer performs the following analysis:
1) Statistics Analysis - The optimizer recommends the gathering of statistics on objects with missing or stale statistics. Additional statistics for these objects are stored in an SQL profile.
2) SQL Profiling - The optimizer may be able to improve performance by gathering additional statistics and altering session specific parameters such as the OPTIMIZER_MODE.
 If such improvements are possible the information is stored in an SQL profile.
 If accepted this information can then used by the optimizer when running in normal mode.
 Unlike a stored outline which fixes the execution plan, an SQL profile may still be of benefit when the contents of the table alter drastically.
 Even so, it's sensible to update profiles periodically. The SQL profiling is not performed when the tuining optimizer is run in limited mode.
3) Access Path Analysis - The optimizer investigates the effect of new or modified indexes on the access path.
 It's index recommendations relate to a specific statement so where necessary it will also suggest the use of the SQL Access Advisor to check the impact of these indexes on a representative SQL workload.
SQL Structure Analysis - The optimizer suggests alternatives for SQL statements that contain structures that may impact on performance.
 The implementation of these suggestions requires human intervention to check their validity.


SQL Tuning Advisor
In order to access the SQL tuning advisor API a user must be granted the ADVISOR privilege:

CONN sys/password AS SYSDBA
GRANT ADVISOR TO scott;
CONN scott/tiger
The first step when using the SQL tuning advisor is to create a new tuning task using the CREATE_TUNING_TASK function.
The statements to be analyzed can be retrieved from the Automatic Workload Repository (AWR), the cursor cache, an SQL tuning set or specified manually:

SET SERVEROUTPUT ON

-- Tuning task created for specific a statement from the AWR.
DECLARE
  l_sql_tune_task_id  VARCHAR2(100);
BEGIN
  l_sql_tune_task_id := DBMS_SQLTUNE.create_tuning_task (
                          begin_snap  => 764,
                          end_snap    => 938,
                          sql_id      => '19v5guvsgcd1v',
                          scope       => DBMS_SQLTUNE.scope_comprehensive,
                          time_limit  => 60,
                          task_name   => '19v5guvsgcd1v_AWR_tuning_task',
                          description => 'Tuning task for statement 19v5guvsgcd1v in AWR.');
  DBMS_OUTPUT.put_line('l_sql_tune_task_id: ' || l_sql_tune_task_id);
END;
/

-- Tuning task created for specific a statement from the cursor cache.
DECLARE
  l_sql_tune_task_id  VARCHAR2(100);
BEGIN
  l_sql_tune_task_id := DBMS_SQLTUNE.create_tuning_task (
                          sql_id      => '19v5guvsgcd1v',
                          scope       => DBMS_SQLTUNE.scope_comprehensive,
                          time_limit  => 60,
                          task_name   => '19v5guvsgcd1v_tuning_task',
                          description => 'Tuning task for statement 19v5guvsgcd1v.');
  DBMS_OUTPUT.put_line('l_sql_tune_task_id: ' || l_sql_tune_task_id);
END;
/

-- Tuning task created from an SQL tuning set.
DECLARE
  l_sql_tune_task_id  VARCHAR2(100);
BEGIN
  l_sql_tune_task_id := DBMS_SQLTUNE.create_tuning_task (
                          sqlset_name => 'test_sql_tuning_set',
                          scope       => DBMS_SQLTUNE.scope_comprehensive,
                          time_limit  => 60,
                          task_name   => 'sqlset_tuning_task',
                          description => 'Tuning task for an SQL tuning set.');
  DBMS_OUTPUT.put_line('l_sql_tune_task_id: ' || l_sql_tune_task_id);
END;
/

-- Tuning task created for a manually specified statement.
DECLARE
  l_sql               VARCHAR2(500);
  l_sql_tune_task_id  VARCHAR2(100);
BEGIN
  l_sql := 'SELECT e.*, d.* ' ||
           'FROM   emp e JOIN dept d ON e.deptno = d.deptno ' ||
           'WHERE  NVL(empno, ''0'') = :empno';

  l_sql_tune_task_id := DBMS_SQLTUNE.create_tuning_task (
                          sql_text    => l_sql,
                          bind_list   => sql_binds(anydata.ConvertNumber(100)),
                          user_name   => 'scott',
                          scope       => DBMS_SQLTUNE.scope_comprehensive,
                          time_limit  => 60,
                          task_name   => 'emp_dept_tuning_task',
                          description => 'Tuning task for an EMP to DEPT join query.');
  DBMS_OUTPUT.put_line('l_sql_tune_task_id: ' || l_sql_tune_task_id);
END;
/
If the TASK_NAME parameter is specified it's value is returned as the SQL tune task identifier.
If ommitted a system generated name like "TASK_1478" is returned.
If the SCOPE parameter is set to scope_limited the SQL profiling analysis is omitted.
The TIME_LIMIT parameter simply restricts the time the optimizer can spend compiling the recommendations.

The following examples will reference the last tuning set as it has no external dependancies other than the SCOTT schema.
The NVL in the SQL statement was put in to provoke a reaction from the optimizer.
In addition we can delete the statistics from one of the tables to provoke it even more:

EXEC DBMS_STATS.delete_table_stats('SCOTT','EMP');

With the tuning task defined the next step is to execute it using the EXECUTE_TUNING_TASK procedure:

EXEC DBMS_SQLTUNE.execute_tuning_task(task_name => 'emp_dept_tuning_task');

During the execution phase you may wish to pause and restart the task, cancel it or reset the task to allow it to be re-executed:

-- Interrupt and resume a tuning task.
EXEC DBMS_SQLTUNE.interrupt_tuning_task (task_name => 'emp_dept_tuning_task');
EXEC DBMS_SQLTUNE.resume_tuning_task (task_name => 'emp_dept_tuning_task');

-- Cancel a tuning task.
EXEC DBMS_SQLTUNE.cancel_tuning_task (task_name => 'emp_dept_tuning_task');

-- Reset a tuning task allowing it to be re-executed.
EXEC DBMS_SQLTUNE.reset_tuning_task (task_name => 'emp_dept_tuning_task');

The status of the tuning task can be monitored using the DBA_ADVISOR_LOG view:

SELECT task_name, status FROM dba_advisor_log WHERE owner = 'SCOTT';

TASK_NAME                      STATUS
------------------------------ -----------
emp_dept_tuning_task           COMPLETED

1 row selected.

Once the tuning task has executed successfully the recommendations can be displayed using the REPORT_TUNING_TASK function:

SET LONG 10000;
SET PAGESIZE 1000
SET LINESIZE 200
SELECT DBMS_SQLTUNE.report_tuning_task('SYS_AUTO_SPCADV_19292320092012') AS recommendations FROM dual;
SET PAGESIZE 24In this case the output looks like this:

RECOMMENDATIONS
--------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name   : emp_dept_tuning_task
Scope              : COMPREHENSIVE
Time Limit(seconds): 60
Completion Status  : COMPLETED
Started at         : 05/06/2004 09:29:13
Completed at       : 05/06/2004 09:29:15

-------------------------------------------------------------------------------
SQL ID  : 0wrmfv2yvswx1
SQL Text: SELECT e.*, d.* FROM   emp e JOIN dept d ON e.deptno = d.deptno
          WHERE  NVL(empno, '0') = :empno

-------------------------------------------------------------------------------
FINDINGS SECTION (2 findings)
-------------------------------------------------------------------------------

1- Statistics Finding
---------------------
  Table "SCOTT"."EMP" and its indices were not analyzed.

  Recommendation
  --------------
    Consider collecting optimizer statistics for this table and its indices.
    execute dbms_stats.gather_table_stats(ownname => 'SCOTT', tabname =>
            'EMP', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
            method_opt => 'FOR ALL COLUMNS SIZE AUTO', cascade => TRUE)

  Rationale
  ---------
    The optimizer requires up-to-date statistics for the table and its indices in order to select a good execution plan.

2- Restructure SQL finding (see plan 1 in explain plans section)
----------------------------------------------------------------
  The predicate NVL("E"."EMPNO",0)=:B1 used at line ID 2 of the execution plan
  contains an expression on indexed column "EMPNO". This expression prevents
  the optimizer from selecting indices on table "SCOTT"."EMP".

  Recommendation
  --------------
    Rewrite the predicate into an equivalent form to take advantage of indices. Alternatively, create a function-based index on the expression.

  Rationale
  ---------
    The optimizer is unable to use an index if the predicate is an inequality condition or if there is an expression or an implicit data type conversion on the indexed column.

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

1- Original
-----------
Plan hash value: 1863486531

----------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |     1 |   107 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |         |     1 |   107 |     4   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL          | EMP     |     1 |    87 |     3   (0)| 00:00:01 |
|   3 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |
|   4 |    INDEX UNIQUE SCAN         | PK_DEPT |     1 |       |     0   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement

-------------------------------------------------------------------------------


1 row selected.

Once the tuning session is over the tuning task can be dropped using the DROP_TUNING_TASK procedure:

exec DBMS_SQLTUNE.drop_tuning_task (task_name => 'emp_dept_tuning_task');

Managing SQL Profiles

To manage SQL profiles a user needs the following privileges:

CONN sys/password AS SYSDBA

GRANT CREATE ANY SQL PROFILE TO scott;
GRANT DROP ANY SQL PROFILE TO scott;
GRANT ALTER ANY SQL PROFILE TO scott;

CONN scott/tiger

If the recommendations of the SQL tuning advisor include a suggested profile you can choose to accept it using the ACCEPT_SQL_PROFILE procedure:

SET SERVEROUTPUT ON
DECLARE
  l_sql_tune_task_id  VARCHAR2(20);
BEGIN
  l_sql_tune_task_id := DBMS_SQLTUNE.accept_sql_profile (
                          task_name => 'emp_dept_tuning_task',
                          name      => 'emp_dept_profile');
  DBMS_OUTPUT.put_line('l_sql_tune_task_id: ' || l_sql_tune_task_id);
END;
/

The NAME parameter is used to specify a name for the profile. If it is not specified a system generated name will be used.

The STATUS, NAME, DESCRIPTION, and CATEGORY attributes of an SQL profile can be altered using the ALTER_SQL_PROFILE procedure:

BEGIN
  DBMS_SQLTUNE.alter_sql_profile (
    name            => 'emp_dept_profile',
    attribute_name  => 'STATUS',
    value           => 'DISABLED');
END;
/
Existing SQL profiles can be dropped using the DROP_SQL_PROFILE procedure:

BEGIN
  DBMS_SQLTUNE.drop_sql_profile (
    name   => 'emp_dept_profile',
    ignore => TRUE);
END;
/

The IGNORE parameter prevents errors being reported if the specified profile does not exist.

SQL Tuning Sets
An SQL tuning set is a group of statements along with their execution context. These can be created automatically via Enterprise Manager or manually provided you have the necessary privileges:

CONN sys/password AS SYSDBA
GRANT ADMINISTER ANY SQL TUNING SET TO scott;
CONN scott/tiger
An SQL tuning set is created using the CREATE_SQLSET procedure:

BEGIN
  DBMS_SQLTUNE.create_sqlset (
    sqlset_name  => 'test_sql_tuning_set',
    description  => 'A test SQL tuning set.');
END;
/
Statements are added to the set using the LOAD_SQLSET procedure which accepts a REF CURSOR of statements retrieved using one of the following pipelined functions:

SELECT_WORKLOAD_REPOSITORY - Retrieves statements from the Automatic Workload Repository (AWR).
SELECT_CURSOR_CACHE - Retrieves statements from the cursor cache.
SELECT_SQLSET - Retrieves statements from another SQL tuning set.
The following are examples of their usage:

-- Load the SQL set from the Automatic Workload Repository (AWR).
DECLARE
  l_cursor  DBMS_SQLTUNE.sqlset_cursor;
BEGIN
  OPEN l_cursor FOR
    SELECT VALUE(p)
    FROM   TABLE (DBMS_SQLTUNE.select_workload_repository (
                    765,  -- begin_snap
                    766,  -- end_snap
                    NULL, -- basic_filter
                    NULL, -- object_filter
                    NULL, -- ranking_measure1
                    NULL, -- ranking_measure2
                    NULL, -- ranking_measure3
                    NULL, -- result_percentage
                    10)   -- result_limit
                  ) p;

  DBMS_SQLTUNE.load_sqlset (
    sqlset_name     => 'test_sql_tuning_set',
    populate_cursor => l_cursor);
END;
/

-- Load the SQL set from the cursor cache.
DECLARE
  l_cursor  DBMS_SQLTUNE.sqlset_cursor;
BEGIN
  OPEN l_cursor FOR
    SELECT VALUE(p)
    FROM   TABLE (DBMS_SQLTUNE.select_cursor_cache (
                    NULL, -- basic_filter
                    NULL, -- object_filter
                    NULL, -- ranking_measure1
                    NULL, -- ranking_measure2
                    NULL, -- ranking_measure3
                    NULL, -- result_percentage
                    1)    -- result_limit
                  ) p;

  DBMS_SQLTUNE.load_sqlset (
    sqlset_name     => 'test_sql_tuning_set',
    populate_cursor => l_cursor);
END;
/

-- Create a new set and load it from the existing one.
DECLARE
  l_cursor  DBMS_SQLTUNE.sqlset_cursor;
BEGIN
  DBMS_SQLTUNE.create_sqlset(
    sqlset_name  => 'test_sql_tuning_set_2',
    description  => 'Another test SQL tuning set.');

  OPEN l_cursor FOR
    SELECT VALUE(p)
    FROM   TABLE (DBMS_SQLTUNE.select_sqlset (
                    'test_sql_tuning_set', -- sqlset_name
                    NULL,                  -- basic_filter
                    NULL,                  -- object_filter
                    NULL,                  -- ranking_measure1
                    NULL,                  -- ranking_measure2
                    NULL,                  -- ranking_measure3
                    NULL,                  -- result_percentage
                    NULL)                  -- result_limit
                  ) p;

  DBMS_SQLTUNE.load_sqlset (
    sqlset_name     => 'test_sql_tuning_set_2',
    populate_cursor => l_cursor);
END;
/

The contents of an SQL tuning set can be displayed using the SELECT_SQLSET function:

SELECT *
FROM   TABLE(DBMS_SQLTUNE.select_sqlset ('test_sql_tuning_set'));References can be added to a set to indicate its usage by a client using the ADD_SQLSET_REFERENCE function. The resulting reference ID can be used to remove it using the REMOVE_SQLSET_REFERENCE procedure:

DECLARE
  l_ref_id  NUMBER;
BEGIN
  -- Add a reference to a set.
  l_ref_id := DBMS_SQLTUNE.add_sqlset_reference (
    sqlset_name => 'test_sql_tuning_set',
    reference   => 'Used for manual tuning by SQL*Plus.');

  -- Delete the reference.
  DBMS_SQLTUNE.remove_sqlset_reference (
    sqlset_name  => 'test_sql_tuning_set',
    reference_id => l_ref_id);
END;
/
The UPDATE_SQLSET procedure is used to update specific string (MODULE and ACTION) and number (PRIORITY and PARSING_SCHEMA_ID) attributes of specific statements within a set:

BEGIN
  DBMS_SQLTUNE.update_sqlset (
    sqlset_name     => 'test_sql_tuning_set',
    sql_id          => '19v5guvsgcd1v',
    attribute_name  => 'ACTION',
    attribute_value => 'INSERT');
END;
/
The contents of a set can be trimmed down or deleted completely using the DELETE_SQLSET procedure:

BEGIN
  -- Delete statements with less than 50 executions.
  DBMS_SQLTUNE.delete_sqlset (
    sqlset_name  => 'test_sql_tuning_set',
    basic_filter => 'executions < 50');

  -- Delete all statements.
  DBMS_SQLTUNE.delete_sqlset (
    sqlset_name  => 'test_sql_tuning_set');
END;
/
Tuning sets can be dropped using the DROP_SQLSET procedure:

BEGIN
  DBMS_SQLTUNE.drop_sqlset (sqlset_name => 'test_sql_tuning_set');
  DBMS_SQLTUNE.drop_sqlset (sqlset_name => 'test_sql_tuning_set_2');
END;
/


Oracle 11g:
-----------

Oracle 11g automatically runs the SQL Tuning Advisor against high impact SQL statements during maintenance windows. This process involves the following steps:

AWR statistics are used to compile an ordered list of the SQL statements with the greatest performance impact on the system, where the impact is the sum of the CPU and I/O times for the statement during the past week.
The list excludes statements that are inherently less tunable, such as recently (within a month) tuned recursive statements, parallel queries, DML, DDL and SQL statements whose performance problems are caused by concurrency issues.
The SQL tuning advisor is run against each statement in turn. The outcome may include both SQL profiles and other recommendations.
Suggested SQL profiles are performance tested, and those that result in at least a threefold improvement are accepted if the ACCEPT_SQL_PROFILES parameter is set to TRUE, or reported if it is set to FALSE.
The accepted SQL profiles are optionally implemented . Several factors many prevent SQL profiles from being implemented automatically, including stale optimizer statistics of dependent objects.
The TYPE column of the DBA_SQL_PROFILES view indicates if SQL profiles are created manually (MANUAL) or automatically (AUTO-TUNE).
The ENABLE and DISABLE procedures of the DBMS_AUTO_TASK_ADMIN package control whether automatic SQL tuning is included in the automated maintenance tasks.

-- Enable
BEGIN
  DBMS_AUTO_TASK_ADMIN.enable(
    client_name => 'sql tuning advisor',
    operation   => NULL,
    window_name => NULL);
END;
/

-- Disable
BEGIN
  DBMS_AUTO_TASK_ADMIN.disable(
    client_name => 'sql tuning advisor',
    operation   => NULL,
    window_name => NULL);
END;
/
It is also indirectly disabled by setting the STATISTICS_LEVEL parameter to BASIC, as this stops automatic statistics gathering by the AWR.

The SET_TUNING_TASK_PARAMETER procedure of the DBMS_SQLTUNE package controls the behavior of the SQL tuning advisor. The parameters specifically for the automatic runs include:

ACCEPT_SQL_PROFILES - Automatically accept SQL profiles (default FALSE).
MAX_SQL_PROFILES_PER_EXEC - The maximum number of SQL profiles automatically implemented per run (default 20).
MAX_AUTO_SQL_PROFILES - The maximum number of automatic SQL profiles allowed on the system (default 10000).
The current parameter values are displayed using the %_ADVISOR_PARAMETERS views.

COLUMN parameter_value FORMAT A30

SELECT parameter_name, parameter_value
FROM   dba_advisor_parameters
WHERE  task_name = 'SYS_AUTO_SQL_TUNING_TASK'
AND    parameter_name IN ('ACCEPT_SQL_PROFILES',
                          'MAX_SQL_PROFILES_PER_EXEC',
                          'MAX_AUTO_SQL_PROFILES');

PARAMETER_NAME                 PARAMETER_VALUE
------------------------------ ------------------------------
ACCEPT_SQL_PROFILES            FALSE
MAX_SQL_PROFILES_PER_EXEC      20
MAX_AUTO_SQL_PROFILES          10000

3 rows selected.

SQL>
The following code shows how the SET_TUNING_TASK_PARAMETER procedure is used to turn on acceptance of automatically generated SQL profiles.

BEGIN
  DBMS_SQLTUNE.set_tuning_task_parameter(
    task_name => 'SYS_AUTO_SQL_TUNING_TASK',
    parameter => 'ACCEPT_SQL_PROFILES',
    value     => 'TRUE');
END;
/
The REPORT_AUTO_TUNING_TASK function of the DBMS_SQLTUNE package returns a CLOB containing a report from the specified automatic tuning task. Setting the BEGIN_EXEC and END_EXEC parameters to NULL produces a report from the most recent execution.

VARIABLE l_report CLOB;
BEGIN
  :l_report := DBMS_SQLTUNE.report_auto_tuning_task(
    begin_exec   => NULL,
    end_exec     => NULL,
    type         => DBMS_SQLTUNE.type_text,     -- 'TEXT'
    level        => DBMS_SQLTUNE.level_typical, -- 'TYPICAL'
    section      => DBMS_SQLTUNE.section_all,   -- 'ALL'
    object_id    => NULL,
    result_limit => NULL);
END;
/

SET LONG 1000000
PRINT :l_report

L_REPORT
--------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name                        : SYS_AUTO_SQL_TUNING_TASK
Tuning Task Owner                       : SYS
Workload Type                           : Automatic High-Load SQL Workload
Execution Count                         : 31
Current Execution                       : EXEC_1_25
Execution Type                          : TUNE SQL
Scope                                   : COMPREHENSIVE
Global Time Limit(seconds)              : 3600
Per-SQL Time Limit(seconds)             : 1200
Completion Status                       : COMPLETED
Started at                              : 01/16/2008 22:00:06
Completed at                            : 01/16/2008 22:00:46
Number of Candidate SQLs                : 0
Cumulative Elapsed Time of SQL (s)      : 0

-------------------------------------------------------------------------------


SQL>
As you can see from the above report, this was run against a very quiet system, so there were no candidate SQL statements to process. If this were run against a more active system, you might expect the report to contain the following sections:

General information - High-level information about the SQL tuning task.
Summary - A summary of the SQL statements tuned during the task, including the estimated benefit associated with the tuning operation.
Tuning finding - Information about findings, acceptance of the profile, implementation of the profile, and detailed execution statistics for each analyzed statement.
Explain plans - The old and new execution plans for each analyzed statement.
Errors - Any errors encountered during the task.

col STATUS_MESSAGE for a30
col ERROR_MESSAGE for a40
select owner,TASK_NAME,EXECUTION_START,EXECUTION_END,STATUS,STATUS_MESSAGE,ERROR_MESSAGE from dba_advisor_log order by EXECUTION_START;

SET LONG 10000;
SET PAGESIZE 1000
SET LINESIZE 200
SELECT DBMS_SQLTUNE.report_tuning_task('SYS_AUTO_SPCADV_59032226092012') AS recommendations FROM dual;


set serveroutput on

DECLARE
 retVal CLOB;
BEGIN
  retVal := dbms_auto_sqltune.report_auto_tuning_task(type=>'HTML', result_limit=>20);
  dbms_output.put_line(retVal);
END;
/

Saturday, December 8, 2012


ORA-01455: converting column overflows integer datatype


ORA-01455: converting column overflows integer datatype

Error:
Export of 11g Rel2 using 10g Client will have the above error message at exporting triggers.


Error:
Export of 11g Rel2 using 10g Client will have the above error message at exporting triggers.

ORA-01455: converting column overflows integer datatype

EXP-00000: Export terminated unsuccessfully

Cause:
This is an Oracle Bug. The root cause is that the converted form of the specified expression was too large for the specified datatype.

Solution:

Solution 1 : Try with an Oracle 11g Release 2 EXP client against the Oracle 11g Release 2.

Solution 2 : Use the triggers=n option, that allows an export of a schema made by an Oracle 10.2 client against an Oracle 11g release 2 to complete successfully.



ORA-1455 is raised when exporting from an 11.2 database using a 9i,10g or 11gR1 exp utility


Solution

Use the Datapump export utility (EXPDP) instead of traditional EXP.

OR

Run the below sql to see any empty table present with no extent allocated.

SQL> SELECT owner, table_name
     FROM dba_tables
     WHERE segment_created = 'NO'
     AND owner NOT IN ('ORDSYS', 'MDSYS', 'CTXSYS', 'ORDPLUGINS',
                       'LBACSYS', 'XDB', 'SI_INFORMTN_SCHEMA', 'DIP',
                       'DBSNMP', 'EXFSYS', 'WMSYS', 'ORACLE_OCM',
                       'ANONYMOUS', 'XS$NULL', 'APPQOSSYS')
     ORDER by 1, 2;


Allocate at least 1 extent for the offending tables reported in the above query using:
SQL> ALTER TABLE ... ALLOCATE EXTENT;

OR
Recreate the source 11.2 database with the initialization parameter DEFERRED_SEGMENT_CREATION=FALSE.

Command to check installed oracle binaries is 64bit or 32bit :

$ORACLE_HOME/bin/genezi -v

How to find ORACLE HOME from database


SELECT substr(file_spec,1,instr(file_spec,'lib')-2) ORACLE_HOME FROM dba_libraries WHERE library_name='DBMS_SUMADV_LIB';

or

var OHM varchar2(100);
EXEC dbms_system.get_env('ORACLE_HOME', :OHM) ;
PRINT OHM


Friday, June 29, 2012


Limitations on Oracle Roles:
Oracle roles have some limitations. In particular object privileges are granted through Oracle roles can not be used when writing PL/SQL code. When writing PL/SQL code, you must have direct grants to the objects in the database that your code is accessing.

Friday, November 18, 2011

Exadata Concept - Storage Index , Smart Scan - Demo

Exadata Concept - Storage Index , Smart Scan - Demo

Exadata is a Database Appliance containing a Storage Server which is database aware, hence it provides the fastest medium to reduce I/O and ensures that only required blocks travels between Storage Server to Database Servers. Although Exadata has an infiniband to communicate between storage server and database machine and infiniband provides a 40Gbps communication.

In the below test case i would be demonstrating the following things

1) Storage Server Access via CELLCLI
2) Smart Scan in Exadata
3) Storage Indexes in Exadata

Lets see some of the hardware portion of Exadata.

Physical Structures

Command

Utilities

Physical Disk & LUN

list physicaldisk;

CELLCLI

CELL Disks

list celldisk

CELLCLI

GRID Disk

list griddisk

CELLCLI

ASM Disk

lsdg -G DATA

ASMCMD

ASM Disk Group

lsdg -G DATA

ASMCMD

ASM Files

ls -s

ASMCMD



One Physical disk can be part of LUN's as defined in the Striping, then Each LUN or Physical Disk could be mapped to CELL Disks inside exadata. These Cell Disks are partitioned and grouped in as GRID Disk.

When you create an ASM Disk Group, the ASM Disks are mapped to GRID Disk at storage server. Since Exadata Storage Server runs on Oracle Enterprise Linux, it is possible to login on the storage server as root user and use the new utility called as CELLCLI, this utility allows you to quert exadata cell disks and Grid disk along with creation of FLASH Disk and different IORM Management.


[root@qr01cel01 ~]# cellcli
CellCLI: Release 11.2.2.1.0 - Production on Thu Oct 27 03:44:36 EDT 2011

Copyright (c) 2007, 2009, Oracle. All rights reserved.
Cell Efficiency Ratio: 11M

CellCLI> list physical disk;
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK00

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK00 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK01

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK01 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK02

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK02 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK03

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK03 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK04

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK04 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK05

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK05 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK06

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK06 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK07

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK07 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK08

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK08 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK09

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK09 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK10

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK10 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK11

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK11 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH00

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH00 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH01

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH01 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH02

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH02 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH03

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH03 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH04

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH04 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH05

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH05 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH06

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH06 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH07

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH07 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH08

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH08 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH09

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH09 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH10

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH10 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH11

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH11 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH12

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH12 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH13

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH13 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH14

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH14 normal
/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH15

/opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/FLASH15 normal


You can list the celldisk as well, remember cell disks are mapped to physical disks or LUN

CellCLI> list celldisk;
CD_00_qr01cel01 normal
CD_01_qr01cel01 normal
CD_02_qr01cel01 normal
CD_03_qr01cel01 normal
CD_04_qr01cel01 normal
CD_05_qr01cel01 normal
CD_06_qr01cel01 normal
CD_07_qr01cel01 normal
CD_08_qr01cel01 normal
CD_09_qr01cel01 normal
CD_DISK10_qr01cel01 normal
CD_DISK11_qr01cel01 normal
FD_00_qr01cel01 normal
FD_01_qr01cel01 normal
FD_02_qr01cel01 normal
FD_03_qr01cel01 normal
FD_04_qr01cel01 normal
FD_05_qr01cel01 normal
FD_06_qr01cel01 normal
FD_07_qr01cel01 normal
FD_08_qr01cel01 normal
FD_09_qr01cel01 normal
FD_10_qr01cel01 normal
FD_11_qr01cel01 normal
FD_12_qr01cel01 normal
FD_13_qr01cel01 normal
FD_14_qr01cel01 normal
FD_15_qr01cel01 normal

Check the Details of celldisk for individual celldisk and list out the devices being used


CellCLI> list celldisk CD_00_qr01cel01 detail;
name: CD_00_qr01cel01
comment:
creationTime: 2010-12-09T21:10:33-05:00
deviceName: /opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK00
devicePartition: /opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK00
diskType: HardDisk
errorCount: 0
freeSpace: 0
id: 0000012c-ce0b-412f-0000-000000000000
interleaving: none
lun: /opt/oracle/cell11.2.2.1.0_LINUX.X64_100929/disks/raw/DISK00
raidLevel: "RAID 0"
size: 1.203125G
status: normal


As i told earlier that Grid disks are group of cell disks, you can list out grid disk by the below command.

CellCLI> list griddisk;
DATA_CD_00_qr01cel01 active
DATA_CD_01_qr01cel01 active
DATA_CD_02_qr01cel01 active
DATA_CD_03_qr01cel01 active
DATA_CD_04_qr01cel01 active
DATA_CD_05_qr01cel01 active
DATA_CD_06_qr01cel01 active
DATA_CD_07_qr01cel01 active
DATA_CD_08_qr01cel01 active
DATA_CD_09_qr01cel01 active
highredint1 active
highredint2 active
highredint3 active
jgd active
RECO_CD_00_qr01cel01 active
RECO_CD_01_qr01cel01 active
RECO_CD_02_qr01cel01 active
RECO_CD_03_qr01cel01 active
RECO_CD_04_qr01cel01 active
RECO_CD_05_qr01cel01 active
RECO_CD_06_qr01cel01 active
RECO_CD_07_qr01cel01 active
RECO_CD_08_qr01cel01 active
RECO_CD_09_qr01cel01 active
SYSTEMDG_CD_00_qr01cel01 active
SYSTEMDG_CD_01_qr01cel01 active
SYSTEMDG_CD_02_qr01cel01 active
SYSTEMDG_CD_03_qr01cel01 active
SYSTEMDG_CD_04_qr01cel01 active
SYSTEMDG_CD_05_qr01cel01 active
SYSTEMDG_CD_06_qr01cel01 active
SYSTEMDG_CD_07_qr01cel01 active
SYSTEMDG_CD_08_qr01cel01 active
SYSTEMDG_CD_09_qr01cel01 active

Details of Grid Disk for individual grid disk and its cell disk can be displayed by using the below command

CellCLI> list griddisk DATA_CD_00_qr01cel01 detail
name: DATA_CD_00_qr01cel01
availableTo:
cellDisk: CD_00_qr01cel01
comment:
creationTime: 2010-12-09T21:11:49-05:00
diskType: HardDisk
errorCount: 0
id: 0000012c-ce0c-6c96-0000-000000000000
offset: 128M
size: 688M
status: active

CellCLI>


Now lets have a look at ASMCMD which is part of our Database machine and see how our disk groups are mapped to Storage Server.

ASMCMD> lsdsk -G DATA
Path
o/192.168.1.11/DATA_CD_00_qr01cel01
o/192.168.1.11/DATA_CD_01_qr01cel01
o/192.168.1.11/DATA_CD_02_qr01cel01
o/192.168.1.11/DATA_CD_03_qr01cel01
o/192.168.1.11/DATA_CD_04_qr01cel01
o/192.168.1.11/DATA_CD_05_qr01cel01
o/192.168.1.11/DATA_CD_06_qr01cel01
o/192.168.1.11/DATA_CD_07_qr01cel01
o/192.168.1.11/DATA_CD_08_qr01cel01
o/192.168.1.11/DATA_CD_09_qr01cel01
o/192.168.1.12/DATA_CD_00_qr01cel02
o/192.168.1.12/DATA_CD_01_qr01cel02
o/192.168.1.12/DATA_CD_02_qr01cel02
o/192.168.1.12/DATA_CD_03_qr01cel02
o/192.168.1.12/DATA_CD_04_qr01cel02
o/192.168.1.12/DATA_CD_05_qr01cel02
o/192.168.1.12/DATA_CD_06_qr01cel02
o/192.168.1.12/DATA_CD_07_qr01cel02
o/192.168.1.12/DATA_CD_08_qr01cel02
o/192.168.1.12/DATA_CD_09_qr01cel02
o/192.168.1.13/DATA_CD_00_qr01cel03
o/192.168.1.13/DATA_CD_01_qr01cel03
o/192.168.1.13/DATA_CD_02_qr01cel03
o/192.168.1.13/DATA_CD_03_qr01cel03
o/192.168.1.13/DATA_CD_04_qr01cel03
o/192.168.1.13/DATA_CD_05_qr01cel03
o/192.168.1.13/DATA_CD_06_qr01cel03
o/192.168.1.13/DATA_CD_07_qr01cel03
o/192.168.1.13/DATA_CD_08_qr01cel03
o/192.168.1.13/DATA_CD_09_qr01cel03
ASMCMD> exit

You can see that all ASM Disks are mapped to GRID Disks, and a disk group DATA is created out of it.


Lets start with the Storage Index and Smart Scan technology by login into the Database Machine and Oracle Database for our test scenario.
For the test case, i have created a user and provided necessary privileges to it.

[oracle@qr01db01 ~]$ sqlplus

SQL*Plus: Release 11.2.0.2.0 Production on Thu Oct 27 07:46:52 2011

Copyright (c) 1982, 2010, Oracle. All rights reserved.

Enter user-name: / as sysdba

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

SQL> create user ritesh identified by pass;

User created.

Elapsed: 00:00:00.27
SQL> grant dba to ritesh;

Grant succeeded.

Elapsed: 00:00:00.01


Lets login to Ritesh User and create a table which contains 10 Million rows, since we are using connect by level to generate 10 million
rows, we need to have a high PGA memory. Instead of setting PGA, i have changed the workarea_size_policy to manual and used
sort_area_size to 1GB.


SQL> conn ritesh/pass

Connected.

SQL> alter session set sort_area_size=1073741824;

Session altered.

Elapsed: 00:00:00.00

SQL> alter session set workarea_size_policy=MANUAL;

Session altered.

Elapsed: 00:00:00.00

SQL> create table oracledba_emp1 as
select rownum t1,rownum+1 t2 ,'Testing for Storage Indexes' t3
from dual connect by level<10000000; Table created. Elapsed: 00:00:43.48 SQL> select bytes/1024/1024 as gb from user_segments where segment_name='ORACLEDBA_EMP1';

GB
----------
496

Elapsed: 00:00:00.41


The table that i have created is nearly 500 MB at the moment, now the below query would demonstrate the use of storage index and smart
scan. Everytime when we run an operation in a session and we want to verify whether the operation is using the feature of exadata or now we could run this query and see how much physicall I/O is avoided to be accessed or to be travelled.

SQL> select
2 name,value/1024/1024 as stat_value
3 from v$mystat s, v$statname n
4 where s.statistic# = n.statistic# and n.name in (
5 'cell physical IO bytes saved by storage index',
6 'cell physical IO interconnect bytes returned by smart scan')
/

NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 0
cell physical IO interconnect bytes returned by smart scan .000328064

Elapsed: 00:00:00.33

SQL> save sess_wait;
Created file sess_wait.sql
SQL> @ sess_wait

NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 0
cell physical IO interconnect bytes returned by smart scan .000328064

Elapsed: 00:00:00.16

Now lets run a query against the table, note that there is no physical index being created on the table. lets see how the query behaves.


SQL> select * from ORACLEDBA_EMP1 where T1=4711;

T1 T2 T3
---------- ---------- ---------------------------
4711 4712 Testing for Storage Indexes

Elapsed: 00:00:20.01
SQL> @ sess_wait

NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 0
cell physical IO interconnect bytes returned by smart scan .072860718

You can see that there is no use of storage index and the query has taken nearly 20 seconds to finish. Now lets run the query again.

SQL> select * from ORACLEDBA_EMP1 where T1=4711;

T1 T2 T3
---------- ---------- ---------------------------
4711 4712 Testing for Storage Indexes

Elapsed: 00:00:00.06
SQL> @ sess_wait

NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 485.015625
cell physical IO interconnect bytes returned by smart scan .147186279

You can see that when we executed the query for the second time, then the query took only .06 seconds to finish. Query against a 500 MB table without a index lead to an improvement of nearly 1000% with exadata because of Storage Indexes. The value of 485 MB visible in by session statistics shows that storage index has saved at least 485 MB of data for a physical read.

Note : Storage Index takes time to create and they are created at storage server, thats why its being told that Exadata Storage Server is a database aware storage.

Now lets disable the feature of storage index of Exadata and see how it behaves in Non-Exadata environment. I am doing this by setting up an Underscore parameter.

SQL> conn / as sysdba
Connected.
SQL> col NAME format a40
SQL> col VALUE format a10
SQL> col DESCRIPTION format a40
SQL> col TYPE forma a10
SQL> col DEFLT forma a10
SQL> set lines 140
SQL> select a.ksppinm name,
2 b.ksppstvl value,
3 b.ksppstdf deflt,
4 decode(a.ksppity, 1,'boolean', 2,'string', 3,'number', 4,'file', a.ksppity) type,
5 a.ksppdesc description
6 from
7 sys.x$ksppi a,sys.x$ksppcv b
8 where
9 a.indx = b.indx
10 and (a.ksppinm like '\_%storageidx_disabled%' escape '\' or
11 12 a.ksppinm like '\_%cell_smart_scan%' escape '\'
13 ) order by name;

NAME VALUE DEFLT TYPE DESCRIPTION
---------------------------------- ---------- ---------- ---------- --------------------------
_allow_cell_smart_scan_attr TRUE TRUE boolean Allow checking

smart_scan_capable Attr
_kcfis_storageidx_disabled FALSE TRUE boolean Don't use storage index
optimization on the
storage cell

Now lets see if we disable the storage index feature by setting the undocumented parameter, how system behaves thereafter.

dbm1> conn ritesh/pass
Connected.
dbm1> select * from ORACLEDBA_EMP1 where T1=4711; -- With Storage Index
T1 T2 T3
---------- ---------- ---------------------------
4711 4712 Testing for Storage Indexes

Elapsed: 00:00:00.14

dbm1> @ sess_wait
NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 485.015625
cell physical IO interconnect bytes returned by smart scan .001792908

Elapsed: 00:00:00.01

dbm1> alter session set "_kcfis_storageidx_disabled"=TRUE; -- Storage Index Disabled Here

Session altered.

Elapsed: 00:00:00.00
dbm1> select * from ORACLEDBA_EMP1 where T1=4711; -- Without Storage Index
T1 T2 T3
---------- ---------- ---------------------------
4711 4712 Testing for Storage Indexes

Elapsed: 00:00:11.36

dbm1> @ sess_wait
NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 485.015625
cell physical IO interconnect bytes returned by smart scan .074325562

Elapsed: 00:00:00.00


dbm1> alter session set "_kcfis_storageidx_disabled"=FALSE; -- Enable Storage Indexes

Session altered.

Elapsed: 00:00:00.00
dbm1> select * from ORACLEDBA_EMP1 where T1=4711; -- With Storage Indexes

T1 T2 T3
---------- ---------- ---------------------------
4711 4712 Testing for Storage Indexes

Elapsed: 00:00:00.06
dbm1> @ sess_wait

NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 970.03125
cell physical IO interconnect bytes returned by smart scan .076118469

Elapsed: 00:00:00.01

Storage Index also works with bind variables, have a check with that.

dbm1> @ sess_wait

NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 970.03125
cell physical IO interconnect bytes returned by smart scan .076118469

Elapsed: 00:00:00.01

dbm1> variable b number
dbm1> exec :b:=1541;

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.03

dbm1> select * from ORACLEDBA_EMP1 where T1=:b;
T1 T2 T3
---------- ---------- ---------------------------
1541 1542 Testing for Storage Indexes

Elapsed: 00:00:00.05

dbm1> @ sess_wait
NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 1,455.0469
cell physical IO interconnect bytes returned by smart scan .0779

Elapsed: 00:00:00.01

Now lets see a small glimpse of smart scan feature

dbm1> create table oracledba_emp2 as select * from oracledba_emp1;

Table created.

Elapsed: 00:00:40.34
dbm1> @ sess_wait
NAME STAT_VALUE
---------------------------------------------------------------- ----------
cell physical IO bytes saved by storage index 1,455.0469
cell physical IO interconnect bytes returned by smart scan 440.5917

Elapsed: 00:00:00.00
dbm1>

Oracle 12c Cloud Enterprise Manager.

Sunday, October 9, 2011

Truncate privilege to user b on tables of user A


Request: Need to provide truncate privilege to user B on table A.test_table.

1) Connect to user A

2) Create procedure to truncate table as below:

create or replace procedure truncate_test_table
as
l_sql varchar2(2500); 
begin
l_sql := 'TRUNCATE TABLE A.TEST_TABLE'; 
execute immediate l_sql; 
end; 
/ 

2) Grant the procedure to User B:

grant execute on A.truncate_test_table to b;

3) Try executing the procedure from User B as below:

begin
A.truncate_test_table; 
end; 
/ 

Sharing a Folder from HostOS to Vmware Guest OS


I tried to share a folder from my windows machine(HOST OS) to Linux (VMWare Guest OS).
I breaked my head for more than an hour and found an article from vmware site.

1) Share the folder in windows (Right click the folder click share button and provide access to any windows user) which you want to share with Linux.
2)In Linux machine (VMWare Guest OS) login as root and issue below command.

mkdir /mnt/docs
mount -t smbfs -o username=<Windows system user account>,password=<password> //<Win_Hostname>/docs /mnt/docs

Now you can see the shared folder under /mnt/docs.

Eventhogh this is simple i wasted 1+ hour for this,so thought of sharing........

Wednesday, August 10, 2011

Oracle 11g: Access Control List and ORA-24247

Oracle 11g: Access Control List and ORA-24247

From 11g Oracle offers more fine-grained access control for users to access external network resources With ACL’s.

Prior 11g:
The packages UTL_MAIL, UTL_SMTP, UTL_HTTP, UTL_TCP etc. allow communication beyond the database server to the outside world, but when granted access, all hosts can be accessed.
This can be interpreted as a security flaw as no login is required when using UTL_TCP.
For example. DBA’s are advised to revoke the execute privileges from public on these kind of packages.

Since Oracle 11g:
The Access Control List is introduced. You not only can control who has access to these packages by granting, but now you can also control which resources they can call.
For instance, when a user is granted to send emails using UTL_MAIL, you can also control that he/she is only able to send through a specified mail server.
At first this looks like a obstacle (ORA-24247), but since the Voyager worm struck Oracle databases a year ago, it is introduced as an extra security measurement.

I faced the same scenario with my client,
Client complained saying his package is not working after the DB is upgraded to 11gR2 and throws below error.


ORA-24247: network access denied by access control list (ACL)
Here are athe steps i followed to resolve this issue.
NOTE: Package,DB and host name

[oracle@unixprod]:../oracle>
[oracle@unixprod]:../oracle>. oraenv
ORACLE_SID = [PROD1] ? PROD1
The Oracle base for ORACLE_HOME=/local/oracle/product/11.2.0.2 is /local/oracle/product/11.2.0.2
[oracle@unixprod]:../oracle>sqlplus '/as sysdba'

SQL*Plus: Release 11.2.0.2.0 Production on Tue Aug 9 15:32:24 2011

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> select name from v$database;

NAME
---------
PROD1

SQL> conn user1/******
Connected.
SQL> show user
USER is "USER1"

SQL> exec END_REPORT.send_email('1111','ramshankar80@gmail.com','123','123');
BEGIN END_REPORT.send_email('1011','ram.shankar@am.sony.com','123','123'); END;

*
ERROR at line 1:
ORA-24247: network access denied by access control list (ACL)
ORA-06512: at "USER1.END_REPORT", line 4275
ORA-06512: at line 1
SQL> desc END_REPORT
..............
PROCEDURE SEND_EMAIL
Argument Name                  Type                    In/Out Default?
------------------------------ ----------------------- ------ --------
I_FISCAL_DATE                  VARCHAR2                IN
I_EMAIL_ID                     VARCHAR2                IN
I_ERROR_CODE                   VARCHAR2                IN
I_ERROR_MESSAGE                VARCHAR2                IN
..................
SQL> !

[oracle@ubetud17]:../oracle>[oracle@ubetud17]:../oracle>oerr ora 24247
24247, 00000, "network access denied by access control list (ACL)"
// *Cause:    No access control list (ACL) has been assigned to the target host or the privilege necessary to access the target host has not
//                been granted to the user in the access control list.
// *Action:   Ensure that an access control list (ACL) has been assigned to the target host and the privilege necessary to access the
//            target host has been granted to the user.
[oracle@ubetud17]:../oracle>exit
SQL> show user
USER is "USER1"
SQL> conn /as sysdba
Connected.
SQL> begin
dbms_network_acl_admin.create_acl (
acl         => 'utl_mail.xml',
description => 'Allow mail to be send',
principal   => 'USER1',
is_grant    => TRUE,
privilege   => 'connect'
);
commit;
end;
/
  2    3    4    5    6    7    8    9   10   11

PL/SQL procedure successfully completed.

SQL> SQL> begin
dbms_network_acl_admin.add_privilege (
acl       => 'utl_mail.xml',
principal => 'USER1',
is_grant  => TRUE,
privilege => 'resolve'
);
commit;
end;
/
  2    3    4    5    6    7    8    9   10

PL/SQL procedure successfully completed.

SQL> SQL> begin
dbms_network_acl_admin.assign_acl(
acl  => 'utl_mail.xml',
host => '<smtp host name or IP address>'
);
commit;
end;
/
  2    3    4    5    6    7    8
PL/SQL procedure successfully completed.


SQL> conn user1
Connected.
SQL> show user
USER is "USER1"

SQL> exec END_REPORT.send_email('1111','ramshankar80@gmail.com','123','123');

PL/SQL procedure successfully completed.

SQL>

Cleaning Up the Access Control List
BEGIN
  DBMS_NETWORK_ACL_ADMIN.unassign_acl (
    acl         => 'utl_mail.xml',
    host        => 'smtp_host_name');
  COMMIT;
END;
/

Delete a privilege from Access Control List
BEGIN
  DBMS_NETWORK_ACL_ADMIN.delete_privilege (
    acl         => 'utl_mail.xml',
    principal   => 'utl_mail_p',
    is_grant    => TRUE,
    privilege   => 'connect');
  COMMIT;
END;
/
Drop an Access Control List
BEGIN
  DBMS_NETWORK_ACL_ADMIN.DROP_ACL (
    acl         => 'utl_mail.xml');
  COMMIT;
END;
/

Qery to view the Access Control List details:

col principal for a40
col acl for a40
set pages 340
set lines 300
select acl , principal , privilege , is_grant from DBA_NETWORK_ACL_PRIVILEGES;
select acl , host , lower_port , upper_port from DBA_NETWORK_ACLS;

Send_mail Procedure

CREATE PROCEDURE send_mail_test
(sender IN VARCHAR2
,recipient IN VARCHAR2
,subject IN VARCHAR2
,message IN VARCHAR2)
IS
mailhost VARCHAR2(30) := 'smtp_host_server';
mail_conn utl_smtp.connection;
crlf VARCHAR2(2) := CHR(13) || CHR(10);
mesg VARCHAR2(32000);
BEGIN
mail_conn := utl_smtp.open_connection(mailhost, 25);
mesg := 'Date: ' || TO_CHAR(SYSDATE, 'dd Mon yy hh24:mi:ss') || crlf
||'From: <' || sender || '>' || crlf ||
'Subject: '|| subject || crlf ||
'To: ' || recipient || crlf ||
'' || crlf || message;
utl_smtp.helo(mail_conn, mailhost);
utl_smtp.mail(mail_conn, sender);
utl_smtp.rcpt(mail_conn, recipient);
utl_smtp.data(mail_conn, mesg);
utl_smtp.quit(mail_conn);
EXCEPTION
WHEN OTHERS THEN
NULL;
END;

exec send_mail_test (' oracle@host_name.com','ramshankar80@gmail.com','test subject','test body');