Data … as usual

All things about data by Laurent Leturgez

Useful emcli commands in EM Cloud Control 12c

If like me, you are addicted to command line, this post will help you to realize useful operation in EM Cloud Control 12c using emcli tool rather than GUI.

You can use emcli when you need to implement batch scripts on your Oracle Management Server (OMS).

  • Login to EM
$ emcli login -username=sysman
Enter password :
Login successful

OR

$ emcli login -username=sysman -password=XXXXXX
Login successful
  • Synchronize emcli with the OMS
$ emcli sync
Synchronized successfully
  • Logout EM
$ emcli logout
Logout successful
  • List all the targets already promoted
$ emcli get_targets
Status  Status           Target Type           Target Name
 ID
-9      n/a              group                 OFM
1       Up               host                  xxxdb-prod3.mydomain.com
1       Up               host                  xxxdb-prod2.mydomain.com
1       Up               host                  xxxlgc-prod2.mydomain.com
1       Up               host                  xxxdb-prod1.mydomain.com
1       Up               j2ee_application      /EMGC_GCDomain/GCDomain/EMGC_OMS1/e
                                               mgc
1       Up               j2ee_application      /EMGC_GCDomain/GCDomain/EMGC_OMS1/O
                                               CMRepeater
1       Up               j2ee_application      /EMGC_GCDomain/GCDomain/EMGC_OMS1/e
                                               mpbs
-9      n/a              metadata_repository   /EMGC_GCDomain/GCDomain/EMGC_ADMINS
                                               ERVER/mds-sysman_mds
-9      n/a              metadata_repository   /EMGC_GCDomain/GCDomain/EMGC_ADMINS
                                               ERVER/mds-owsm
1       Up               oracle_apache         /EMGC_GCDomain/instance1/ohs1
1       Up               oracle_apm            /EMGC_GCDomain/GCDomain/EMGC_OMS1/o
                                               racle.security.apm(11.1.1.3.0)
1       Up               oracle_beacon         EM Management Beacon
1       Up               oracle_em_service     EM Console Service
1       Up               oracle_em_service     EM Jobs Service
1       Up               oracle_emd            xxxdb-prod1.mydomain.com:1830
1       Up               oracle_emd            xxxdb-prod3.mydomain.com:1830
1       Up               oracle_emd            xxxlgc-prod2.mydomain.com:3872
1       Up               oracle_emd            xxxdb-prod2.mydomain.com:1830
1       Up               oracle_emrep          Management Services and Repository
-9      n/a              oracle_home           agent12g1_9_xxxlgc-prod2
-9      n/a              oracle_home           WebLogicServer10_3_5_0_0_xxxlgc-pro
                                               d2
-9      n/a              oracle_home           oms12g1_3_xxxlgc-prod2
-9      n/a              oracle_home           webtier12g1_20_xxxlgc-prod2
-9      n/a              oracle_ias_farm       EMGC_GCDomain
1       Up               oracle_oms            xxxlgc-prod2.mydomain.com:4889_Managem
                                               ent_Service
1       Up               oracle_oms_console    xxxlgc-prod2.mydomain.com:4889_Managem
                                               ent_Service_CONSOLE
1       Up               oracle_oms_pbs        xxxlgc-prod2.mydomain.com:4889_Managem
                                               ent_Service_PBS
-9      n/a              weblogic_domain       /EMGC_GCDomain/GCDomain
1       Up               weblogic_j2eeserver   /EMGC_GCDomain/GCDomain/EMGC_OMS1
1       Up               weblogic_j2eeserver   /EMGC_GCDomain/GCDomain/EMGC_ADMINSERVER
  • Delete a specific target
$ emcli delete_target -name="/wlstest_wlstest/wlstest/myServer_jvm" -type="java_virtual_machine"
  • Delete an agent and its targets
$ emcli delete_target -name="xxxlgc-prod2.mydomain.com:3872" -type="oracle_emd" -delete_monitored_targets
  • Follow a plugin deployment (on the OMS / on an agent)
-- Oracle Database plugin
$ emcli get_plugin_deployment_status -plugin_id=oracle.sysman.db
-- Oracle Fusion Middleware plugin
$ emcli get_plugin_deployment_status -plugin_id=oracle.sysman.emas
-- My Oracle Support plugin
$ emcli get_plugin_deployment_status -plugin_id=oracle.sysman.mos
  • Import an update (for example: a plugin update) into the software library.
