Saturday, January 22, 2011

SQL*Net - listener.ora

Sample listener.ora

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
      (ADDRESS = (PROTOCOL = TCP)(HOST = bloo)(PORT = 1521))
    )
  )

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = scr10)
      (ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1)
      (SID_NAME = scr10)
    )
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /u01/app/oracle/product/10gASM)
      (PROGRAM = extproc)
    )
  )

SQL*Net - tnsnames.ora



  • Sample dedicated connection


  • Listener entry

  • Sample dedicated connection

    SCR9 =
      (DESCRIPTION =
        (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = bloo)(PORT = 1521))
        )
        (CONNECT_DATA =
          (SERVER = DEDICATED)
          (SERVICE_NAME = scr9)
        )
      )
    

    Listener entry

    LISTENER_+ASM =
      (ADDRESS = (PROTOCOL = TCP)(HOST = bloo)(PORT = 1522))
    

    Miscellaneous - utl_file

    Create a test procedure

    create or replace procedure andy_file_test (
      path       in varchar2,
      filename   in varchar2,
      text  in varchar2
    )
    is
        output_file  utl_file.file_type;
    begin
        output_file := utl_file.fopen (path,filename, 'W');
    
        utl_file.put_line (output_file, text);
    
        utl_file.fclose(output_file);
    end;
    /
    

    Run the procedure

    execute andy_file_test('/home/oracle/andy/file_test','andy.txt','hello world');
    


    Miscellaneous - Useful UNIX



  • Find/Zip/Move/Delete files older than x days


  • Delete the 500 oldest files


  • Find and grep


  • list all files opened by a process


  • ls -l sorted by size


  • cpio unzip syntax


  • man commands


  • pipes


  • Turn off auto indent and bracket matching in vi


  • Capture a control charater


  • Configure ksh environment


  • Show routing tables


  • Check all logs for ORA- errors

  • Find/Zip/Move/Delete files older than x days

    find ./ -name "*.ARC" -mtime +1 -exec ls -l {} \;
    
    find ./ -name "*.ARC" -mtime +1 -exec rm {} \;
    find ./ -name "*.ARC" -mtime +1 -exec gzip {} \;
    find ./ -name "*.arch" -mtime +1 -exec mv {} /u01/andy/;
    

    Delete the 500 oldest files

    rm -f `ls -tr|head -500`
    

    Find and grep

    find ./ -grep <what> {} \; -print 2>/dev/null
    
    Or...
    find ./ -exec grep -l "string" {} \;


    list all files opened by a process

    lsof -p <pid>

    ls -l sorted by size

    ls -l |sort -k 5
    

    du -sk *|sort -n

    cpio unzip syntax

    cpio -idmv < <filename>
    

    man commands

    man -k <what> -displays the chapters containing the specified
    man <chapter> <what> -shows the page
    

    pipes

    mknod <name> p
    


    Turn off auto indent and bracket matching in vi

    :set noai nosm
    


    Capture a control charater
    ctl-v then press the control key (eg. backspace)

    Configure ksh environment
    To display the current settings
    set -o
    


    To set HP/UX stylee...
    set -o vi
    set -o vi-esccomplete
    

    Show routing tables

    netstat -r


    Check all logs for ORA- errors

    grep ^ORA- *log |cut -f2 -d"-"|cut -f1 -d:|awk '{print "ORA-" $1}'|sort -u
    

    Backup - Datapump



  • Create an oracle directory


  • create the default data pump directory


  • Export


  • Import

  • Create an oracle directory

    create directory my_dir as '/home/oracle/andyb';
    

    create the default data pump directory

    create directory data_pump_dir as '/u01/ora_backup/datapump';
    

    Export

    expdp system/****** schemas=andy dumpfile=andy.dp directory=my_dir
    

    Import

    impdp system/****** schemas=andy dumpfile=andy.dp directory=my_dir
    


    Backup - Flashback

    To put the session back in time
    Note. undo_management must be auto
    Note. Take a look at undo_retention to get an idea of how far back you might be able to go.
    Note. This can't be run as sys - system works though

    exec dbms_flashback.enable_at_time(to_date('2006-AUG-24 12:00:00', 'YYYY-MON-DD HH24:MI:SS'));
    
    To disable flashback run...
    exec dbms_flashback.disable;
    

    Copy old data into a new table
    First, create an empty copy of the source table...
    create table old_test_table
    tablespace andy
    as select *
    from test_table
    where rownum < 1
    /
    
    Now, insert the old data into it...
    insert /*+ APPEND */ old_test_table
     (select * from test_table as of timestamp
     to_timestamp('24-AUG-06 12:00:00','DD-MON-YY HH24:MI:SS'))
    /
    

    Export a database from a point in time

    exp / file=full_scr9.dmp log=full_scr9.log flashback_time=TO_TIMESTAMP('10-09-2006 09:00:00', 'DD-MM-YYYY HH24:MI:SS')
    
    exp / parfile=full_scr9.par
    parfile...
    userid=system/******
    file=full_scr9.dmp
    log=full_scr9.log
    flashback_time='2006-09-13 12:00:00'
    

    Find the current SCN number

    select dbms_flashback.get_system_change_number from dual
    /
    

    Set the database recovery directory and size
    These settings are dynamic
    alter system set db_recovery_file_dest='<path>' scope=both
    /
    alter system set db_recovery_file_dest_size=<size> scope=both
    /

    Set the flashback database retention target

    alter system set db_flashback_retention_target=<minutes> scope=both
    /
    


    Backup - Import-Export



  • Import/export to gzip through a pipe


  • Example parameter file


  • Example nohup script


  • Resumable import parameters

  • Import/export to gzip through a pipe
    to export to gzip...
    mknod andypipe p
    gzip < andypipe > filename.dmp.gz &
    exp ... file=andypipe ...
    

    and to import...
    mknod andypipe p
    gunzip -c filename.dmp.gz > andypipe &
    imp ... file=andypipe ...
    

    Example parameter file

    userid=/
    file=/u03/scr9/oradata/expimp/exppipe
    log=/u03/scr9/oradata/expimp/imp_scr9.log
    rows=y
    constraints=n
    ignore=y
    indexes=n
    grants=n
    full=n
    feedback=10000
    direct=y
    fromuser=andy,user2
    touser=andy,user2
    
    to use the file...
    exp parfile=<file>
    imp parfile=<file>


    Example nohup script

    #!/usr/bin/ksh
    export ORAENV_ASK=NO
    export ORACLE_SID=scr10
    . /usr/local/bin/oraenv
    rm andypipe 2>/dev/null
    mknod andypipe p
    gzip < andypipe > full_scr10.dmp.gz &
    exp / full=y indexes=N grants=N statistics=none file=andypipe log=full_scr10.log
    rm andypipe 2>/dev/null
    
    to use the script...
    chmod 700 <file>
    nohup ./<file> &
    

    Resumable import parameters

    resumable=y
    resumable_name=<name to apear in dba_resumable>
    resumable_timeout=<timeout in seconds>
    
    Note. If you are importing using a user other than sys or system, it will need the system priv 'resumable' granting to it:
    grant resumable to <user>;
    
    Note. If a resumable job hits a problem which causes it to be suspended, you will not necessarily see a message indicating that on the screen. You need to constantly monitor either the alert log or the dba_resumable view.
    set lines 100 pages 999
    col name format a20
    select name
    , start_time
    , suspend_time
    , status
    from dba_resumable
    /

    If the job gets suspended, you can see the reason why with the next query
    set lines 100 pages 999
    select error_msg
    from dba_resumable
    where name like '&resumable_name'
    /
    

    Backup - RMAN



  • Create a catalog


  • Register a database


  • Un-register a database


  • Reset the catalog after a restlogs on the target


  • Resync the catalog with the target controlfile


  • Delete a backup


  • Backup a database


  • Restore/recover a database


  • Show the controlfile backup record


  • Misc commands

  • Create a catalog

    create a tablespace
    create a user
    grant connect, resource, recovery_catalog_owner to user
    

    rman catalog user/pass@db
    create catalog tablespace "<tablespace_name>";

    Note. <tablespace_name> is case sensitive (i.e. it must be uppercase)

    Note. If you get the error 'rman: can't open catalog', make sure that oracle's rman is being run (which rman). X11 also has a command called rman. Rename it if necessary.


    Register a database
    Note. ensure the target db has a password file
    rman catalog user/pass@rmandb target user/pass@db
    

    register database;
    

    Un-register a database
    sqlplus user/pass@rmandb
    select * from rc_database;
    select db_key, db_id from db;

    execute dbms_rcvcat.unregisterdatabase(<db_key>, <db_id>);

    Reset the catalog after a restlogs on the target
    reset database;
    

    Resync the catalog with the target controlfile
    resync catalog;
    

    Delete a backup
    allocate channel...
    delete backuppiece <number>;
    release channel;
    

    Backup a database
    backup database plus archivelog format '/u01/ora_backup/rman/%d_%u_%s';
    

    run {
    allocate channel t1 type disk;
    backup current controlfile format '/u01/ora_backup/rman/%d_%u_%s';
    backup database format '/u01/ora_backup/rman/%d_%u_%s';
    backup archivelog all delete input format '/u01/ora_backup/rman/arch_%d_%u_%s';
    release channel t1;
    }
    

    run {
    allocate channel t1 type disk;
    backup archivelog all delete input format '/u01/ora_backup/rman/arch_%d_%u_%s';
    release channel t1;
    }
    

    Cold backup (archivelog or noarchivelog mode)
    run {
    allocate channel t1 type disk;
    shutdown immediate;
    startup mount;
    backup database include current controlfile format '/u01/ora_backup/rman/%d_%u_%s';
    alter database open;
    }

    run {
         allocate channel  t1 type disk;
         backup archivelog all delete input;
    }

    Restore/recover a database
    Full restore and recovery
    startup nomount;
    run {
      allocate channel  t1 type disk;
      allocate channel  t2 type disk;
      allocate channel  t3 type disk;
      allocate channel  t4 type disk;
      restore controlfile;
      restore archivelog all;
      alter database mount;
      restore database;
      recover database;
    }
    sql 'alter database open resetlogs';
    

    Restore and roll forward to a point in time
    startup nomount;
    run {
      set until time ="to_date('30/08/2006 12:00','dd/mm/yyyy hh24:mi')";
      allocate channel  t1 type disk;
      allocate channel  t2 type disk;
      allocate channel  t3 type disk;
      allocate channel  t4 type disk;
      restore controlfile;
      restore archivelog all;
      alter database mount;
      restore database;
      recover database;
    }
    sql 'alter database open resetlogs';
    

    If the archive logs are already in place:
    startup mount;
    run {
      set until time ="to_date('08/02/2007 14:00','dd/mm/yyyy hh24:mi')";
      allocate channel  t1 type disk;
      allocate channel  t2 type disk;
      allocate channel  t3 type disk;
      allocate channel  t4 type disk;
      restore database;
      recover database;
    }
    sql 'alter database open resetlogs';
    
    startup mount;
    run {
      allocate channel  t1 type disk;
      recover database;
    }
    

    Show the controlfile backup record
    set pages 999 lines 100
    col name format a60
    break on set_stamp skip 1
    select set_stamp
    , to_char(ba.completion_time, 'HH24:MI DD/MM/YY') finish_time
    , df.name
    from v$datafile  df
    , v$backup_datafile  ba
    where df.file# = ba.file#
    and ba.file# != 0
    order  by set_stamp, ba.file#
    /
    

    Misc commands
    list backupset;
    list backup of database;
    list backup of archivelog all;
    report obsolete;
    report obsolete redundancy = 2;
    delete obsolete; - remove unneeded backups
    restore database validate; - check the backup
    report unrecoverable;
    report schema; - show current db files
    crosscheck backup; - make sure the backups in the catalog still physically exist
    delete expired backup; - delete epired backups found by crosscheck
    rman target sys/*****@scr10 catalog rman/rman@dbarep
    LIST BACKUPSET OF DATABASE; 
    ALLOCATE CHANNEL FOR MAINTENANCE DEVICE TYPE DISK;
    DELETE OBSOLETE REDUNDANCY = 4 device type disk; 
    delete obsolete REDUNDANCY = 2 device type disk;
    

    Delete archive log older than...
    DELETE NOPROMPT ARCHIVELOG UNTIL TIME "SYSDATE-5"
    
    Crosscheck the available archivelogs (fixes RMAN-06059)
    change archivelog all crosscheck;
    

    Backup - DataGuard

    Startup commands

    startup nomount
    alter database mount standby database;
    alter database recover managed standby database disconnect;


    To remove a delay from a standby

    alter database recover managed standby database cancel;
    alter database recover managed standby database nodelay disconnect;
    
    Cancel managed recovery

    alter database recover managed standby database cancel;
    

    Register a missing log file

    alter database register physical logfile '<fullpath/filename>';
    

    If FAL doesn't work and it says the log is already registered

    alter database register or replace physical logfile '<fullpath/filename>';
    
    If that doesn't work, try this...
    shutdown immediate
    startup nomount
    alter database mount standby database;
    alter database recover automatic standby database;
    
    wait for the recovery to finish - then cancel
    shutdown immediate
    startup nomount
    alter database mount standby database;
    alter database recover managed standby database disconnect; 
    

    Check which logs are missing
    Run this on the standby...
    select local.thread#
    ,      local.sequence# from 
           (select thread#
           ,       sequence# 
           from    v$archived_log 
           where dest_id=1) local 
    where  local.sequence# not in 
           (select sequence#
           from v$archived_log
           where dest_id=2 and 
           thread# = local.thread#)
    /
    
    Disable/Enable archive log destinations

    alter system set log_archive_dest_state_2 = 'defer';
    alter system set log_archive_dest_state_2 = 'enable';
    

    Turn on fal tracing on the primary db

    alter system set LOG_ARCHIVE_TRACE = 128;
    

    Stop the Data Guard broker

    alter system set dg_broker_start=false
    /
    

    Show the current instance role

    select database_role
    from v$database
    /
    

    Logical standby apply stop/start
    Stop...
    alter database stop logical standby apply;
    
    Start...
    alter database start logical standby apply;
    

    See how up to date a physical standby is
    Run this on the primary
    set numwidth 15
    select max(sequence#) current_seq
    from v$log
    /
    
    Then run this on the standby
    set numwidth 15
    select max(applied_seq#) last_seq
    from v$archive_dest_status
    /
    
    Display info about all log destinations
    To be run on the primary
    set lines 100
    set numwidth 15
    column ID format 99
    column "SRLs" format 99 
    column active format 99 
    col type format a4
    
    select ds.dest_id id
    , ad.status
    , ds.database_mode db_mode
    , ad.archiver type
    , ds.recovery_mode
    , ds.protection_mode
    , ds.standby_logfile_count "SRLs"
    , ds.standby_logfile_active active
    , ds.archived_seq#
    from v$archive_dest_status ds
    , v$archive_dest  ad
    where ds.dest_id = ad.dest_id
    and ad.status != 'INACTIVE'
    order by
     ds.dest_id
    /
    

    Display log destinations options
    To be run on the primary
    set numwidth 8 lines 100
    column id format 99 
    select dest_id id
    , archiver
    , transmit_mode
    , affirm
    , async_blocks async
    , net_timeout net_time
    , delay_mins delay
    , reopen_secs reopen
    , register,binding 
    from v$archive_dest
    order by
     dest_id
    /
    

    List any standby redo logs

    set lines 100 pages 999
    col member format a70
    select st.group#
    , st.sequence#
    , ceil(st.bytes / 1048576) mb
    , lf.member
    from v$standby_log st
    , v$logfile lf
    where st.group# = lf.group#
    /
    

    Performance - AWR



  • Display a list of snapshots


  • Produce a report


  • To see the snapshot interval and retention period


  • Change the snapshot interval


  • Change the retention period


  • Manually take a snapshot


  • List all baselines


  • Create a baseline


  • Remove a baseline


  • Enable/Disable automatic snapshots


  • Time model queries


  • Produce an Active Session History (ASH) report

  • Display a list of snapshots

    set lines 100 pages 999
    select snap_id
    , snap_level
    , to_char(begin_interval_time, 'dd/mm/yy hh24:mi:ss') begin
    from dba_hist_snapshot 
    order by 1
    /
    

    Produce a report

    @?/rdbms/admin/awrrpt.sql 
    
    To see the snapshot interval and retention period

    col snap_interval format a30
    col retention format a30
    select snap_interval
    , retention
    from dba_hist_wr_control
    /
    

    Change the snapshot interval
    Note. This example changes it to 30 minutes
    exec dbms_workload_repository.modify_snapshot_settings (interval => 30)
    

    Change the retention period
    Note. This example changes it to two weeks (14 days)
    exec dbms_workload_repository.modify_snapshot_settings (retention => 14*24*60)

    Manually take a snapshot

    exec dbms_workload_repository.create_snapshot
    

    List all baselines

    set lines 100
    col baseline_name format a40
    select baseline_id
    , baseline_name
    , start_snap_id
    , end_snap_id 
    from dba_hist_baseline
    order by 1
    /
    

    Create a baseline

    exec dbms_workload_repository.create_baseline (<start snap>, <endsnap>,'<name>')
    

    Remove a baseline

    exec dbms_workload_repository.drop_baseline('<baseline name>')
    

    Enable/Disable automatic snapshots
    Note. This job is enabled by default
    exec dbms_scheduler.enable('GATHER_STATS_JOB')
    

    and to disable...
    exec dbms_scheduler.disable('GATHER_STATS_JOB')
    

    Time model queries
    System time model
    set lines 100 pages 999
    select stat_name
    , value
    from v$sys_time_model
    order by value desc
    /
    
    Session time model
    set lines 100 pages 999
    select stat_name
    , value
    from v$sess_time_model
    where sid = '&sid'
    order by value desc
    /
    

    Produce an Active Session History (ASH) report

    @?/rdbms/admin/ashrpt.sql
    

    Performance - Statspack




  • Take a snapshot



  • Delete one or more snapshots



  • Generate a report



  • List snapshots



  • Install statspack



  • Uninstall statspack



  • Schedule and hourly snapshot

  • Take a snapshot

    exec statspack.snap;
    
    Or to specify a level...
    exec statspack.snap(i_snap_level => 6, i_modify_parameter => 'true');
    
    Level 0 - This level captures general statistics, including rollback segment, row cache, SGA, system events, background events, session events, system statistics, wait statistics, lock statistics, and Latch information.

    Level 5 - This level includes capturing high resource usage SQL Statements, along with all data captured by lower levels.

    Level 6 - This level includes capturing SQL plan and SQL plan usage information for high resource usage SQL Statements, along with all data captured by lower levels.

    Level 7 - This level captures segment level statistics, including logical and physical reads, row lock, itl and buffer busy waits, along with all data captured by lower levels.

    Level 10 - This level includes capturing Child Latch statistics, along with all data captured by lower levels.


    Delete one or more snapshots

    @?/rdbms/admin/sppurge;
    
    Generate a report
    @?/rdbms/admin/spreport.sql
    
    List snapshots
    col "Date/Time" format a30
    select snap_id
    ,       snap_level
    , to_char(snap_time,'HH24:MI:SS DD-MM-YYYY') "Date/Time"
    from stats$snapshot
    , v$database
    order by snap_id
    /
    
    Install statspack
    1. Create a tablespace (minimum size 100MB)
    2. Run...
    @?/rdbms/admin/spcreate
    
    Uninstall statspack
    @?/rdbms/admin/spdrop
    

    Schedule and hourly snapshot
    @?/rdbms/admin/spauto.sql
    
    Note. This uses dbms_job, so job_queue_processes needs to be set greater than 0.

    To see the job:
    select job
    , what
    from dba_jobs
    /
    
    To delete the job:
    exec dbms_job.remove(<job number>);
    

    Performance - Memory

    SGA breakdown

    set lines 100 pages 999
    col bytes format 999,999,999
    compute sum of bytes on pool
    break  on pool skip 1
    select pool
    , name
    , bytes
    from  v$sgastat
    order  by pool
    , name
    /
    
    PGA usage by username

    select st.sid "SID",
     sn.name "TYPE",
     ceil(st.value / 1024 / 1024) "MB"
    from v$sesstat st,
     v$statname sn
    where st.statistic# = sn.statistic#
    and  sid in (select sid
      from v$session
      where username like '&user')
    and upper(sn.name) like '%PGA%'
    order by st.sid,
      st.value desc
    /
    
    Display pool usage

    select name
    , sum(bytes)
    from v$sgastat
    where pool like 'shared pool'
    group by name
    /
    

    Performance - Query Tuning

    Create a plan table

    @?/rdbms/admin/utlxplan.sql 
    

    Autotrace
    To switch it on:
    column plan_plus_exp format a100
    
    set autotrace on explain   # Displays the execution plan only. 
    set autotrace traceonly explain # dont run the query
    set autotrace on  # Shows the execution plan as well as statistics of the statement. 
    set autotrace on statistics  # Displays the statistics only. 
    set autotrace traceonly      # Displays the execution plan and the statistics
    

    To switch it off:
    set autotrace off  

    Explain plan

    explain plan for
    select ...
    

    or...
    explain plan set statement_id = 'bad1' for
    select...
    

    Then to see the output...
    set lines 100 pages 999
    @?/rdbms/admin/utlxpls
    

    Find a query's hash
    Put something unique in the like clause
    select hash_value, sql_text
    from v$sqlarea
    where sql_text like '%TIMINGLINKS%FOLDERREF%'
    /
    
    Grab the sql associated with a hash

    select sql_text
    from v$sqlarea
    where hash_value = '&hash'
    /
    
     
    Look at a query's stats in the sql area
    select executions
    , cpu_time
    , disk_reads
    , buffer_gets
    , rows_processed
    , buffer_gets / executions
    from v$sqlarea
    where hash_value = '&hash'
    /
    

    Performance - Statistics



  • Gather database statistics


  • Gather stats for a single schema...


  • Delete stats


  • Gather system stats


  • Export/Import optimizer statistics


  • Old style analyze


  • Show a count of analyezed tables broken down by schema


  • Show tables that have analyze dates older than today

  • Gather database statistics
    Gather stats on the entire database...
    execute dbms_stats.gather_database_stats;

    Or...
    execute dbms_stats.gather_database_stats( -
    estimate_percent => 1, -
    method_opt => 'FOR ALL COLUMNS SIZE 1',-
    cascade => TRUE);
    

    Gather stats for a single schema...

    execute dbms_stats.gather_schema_stats('SCOTT');
    
    Or...
    execute dbms_stats.gather_schema_stats( -
    ownname => 'SCOTT', -
    estimate_percent => 1, -
    method_opt => 'FOR ALL COLUMNS SIZE 1',-
    cascade => TRUE);
    
    You can let oracle come up with the estimate figure by using dbms_stats.auto_sample_size

    or...
    execute dbms_stats.gather_schema_stats( -
    ownname => 'SYS', -
    cascade => TRUE);
    
    Table statistics
    exec dbms_stats.gather_table_stats('<owner>', '<table_name>');
    

    Delete stats

    exec dbms_stats.delete_database_stats;
    
    exec dbms_stats.delete_schema_stats('SCOTT');
    
    exec dbms_stats.delete_table_stats('SCOTT', 'EMPLOYEES');
    exec dbms_stats.delete_index_stats('SCOTT', 'EMPLOYEES_PK');

    Gather system stats

    execute dbms_stats.gather_system_stats('Start');
    

    Wait for a while - idealy with the database under a typical workload
    execute dbms_stats.gather_system_stats('Stop');
    
    To see the current system statistics
    select pname
    , pval1 
    from  sys.aux_stats$ 
    where  sname = 'SYSSTATS_MAIN'
    /
    
    Export/Import optimizer statistics
    Create a table to hold the statistics...
    exec dbms_stats.create_stat_table(ownname => 'SYS',-
    stattab => 'prod_stats', tblspace => 'USERS'); 
    
    Populate the table with the current stats...
    exec dbms_stats.export_schema_stats(ownname => 'SCOTT',-
    statown=>'SYS', stattab=>'prod_stats');

    At this point you need to:
    1) take an export of the 'prod_stats' table
    2) import 'prod_stats' into the target database
    3) load the statistics using this command...
    exec dbms_stats.import_schema_stats(ownname => 'SCOTT',-
    statown=>'SYS', stattab=>'prod_stats');
    

    Old style analyze

    analyze table employees compute statistics;
    
    analyze table employees estimate statistics sample 100 rows;

    analyze table employees estimate statistics sample 15 percent;
    analyze index employees_ind compute statistics;
    

    Show a count of analyezed tables broken down by schema

    set pages 999 lines 100
    select a.owner
    , a.total_tables tables
    , nvl(b.analyzed_tables,0) analyzed
    from (select owner
     , count(*) total_tables
     from dba_tables
     group by owner) a
    , (select owner
     , count(last_analyzed) analyzed_tables
     from dba_tables
     where last_analyzed is not null
     group by owner) b
    where a.owner = b.owner (+)
    and a.owner not in ('SYS', 'SYSTEM')
    order by a.total_tables - nvl(b.analyzed_tables,0) desc
    /
    

    Show tables that have analyze dates older than today
    This is useful if you are running an analyze and want to see how much is left to do
    select count(last_analyzed) left_to_do
    from dba_tables
    where owner = '&schema'
    and trunc(last_analyzed) < trunc(sysdate)
    order by 1
    /
    

    Performance - Waits



  • Top ten hotest objects by touch count


  • Waits by file


  • Segment Waits


  • Time waited for latches


  • Identify hot blocks


  • Look at the performance stats for the instance

  • Top ten hotest objects by touch count

    col owner  format a20 trunc
    col object_name format a30
    col touches  format 9,999,999
    select *
    from (
     select count(*)
     , sum(tch) TOUCHES
     , u.name OWNER
     , o.name OBJECT_NAME
     from  x$bh x
     , obj$ o
     , user$ u
     where x.obj = o.obj#
     and o.owner# = u.user#
     group  by u.name, o.name
       order by 2 desc
     )
    where rownum < 11
    /
    

    Waits by file

    col name format a60
    select name
    , count 
    from x$kcbfwait
    , v$datafile
    where indx + 1 = file#
    order by 2
    /
    


    Segment Waits

    select object_name
    , obj#
    , statistic_name
    , value
    from v$segment_statistics
    where owner like '&owner'
    and statistic_name like '%waits%'
    and value > 0
    order by statistic_name
    ,  value desc
    /
    


    Time waited for latches

    col event format a30
    select event
    , time_waited
    , round(time_waited*100/ SUM (time_waited) OVER(),2) wait_pct
    from (
     select event
     , time_waited
     from v$system_event
     where event not in (
      'Null event'
      ,'client message'
      ,'rdbms ipc reply'
      ,'smon timer'
      ,'rdbms ipc message'
      ,'PX Idle Wait'
      ,'PL/SQL lock timer'
      ,'file open'
      ,'pmon timer'
      ,'WMON goes to sleep'
      ,'virtual circuit status'
      ,'dispatcher timer'
      ,'SQL*Net message from client'
      ,'parallel query dequeue wait'
      ,'pipe get')
     union
      (
      select name
      ,  value
      from v$sysstat
      where name like 'CPU used when call started'
      )
     )
    order by 2 desc
    /
    


    Identify hot blocks
    Look at all waits for the instance
    col event format a30
    select  event
    , total_waits
    , time_waited
    from v$system_event 
    where event like '%wait%'
    order  by 2,3
    /
    


    If there are lots of 'data block' waits, get a break-down of them
    select *
    from v$waitstat
    /
     
    Then run this to identify the file, block and reason code...
    select p1 "File #"
    , p2 "Block #"
    , p3 "Reason Code"
    from v$session_wait
    where event = 'buffer busy waits'
    /
     
    Note. You might need to run this a few times before anything is displayed.
    
     
    Look at the performance stats for the instance
    select n.name
    , s.value
    from v$statname n
    , v$sysstat s
    where n.statistic# = s.statistic#
    order  by n.class
    , n.name
    /
    

    Performance - Locks DDL



  • Show all ddl locks in the system


  • Slightly more simple version of the above


  • Generate kill statement for ddl locking sessions

  • Show all ddl locks in the system

    select decode(lob.kglobtyp, 
      0, 'NEXT OBJECT', 1, 'INDEX', 2, 'TABLE', 3, 'CLUSTER',
      4, 'VIEW', 5, 'SYNONYM', 6, 'SEQUENCE',
      7, 'PROCEDURE', 8, 'FUNCTION', 9, 'PACKAGE',
      11, 'PACKAGE BODY', 12, 'TRIGGER',
      13, 'TYPE', 14, 'TYPE BODY',
      19, 'TABLE PARTITION', 20, 'INDEX PARTITION', 21, 'LOB',
      22, 'LIBRARY', 23, 'DIRECTORY', 24, 'QUEUE',
      28, 'JAVA SOURCE', 29, 'JAVA CLASS', 30, 'JAVA RESOURCE',
      32, 'INDEXTYPE', 33, 'OPERATOR',
      34, 'TABLE SUBPARTITION', 35, 'INDEX SUBPARTITION',
      40, 'LOB PARTITION', 41, 'LOB SUBPARTITION',
      42, 'MATERIALIZED VIEW',
      43, 'DIMENSION',
      44, 'CONTEXT', 46, 'RULE SET', 47, 'RESOURCE PLAN',
      48, 'CONSUMER GROUP',
      51, 'SUBSCRIPTION', 52, 'LOCATION',
      55, 'XML SCHEMA', 56, 'JAVA DATA',
      57, 'SECURITY PROFILE', 59, 'RULE',
      62, 'EVALUATION CONTEXT','UNDEFINED'
     ) object_type
    , lob.kglnaobj object_name
    , pn.kglpnmod lock_mode_held
    , pn.kglpnreq lock_mode_requested
    , ses.sid
    , ses.serial#
    , ses.username
    from v$session_wait vsw
    , x$kglob  lob
    , x$kglpn  pn
    , v$session ses
    where vsw.event = 'library cache lock'
    and vsw.p1raw = lob.kglhdadr
    and lob.kglhdadr = pn.kglpnhdl
    and pn.kglpnmod != 0
    and pn.kglpnuse = ses.saddr
    /
    


    Slightly more simple version of the above

    select ses.username
    , ddl.session_id
    , ses.serial#
    , owner || '.' || ddl.name object
    , ddl.type
    , ddl.mode_held
    from dba_ddl_locks ddl
    , v$session ses
    where owner like '%userid%'
    and ddl.session_id = ses.sid
    /
    


    Performance - Locks DML

    Show sessions that are blocking each other

    select 'SID ' || l1.sid ||' is blocking  ' || l2.sid blocking
    from v$lock l1, v$lock l2
    where l1.block =1 and l2.request > 0
    and l1.id1=l2.id1
    and l1.id2=l2.id2
    /
    
    Show locked objects

    set lines 100 pages 999
    col username  format a20
    col sess_id  format a10
    col object format a25
    col mode_held format a10
    select oracle_username || ' (' || s.osuser || ')' username
    , s.sid || ',' || s.serial# sess_id
    , owner || '.' || object_name object
    , object_type
    , decode( l.block
     , 0, 'Not Blocking'
     , 1, 'Blocking'
     , 2, 'Global') status
    , decode(v.locked_mode
     , 0, 'None'
     , 1, 'Null'
     , 2, 'Row-S (SS)'
     , 3, 'Row-X (SX)'
     , 4, 'Share'
     , 5, 'S/Row-X (SSX)'
     , 6, 'Exclusive', TO_CHAR(lmode)) mode_held
    from v$locked_object v
    , dba_objects d
    , v$lock l
    , v$session s
    where  v.object_id = d.object_id
    and  v.object_id = l.id1
    and  v.session_id = s.sid
    order by oracle_username
    , session_id
    /
    

    Show which row is locked

    select do.object_name
    , row_wait_obj#
    , row_wait_file#
    , row_wait_block#
    , row_wait_row#
    , dbms_rowid.rowid_create (1, ROW_WAIT_OBJ#, ROW_WAIT_FILE#, 
        ROW_WAIT_BLOCK#, ROW_WAIT_ROW#)
    from v$session s
    , dba_objects do
    where sid=&sid
    and  s.ROW_WAIT_OBJ# = do.OBJECT_ID
    /
    
    Then select the row with that rowid...
    select * from <table> where rowid=<rowid>;
    
    List locks
    column lock_type format a12
    column mode_held format a10
    column mode_requested format a10
    column blocking_others format a20
    column username format a10
    SELECT session_id
    , lock_type
    , mode_held
    , mode_requested
    , blocking_others
    , lock_id1
    FROM dba_lock l
    WHERE  lock_type NOT IN ('Media Recovery', 'Redo Thread')
    /
    

    Performance - General

    Show currently exectuing sql

    select sql_text
    from v$sqlarea
    where users_executing > 0
    /
    


    Session statistics

    select sn.name
    , st.value
    from v$sesstat st
    , v$statname sn
    where st.STATISTIC# = sn.STATISTIC#
    and st.VALUE > 0
    and st.SID = &SID
    order  by value desc
    /
    


    Resource intensive sql
    change 8192 to match block size
    select sql_text
    ,      executions
    ,      to_char((((disk_reads+buffer_gets)/executions) * 8192)/1048576, '9,999,999,990.00')
       as total_gets_per_exec_mb
    ,      to_char((( disk_reads             /executions) * 8192)/1048576, '9,999,999,990.00')
       as disk_reads_per_exec_mb
    ,      to_char((( buffer_gets            /executions) * 8192)/1048576, '9,999,999,990.00')
       as buffer_gets_per_exec_mb
    ,      parsing_user_id
    from   v$sqlarea
    where  executions > 10
    order by 6 desc
    /
    
    db_cache_advice needs to be on for the above to work
    File io stats
    Requires timed_statistics=true
    set lines 80 pages 999
    col fname heading "File Name" format a60
    col sizemb heading "Size(Mb)" format 99,999
    col phyrds heading "Reads" format 999,999,999
    col readtim heading "Time" format 99.999
    col phywrts heading "Writes" format 9,999,999
    col writetim heading "Time" format 99.999
    select  lower(name) fname
    ,       (bytes / 1048576) sizemb
    ,       phyrds
    , readtim
    ,       phywrts
    , writetim
    from    v$datafile df
    ,       v$filestat fs
    where   df.file# = fs.file#
    order   by 1
    /
    
    In session tracing
    To switch it on:
    exec dbms_system.set_sql_trace_in_session (<sid>, <serial#>, true);
    

    To switch it off:
    exec dbms_system.set_sql_trace_in_session (<sid>, <serial#>, false);
    


    switch on event 10046
    To switch it on:
    alter session set events '10046 trace name context forever, level 8';

    To switch it off:
    alter session set events '10046 trace name context off'; 
    


    Rows per block

    select    avg(row_count) avg
    , max(row_count) max
    , min(row_count) min
    from      (
      select  count(*) row_count
      from    &table_name
      group   by substr(rowid, 1, 15)
      )
    /
    


    Show the buffer cache advisory
    Note. The current setting is halfway down and has a read factor of one.
    set lines 100 pages 999
    col est_mb format 99,999
    col estd_physical_reads format 999,999,999,999,999
    select size_for_estimate est_mb
    , estd_physical_read_factor
    , estd_physical_reads
    from v$db_cache_advice
    where name = 'DEFAULT'
    order by size_for_estimate
    /
    
    alter system set db_cache_advice=on;
    

    Structure - Triggers

    List triggers by schema

    set lines 100 pages 999
    select trigger_name
    , trigger_type
    , table_name
    , status
    from dba_triggers
    where owner = '&owner'
    order by status, table_name
    /
    

    Display all triggers on the specified table

    set lines 100 pages 999
    select trigger_name
    , trigger_type
    , status
    from dba_triggers
    where owner = '&owner'
    and table_name = '&table'
    order by status, trigger_name
    /
    

    Enable/Disable a trigger

    alter trigger <trigger_name> enable
    /
    
    or...
    alter trigger <trigger_name> disable
    /
    

    Structure - Partitions

    List partitioned tables

    set pages 999 lines 100
    col table_name format a40
    select table_name
    , partitioning_type type
    , partition_count partitions
    from dba_part_tables
    where owner = '&owner'
    order by 1
    /
    

    List a tables partitions

    set pages 999 lines 100
    col high_value format a20
    col tablespace_name format a20
    select partition_name
    , tablespace_name
    , high_value
    from dba_tab_partitions
    where table_owner = '&owner'
    and table_name = '&table_name'
    order by partition_position
    /
    


    Show partition sizes for the specified table

    set pages 999 lines 100
    col tablespace_name format a20
    col num_rows format 999,999,999
    select p.partition_name
    , p.tablespace_name
    , p.num_rows
    , ceil(s.bytes / 1024 / 1204) mb
    from dba_tab_partitions p
    , dba_segments s
    where p.table_owner = s.owner
    and p.partition_name = s.partition_name
    and  p.table_name = s.segment_name
    and p.table_owner = '&owner'
    and p.table_name = '&table_name'
    order by partition_position
    /
    
    Move a partition to a new tablespace

    alter table <table_name>
    move partition <partition_name>
    tablespace <tablespace_name>
    nologging
    /
    



    Add a partition

    alter table <table_name>
    add partition <partition_name> values less than (<value>)
    tablespace <tablespace_name>
    /
    
    or...
    alter table <table_name>
    add partition <partition_name> values (<value>)
    tablespace <tablespace_name>
    /
    


    Split a partition

    alter table <table_name>
    split partition <partition_name> at (<value>)
    into (partition <partition_name>, partition <partition_name>)
    update global indexes
    /
    
    Drop a partition

    alter table <table_name> drop partition <partition_name>
    /
    


    Truncate a partition

    alter table <table_name> truncate partition <partition_name>
    /
    

    Structure - Materialized view

    Create a view log for the master table
    This is required for fast refresh
    create materialized view log on <table>
    /
    
    or...
    create materialized view log on <table>
    tablespace <tablespace_name>
    /
    


    List all materialized view logs

    select  log_owner,log_table from dba_mview_logs
    /

    Create a simple materialized view

    create materialized view andy_mview
    refresh [fast | complete | force]
    start with sysdate
    next sysdate + 1/24
    with primary key
    as select * from test_table
    /
    
    Fast = update changes only
    Complete = wipe and repopulate the mview
    Force = fast if possible, complete if not.
     



    Show all materialized and resfresh times

    set lines 100 pages 999
    col last_refresh format a20
    select owner
    , mview_name
    , to_char(last_refresh_date, 'dd/mm/yy hh24:mi') last_refresh
    from dba_mviews
    order by owner, last_refresh
    /
    
    Output:
    OWNER           MVIEW_NAME                     LAST_REFRESH
    --------------- ------------------------------ --------------------
    APPS            LOCATION_PRODUCT_SVC           02/11/10 10:17
    APPS            MGIARPD_PTY_CORP_HIER_DOWN_MV  05/10/10 03:11
    APPS            MGIARPD_PTY_ASSC_HIER_DOWN_MV  05/10/10 03:20
    APPS            MGIAR_COUNTRY_MASTER           14/07/10 10:45
    APPS            MGIHZ_DMA                      14/07/10 10:46
    APPS            MGIAR_IDENTIFICATION_CAT       14/07/10 10:47
    APPS            MGIHZ_POSTAL_CODE              14/07/10 10:48

    Show materialized view tables and masters

    set lines 100
    col mview format a40
    col master format a40
    select owner || '.' || name mview
    , master_owner || '.' || master master
    from dba_mview_refresh_times
    /
    
    Output:
    MVIEW                                    MASTER
    ---------------------------------------- ----------------------------------------
    MSC.MSC_SUPPLIER_TREE_MV                 MSC.MSC_TRADING_PARTNERS
    MSC.MSC_ATP_PLAN_SN                      MSC.MSC_PLANS
    MSC.MSC_ATP_PLAN_SN                      MSC.MSC_APPS_INSTANCES
    MSC.MSC_ATP_PLAN_SN                      MSC.MSC_TRADING_PARTNERS
    MSC.MSC_ATP_PLAN_SN                      MSC.MSC_SYSTEM_ITEMS


    Show refresh jobs in dba_jobs
    This is useful for spotting failures
    set lines 100
    col job format 9999
    col log_user format a15
    col last format a15
    col next format a15
    col fail format 9999
    col what format a20
    select job
    , log_user
    , to_char(last_date, 'dd/mm/yy hh24:mi') last
    , to_char(next_date, 'dd/mm/yy hh24:mi') next
    , failures fail
    , replace(what, '"') what
    from dba_jobs
    where what like '%dbms_refresh.refresh%'
    /
    

    Structure - Constraints

    Show all constraints on a table

    col type format a10
    col cons_name format a30
    select decode(constraint_type,
      'C', 'Check',
      'O', 'R/O View',
      'P', 'Primary',
      'R', 'Foreign',
      'U', 'Unique',
      'V', 'Check view') type
    , constraint_name cons_name
    , status
    , last_change
    from dba_constraints
    where owner like '&owner'
    and table_name like '&table_name'
    order by 1
    /
    Output:
    Enter value for owner: ANDY
    old  12: where  owner like '&owner'
    new  12: where  owner like 'ANDY'
    Enter value for table_name: LOCATION
    old  13: and    table_name like '&table_name'
    new  13: and    table_name like 'LOCATION'
    
    TYPE       CONS_NAME                      STATUS   LAST_CHAN
    ---------- ------------------------------ -------- ---------
    Primary    LOCATION_PK                    ENABLED  15-OCT-07
    
    1 row selected.
    

    List tables that are using the specified table as a foreign key

    set lines 100 pages 999
    select a.owner
    , a.table_name
    , a.constraint_name
    from dba_constraints a
    , dba_constraints b
    where a.constraint_type = 'R'
    and  a.r_constraint_name = b.constraint_name
    and  a.r_owner  = b.owner
    and  b.owner = '&table_owner'
    and b.table_name = '&table_name'
    /
    Output:
    Enter value for table_owner: ANDY
    old   9: and    b.owner = '&table_owner'
    new   9: and    b.owner = 'ANDY'
    Enter value for table_name: LOCATION
    old  10: and    b.table_name = '&table_name'
    new  10: and    b.table_name = 'LOCATION'
    
    OWNER           TABLE_NAME                     CONSTRAINT_NAME
    --------------- ------------------------------ ------------------------------
    ANDY            BOX                            BOX_LOCATION_FK
    
    1 row selected.
    
    Same as above, but produces 'disable constraint' statements
    set lines 100 pages 999
    col discon format a100 
    select 'alter table '||a.owner||'.'||a.table_name||' disable constraint
    '||a.constraint_name||';' discon
    from dba_constraints a
    , dba_constraints b
    where a.constraint_type = 'R'
    and  a.r_constraint_name = b.constraint_name
    and a.r_owner  = b.owner
    and  b.owner = '&table_owner'
    and b.table_name = '&table_name'
    /
    
    Produce a list of disabled fk constraints
    set lines 100 pages 999
    col table format a60
    col constraint_name format a30
    select owner||'.'||table_name "table"
    , constraint_name
    from dba_constraints
    where status = 'DISABLED'
    and constraint_type = 'R'
    and owner not in ('SYS','SYSTEM')
    order by 1,2
    /
    
    Produce enable statements all disabled fk constraints
    set lines 100 pages 999
    select 'alter table '||owner||'.'||table_name||' enable constraint
    '||constraint_name||';' "enable"
    from dba_constraints
    where status = 'DISABLED'
    and constraint_type = 'R'
    and owner not in ('SYS','SYSTEM')
    order by 1
    /
    
    List parent tables that may need fixing/re-importing
    select distinct r.owner || '.' || r.table_name "exp"
    from dba_constraints c
    , dba_constraints r
    where c.status = 'DISABLED'
    and c.constraint_type = 'R'
    and c.r_owner = r.owner
    and c.r_constraint_name = r.constraint_name
    and c.owner not in ('SYS','SYSTEM')
    order by 1
    /
    
    List missing foriegn key values
    Note. Useful for resolving ORA-02298
    select  'select '||cc.column_name-
            ||' from '||c.owner||'.'||c.table_name-
            ||' a where not exists (select ''x'' from '-
            ||r.owner||'.'||r.table_name-
            ||' where '||rc.column_name||' = a.'||cc.column_name||')'
    from    dba_constraints c,
            dba_constraints r,
            dba_cons_columns cc,
            dba_cons_columns rc
    where   c.constraint_type = 'R'
    and     c.owner not in ('SYS','SYSTEM')
    and     c.r_owner = r.owner
    and     c.owner = cc.owner
    and     r.owner = rc.owner
    and     c.constraint_name = cc.constraint_name
    and     r.constraint_name = rc.constraint_name
    and     c.r_constraint_name = r.constraint_name
    and     cc.position = rc.position
    and     c.owner = '&table_owner'
    and     c.table_name = '&table_name'
    and     c.constraint_name = '&constraint_name'
    order   by c.owner, c.table_name, c.constraint_name, cc.position
    /
    
    Show all table constraints for a user
    Note. This still needs some work...
    set lines 100 pages 999
    break on table_name
    select  table_name
    , decode(constraint_type, 
             'C', 'Check', 
             'O', 'R/O View', 
             'P', 'Primary', 
             'R', 'Foreign', 
             'U', 'Unique', 
             'V', 'Check view') type
    , nvl(index_name, R_CONSTRAINT_NAME) "IDX"
    from  dba_constraints
    where owner like '&user'
    order by table_name
    , decode(constraint_type, 
     'P','0','R','1','U','2','C','3','O','4','V','5')
    /
    
    Output:
    Enter value for user: ANDY
    old  11: where  owner like '&user'
    new  11: where  owner like 'ANDY'
    
    TABLE_NAME                     TYPE       IDX
    ------------------------------ ---------- ------------------------------
    BOX                            Primary    BOX_PK
                                   Foreign    LOCATION_PK
    CD                             Primary    CD_PK
                                   Foreign    BOX_PK
    LOCATION                       Primary    LOCATION_PK
    LOTS_OF_ROWS                   Primary    SYS_C0023467
    TEST_TABLE                     Primary    SYS_C0027234
    TRACK                          Primary    TRACK_PK
                                   Foreign    CD_PK
    
    9 rows selected.
    

    Structure - Undo

    Display the rollback segments

    select segment_name
    , status
    from dba_rollback_segs
    /
    Output:
    _SYSSMU17$                     ONLINE
    _SYSSMU18$                     ONLINE
    _SYSSMU19$                     OFFLINE
    _SYSSMU20$                     OFFLINE

    4 rows selected.

    Alter undo retention

    alter system set undo_retention=500 scope=memory;


    What's in undo

    select tablespace_name
    , status
    , count(*) as HOW_MANY
    from dba_undo_extents
    group by tablespace_name
    , status
    /
    Output:
    TABLESPACE_NAME                          STATUS     HOW_MANY
    ---------------------------------------- -------- ----------
    UNDOTBS2                                 EXPIRED         129
    UNDOTBS2                                 UNEXPIRED         3
    
    2 rows selected.
    

    Is anything rolling back at the moment?
    Look for the used_ublk value decreasing. If it is, the session connected with it is rolling back. When it reaches zero, rollback is complete.
    set lines 100 pages 999
    col username format a15
    col command format a20
    select ses.username
    , substr(ses.program, 1, 19) command
    , tra.used_ublk
    from v$session ses
    , v$transaction tra
    where ses.saddr = tra.ses_addr
    /
    Output:
    USERNAME        COMMAND                    USED_UBLK
    --------------- -------------------- ---------------
    MTDFUSR         sqlplus.exe                        1
    ACTUATE         fctsrvr9.exe                       1
    APPS            frmweb@pmnblx1104 (                1
    APPS            Toad.exe                           1
    APPS            JDBC Thin Client                   1

    Structure - Redo Logs

    Remove drop

    alter database drop logfile member '<filename>';
    

    add logfile members

    alter database add logfile member '<filename>' to group <group>;
    


    List members and sizes

    col member format a60
    col "Size MB" format 9,999,999
    select lf.member
    , ceil(lg.bytes / 1024 / 1024) "Size MB"
    from v$logfile lf
    , v$log lg
    where lg.group# = lf.group#
    order by 1
    /
    Output:
    MEMBER                                                          Size MB
    ------------------------------------------------------------ ----------
    +Q_FRA/orq2/onlinelog/log01a.dbf                                  512
    +Q_FRA/orq2/onlinelog/log01b.dbf                                  512
    +Q_FRA/orq2/onlinelog/log02a.dbf                                  512
    +Q_FRA/orq2/onlinelog/log02b.dbf                                  512
    +Q_FRA/orq2/onlinelog/log03a.dbf                                  512
    +Q_FRA/orq2/onlinelog/log03b.dbf                                  512
    +Q_FRA/orq2/onlinelog/log04a.dbf                                  512
    +Q_FRA/orq2/onlinelog/log04b.dbf                                  512
    +Q_FRA/orq2/onlinelog/log05a.dbf                                  512
    +Q_FRA/orq2/onlinelog/log05b.dbf                                  512
    +Q_FRA/orq2/onlinelog/log06a.dbf                                  512
    +Q_FRA/orq2/onlinelog/log06b.dbf                                  512
    12 rows selected.