QUERIES
STATUS
Startup time
select to_char(startup_time, 'HH24:MI DD-MON-YY') "Startup time"
from v$instance
/
How large is the database
col "Database Size" format a20
col "Free space" format a20
col "Used space" format a20
select round(sum(used.bytes) / 1024 / 1024 / 1024 ) || ' GB' "Database Size"
, round(sum(used.bytes) / 1024 / 1024 / 1024 ) -
round(free.p / 1024 / 1024 / 1024) || ' GB' "Used space"
, round(free.p / 1024 / 1024 / 1024) || ' GB' "Free space"
from (select bytes from v$datafile
union all
select bytes from v$tempfile
union all
select bytes from v$log) used,
(select sum(bytes) as p from dba_free_space) free
group by free.p
/
Distribution of objects and data
Which schemas are taking up all of the space
set pages 999
col "size MB" format 999,999,999
col "Objects" format 999,999,999
select obj.owner "Owner",obj_cnt "Objects",
decode(seg_size, NULL, 0, seg_size) "size MB"
from (select owner, count(*) obj_cnt
from dba_objects group by owner) obj,
(select owner, ceil(sum(bytes)/1024/1024) seg_size
from dba_segments group by owner) seg
where obj.owner = seg.owner(+)
order by 3 desc ,2 desc, 1
/
Show the ten largest objects in the database
Col owner format a15
Col segment_name format a30
Col segment_type format a15
Col mb format 999,999,999
select owner,segment_name,segment_type,mb
from(select owner,segment_name,segment_type,bytes / 1024 / 1024 "MB"
from dba_segments
order by bytes desc
)
where rownum < 11
/
Is java installed in the database?
This will return 9000'ish if it is...
select count(*)
from all_objects
where object_type like '%JAVA%'
and owner = 'SYS'
/
Display character set information
select * from nls_database_parameters
/
Show all used features
select name
, detected_usages
from dba_feature_usage_statistics
where detected_usages > 0
/
SESSION
Show all connected users
set lines 100 pages 999
col ID format a15
select username,sid || ',' || serial# "ID",status,
last_call_et "Last Activity"
from v$session
where username is not null
order by status desc,
last_call_et desc
/
Time since last user activity
set lines 100 pages 999
select username
, floor(last_call_et / 60) "Minutes"
, status
from v$session
where username is not null
order by last_call_et
/
Sessions sorted by logon time
set lines 100 pages 999
col ID format a15
col osuser format a15
col login_time format a14
select username
, osuser
, sid || ',' || serial# "ID"
, status
, to_char(logon_time, 'hh24:mi dd/mm/yy') login_time
, last_call_et
from v$session
where username is not null
order by login_time
/
Show user info including os pid
col "SID/SERIAL" format a10
col username format a15
col osuser format a15
col program format a40
select s.sid || ',' || s.serial# "SID/SERIAL"
, s.username
, s.osuser
, p.spid "OS PID"
, s.program
from v$session s
, v$process p
Where s.paddr = p.addr
order by to_number(p.spid)
/
Show a users current sql
Select sql_text
from v$sqlarea
where (address, hash_value) in
(select sql_address, sql_hash_value
from v$session
where username like '&username')
/
Session status associated with the specified os process id
select s.username
, s.sid
, s.serial#
, p.spid
, last_call_et
, status
from V$SESSION s
, V$PROCESS p
where s.PADDR = p.ADDR
and p.spid='&pid'
/
All active sql
set feedback off
set serveroutput on size 9999
column username format a20
column sql_text format a55 word_wrapped
begin
for x in
(select username||'('||sid||','||serial#||') ospid = '|| process ||
' program = ' || program username,
to_char(LOGON_TIME,' Day HH24:MI') logon_time,
to_char(sysdate,' Day HH24:MI') current_time,
sql_address,
sql_hash_value
from v$session
where status = 'ACTIVE'
and rawtohex(sql_address) <> '00'
and username is not null ) loop
for y in (select sql_text
from v$sqlarea
where address = x.sql_address ) loop
if ( y.sql_text not like '%listener.get_cmd%' and
y.sql_text not like '%RAWTOHEX(SQL_ADDRESS)%' ) then
dbms_output.put_line( '--------------------' );
dbms_output.put_line( x.username );
dbms_output.put_line( x.logon_time || ' ' || x.current_time || ' SQL#=' ||
x.sql_hash_value);
dbms_output.put_line( substr( y.sql_text, 1, 250 ) );
end if;
end loop;
end loop;
end;
/
Display any long operations
set lines 100 pages 999
col username format a15
col message format a40
col remaining format 9999
select username
, to_char(start_time, 'hh24:mi:ss dd/mm/yy') started
, time_remaining remaining
, message
from v$session_longops
where time_remaining = 0
order by time_remaining desc
/
List open cursors per user
set pages 999
select sess.username
, sess.sid
, sess.serial#
, stat.value cursors
from v$sesstat stat
, v$statname sn
, v$session sess
where sess.username is not null
and sess.sid = stat.sid
and stat.statistic# = sn.statistic#
and sn.name = 'opened cursors current'
order by value
/
Or alternatively...
set lines 100 pages 999
select count(hash_value) cursors
, sid
, user_name
from v$open_cursor
group by
sid
, user_name
order by
cursors
/
INIT PARAMETERS
Show latent parameter changes
select name
, value
from v$parameter
where ismodified != 'FALSE'
/
Show non-default parameters
set pages 999 lines 100
col name format a30
col value format a50
select name
, value
from v$parameter
where isdefault = 'FALSE'
and value is not null
order by name
/
or for name='parameter' style...
set pages 999 lines 100
select name || '=' || decode(type, 2, '''') || value
|| decode(type, 2, '''') parameter
from v$parameter
where isdefault = 'FALSE'
and value is not null
order by name
/
Reset/Unset a spfile parameter
Setting a parameter to =' ' often isn't enough. Do this instead...
alter system reset <parameter> scope=spfile sid='*'
/
The sid='*' bit is always necessary, even in non RAC database.
USER
List users
set pages 999 lines 100
col username format a20
col status format a8
col tablespace format a20
col temp_ts format a20
select username
, account_status status
, created
, default_tablespace tablespace
, temporary_tablespace temp_ts
from dba_users
order by username
/
Lock or unlock a user
alter user <username> account lock;
And to unlock...
alter user <username> account unlock;
ROLE
Find a role
select *
from dba_roles
where role like '&role'
/
Show what roles are granted to a user
select grantee
, granted_role
, admin_option
from dba_role_privs
where grantee like upper('&username')
/
Show what system privileges are granted to a role
select privilege
, admin_option
from role_sys_privs
where role like '&role'
/
Show what table privileges are granted to a role
select owner || '.' || table_name "TABLE"
, column_name
, privilege
, grantable
from role_tab_privs
where role like '&role'
/
Administration - ASM
• Check if css is running/working
• Display disk-groups
• Show disk space usage
• Create a disk group
• Add a disk to a group
• Drop a disk group
• Is ASM performing a balancing operation
• Check the internal consistency of a diskgroup
Check if css is running/working
crsctl check cssd
Display disk-groups
set lines 100
col name format a10
col path format a30
select name
, group_number
, disk_number
, mount_status
, state
, path
from v$asm_disk
order by group_number
/
note. A group number of zero his indicates that a disk is available but hasn't yet been assigned to a
disk group.
Show disk space usage
select name
, group_number
, disk_number
, total_mb
, free_mb
from v$asm_disk
order by group_number
/
Create a disk group
create diskgroup data1
external redundancy
disk '/dev/raw/raw1'
/
or with multiple raw partitions...
multiple disks
create diskgroup data2
external redundancy
disk '/dev/raw/raw2'
, '/dev/raw/raw3'
/
or with multiple fail groups...
create diskgroup data3
normal redundancy
failgroup controller1 disk '/dev/raw/raw4'
failgroup controller2 disk '/dev/raw/raw6'
/
Add a disk to a group
alter diskgroup data1
add disk '/dev/raw/raw4'
/
Wildcards can be used for raw device names (eg. raw*)
Drop a disk group
drop diskgroup '<name>'
/
Is ASM performing a balancing operation
select *
from v$asm_operation
/
Mount/dismount disk groups
alter diskgroup all mount
alter diskgroup data1 mount
alter diskgroup all dismount
alter diskgroup data1 dismount
Check the internal consistency of a diskgroup
alter diskgroup data1 check all
/
Administration - RAC 10gR2
• Start, stop and check CRS (Cluster Ready Services)
• Start/stop nodeapps
• Start/stop asm
• Start/stop a database (all nodes)
• Start/stop an individual instance
• Check the VIP config
• Change the VIP address, subnetmask or interface
• Locate the voting disk
• Retrive OCR (Oracle Cluster Registry) information
• To prevent a database starting at boot time
• Change the private interconnect subnet
Start, stop and check CRS (Cluster Ready Services)
Note. Start/stop need to be run as root from the CRS home.
Start CRS
crsctl start crs
Stop CRS
crsctl stop crs
Check CRS's status
crsctl check crs
See the status of the various services
crs_stat -t
Start/stop nodeapps
srvctl start nodeapps -n <node name>
srvctl stop nodeapps -n <node name>
Start/stop asm
srvctl start asm -n <node name>
srvctl stop asm -n <node name>
Start/stop a database (all nodes)
srvctl start database -d <database name>
srvctl stop database -d <database name>
Start/stop an individual instance
srvctl start instance -d <database name> -i <instance name>
srvctl stop instance -d <database name> -i <instance name>
Check the VIP config
srvctl config nodeapps -n <node> -a -g -s -l
Change the VIP address, subnetmask or interface
srvctl stop nodeapps -n <node1>
srvctl stop nodeapps -n <node2>
srvctl modify nodeapps -n <node1> -A <ip_address>/<net mask>/<interface>
srvctl modify nodeapps -n <node2> -A <ip_address>/<net mask>/<interface>
srvctl start nodeapps -n <node1>
srvctl start nodeapps -n <node2>
Locate the voting disk
crsctl query css votedisk
Retrive OCR (Oracle Cluster Registry) information
ocrcheck
To prevent a database starting at boot time
srvctl disable database -d <database name>
Change the private interconnect subnet
First find the interface which is in use as the interconnect - run as root from the crs home:
oifcfg getif
Make a note of the interface name (eth1 in the following example), then
run the following:
oifcfg delif -global eth1
oifcfg setif -global eth1/<your new subnet>:cluster_interconnect
Administration - Job Scheduler
• List scheduled jobs
• Submit a job
• Remove a job
• Reset a broken job
• Add a program to the 10g scheduler (os program)
• Add a program to the 10g scheduler (stored procedure)
• Schedule a 10g job
List scheduled jobs
set lines 100 pages 999
col schema_user format a15
col fails format 999
select job
, schema_user
, to_char(last_date, 'hh24:mi dd/mm/yy') last_run
, to_char(next_date, 'hh24:mi dd/mm/yy') next_run
, failures fails
, broken
, substr(what, 1, 15) what
from dba_jobs
order by 4
/
Submit a job
dbms_job.submit('<code>', <start time>, <repeat time>, TRUE);
For example:
declare
job_id number;
begin
dbms_job.submit(
job_id
, 'andy.daily_data_clense'
, trunc(sysdate+1)+22/24
, 'sysdate+1'
, true);
end;
/
This will run a stored procedure called 'daily_data_clense' each day at 10pm.
Remove a job
You need to be connected as the user who owns the job
exec dbms_job.remove(<job number>);
Reset a broken job
You need to be connected as the user who owns the job
exec dbms_job.broken(<job number>, FALSE);
Add a program to the 10g scheduler (os program)
begin
dbms_scheduler.create_program(
program_name=>'ANDY.job_test',
program_action=>'/home/oracle/andyb/job_test.sh',
program_type=>'EXECUTABLE',
comments=>'test job',
enabled=>TRUE);
end;
/
Add a program to the 10g scheduler (stored procedure)
begin
dbms_scheduler.create_program(
program_name=>'ANDY.job_test',
program_action=>'andy.job_test',
program_type=>'STORED_PROCEDURE',
comments=>'test program',
enabled=>TRUE);
end;
/
Schedule a 10g job
begin
dbms_sheduler.create_job(
job_name=>'andy.andy_job_test',
program_name=>'andy.job_test',
start_date=>
)
Administration - Recycle bin
• Display the contents of the recycle bin
• Empty the recycle bin
• Drop an object with out putting it in the recycle bin
Display the contents of the recycle bin
show recyclebin
Empty the recycle bin
purge recyclebin
Drop an object with out putting it in the recycle bin
drop <object_type> <object_name> purge;
Structure - Tablespace
• Tablespace usage
• Show the files that comprise a tablespace
• Tablespaces >80% full
• User quotas on all tablespaces
• List all objects in a tablespace
• Show all tablespaces used by a user
• Create a temporary tablespace
• Alter a databases default temporary tablespace
• Show segments that are approaching max_extents
• List the contents of the temporary tablespace(s)
Tablespace usage
set pages 999
col tablespace_name format a40
col "size MB" format 999,999,999
col "free MB" format 99,999,999
col "% Used" format 999
select tsu.tablespace_name, ceil(tsu.used_mb) "size MB"
, decode(ceil(tsf.free_mb), NULL,0,ceil(tsf.free_mb)) "free MB"
, decode(100 - ceil(tsf.free_mb/tsu.used_mb*100), NULL, 100,
100 - ceil(tsf.free_mb/tsu.used_mb*100)) "% used"
from (select tablespace_name, sum(bytes)/1024/1024 used_mb
from dba_data_files group by tablespace_name union all
select tablespace_name || ' **TEMP**'
, sum(bytes)/1024/1024 used_mb
from dba_temp_files group by tablespace_name) tsu
, (select tablespace_name, sum(bytes)/1024/1024 free_mb
from dba_free_space group by tablespace_name) tsf
where tsu.tablespace_name = tsf.tablespace_name (+)
order by 4
/
Show the files that comprise a tablespace
set lines 100
col file_name format a70
select file_name
, ceil(bytes / 1024 / 1024) "size MB"
from dba_data_files
where tablespace_name like '&TSNAME'
/
Tablespaces >80% full
set pages 999 lines 100
col tablespace_name format a40
col "size MB" format 999999999
col "% Used" format 999
col "80%" format 999999
col "75%" format 999999
select tsu.tablespace_name
, ceil(tsu.used_mb) "size MB"
, 100 - floor(tsf.free_mb/tsu.used_mb*100) "% Used"
, (tsu.used_mb / 100) * (20 - floor(tsf.free_mb/tsu.used_mb*100)) "80%"
, (tsu.used_mb / 100) * (25 - floor(tsf.free_mb/tsu.used_mb*100)) "75%"
from (select tablespace_name, sum(bytes)/1024/1024 used_mb
from dba_data_files group by tablespace_name) tsu
, (select tablespace_name, sum(bytes)/1024/1024 free_mb
from dba_free_space group by tablespace_name) tsf
where tsu.tablespace_name = tsf.tablespace_name (+)
and 100 - floor(tsf.free_mb/tsu.used_mb*100) >= 80
order by 3,4,5
/
User quotas on all tablespaces
col quota format a10
select username
, tablespace_name
, decode(max_bytes, -1, 'unlimited'
, ceil(max_bytes / 1024 / 1024) || 'M' ) "QUOTA"
from dba_ts_quotas
where tablespace_name not in ('TEMP')
/
List all objects in a tablespace
set pages 999
col owner format a15
col segment_name format a40
col segment_type format a20
select owner
, segment_name
, segment_type
from dba_segments
where lower(tablespace_name) like lower('%&tablespace%')
order by owner, segment_name
/
Show all tablespaces used by a user
select tablespace_name
, ceil(sum(bytes) / 1024 / 1024) "MB"
from dba_extents
where owner like '&user_id'
group by tablespace_name
order by tablespace_name
/
Create a temporary tablespace
create temporary tablespace temp
tempfile '<file_name>' size 500M
/
Alter a databases default temporary tablespace
alter database default temporary tablespace temp
/
Show segments that are approaching max_extents
col segment_name format a40
select owner
, segment_type
, segment_name
, max_extents - extents as "spare"
, max_extents
from dba_segments
where owner not in ('SYS','SYSTEM')
and (max_extents - extents) < 10
order by 4
/
To change maxextents
alter <segment_type> <segment_name> storage(maxextents 150);
List the contents of the temporary tablespace(s)
set pages 999 lines 100
col username format a15
col mb format 999,999
select su.username
, ses.sid
, ses.serial#
, su.tablespace
, ceil((su.blocks * dt.block_size) / 1048576) MB
from v$sort_usage su
, dba_tablespaces dt
, v$session ses
where su.tablespace = dt.tablespace_name
and su.session_addr = ses.saddr
/
Structure - Objects
• Find an object
• Invalid objects
• Show the size of an object
• All objects owned by a user
• Source code of a procedure
• Get an objects ddl (9i onwards)
• Display compilation errors and warnings
• Find all tables containing the specified column
• List all tables owned by a user sorted by size
Find an object
set pages 999
col owner format a15
col object_name format a40
col object_type format a20
select owner
, object_name
, object_type
from dba_objects
where lower(object_name) like lower('%&object%')
order by owner, object_type, object_name
/
Invalid objects
List invalid objects...
set lines 200 pages 999
col "obj" format a40
select owner || '.' || object_name "obj",
object_type
from dba_objects
where status = 'INVALID'
/
Recompile all invalid objects...
@?/rdbms/admin/utlrp.sql
Show the size of an object
col segment_name format a20
select segment_name
, bytes "SIZE_BYTES"
, ceil(bytes / 1024 / 1024) "SIZE_MB"
from dba_segments
where segment_name like '&obj_name'
/
All objects owned by a user
col object_name format a40
select object_name
, object_type
from dba_objects
where owner = '&user'
order by object_type, object_name
/
Source code of a procedure
select text
from dba_source
where owner = 'ANDY'
and name = 'FILE_TEST'
and type = 'PACKAGE BODY'
order by line
/
Get an objects ddl (9i onwards)
Note. Works for 9i and newer.
Parameters: OBJECT_TYPE, OBJECT_NAME, SCHEMA
set pagesize 0
set long 90000
select dbms_metadata.get_ddl('TABLE','TABLE_A','ANDY') from dual;
Display compilation errors and warnings
show errors
show errors view <veiw_name>
show errors procedure <proc_name>
select * from dba_errors;
Find all tables containing the specified column
set pages 999 lines 100
col tab format a60
col column_name format a20
select owner || '.' || table_name as tab
, column_name
from dba_tab_columns
where column_name like upper('&col')
/
List all tables owned by a user sorted by size
set lines 100 pages 999
col segment_name format a40
col mb format 999,999,999
select segment_name
, ceil(sum(bytes) / 1024 / 1024) "MB"
from dba_segments
where owner like '&user'
and segment_type = 'TABLE'
group by segment_name
order by ceil(sum(bytes) / 1024 / 1024) desc
/
Structure - Indexes
• Index info by table
• Show indexed columns
Index info by table
select i.index_name
, i.tablespace_name
, ceil(s.bytes / 1048576) "Size MB"
from dba_indexes i
, dba_segments s
where i.index_name = s.segment_name
and table_name like '&table'
order by 2, 1
/
Show indexed columns
select column_name
from dba_ind_columns
where index_name = '&index'
order by column_position
/
Structure - Files
• Display all datafiles, tempfiles and logfiles (and their sizes)
• Quick datafile health check
• Show directories that contain datafiles
• List autoextensible datafiles
• Turn autoextend off for all datafiles
• Move files between disks
• List controlfiles
• Create an OS command for every file in the database
• Find duplicate filenames
• List files that are in hot-backup mode
Display all datafiles, tempfiles and logfiles (and their sizes)
set lines 100 pages 999
col name format a50
select name, bytes
from (select name, bytes
from v$datafile
union all
select name, bytes
from v$tempfile
union all
select lf.member "name", l.bytes
from v$logfile lf
, v$log l
where lf.group# = l.group#
union all
select name, 0
from v$controlfile) used
, (select sum(bytes) as p
from dba_free_space) free
/
Quick datafile health check
You should only see online and system (maybe read-only too)
select distinct status from v$datafile
/
Show directories that contain datafiles
select distinct substr(name, 1, instr(name, '/', -1)) DIR
from v$datafile
order by 1
/
List autoextensible datafiles
select file_name
from dba_data_files
where autoextensible = 'YES'
/
Turn autoextend off for all datafiles
select 'alter database datafile ''' || file_name || ''' autoextend off;'
from dba_data_files
/
Move files between disks
set trimspool on wrap off
set heading off
set verify off
set pages 1000 lines 100
spool rename.sql
select 'alter database rename file ''' ||
name || ''' to ''' ||
replace(name || ''';', '/u01', '/u02')
from v$datafile
/
select 'alter database rename file ''' ||
member || ''' to ''' ||
replace(member || ''';', '/u01', '/u02')
from v$logfile
/
spool off
List controlfiles
select name
from v$controlfile
/
Create an OS command for every file in the database
The example deletes all files
select 'rm ' || name
from (select name
from v$datafile
union all
select name
from v$tempfile
union all
select member
from v$logfile
union all
select name
from v$controlfile
)
/
Find duplicate filenames
Searches for files with the same name in all directories
select count(substr(name, instr(name, '/', -1) + 1, 999)) "total"
, count(distinct substr(name, instr(name, '/', -1) + 1, 999)) "distinct"
from v$datafile
/
List files that are in hot-backup mode
set lines 100 pages 999
col name format a60
select df.name
, b.status
, to_char(time, 'hh24:mi:ss dd/mm/yyyy') time
from v$datafile df
, v$backup b
where df.file# = b.file#
and b.status = 'ACTIVE'
order by b.file#
/
Structure - Redo Logs
• Remove drop
• add logfile members
• List members and sizes
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
/
Structure - Undo
• Converting from Rollback to Undo
• Display the rollback segments
• Alter undo retention
• What's in undo
• Is anything rolling back at the moment?
Display the rollback segments
select segment_name
, status
from dba_rollback_segs
/
Alter undo retention
alter system set undo_retention=500 scope=memory;
Note. This is in seconds
What's in undo
select tablespace_name
, status
, count(*) as HOW_MANY
from dba_undo_extents
group by tablespace_name
, status
/
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
/
Structure - Constraints
• Show all constraints on a table
• List tables that are using the specified table as a foreign key
• Produce a list of disabled fk constraints
• Produce enable statements all disabled fk constraints
• List parent tables that may need fixing/re-importing
• List missing foriegn key values
• Show all table constraints for a user
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
/
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'
/
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')
/
Structure - Materialized view
• Create a view log for the master table
• List all materialized view logs
• Create a simple materialized view
• Show all materialized and resfresh times
• Show materialized view tables and masters
• Show refresh jobs in dba_jobs
• Manually start a refresh
• Force a complete refresh
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
/
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
/
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%'
/
Manually start a refresh
execute dbms_mview.refresh ('<owner.mv_table>');
Force a complete refresh
execute dbms_mview.refresh ('<owner.mv_table>','C');
Structure - Partitions
• List partitioned tables
• List a tables partitions
• Show partition sizes for the specified table
• Move a partition to a new tablespace
• Add a partition
• Split a partition
• Drop a partition
• Truncate a partition
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>
/
Performance - General
• Show currently exectuing sql
• Session statistics
• Resource intensive sql
• File io stats
• In session tracing
• switch on event 10046
• Rows per block
• Show the buffer cache advisory
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
/
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';
Note. use tkprof to interpret the results.
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
/
db_cache_advice needs to be on for the above to work
alter system set db_cache_advice=on;
Performance - Locks DML
• Show sessions that are blocking each other
• Show locked objects
• Show which row is locked
• List locks
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 - 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
/
Generate kill statement for ddl locking sessions
select 'alter system kill session ''' || ddl.session_id || ',' || ses.serial#
|| ''' immediate;'
from dba_ddl_locks ddl
, v$session ses
where owner like '%userid%'
and ddl.session_id = ses.sid
/
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 - 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 - Query Tuning
• Create a plan table
• Autotrace
• Explain plan
• Find a query's hash
• Grab the sql associated with a hash
• Look at a query's stats in the sql area
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 - Memory
• SGA breakdown
• PGA usage by username
• Display pool usage
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 - 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 - 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
Backup - DataGuard
• Startup commands
• To remove a delay from a standby
• Cancel managed recovery
• Register a missing log file
• If FAL doesn't work and it says the log is already registered
• Check which logs are missing
• Disable/Enable archive log destinations
• Turn on fal tracing on the primary db
• Stop the Data Guard broker
• Show the current instance role
• Logical standby apply stop/start
• See how up to date a physical standby is
• Display info about all log destinations
• Display log destinations options
• List any standby redo logs
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#
/
Backup - Flashback
• To put the session back in time
• Copy old data into a new table
• Export a database from a point in time
• Find the current SCN number
• Set the database recovery directory and size
• Set the flashback database retention target
• Turn on flashback database
• What is the earliest time the database can be flashed back to?
• Get a list of times and scn numbers
• Flash the database back
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
/
Turn on flashback database
shutdown immediate
startup mount
alter database flashback on;
alter database open;
What is the earliest time the database can be flashed back to?
select oldest_flashback_scn scn
, to_char(oldest_flashback_time, 'hh24:mi:ss dd/mm/yyyy') oldest_time
from v$flashback_database_log
/
Get a list of times and scn numbers
set pages 999
select scn
, to_char(time_dp, 'hh24:mi:ss dd/mm/yyyy') time
from smon_scn_time
order by scn
/
Flash the database back
shutdown immediate
startup mount exclusive
flashback database to scn <scn>;
or...
flashback database to timestamp to_timestamp('22/04/2007 19:30:00','dd/mm/yyyy
hh24:mi:ss');
alter database open resetlogs;
Manual upgrade from 9i to 10g Release 2
This procedure describes the steps necessary to manually upgrade a database from 9.2.x to 10.2.x.
It assumes that you have already installed 10g onto the server. Of course, it is essential that you
take a backup of your database before attempting any upgrade.
• 1. Compile any invalid objects
@?/rdbms/admin/utlrp.sql
• 2. Create a sysaux tablespace
Having a sysaux tablespace is a requirement in 10g. So, if you haven't already got one, create one
now.
create tablespace sysaux
datafile '<file_name>' size 512M
extent management local
segment space management auto
/
• 3. Run utlu102i.sql
This utility script checks that the database is ready to be upgraded to 10g. It also identifies any
actions that need to be taken. The script is located in the 10g oracle home, so you will need to
specify the full path to it.
@/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/utlu102i.sql
Review the output and make any necessary alterations. Make a note of how many invalid objects
there are.
• 4. Shut the database down with either normal or immediate
shutdown immediate
• 5. Copy the spfile (or pfile) and the password file from the existing home to the 10g one.
cp ${ORACLE_HOME}/dbs/*${ORACLE_SID}* <new_home>/dbs/
• 6. Edit oratab
Alter /etc/oratab (or /var/opt/oracle/oratab) to point to the10g home. Once done, rerun oraenv to
bring the alteration into effect.
• 7. Upgrade the database
sqlplus "/ as sysdba"
startup upgrade
This next bit is the upgrade itself. It takes roughly half an hour to complete. Spool the output to a
file so that you can review it afterward.
@?/rdbms/admin/catupgrd.sql
• 8. Recompile any invalid objects
@?/rdbms/admin/utlrp.sql
Compare the number of invalid objects with the number noted in step 3. It should hopefully be the
same or less.
• 9. Then check the status of the upgrade
@?/rdbms/admin/utlu102s.sql
• 10. Alter or remove initialisation parameters
Temporarily creating a pfile is the easiest way.
create pfile from spfile;
shutdown immediate
vi ${ORACLE_HOME}/dbs/init${ORACLE_SID}.ora
Alter/remove parameters identified in step 9. Set compatible to 10.2.0.0.0
startup
create spfile from pfile;
shutdown immediate
startup
That's it!
Capture all SQL run between two points in time
tnsManager - Distribute tnsnames the easy way and for free!
There are situations where it is useful to capture the SQL that a particular user is running in the
database. Usually you would simply enable session tracing for that user, but there are two potential
problems with that approach.
The first is that many web based applications maintain a pool of persistent database connections
which are shared amongst multiple users. The second is that some applications connect, run some
SQL and disconnect very quickly, making it tricky to enable session tracing at all (you could of
course use a logon trigger to enable session tracing in this case).
A quick and dirty solution to the problem is to capture all SQL statements that are run between two
points in time.
The following procedure will create two tables, each containing a snapshot of the database at a
particular point. The tables will then be queried to produce a list of all SQL run during that period.
If possible, you should do this on a quiet development system - otherwise you risk getting way too
much data back.
• 1. Take the first snapshot
Run the following sql to create the first snapshot:
• create table sql_exec_before as
• select executions
• , hash_value
• from v$sqlarea
• /
• 2. Get the user to perform their task within the application
• 3. Take the second snapshot
• select aft.hash_value
• from sql_exec_before bef
• , sql_exec_after aft
• where aft.executions > bef.executions
• and aft.hash_value = bef.hash_value (+)
• /
• 4. Check the results
Now that you have captured the SQL it is time to query the results.
This first query will list all query hashes that have been executed:
• select aft.hash_value
• from sql_exec_before bef
• , sql_exec_after aft
• where aft.executions > bef.executions
• and aft.hash_value = bef.hash_value (+)
• /
This one will display the hash and the SQL itself:
set pages 999 lines 100
break on hash_value
select hash_value
, sql_text
from v$sqltext
where hash_value in (
select aft.hash_value
from sql_exec_before bef
, sql_exec_after aft
where aft.executions > bef.executions
and aft.hash_value = bef.hash_value (+)
)
order by
hash_value
, piece
/
• 5. Tidy up
Don't forget to remove the snapshot tables once you've finished:
• drop table sql_exec_before
• /
•
• drop table sql_exec_after
• /