$ emcli import_update -file="p14018177_112000_Generic.zip" -omslocal
  • Deploy a plugin on the OMS
$ emcli deploy_plugin_on_server -plugin=oracle.sysman.db -sys_password=XXXXX
  • Deploy a plugin on EM agent(s)
$ emcli deploy_plugin_on_agent -plugin="oracle.sysman.db"  -agent_names="xxxdb-prod1.mydomain.com:3872;xxxdb-prod2.mydomain.com:3872"
  • List available agents in the library
$ emcli get_supported_platforms
Getting list of platforms ...
Check the logs at /home/oracle/agent.log
About to access self-update code path to retrieve the platforms list..
Getting Platforms list ...
-----------------------------------------------
Version = 12.1.0.1.0
 Platform = Linux x86-64
-----------------------------------------------
Version = 12.1.0.1.0
 Platform = Linux x86
-----------------------------------------------
Version = 12.1.0.1.0
 Platform = IBM AIX on POWER Systems (64-bit)
-----------------------------------------------
Version = 12.1.0.1.0
 Platform = Microsoft Windows (32-bit)
-----------------------------------------------
Version = 12.1.0.1.0
 Platform = Microsoft Windows (64-bit)
-----------------------------------------------
Platforms list displayed successfully
  • Download an agent from the library (used for agentDeploy.sh script method)
$ emcli get_agentimage -destination=/home/oracle -platform="Microsoft Windows x64 (64-bit)" -version="12.1.0.1.0"
Platform:Microsoft Windows x64 (64-bit)
Destination:/home/oracle
 === Partition Detail ===
Space free : 11 GB
Space required : 1 GB
Check the logs at /home/oracle/get_agentimage_2012-06-11_15-18-09-PM.log
Setting property ORACLE_HOME to:/u02/Middleware/oms
calling pulloneoffs with arguments:/u02/Middleware/oms/u02/softLibrary/32/C0C9BF40C6A36668E0439D33010AE58512.1.0.1.0windows_x64
Check this logs for more information: /u02/Middleware/oms/sysman/prov/agentpush/logs
  • Set monitoring credentials for a specific target (example given for an Oracle database instance)
$ emcli set_credential -target_type=oracle_database -target_name="prod1" -credential_set=DBCredsMonitoring -user=sysman -column="Role:SYSDBA;UserName:sys;password:XXXXX" -monitoring

Measuring RMAN IO Rates

The RMAN debug option is usually used by Oracle support to get internal information etc. Nevertheless, you can use this option to get information on RMAN backup IO Rates.

For example, you have ran this command:

[oracle@oel ~]$ rman target / trace uncompressed_dbg.trc
RMAN> debug on
RMAN> backup as backupset database;
RMAN> debug off
RMAN> exit

Note: if you want a lightweight trace which includes only IO related events, you can use the “debug io” command.

If you grep the trace file and search the DBGIO pattern, you will print very interesting information about IO Rates:

