Archive for the ‘scripts’ Category

Identify what auditing is on

Wednesday, January 17th, 2007

Suspect too much auditing is on on a database? This script will show you what auditing is on:

set pages 9999
select * from DBA_STMT_AUDIT_OPTS ;
select * from DBA_PRIV_AUDIT_OPTS ;
set termout off lines 192
spool 1.tmp
select * from DBA_OBJ_AUDIT_OPTS ;
spool off
set termout on lines 80
host egrep '(S/|A/|/S|/A)' 1.tmp

Note that the unix command egrep is used to filter the dba_obj_audit_opts rows of interest.

Ref: Oracle Database Security Guide, Chapter 12

Pre 9202/9014: Advanced queuing runs away with server memory.

Monday, January 15th, 2007

Using the below memory listing script, I found two databases with large PGAs. That was strange since pga_aggregate_target was unset, sort_area_size was just 64k, and there were very few sessions. Checking PGA at session level showed the QMN sessions had high memory usage (over 200mb each). Which pointed to bug 2227360 “QMN process leaking memory”

It is fixed in 9.0.1.4/9.2.0.2 and above, but I was on 9.2.0.1. So the workaround is to kill the QMN (=AQ) sessions. Sounds drastic, but oracle restarts the processes apparently cleanly, with just a message in the alert log like:

Restarting dead background process QMN0
QMN0 started with pid=9

And that is the memory then freed up – for a while at least, you have to be prepared to kill those sessions every so often as the memory leaks build up, if, that is, you can’t patch up.

I used the below script to kill the sessions. I didn’t need to use the drastic “kill -9” on this occasion, but sometimes sessions take forever to go without that.

select 'alter system kill session '''||s.sid||','||s.serial#||''' ;',
'kill -9 '||p.spid
from v$session s, v$process p
where s.paddr = p.addr
and s.program like '%QMN%'
/

Reference: Metalink Note 233101.1.

Tablespace space with sm$ views + database level space

Monday, January 15th, 2007

The sm$ views are an easy way of seeing tablespace space usage. There is also an sm$ts_free view.

set pages 9999
col tot_mb form 999,999
col use_mb form 999,999
col pct_used form 999
select t.tablespace_name, t.bytes/1024/1024 tot_mb, u.bytes/1024/1024 use_mb, 100*u.bytes/t.bytes pct_used
from sys.sm$ts_avail t, sys.sm$ts_used u
where t.tablespace_name = u.tablespace_name(+)
order by 4 desc
/
-- two queries below for ancient dictionary managed tablespaces only
select owner, segment_name, extents, pct_increase, max_extents, next_extent/1024/1024, tablespace_name
from dba_segments
where extents > max_extents - 5
/
select owner, segment_name, extents, pct_increase, max_extents, next_extent/1024/1024, tablespace_name
from dba_segments s
where next_extent > ( select max(f.bytes) from dba_free_space f where f.tablespace_name = s.tablespace_name)
/

– *Update* – and also database level space:

select sum(bytes)/1024/1024/1024 allocated_gb
from (
  select sum(bytes) bytes from dba_data_files
  union all
  select sum(bytes) bytes from dba_temp_files
  union all
  select sum(l.bytes) bytes from v$log l, v$logfile f where l.group# = f.group#
)
/
select sum(bytes)/1024/1024/1024 used_gb
from sys.sm$ts_used
/

– *Update2* – generate script to add 1000m to each datafile:

set pages 9999 lines 112
select 'alter database datafile '''||file_name||''' resize '||(bytes+1000*1024*1024)/1024/1024||' m ;'
from dba_data_files where tablespace_name in ('TS_INDEX1')
order by 1
/

rman crosscheck archivelog all

Friday, January 12th, 2007

If archived redo logs are (wrongly) deleted/moved/compressed from disk without being backed up, the rman catalog will not know this has happened, and will keep attempting to backup the missing archived redo logs. That will cause rman archived redo log backups to fail altogether with an error like:

RMAN-06059: expected archived log not found, lost of archived log compromises recoverability

If you can, you should bring back the missing archved redo logs to their original location and name, and let rman back them up. But if that is impossible, the workaround is to “crosscheck archivelog all”, like:

rman <<e1
connect target /
connect catalog username/password@catalog
run {
allocate channel c1 type disk ;
crosscheck archivelog all ;
release channel c1 ;
}
e1

You’ll get output like this:

validation succeeded for archived log
archive log filename=D:REDOARCHARCH_1038.DBF recid=1017 stamp=611103638

for every archived log as they are all checked on disk. That should be the catalog fixed, run an archivelog backup to make sure.

[Ref: Metalink ]

Is database using pfile (init.ora), or spfile?

Thursday, January 11th, 2007

Very useful SQL, from Tom Kyte:

select decode(count(*), 1, 'spfile', 'pfile' ) from v$spparameter where rownum=1 and isspecified='TRUE' ;

If it it using an spfile, an easy way to see the parameters is to generate an init.ora copy:

SQL> conn / as sysdba

(or connect as sysoper)

SQL> create pfile = '/tmp/init.ora' from spfile;

9i unix startup / shutdown with listener password

Thursday, January 11th, 2007

Thanks to Laurent Schneider for tips on how to handle listener passwords in scripts. [Update 12-Jan-2007 - ammended script following Laurent's comment, and update 09-Feb-2007 - ammended script following Kevin's comment]

A system startup/shutdown shell script I just used that copes with listener passwords is below.

The location of the listener.ora file was /etc in my case, but that can be different in other servers. The script assumes oracle environment variables are all set correctly at login (the “su -”). This is 9i specific – as explained on Laurent Schneider’s blog post, things are different/better with 10g. Also is only designed to work with a single listener with the default name, LISTENER).

For this script to actually run at system startup/shutdown time, it needs to be linked into the /etc/rc*.d directories, at least /etc/rc3.d (the default startup/shutdown level) although I put it in the others also. That is, as root user:

(more…)

Script run against every running database, listing total oracle memory (sga+pga)

Thursday, January 11th, 2007

This shell script runs against every database that is up and running (has an entry in the ps list). Which I think is better than searching through oratab (since not all of those may be up and running, esp. on dev machines).

You can run any SQL within it, but this particular version prints out the total oracle memory (sga and pga) use. That is useful because there is often a risk of more memory being allocated to oracle than actual physical memory on the server. That is especially true of dev servers with many databases running.

export ORAENV_ASK=NO
for ORACLE_SID in `ps -ef|grep pmon|grep -v grep|awk -F_ '{print $3}'`
do
. oraenv
sqlplus -s "/ as sysdba" <<e1
set pages 0 head off feed off
select '$ORACLE_SID sga', sum(value)/1024/1024 mb from v\$sga
/
select '$ORACLE_SID pga', sum(value)/1024/1024 mb from v\$sesstat s, v\$statname n
where s.statistic# = n.statistic#
and n.name = 'session pga memory'
group by '$ORACLE_SID pga'
/
–- select '$ORACLE_SID sga_max_size', value/1024/1024 mb from v\$parameter where name = 'sga_max_size';
–- select '$ORACLE_SID pga_target', value/1024/1024 mb from v\$parameter where name = 'pga_aggregate_target';
e1
done

The results are best pasted into a spreadsheet where there are many databases.

On 9i on Solaris, sga_max_size preallocates the memory at OS leve, making it largely useless, so there would be worth also checking that, with e.g. the commented out line above.

One thing to watch is that to query a v$ or sm$ view direct from a shell script, you have to escape out the $, hence the “v$” above rather than "v$".

Array use in this script (rather than clumsier writing to temporary files) came from Daniel D’Souza.