Oracle 101
Oracle Database Monitoring and Tuning
Information here is useful for all Oracle databases ; some examples are geared
toward Oracle 8 on Solaris, AIX, and Linux systems.
Back to top page
email ...
js99@rocket99.com
Copyright 1998-2006 © Citisoft, Inc. All Rights Reserved.
What is going on in the database?
This SQL will display the commands that are currently executing.
set serverout on size 999999
set linesize 155
declare
begin
dbms_output.put_line(' ');
dbms_output.put_line('------------- Start report for waiting sessions with current SQL ---------------');
for x in (select vs.inst_id, vs.sid || ',' || vs.serial# sidser, vs.sql_address, vs.sql_hash_value,
vs.last_call_et, vsw.seconds_in_wait, vsw.event, vsw.state
from gv$session_wait vsw, gv$session vs
where vsw.sid = vs.sid
and vsw.inst_id = vs.inst_id
and vs.type <> 'BACKGROUND'
and vsw.event NOT IN ('rdbms ipc message'
,'smon timer'
,'pmon timer'
,'SQL-Net message from client'
,'lock manager wait for remote message'
,'ges remote message'
,'gcs remote message'
,'gcs for action'
,'client message'
,'pipe get'
,'Null event'
,'PX Idle Wait'
,'single-task message'
,'PX Deq: Execution Msg'
,'KXFQ: kxfqdeq - normal deqeue'
,'listen endpoint status'
,'slave wait'
,'wakeup time manager'))
loop
begin
dbms_output.put_line('Event WaitState InstID SidSerial LastCallEt SecondsInWait');
dbms_output.put_line('------------------------- -------------------- ------ ----------- ---------- -------------');
dbms_output.put_line(rpad(x.event,25) ||' '|| rpad(x.state,20) ||' '|| lpad(x.inst_id,6) ||' '|| lpad(x.sidser,11) ||'
'|| lpad(x.last_call_et,10) ||' '|| lpad(x.seconds_in_wait,13));
dbms_output.put_line(' SQLText ');
dbms_output.put_line('----------------------------------------------------------------');
for y in (select sql_text
from gv$sqltext
where address = x.sql_address
and hash_value = x.sql_hash_value
and inst_id = x.inst_id
order by piece)
loop
dbms_output.put_line(y.sql_text);
end loop;
end;
end loop;
dbms_output.put_line('-------------- End report for sessions waiting with current SQL ----------------');
dbms_output.put_line(' ');
end;
Version information
SELECT * FROM product_component_version ;
List free and used space in database
SELECT sum(bytes)/1024 "free space in KB"
FROM dba_free_space;
SELECT sum(bytes)/1024 "used space in KB"
FROM dba_segments;
List session information
SELECT * FROM V$SESSION ;
List names and default storage parameters for all tablespaces
SELECT TABLESPACE_NAME, INITIAL_EXTENT, NEXT_EXTENT, MAX_EXTENTS,
PCT_INCREASE, MIN_EXTLEN
FROM DBA_TABLESPACES;
Tablespace types, and availability of data files
SELECT TABLESPACE_NAME, CONTENTS, STATUS
FROM DBA_TABLESPACES;
List information about tablespace to which datafiles belong
SELECT FILE_NAME,TABLESPACE_NAME,BYTES,AUTOEXTENSIBLE,
MAXBYTES,INCREMENT_BY
FROM DBA_DATA_FILES;
List data file information
SELECT FILE#,T1.NAME,STATUS,ENABLED,BYTES,CREATE_BYTES,T2.NAME
FROM V$DATAFILE T1, V$TABLESPACE T2
WHERE T1.TS# = T2.TS# ;
List tablespace fragmentation information
SELECT tablespace_name,COUNT(*) AS fragments,
SUM(bytes) AS total,
MAX(bytes) AS largest
FROM dba_free_space
GROUP BY tablespace_name;
Check the current number of extents and blocks allocated to a segment
SELECT SEGMENT_NAME,TABLESPACE_NAME,EXTENTS,BLOCKS
FROM DBA_SEGMENTS;
Check the extents for a given segment
SELECT TABLESPACE_NAME, COUNT(*), MAX(BLOCKS), SUM(BLOCKS)
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NUMBER ;
Extent information
SELECT segment_name, extent_id, blocks, bytes
FROM dba_extents
WHERE segment_name = TNAME ;
Extent information for a table
SELECT segment_name, extent_id, blocks, bytes
FROM dba_extents
WHERE segment_name = TNAME ;
List segments with fewer than 5 extents remaining
SELECT segment_name,segment_type,
max_extents, extents
FROM dba_segments
WHERE extents+5 > max_extents
AND segment_type<>'CACHE';
List segments reaching extent limits
SELECT s.segment_name,s.segment_type,s.tablespace_name,s.next_extent
FROM dba_segments s
WHERE NOT EXISTS (SELECT 1
FROM dba_free_space f
WHERE s.tablespace_name=f.tablespace_name
HAVING max(f.bytes) > s.next_extent);
List table blocks, empty blocks, extent count, and chain block count
SELECT blocks as BLOCKS_USED, empty_blocks
FROM dba_tables
WHERE table_name=TNAME;
SELECT chain_cnt AS CHAINED_BLOCKS
FROM dba_tables
WHERE table_name=TNAME;
SELECT COUNT(*) AS EXTENT_COUNT
FROM dba_extents
WHERE segment_name=TNAME;
Information about all rollback segments in the database
SELECT SEGMENT_NAME,TABLESPACE_NAME,OWNER,STATUS
FROM DBA_ROLLBACK_SEGS;
/* General Rollback Segment Information */
SELECT t1.name, t2.extents, t2.rssize, t2.optsize, t2.hwmsize, t2.xacts, t2.status
FROM v$rollname t1, v$rollstat t2
WHERE t2.usn = t1.usn ;
/* Rollback Segment Information - Active Sessions */
select t2.username, t1.xidusn, t1.ubafil, t1.ubablk, t2.used_ublk
from v$session t2, v$transaction t1
where t2.saddr = t1.ses_addr
Statistics of the rollback segments currently used by instance
SELECT T1.NAME, T2.EXTENTS, T2.RSSIZE, T2.OPTSIZE, T2.HWMSIZE,
T2.XACTS, T2.STATUS
FROM V$ROLLNAME T1, V$ROLLSTAT T2
WHERE T1.USN = T2.USN AND
T1.NAME LIKE '%RBS%';
List sessions with active transactions
SELECT s.sid, s.serial#
FROM v$session s
WHERE s.saddr in
(SELECT t.ses_addr
FROM V$transaction t, dba_rollback_segs r
WHERE t.xidusn=r.segment_id
AND r.tablespace_name='RBS');
Active sorts in instance
SELECT T1.USERNAME, T2.TABLESPACE, T2.CONTENTS, T2.EXTENTS, T2.BLOCKS
FROM V$SESSION T1, V$SORT_USAGE T2
WHERE T1.SADDR = T2.SESSION_ADDR ;
Index & constraint information
SELECT index_name,table_name,uniqueness
FROM dba_indexes
WHERE index_name in
(SELECT constraint_name
FROM dba_constraints
WHERE table_name = TNAME
AND constraint_type in ('P','U')) ;
Updating statistics for a table or schema
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCHEMA1','COMPANY');
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('SCHEMA1');
ANALYZE TABLE COMPANY COMPUTE STATISTICS ;
List tables and synonyms
set pagesize 0;
select 'TABLE:',table_name,'current' from user_tables
union
select 'SYNONYM:',synonym_name,table_owner from user_synonyms
order by 1,2 ;
Constraint columns
SELECT constraint_name,table_name, column_name
FROM dba_cons_columns
WHERE table_name = TNAME
ORDER BY table_name, constraint_name, position
END IF;
Constraint listing
SELECT constraint_name, table_name,
constraint_type, validated, status
FROM dba_constraints;
Indexed column listing
select
b.uniqueness, a.index_name, a.table_name, a.column_name
from user_ind_columns a, user_indexes b
where a.index_name=b.index_name
order by a.table_name, a.index_name, a.column_position;
Trigger listing
SELECT trigger_name, status
FROM dba_triggers ;
Tuning: library cache
Glossary:
pins = # of time an item in the library cache was executed
reloads = # of library cache misses on execution
Goal:
get hitratio to be less than 1
Tuning parm:
adjust SHARED_POOL_SIZE in the initxx.ora file, increasing by small increments
SELECT SUM(PINS) EXECS,
SUM(RELOADS)MISSES,
SUM(RELOADS)/SUM(PINS) HITRATIO
FROM V$LIBRARYCACHE ;
Tuning: data dictionary cache
Glossary:
gets = # of requests for the item
getmisses = # of requests for items in cache which missed
Goal:
get rcratio to be less than 1
Tuning parm:
adjust SHARED_POOL_SIZE in the initxx.ora file, increasing by small increments
SELECT SUM(GETS) HITS,
SUM(GETMISSES) LIBMISS,
SUM(GETMISSES)/SUM(GETS) RCRATIO
FROM V$ROWCACHE ;
Tuning: buffer cache
Calculation:
buffer cache hit ratio = 1 - (phy reads/(db_block_gets + consistent_gets))
Goal:
get hit ratio in the range 85 - 90%
Tuning parm:
adjust DB_BLOCK_BUFFERS in the initxx.ora file, increasing by small increments
SELECT NAME, VALUE
FROM V$SYSSTAT WHERE NAME IN
('DB BLOCK GETS','CONSISTENT GETS','PHYSICAL READS');
Tuning: sorts
Goal:
Increase number of memory sorts vs disk sorts
Tuning parm:
adjust SORT_AREA_SIZE in the initxx.ora file, increasing by small increments
SELECT NAME, VALUE
FROM V$SYSTAT
WHERE NAME LIKE '%SORT%';
Tuning: dynamic extension
An informational query.
SELECT NAME, VALUE
FROM V$SYSSTAT
WHERE NAME='RECURSIVE CALLS' ;
Tuning: rollback segments
Goal:
Try to avoid increasing 'undo header' counts
Tuning method:
Create more rollback segments, try to reduce counts
SELECT CLASS,COUNT
FROM V$WAITSTAT
WHERE CLASS LIKE '%UNDO%' ;
Tuning: physical file placement
Informational in checking relative usages of the physical data files.
SELECT NAME, PHYRDS,PHYWRTS
FROM V$DATAFILE DF, V$FILESTAT FS
WHERE DF.FILE#=FS.FILE# ;
Killing Sessions
Runaway processes can be killed on the UNIX side, or within server manager.
/* Kill a session, specified by the returned sess-id / serial number */
SELECT sid, serial#, username from v$session
ALTER SYSTEM KILL SESSION 'sessid,ser#'
Archive Log Mode Status
/* Status of Archive Log Subsystem */
ARCHIVE LOG LIST
/* log mode of databases */
SELECT name, log_mode FROM v$database;
/* log mode of instance */
SELECT archiver FROM v$instance;
Recovering an Instance
An incomplete recovery is the only option if backups are run periodically
on a cold instance. Complete recovery is possible if archive logging is enabled,
and backups are run while the database is active.
/* diagnose data file problem */
select * from v$recover_file ;
/* diagnose data file problem, by displaying tablespace info */
select file_id, file_name, tablespace_name, status
from dba_data_files ;
/* find archive log files */
select * from v$recovery_log ;
/* incomplete recovery #1 */
svrmgrl> shutdown abort
[[ In Unix copy data files from backup area to data directory(s). ]]
svrmgrl> connect;
svrmgrl> startup;
/* incomplete recovery #2 */
svrmgrl> shutdown abort;
svrmgrl> connect;
svrmgrl> startup mount;
svrmgrl> alter database rename file '/data2/ts05.dbf' to '/backups/ts05.dbf'
svrmgrl> alter database open;
/* incomplete recovery #3, for user error (i.e. drop table ) */
Note: archive logs must exist in LOG_ARCHIVE_DEST
svrmgrl> shutdown abort
[[ backup all files ]]
[[ restore required data file(s), using OS commands ]]
svrmgrl> connect;
svrmgrl> startup mount;
svrmgrl> recover database until time '2002-03-04:15:00:00' ;
svrmgrl> alter database open resetlogs;
/* complete recovery #1, for major recovery operations, closed instance */
Note: archive logs must exist in LOG_ARCHIVE_DEST
svrmgrl> shutdown abort
[[ backup all files ]]
svrmgrl> connect;
svrmgrl> startup mount;
svrmgrl> recover database ;
< or >
svrmgrl> recover datafile '/data4/ts03.dbf'
svrmgrl> startup open;
/* complete recovery #2, for major/minor recovery operations, open instance */
Note: archive logs must exist in LOG_ARCHIVE_DEST
svrmgrl> shutdown abort
[[ backup all files ]]
[[ restore corrupted data files, using OS commands ]]
svrmgrl> connect;
svrmgrl> startup mount;
svrmgrl> set autorecovery on ;
svrmgrl> recover tablespace ts03 ;
< or >
svrmgrl> recover datafile 4 ;
svrmgrl> startup open;
List log file information
These queries list the status / locations of the redo log files.
select group#, member, status from v$logfile ;
select group#,thread#,archived,status from v$log ;
A Simple Monitoring Tool
This tool loops a specified number of times, displaying memory
usage along with user process counts for a specific username.
--=================================================
--
-- proc_ora_monitor
--
-- parm1: username to count
-- parm2: number of loops, 5 sec duration
--
--
--=================================================
set serveroutput on ;
create or replace procedure
proc_ora_monitor ( user1 in varchar, reps1 in integer )
is
i number ;
usercount1 number ;
memory1 number ;
date1 varchar(20) ;
msg varchar(99) ;
begin
i := 0 ;
while ( i < reps1 )
loop
msg := '=> ' || to_char(SYSDATE, 'HH:MM:SS PM');
select count(1)
into usercount1
from sys.v_$session
where username = user1 ;
msg := msg || ', ' || user1 || ': ' || usercount1 ;
select round(sum(bytes)/1024/1024 ,2)
into memory1
from sys.v_$sgastat
where pool = 'shared pool' and
name = 'free memory' ;
msg := msg || ', free mb = ' || memory1 ;
select round(sum(bytes)/1024/1024 ,2)
into memory1
from sys.v_$sgastat
where pool = 'shared pool' and
name = 'processes' ;
msg := msg || ', processes mb = ' || memory1 ;
dbms_output.put_line(msg) ;
dbms_lock.sleep(5) ;
i := i + 1 ;
end loop ;
end;
/
show errors ;
execute proc_ora_monitor('SILVERUSER',2) ;
exit
Connection Errors
-------------------------------------------------------
ORA-01034: ORACLE not available
-------------------------------------------------------
TNS-12564: TNS:connection refused
-------------------------------------------------------
TNS-12530: Unable to start a dedicated server process
-------------------------------------------------------
Connection errors can crop up out of nowhere ; the error
message tend to be vague, and not useful at all. Here's a plan of
attack which will solve many connection issues. Try each step, and
proceed if the problem persists.
1) Check your environment ; verify the variables depicted below are set.
( NT: check the registry )
The example below details a Solaris/CSH environment.
Note the TWO_TASK setting ...
setenv ORACLE_BASE /apps/oracle
setenv ORACLE_HOME ${ORACLE_BASE}
setenv ORACLE_SID db22
setenv TWO_TASK $ORACLE_SID
setenv LD_LIBRARY_PATH $ORACLE_HOME/lib:/usr/lib/X11
setenv ORACLE_PATH $ORACLE_HOME/bin:/usr/bin:/usr/local/bin
setenv ORA_CLIENT_LIB shared
set path = ($ORACLE_HOME/bin /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/bin/X11 .)
2) Try to ping the instance:
tnsping db22
If there's an error, check $ORACLE_HOME/network/admin/tnsnames.ora
3) Restart the TNS service.
Solaris:
1) kill the process, running the tnslsnr binary
2) nohup $ORACLE_HOME/bin/tnslsnr start &
NT:
1) restart the service, in the control panel
4) SQL-Plus / ServerMgr
Try using this syntax: sqlplus user/password@instance
5) Solaris, shell change
Try switching the oracle user to the Bourne or Csh shell ; make a script for SQL-Plus
as follow:
#!/usr/bin/csh
setenv ORACLE_BASE /apps/oracle
setenv ORACLE_HOME ${ORACLE_BASE}
setenv ORACLE_SID db22
setenv LD_LIBRARY_PATH $ORACLE_HOME/lib:/usr/lib/X11
setenv ORACLE_PATH $ORACLE_HOME/bin:/usr/bin:/usr/local/bin
setenv ORA_CLIENT_LIB shared
setenv TWO_TASK $ORACLE_SID
set path = ($ORACLE_HOME/bin /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/bin/X11 .)
sqlplus $1 $2 $3
# OR
#sqlplus $1@$ORACLE_SID
Also verify the oracle user owns the oracle directory tree.
6) Check the pfile, verify the settings detailed below. For this example,
the machine should have at least 512mb of memory, to handle the OS and
other processes.
# 100 MB shared pool memory
shared_pool_size = 104857600
# 65 processes need 130 MB of additional memory
processes = 65
sessions = 65
Solaris: check the "shared memory" and "semaphores" settings
also, in the /etc/system file.
7) Look at sqlnet.log ; also check the alert log in
$ORACLE_HOME/admin/$ORACLE_SID/bdump
8) Verify the Oracle version, SQLNet version, and patched OS are all compatible.
9) If the problem is still a mystery, the server may need to be restarted.
Explain Plan: syntax
Below is sample syntax for explain plan ( getting output from the optimizer )
delete from plan_table
where statement_id = '9999';
commit;
COL operation FORMAT A30
COL options FORMAT A15
COL object_name FORMAT A20
/* ------ Your SQL here ------*/
EXPLAIN PLAN set statement_id = '9999' for
select count(1) from asia_monthly_pricing_data where order_id > 5000
/
/*----------------------------*/
select operation, options, object_name
from plan_table
where statement_id = '9999'
start with id = 0
connect by prior id=parent_id and prior statement_id = statement_id;
exit
/
Back to top page
email ...
js99@rocket99.com
Copyright 1998-2002 © Citisoft, Inc. All Rights Reserved.