[oracle@oel ~]$ grep DBGIO uncompressed_dbg.trc
DBGIO:        channel ORA_DISK_1: set_stamp=780338716 set_count=39 [16:45:16.809] (budf_start)
DBGIO:        channel ORA_DISK_1: blocks=93440 block_size=8192 [16:45:16.816] (budf_name)
DBGIO:        channel ORA_DISK_1: blocks=6400 block_size=8192 [16:45:16.825] (budf_name)
DBGIO:        channel ORA_DISK_1: blocks=1280 block_size=8192 [16:45:16.833] (budf_name)
DBGIO:        channel ORA_DISK_1: blocks=19200 block_size=8192 [16:45:16.840] (budf_name)
DBGIO:        channel ORA_DISK_1: blocks=84480 block_size=8192 [16:45:16.844] (budf_name)
DBGIO:        Type %Comp Blocks     Tot Blocks Blksize    ElpTime(s) IO Rt(b/s) Name [16:46:22.229] (krmkqio)
DBGIO:        ---- ----- ---------- ---------- ---------- ---------- ---------- ----- [16:46:22.229] (krmkqio)
DBGIO:        IN   3.0   192        6400       8192       0          0          +DATA/orcl/datafile/aud_ts.256.752779503 [16:46:22.229] (krmkqio)
DBGIO:        IN   1.3   256        19200      8192       0          0          +DATA/orcl/datafile/t.258.769108187 [16:46:22.247] (krmkqio)
DBGIO:        IN   100.0 1280       1280       8192       0          0          +DATA/orcl/datafile/test.257.764769441 [16:46:22.258] (krmkqio)
DBGIO:        IN   94.1  79488      84480      8192       54         12058624   /u02/oradata/orcl/sysaux01.dbf [16:46:22.258] (krmkqio)
DBGIO:        IN   99.6  93056      93440      8192       59         12920589   /u02/oradata/orcl/system01.dbf [16:46:22.259] (krmkqio)
DBGIO:        OUT        147602                8192       59         20494162   /u01/app/oracle/fast_recovery_area/ORCL/backupset/2012_04_11/o1_mf_nnndf_TAG20120411T164516_7rc67wtn_.bkp [16:46:22.259] (krmkqio)
DBGIO:        AGG  85.1  174272     204800     8192       59         24197224     [16:46:22.282] (krmkqio)
DBGIO:        channel ORA_DISK_1: set_stamp=780338782 set_count=40 [16:46:22.485] (budf_start)
DBGIO:        channel ORA_DISK_1: blocks=71680 block_size=8192 [16:46:22.633] (budf_name)
DBGIO:        Type %Comp Blocks     Tot Blocks Blksize    ElpTime(s) IO Rt(b/s) Name [16:46:29.692] (krmkqio)
DBGIO:        ---- ----- ---------- ---------- ---------- ---------- ---------- ----- [16:46:29.692] (krmkqio)
DBGIO:        IN   15.3  10944      71680      8192       2          44826624   /u02/oradata/orcl/undotbs01.dbf [16:46:29.692] (krmkqio)
DBGIO:        OUT        690                   8192       3          1884160    /u01/app/oracle/fast_recovery_area/ORCL/backupset/2012_04_11/o1_mf_nnndf_TAG20120411T164516_7rc69yo2_.bkp [16:46:29.692] (krmkqio)
DBGIO:        AGG  15.3  10944      71680      8192       2          44826624     [16:46:29.692] (krmkqio)
DBGIO:        channel ORA_DISK_1: set_stamp=780338789 set_count=41 [16:46:29.770] (budf_start)
DBGIO:        channel ORA_DISK_1: blocks=44240 block_size=8192 [16:46:29.774] (budf_name)
DBGIO:        Type %Comp Blocks     Tot Blocks Blksize    ElpTime(s) IO Rt(b/s) Name [16:46:44.898] (krmkqio)
DBGIO:        ---- ----- ---------- ---------- ---------- ---------- ---------- ----- [16:46:44.898] (krmkqio)
DBGIO:        IN   90.1  39872      44240      8192       6          54438570   /u02/oradata/orcl/example01.dbf [16:46:44.899] (krmkqio)
DBGIO:        OUT        8818                  8192       7          10319579   /u01/app/oracle/fast_recovery_area/ORCL/backupset/2012_04_11/o1_mf_nnndf_TAG20120411T164516_7rc6b5rf_.bkp [16:46:44.899] (krmkqio)
DBGIO:        AGG  90.1  39872      44240      8192       6          54438570     [16:46:44.900] (krmkqio)
DBGIO:        channel ORA_DISK_1: set_stamp=780338804 set_count=42 [16:46:45.025] (budf_start)
DBGIO:        channel ORA_DISK_1: blocks=36320 block_size=8192 [16:46:45.029] (budf_name)
DBGIO:        Type %Comp Blocks     Tot Blocks Blksize    ElpTime(s) IO Rt(b/s) Name [16:47:00.056] (krmkqio)
DBGIO:        ---- ----- ---------- ---------- ---------- ---------- ---------- ----- [16:47:00.056] (krmkqio)
DBGIO:        IN   72.6  26368      36320      8192       4          54001664   /u02/oradata/orcl/users01.dbf [16:47:00.056] (krmkqio)
DBGIO:        OUT        26269                 8192       4          53798912   /u01/app/oracle/fast_recovery_area/ORCL/backupset/2012_04_11/o1_mf_nnndf_TAG20120411T164516_7rc6bo1h_.bkp [16:47:00.056] (krmkqio)
DBGIO:        AGG  72.6  26368      36320      8192       4          54001664     [16:47:00.056] (krmkqio)

To simplify the reading of this output, I will focus on the “users01.dbf” datafile backup in the backupset “/u01/app/oracle/fast_recovery_area/ORCL/backupset/2012_04_11/o1_mf_nnndf_TAG20120411T164516_7rc6bo1h_.bkp” (Highlighted in red).

In this part, we can read information above:

TYPE = IN: when rman reads the source file, OUT when it writes it, AGG represents aggregated data for the complete operation (read files and write the backupset to disk or to tape).   .

For example, if we read the IN line, we know that 26368 blocks have been read on a total of 36320 blocks (block size is 8kb), this represents a total of 26368/36320 = 72,6 % of all the datafile blocks. (RMAN backs up only used blocks). This datafile has been read in 4 seconds  at a rate of 54001664 bytes per second (51,5 Mb/sec).

You have the same line for the OUTput operation (ie. writing the backupset to disk).

Others things to see about this tip is the differences between a simple uncompressed backup of a datafile to disk, a compressed (default algorithm) backup of this datafile to disk, and an uncompressed backup of a datafile on disk using the oracle SBT library.

Note: I have flushed my linux filesystem cache between each test. (# echo 3 > /proc/sys/vm/drop_caches)

Here are the results :

  • Default : uncompressed backup to disk
[oracle@oel debug]$ rman target / debug trace debug.trc
RMAN> run {
2> backup as backupset datafile 4;
3> }

[oracle@oel debug]$ grep DBGIO debug.trc
DBGIO:         channel ORA_DISK_1: set_stamp=780405759 set_count=62 [11:22:39.138] (budf_start)
DBGIO:         channel ORA_DISK_1: blocks=36320 block_size=8192 [11:22:39.409] (budf_name)
DBGIO:         Type %Comp Blocks     Tot Blocks Blksize    ElpTime(s) IO Rt(b/s) Name [11:23:04.562] (krmkqio)
DBGIO:         ---- ----- ---------- ---------- ---------- ---------- ---------- ----- [11:23:04.562] (krmkqio)
DBGIO:         IN   72.6  26368      36320      8192       16         13500416   /u02/oradata/orcl/users01.dbf [11:23:04.562] (krmkqio)
DBGIO:         OUT        26269                 8192       17         12658567   /u01/app/oracle/fast_recovery_area/ORCL/backupset/2012_04_12/o1_mf_nnndf_TAG20120412T112238_7rf7pzlp_.bkp [11:23:04.562] (krmkqio)
DBGIO:         AGG  72.6  26368      36320      8192       16         13500416     [11:23:04.563] (krmkqio)
  • Compressed backup to disk
[oracle@oel debug]$ rman target / debug trace debug_comp.trc
RMAN> run {
2> backup as compressed backupset datafile 4;
3> }

[oracle@oel debug]$ grep DBGIO debug_comp.trc
DBGIO:         channel ORA_DISK_1: set_stamp=780405692 set_count=60 [11:21:32.609] (budf_start)
DBGIO:         channel ORA_DISK_1: blocks=36320 block_size=8192 [11:21:32.871] (budf_name)
DBGIO:         Type %Comp Blocks     Tot Blocks Blksize    ElpTime(s) IO Rt(b/s) Name [11:21:48.006] (krmkqio)
DBGIO:         ---- ----- ---------- ---------- ---------- ---------- ---------- ----- [11:21:48.007] (krmkqio)
DBGIO:         IN   72.6  26368      36320      8192       11         19636968   /u02/oradata/orcl/users01.dbf [11:21:48.007] (krmkqio)
DBGIO:         OUT        3737                  8192       12         2551125    /u01/app/oracle/fast_recovery_area/ORCL/backupset/2012_04_12/o1_mf_nnndf_TAG20120412T112132_7rf7nx2s_.bkp [11:21:48.007] (krmkqio)
DBGIO:         AGG  72.6  26368      36320      8192       11         19636968     [11:21:48.007] (krmkqio)

Here we can see there’s less blocks writing to disk, and the IO rate is not the same than the default backup compression.

  • Uncompressed backup to disk using SBT libraries (Only for testing purpose, don’t use this in production)
[oracle@oel debug]$ rman target / debug trace debug_sbt.trc 
RMAN> run {
2> allocate channel 'tape1' type 'sbt_tape' parms 'SBT_LIBRARY=oracle.disksbt,ENV=(BACKUP_DIR=/u02/sbt_bkp)';
3> backup as backupset datafile 4;
4> }

[oracle@oel debug]$ grep DBGIO debug_sbt.trc
DBGIO:         channel tape1: set_stamp=780405909 set_count=64 [11:25:09.810] (budf_start)
DBGIO:         channel tape1: blocks=36320 block_size=8192 [11:25:10.061] (budf_name)
DBGIO:         Type %Comp Blocks     Tot Blocks Blksize    ElpTime(s) IO Rt(b/s) Name [11:25:45.304] (krmkqio)
DBGIO:         ---- ----- ---------- ---------- ---------- ---------- ---------- ----- [11:25:45.304] (krmkqio)
DBGIO:         IN   100.0 36320      36320      8192       25         11901337   /u02/oradata/orcl/users01.dbf [11:25:45.304] (krmkqio)
DBGIO:         OUT        36352                 8192       27         11029466   20n8834l_1_1 [11:25:45.304] (krmkqio)
DBGIO:         AGG  100.0 36320      36320      8192       25         11901337     [11:25:45.305] (krmkqio)

In this example, we can see that, when SBT channel is used, all the blocks of the datafile are read. We can verify this in the MOS note (360443.1):

Unused Block Compression cannot be used by:
  • 3rd party media managers – the whole file is scanned every time a tape backup is done
  • Incremental backups – to get faster incremenals use Block Change Tracking
  • RMAN backup VALIDATE command

Thanks to my colleague Pierre Labrousse (aka Pierre the great 😉 ) who gave me this precious note reference !

Dump ASM disk header … method #2

In a previous post, I explained how to dump ASM Disk header and how to analyze it. This method, which used kfed binary, is a little bit complex because of fields with a complex name extracted from the internal structure.

Another way to proceed and to see main information about asm disks is to use an undocumented binary located in $ORACLE_HOME/bin named amdu.

If amdu is not available in your $ORACLE_HOME/bin directory, you can build it with the next make command:

[oracle@oel ~]$ make -f $ORACLE_HOME/rdbms/lib/ins_rdbms.mk iamdu

To dump your ASM diskheader, you just have to execute this command with the -diskstring option and specify the location of your ASM disk devices (default uses ASM lib directory):

[oracle@oel ~]$ amdu -diskstring='/dev/oracleasm/disks/*'
amdu_2012_03_21_11_14_36/

Now, change directory to the output generated and have a look to the report.txt file:

[oracle@oel ~]$ cd amdu_2012_03_21_11_14_36/
[oracle@oel amdu_2012_03_21_11_14_36]$ cat report.txt
-*-amdu-*-
******************************* AMDU Settings ********************************
ORACLE_HOME = /u01/app/oracle/product/11.2.0.3/dbhome_1
System name: Linux
Node name: oel
Release: 2.6.18-274.18.1.0.1.el5
Version: #1 SMP Thu Feb 9 19:07:16 EST 2012
Machine: x86_64
amdu run: 21-MAR-12 11:14:36
Endianess: 1
--------------------------------- Operations ---------------------------------
------------------------------- Disk Selection -------------------------------
 -diskstring '/dev/oracleasm/disks/*'
------------------------------ Reading Control -------------------------------
------------------------------- Output Control -------------------------------
********************************* DISCOVERY **********************************
----------------------------- DISK REPORT N0001 ------------------------------
 Disk Path: /dev/oracleasm/disks/ASM1
 Unique Disk ID:
 Disk Label:
 Physical Sector Size: 512 bytes
 Disk Size: 1019 megabytes
 Group Name: DATA
 Disk Name: DATA_0000
 Failure Group Name: DATA_0000
 Disk Number: 0
 Header Status: 3
 Disk Creation Time: 2011/05/27 10:57:54.822000
 Last Mount Time: 2012/03/21 08:54:10.221000
 Compatibility Version: 0x0b200000(11020000)
 Disk Sector Size: 512 bytes
 Disk size in AUs: 1019 AUs
 Group Redundancy: 1
 Metadata Block Size: 4096 bytes
 AU Size: 1048576 bytes
 Stride: 113792 AUs
 Group Creation Time: 2011/05/27 10:57:54.456000
 File 1 Block 1 location: AU 2
 OCR Present: NO
----------------------------- DISK REPORT N0002 ------------------------------
 Disk Path: /dev/oracleasm/disks/ASM2
 Unique Disk ID:
 Disk Label:
 Physical Sector Size: 512 bytes
 Disk Size: 1019 megabytes
 Group Name: DATA
 Disk Name: DATA_0001
 Failure Group Name: DATA_0001
 Disk Number: 1
 Header Status: 3
 Disk Creation Time: 2011/05/27 10:57:54.822000
 Last Mount Time: 2012/03/21 08:54:10.221000
 Compatibility Version: 0x0b200000(11020000)
 Disk Sector Size: 512 bytes
 Disk size in AUs: 1019 AUs
 Group Redundancy: 1
 Metadata Block Size: 4096 bytes
 AU Size: 1048576 bytes
 Stride: 113792 AUs
 Group Creation Time: 2011/05/27 10:57:54.456000
 File 1 Block 1 location: AU 0
 OCR Present: NO
******************************* END OF REPORT ********************************

As mentioned, now you know if your disk is part of a disk group, the DG Allocation Unit size, disk size, last mounted time etc.

Of course, this tool can be used regarless of the asm instance status.

 

 

Trace Oracle CBO computations for a specific sql_id

In this post, I will explain how to trace CBO computation (aka 10053 event) for a specific sql_id and in another session.

To do this, we need to know two things:

1) How to trace another session? To do this, I will use undocumented oracle tool “oradebug”. More precisely, I will use the new event declaration syntax which is not based on event id.

2) How to trace CBO computation for a specific sql_id? To do this, I will use the new event declaration syntax (more details in the demonstration above)

To demonstrate this trick, I will consider two sessions:

– The first session (S1) is logged as an application user named LAURENT. This user owns two table T1 and T4, and we only want to trace a specific SQL Query (select count(*) from t4 where id between 500 and 550;).

– The second session (S2) is logged as SYS user who will launch oradebug commands.

* S1 (logged as LAURENT)

SQL> select count(*) from t4 where id between 500 and 550;
COUNT(*)
----------
 51

* S2 (logged as SYS) : querying the dictionary to obtain sql_id associated to the SQL query:

SQL> select sql_id,sql_text from v$sql
 2 where sql_text like 'select count(*) from t4 where id between 500 and 550%';
SQL_ID        SQL_TEXT
------------- --------------------------------------------------------------------------------
2zg40utr7a08n select count(*) from t4 where id between 500 and 550

* S1 (logged as LAURENT): obtain Oracle PID and system PID (spid) of the session we will trace. This information will be used for oradebug in the next step.

SQL> select pid,spid from v$process
 2 where addr=(select paddr from v$session
 3 where sid=(select sid from v$mystat where rownum=1));
PID        SPID
---------- ---------
25         4850

* S2 (Logged as SYS) : we will use oradebug new features to trace a specific sql_id by using the new syntax for tracing CBO Computations (trace[RDBMS.SQL_Optimizer.*])

SQL> ALTER SYSTEM FLUSH SHARED_POOL;
SQL> -- Setting Oracle PID to trace and verify by crossing the result of the system pid
SQL> oradebug setorapid 25
Oracle pid: 25, Unix process pid: 4850, image: oracle@oel (TNS V1-V3)
SQL> -- nolimit to tracefile
SQL> oradebug unlimit
Statement processed.
SQL> -- tracing SQL_Optimizer computation for a specific sql (here's our sql_id)
SQL> oradebug event trace[RDBMS.SQL_Optimizer.*][sql:2zg40utr7a08n]
Statement processed.
SQL> -- obtain the trace file name
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4850.trc

NB : Flushing shared pool is mandatory if you have already shared cursor for the statement to trace in the shared pool.

 

* S1 (Logged as LAURENT) : execute many sql statements in the session including our specific sql statement:

S1 (execute sql_id 2zg40utr7a08n one time, and others sql):
SQL> select count(*) from t4 where id between 500 and 550;
COUNT(*)
----------
 51

SQL> select count(*) from t4 ;
COUNT(*)
----------
 300000

SQL> select count(*) from t1;
COUNT(*)
----------
 294958

Finally, open the tracefile generated, you will only have the CBO computations and statistics for our specific sql_id:

[oracle@oel ~]$ vi /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4850.trc
Registered qb: SEL$1 0xe47325b8 (PARSER)
---------------------
QUERY BLOCK SIGNATURE
---------------------
 signature (): qb_name=SEL$1 nbfros=1 flg=0
 fro(0): flg=4 objn=78460 hint_alias="T4"@"SEL$1"
SPM: statement not found in SMB
**************************
Automatic degree of parallelism (ADOP)
**************************
Automatic degree of parallelism is disabled: Parameter.
PM: Considering predicate move-around in query block SEL$1 (#0)
**************************
Predicate Move-Around (PM)
**************************
OPTIMIZER INFORMATION
******************************************
----- Current SQL Statement for this session (sql_id=2zg40utr7a08n) -----
select count(*) from t4 where id between 500 and 550
*******************************************

.../...

Query Block Registry:
SEL$1 0xe47325b8 (PARSER) [FINAL]
:
 call(in-use=13920, alloc=49184), compile(in-use=88336, alloc=152104), execution(in-use=6016, alloc=8088)
End of Optimizer State Dump
Dumping Hints
=============
====================== END SQL Statement Dump ======================

Update : Bertrand Drouvot has blogged a tricky way to flush a specific sql_id before generating its CBO computation trace file. See link : http://bdrouvot.wordpress.com/2013/09/16/flush-a-single-sql-statement-and-capture-a-10053-trace-for-it/

 

Monitor how are used your table’s columns

If you want to know how are used your columns when they are involved in sql queries, you can use a specific function in the dbms_stats package called REPORT_COL_USAGE.

This function will give you what operation have been executed on your table columns, e.g. :

SQL> set lines 150 pages 400 long 20000000 longchunksize 50000
SQL> select dbms_stats.report_col_usage('SH','SALES') from dual;
DBMS_STATS.REPORT_COL_USAGE('SH','SALES')
-------------------------------------------------------------------------------
LEGEND:
.......
EQ : Used in single table EQuality predicate
RANGE : Used in single table RANGE predicate
LIKE : Used in single table LIKE predicate
NULL : Used in single table is (not) NULL predicate
EQ_JOIN : Used in EQuality JOIN predicate
NONEQ_JOIN : Used in NON EQuality JOIN predicate
FILTER : Used in single table FILTER predicate
JOIN : Used in JOIN predicate
GROUP_BY : Used in GROUP BY expression
...............................................................................
###############################################################################
COLUMN USAGE REPORT FOR SH.SALES
................................
1. AMOUNT_SOLD : EQ RANGE
###############################################################################

In the previous example, we can see the AMOUNT_SOLD column have been accessed with an equality and a range predicates.

If I execute a query which filter on the PROD_ID column, the report will be updated:

SQL> select count(*) from sh.sales where prod_id=400;
COUNT(*)
----------
 0
SQL> select dbms_stats.report_col_usage('SH','SALES') from dual;
DBMS_STATS.REPORT_COL_USAGE('SH','SALES')
--------------------------------------------------------------------------------
LEGEND:
.......
EQ : Used in single table EQuality predicate
RANGE : Used in single table RANGE predicate
LIKE : Used in single table LIKE predicate
NULL : Used in single table is (not) NULL predicate
EQ_JOIN : Used in EQuality JOIN predicate
NONEQ_JOIN : Used in NON EQuality JOIN predicate
FILTER : Used in single table FILTER predicate
JOIN : Used in JOIN predicate
GROUP_BY : Used in GROUP BY expression
...............................................................................
###############################################################################
COLUMN USAGE REPORT FOR SH.SALES
................................
1. AMOUNT_SOLD : EQ RANGE
2. PROD_ID : EQ
###############################################################################

Another feature of this package will report joins that have been done on the table columns (You can have a look to the legend which mentions what the function can report):

SQL> select count(*) from sh.sales s, sh.products p where s.prod_id=p.prod_id;
COUNT(*)
----------
 918843
SQL> select dbms_stats.report_col_usage('SH','SALES') from dual;
DBMS_STATS.REPORT_COL_USAGE('SH','SALES')
--------------------------------------------------------------------------------
LEGEND:
.......
EQ : Used in single table EQuality predicate
RANGE : Used in single table RANGE predicate
LIKE : Used in single table LIKE predicate
NULL : Used in single table is (not) NULL predicate
EQ_JOIN : Used in EQuality JOIN predicate
NONEQ_JOIN : Used in NON EQuality JOIN predicate
FILTER : Used in single table FILTER predicate
JOIN : Used in JOIN predicate
GROUP_BY : Used in GROUP BY expression
...............................................................................
###############################################################################
COLUMN USAGE REPORT FOR SH.SALES
................................
1. AMOUNT_SOLD : EQ RANGE
2. PROD_ID : EQ EQ_JOIN
###############################################################################

If you want to reset usage statistics, use the undocumented procedure RESET_COL_USAGE:

SQL> exec dbms_stats.reset_col_usage('SH','SALES');
PL/SQL procedure successfully completed.
SQL> select dbms_stats.report_col_usage('SH','SALES') from dual;
DBMS_STATS.REPORT_COL_USAGE('SH','SALES')
--------------------------------------------------------------------------------
LEGEND:
.......
EQ : Used in single table EQuality predicate
RANGE : Used in single table RANGE predicate
LIKE : Used in single table LIKE predicate
NULL : Used in single table is (not) NULL predicate
EQ_JOIN : Used in EQuality JOIN predicate
NONEQ_JOIN : Used in NON EQuality JOIN predicate
FILTER : Used in single table FILTER predicate
JOIN : Used in JOIN predicate
GROUP_BY : Used in GROUP BY expression
...............................................................................
###############################################################################
COLUMN USAGE REPORT FOR SH.SALES
................................
###############################################################################

Note: If you execute a query using a function based index, your column name will be the virtual column name used for applying the function:

SQL> exec dbms_stats.reset_col_usage('SH','SALES');
PL/SQL procedure successfully completed.
SQL> drop index idx;
Index dropped.
SQL> create index idx on sh.sales(amount_sold*2);
Index created.
SQL> set autotrace trace
SQL> select count(*) from sh.sales where amount_sold*2>40;

Execution Plan
----------------------------------------------------------
Plan hash value: 875048923
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 25 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX RANGE SCAN| IDX | 45873 | 582K| 25 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("AMOUNT_SOLD"*2>40)

Statistics
----------------------------------------------------------
 12 recursive calls
 0 db block gets
 1828 consistent gets
 1812 physical reads
 0 redo size
 528 bytes sent via SQL*Net to client
 524 bytes received via SQL*Net from client
 2 SQL*Net roundtrips to/from client
 7 sorts (memory)
 0 sorts (disk)
 1 rows processed
SQL> set autotrace off
SQL> select dbms_stats.report_col_usage('SH','SALES') from dual;
DBMS_STATS.REPORT_COL_USAGE('SH','SALES')
--------------------------------------------------------------------------------
LEGEND:
.......
EQ : Used in single table EQuality predicate
RANGE : Used in single table RANGE predicate
LIKE : Used in single table LIKE predicate
NULL : Used in single table is (not) NULL predicate
EQ_JOIN : Used in EQuality JOIN predicate
NONEQ_JOIN : Used in NON EQuality JOIN predicate
FILTER : Used in single table FILTER predicate
JOIN : Used in JOIN predicate
GROUP_BY : Used in GROUP BY expression
...............................................................................
###############################################################################
COLUMN USAGE REPORT FOR SH.SALES
................................
1. SYS_NC00008$ : RANGE
###############################################################################

If you want to desactivate this feature because your database contains a lot of tables and columns and you don’t want to overload your system, you can set the undocumented parameter “_column_tracking_level” to 0 (default value = 1).

All results of the DBMS_STATS.REPORT_COL_USAGE are based on the COL_USAGE$ dictionary table.

Finally, you can use this method to decide if a column needs a histogram or if it’s an unindexed column that needs one.