<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Andrew Fraser DBA &#187; scripts</title>
	<atom:link href="http://andrewfraserdba.com/category/scripts/feed/" rel="self" type="application/rss+xml" />
	<link>http://andrewfraserdba.com</link>
	<description>Oracle DBA (plus SQL Server)</description>
	<lastBuildDate>Fri, 16 Jul 2010 13:26:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>shell script to clean old oracle trace and log files</title>
		<link>http://andrewfraserdba.com/2010/02/26/shell-script-to-clean-old-oracle-trace-and-log-files/</link>
		<comments>http://andrewfraserdba.com/2010/02/26/shell-script-to-clean-old-oracle-trace-and-log-files/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 09:25:00 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://andrewfraserdba.com/?p=211</guid>
		<description><![CDATA[This code cleans up old trace files, log files, core dumps, etc. It is designed to be run from cron. It takes a somewhat brutal approach by deleting files after just 7 days &#8211; good for e.g. dev/test servers, but in production you would probably want to modify this to keep files for longer.
For this [...]]]></description>
			<content:encoded><![CDATA[<p>This code cleans up old trace files, log files, core dumps, etc. It is designed to be run from cron. It takes a somewhat brutal approach by deleting files after just 7 days &#8211; good for e.g. dev/test servers, but in production you would probably want to modify this to keep files for longer.</p>
<p>For this example all oracle files of interest were under directory &#8220;/ora&#8221; &#8211; that would need to be changed to suit other sites.</p>
<pre class="brush:bash, shell"># 1) Remove old oracle-owned aud, trc, trw, core files
#    Also remove old recv error files (these have format ".err_[0-9]")
#    Also remove access_log.<number>, error_log.<number>, emoms.log.<number> files - which are generated in large numbers
#    Only core files named "core.<number>" are removed: because many other files with "core" in their name are not core dumps, are used by oracle.

echo "*** REMOVE OLD ORACLE AUDIT FILES and OLD RECV Error Files and OLD TRACE FILES ***"
find /ora -mtime +7 -user oracle \( \
  -name '*.aud' -o \
  -name '*.trc*' -o \
  -name '*.trw' -o \
  -name 'core.[0-9]*' -o \
  -name '*.err_[0-9]*' -o \
  -name 'access_log.[0-9]*' -o \
  -name 'error_log.[0-9]*' -o \
  -name 'emoms.log.[0-9]*' \) -exec rm {} \;

# 2) Cut down alert logs and listener logs, and also access_log and event_log (webcache/portal/etc.)
#    Old log files are ignored - only log files modified in the last 7 days are worked on.
#    Small log files are ignored - only files bigger than 3mb (=6144*512 byte blocks) are worked on. 3mb is approximately 30,000 lines of text.

echo "*** CUT DOWN THE ALERT LOGS and ORACLE LISTENER.LOG FILE ***"
for FILE in `find /ora -mtime -7 -size +6144 -user oracle \( \
  -name 'alert_*.log' -o \
  -name 'listener*.log' -o \
  -name 'access_log' -o \
  -name 'event_log' -o \
  -name 'http-web-access.log' -o \
  -name 'server.log' \)`
do
  echo "*** cutting $FILE ***"
  cp $FILE $FILE.tmp
  tail -10000 $FILE.tmp > $FILE
  rm $FILE.tmp
done

echo "*** CUT DOWN MESSAGES and WARN FILES  ***"
for FILE in `find /var/log/ -mtime -7 -size +6144 \( \
  -name 'messages' -o \
  -name 'warn'  \)`
do
  echo "*** cutting $FILE ***"
  cp $FILE $FILE.tmp
  tail -10000 $FILE.tmp > $FILE
  rm $FILE.tmp
done

#End of file.</pre>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2010/02/26/shell-script-to-clean-old-oracle-trace-and-log-files/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Move script for ORA-03297: file contains used data beyond requested RESIZE value</title>
		<link>http://andrewfraserdba.com/2009/03/05/move-script-for-ora-03297-file-contains-used-data-beyond-requested-resize-value/</link>
		<comments>http://andrewfraserdba.com/2009/03/05/move-script-for-ora-03297-file-contains-used-data-beyond-requested-resize-value/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 14:57:56 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.andrewfraserdba.com/?p=74</guid>
		<description><![CDATA[Attempting to shrink files which have a lot of empty space can fail with this error:
SQL> alter database datafile '/ora1data/TEST/TEST_ts_data1_f1.dbf' resize 2g ;

ORA-03297: file contains used data beyond requested RESIZE value
Provided you can get an outage, one fix for this is to temporarily move segments to another tablespace using a scripts like this. (Note that [...]]]></description>
			<content:encoded><![CDATA[<p>Attempting to shrink files which have a lot of empty space can fail with this error:</p>
<pre class="brush:sql">SQL> alter database datafile '/ora1data/TEST/TEST_ts_data1_f1.dbf' resize 2g ;

ORA-03297: file contains used data beyond requested RESIZE value</pre>
<p>Provided you can get an outage, one fix for this is to temporarily move segments to another tablespace using a scripts like this. (Note that this script includes the commands to move LOBs).</p>
<pre class="brush:sql">set pages 9999 lines 132
spool go.tmp
select 'alter table '||owner||'.'||table_name||' move tablespace ts_data2 ;'
from dba_tables
where tablespace_name = 'TS_DATA1'
order by 1
/
select 'alter index '||owner||'.'||index_name||' rebuild tablespace ts_data2 ;'
from dba_indexes
where tablespace_name = 'TS_DATA1'
and index_type != 'LOB'
order by 1
/
select 'alter table '||owner||'.'||table_name||' move tablespace ts_data2 lob ('||column_name||') store as (tablespace ts_data2) ;'
from dba_lobs
where tablespace_name = 'TS_DATA1'
order by 1
/
spool off
ed go.tmp</pre>
<p>They can be moved back afterwards, once the original tablespace has been shrunk, if desired.</p>
<p>One thing to watch out for is user tablespace quotas during the moves. If you get errors like this:</p>
<pre class="brush:sql">ORA-01950: no privileges on tablespace 'TS_DATA2'</pre>
<p>You either need to temporarily grant unlimited tablespace privilege to the user affected, or grant them a quota on the new tablespace.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2009/03/05/move-script-for-ora-03297-file-contains-used-data-beyond-requested-resize-value/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using tar with compress or gzip</title>
		<link>http://andrewfraserdba.com/2009/03/05/using-tar-with-compress-or-gzip/</link>
		<comments>http://andrewfraserdba.com/2009/03/05/using-tar-with-compress-or-gzip/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 08:24:43 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.andrewfraserdba.com/?p=62</guid>
		<description><![CDATA[1) To tar files up into a tarball:
tar cvfp - file1 file2 file3 &#62; tarfile.tar
And to untar:
tar xvfp tarfile.tar
2) Now, same thing but with compress added in:
tar cvfp - file1 file2 file3 &#124; compress &#62; tarfile.tar.Z
zcat tarfile.tar.Z &#124; tar xvfp -
3) And, the same thing using gzip rather than compress:
tar cvfp - file1 file2 file3 [...]]]></description>
			<content:encoded><![CDATA[<p>1) To tar files up into a tarball:</p>
<pre class="brush:bash, shell">tar cvfp - file1 file2 file3 &gt; tarfile.tar</pre>
<p>And to untar:</p>
<pre class="brush:bash, shell">tar xvfp tarfile.tar</pre>
<p>2) Now, same thing but with compress added in:</p>
<pre class="brush:bash, shell">tar cvfp - file1 file2 file3 | compress &gt; tarfile.tar.Z
zcat tarfile.tar.Z | tar xvfp -</pre>
<p>3) And, the same thing using gzip rather than compress:</p>
<pre class="brush:bash, shell">tar cvfp - file1 file2 file3 | gzip &gt; tarfile.tar.gz
gunzip -c tarfile.tar.gz | tar xvfp -</pre>
<p>(Or, if you prefer, &#8220;gzip -cd&#8221; is the same as &#8220;gunzip -c&#8221;)</p>
<p>Gzip compresses down in size slightly better than compress, but tends to take slightly longer to do so.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2009/03/05/using-tar-with-compress-or-gzip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing dbms_profiler</title>
		<link>http://andrewfraserdba.com/2007/06/22/installing-dbms_profiler/</link>
		<comments>http://andrewfraserdba.com/2007/06/22/installing-dbms_profiler/#comments</comments>
		<pubDate>Fri, 22 Jun 2007 13:19:32 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[old]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://andrewfraser.wordpress.com/2007/06/22/installing-dbms_profiler/</guid>
		<description><![CDATA[I used the following to install dbms_profiler,  using a central set of system owned tables rather than each user having its own tables:
conn / as sysdba
@?/rdbms/admin/profload.sql
conn system/password
alter user system default tablespace users ;
-- [or any other reasonable tablespace]
@?/rdbms/admin/proftab.sql
GRANT all ON plsql_profiler_runnumber TO PUBLIC;
GRANT all ON plsql_profiler_data TO PUBLIC;
GRANT all ON plsql_profiler_units TO PUBLIC;
GRANT all [...]]]></description>
			<content:encoded><![CDATA[<p>I used the following to install dbms_profiler,  using a central set of system owned tables rather than each user having its own tables:</p>
<pre class="brush:sql">conn / as sysdba
@?/rdbms/admin/profload.sql
conn system/password
alter user system default tablespace users ;
-- [or any other reasonable tablespace]
@?/rdbms/admin/proftab.sql
GRANT all ON plsql_profiler_runnumber TO PUBLIC;
GRANT all ON plsql_profiler_data TO PUBLIC;
GRANT all ON plsql_profiler_units TO PUBLIC;
GRANT all ON plsql_profiler_runs TO PUBLIC;
CREATE PUBLIC SYNONYM plsql_profiler_runs FOR plsql_profiler_runs;
CREATE PUBLIC SYNONYM plsql_profiler_units FOR plsql_profiler_units;
CREATE PUBLIC SYNONYM plsql_profiler_data FOR plsql_profiler_data;
CREATE PUBLIC SYNONYM plsql_profiler_runnumber FOR plsql_profiler_runnumber;
alter user system default tablespace system  ;</pre>
<p>Based on <a href="http://www.oracle-base.com/articles/9i/DBMS_PROFILER.php">Tim Hall&#8217;s post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2007/06/22/installing-dbms_profiler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What SQL and sessions are running?</title>
		<link>http://andrewfraserdba.com/2007/04/20/what-sql-and-sessions-are-running/</link>
		<comments>http://andrewfraserdba.com/2007/04/20/what-sql-and-sessions-are-running/#comments</comments>
		<pubDate>Fri, 20 Apr 2007 10:04:50 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[old]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://andrewfraser.wordpress.com/2007/04/20/what-sql-and-sessions-are-running/</guid>
		<description><![CDATA[GUIs like TOAD and Enterprise Manager can show this better, but they’re not always to hand. Every session active now or within the last minute is shown.
set pages 9999 lines 132
col username form a20
col osuser form a20
col program form a50
col minutes form 999
alter session set nls_date_format = 'Dy DD-Mon-YYYY HH24:MI:SS'
/
select distinct
s.sid, s.username, s.osuser, s.program&#124;&#124;' '&#124;&#124;s.module [...]]]></description>
			<content:encoded><![CDATA[<p>GUIs like TOAD and Enterprise Manager can show this better, but they’re not always to hand. Every session active now or within the last minute is shown.</p>
<pre class="brush:sql">set pages 9999 lines 132
col username form a20
col osuser form a20
col program form a50
col minutes form 999
alter session set nls_date_format = 'Dy DD-Mon-YYYY HH24:MI:SS'
/
select distinct
s.sid, s.username, s.osuser, s.program||' '||s.module program,
s.status, s.last_call_Et/60 minutes, s.logon_time, w.state, w.event, w.seconds_in_wait ,
q.sql_text
from v$session s, v$sql q, v$session_wait w
where ( s.status = 'ACTIVE' or last_call_et < 60 )
and s.sql_hash_value = q.hash_value
and s.sql_address = q.address
and s.sid = w.sid
order by s.sid
/
set pages 9999 lines 80 head on feed 6</pre>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2007/04/20/what-sql-and-sessions-are-running/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bug? with wrong results from all_objects in stored plsql procedures</title>
		<link>http://andrewfraserdba.com/2007/03/02/bug-with-wrong-results-from-all_objects-in-stored-plsql-procedures/</link>
		<comments>http://andrewfraserdba.com/2007/03/02/bug-with-wrong-results-from-all_objects-in-stored-plsql-procedures/#comments</comments>
		<pubDate>Fri, 02 Mar 2007 12:44:49 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[bugs]]></category>
		<category><![CDATA[old]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://andrewfraser.wordpress.com/2007/03/02/bug-with-wrong-results-from-all_objects-in-stored-plsql-procedures/</guid>
		<description><![CDATA[Wouldn&#8217;t it be nice if sql code produced the same result, regardless of whether it is inside a stored procedure or is a standalone plsql block? But that&#8217;s not what happens when the all_ views are used.
Run this code to see the anomaly for yourself:
set serverout on
declare
&#160;&#160;var1 number ;
begin
&#160;&#160;select count(*) into var1 from all_objects ;
&#160;&#160;dbms_output.put_line('all_objects: [...]]]></description>
			<content:encoded><![CDATA[<p>Wouldn&#8217;t it be nice if sql code produced the same result, regardless of whether it is inside a stored procedure or is a standalone plsql block? But that&#8217;s not what happens when the <em>all_ </em>views are used.</p>
<p>Run this code to see the anomaly for yourself:</p>
<p><code>set serverout on<br />
declare<br />
&nbsp;&nbsp;var1 number ;<br />
begin<br />
&nbsp;&nbsp;select count(*) into var1 from all_objects ;<br />
&nbsp;&nbsp;dbms_output.put_line('all_objects: '||var1) ;<br />
end ;<br />
/<br />
create or replace procedure af_temp as<br />
&nbsp;&nbsp;var1 number ;<br />
begin<br />
&nbsp;&nbsp;select count(*) into var1 from all_objects ;<br />
&nbsp;&nbsp;dbms_output.put_line('all_objects: '||var1) ;<br />
end ;<br />
/<br />
exec af_temp ;<br />
drop procedure af_temp ;</code></p>
<p>It&#8217;s the exact same plsql each time, but very different results reported. For example:</p>
<p><code>all_objects: 13501</code></p>
<p><code>PL/SQL procedure successfully completed.</code></p>
<p><code>Procedure created.</code><br />
<code><br />
all_objects: 4929</code></p>
<p><code>PL/SQL procedure successfully completed.</code></p>
<p><code>Procedure dropped.</code></p>
<p>This behaviour appears to occur on all versions &#8211; I tested from 7.3 through 10gR2. The biggest discrepancies in results seem to be with DBA users other than SYS, but all users show some discrepancy.</p>
<p>This issue doesn&#8217;t occur with the <em>dba_</em> views, so best to use them instead in stored plsql objects. That does mean explicitly granting select privileges on the dba_ views being used in stored procedures, which isn&#8217;t necessary for the <em>all_</em> views.</p>
<p>So, is this a bug? I can&#8217;t see any mention of it all in metalink.</p>
<p>It&#8217;s not just an academic issue either: it caused <a href="http://andrewfraser.wordpress.com/2007/02/01/using-10g-datapump-and-scheduler-to-copy-schemas/#more-19">this code of mine</a> to fail to find and drop the objects it was meant to drop.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2007/03/02/bug-with-wrong-results-from-all_objects-in-stored-plsql-procedures/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>10046 tracing in another session</title>
		<link>http://andrewfraserdba.com/2007/02/14/10046-tracing-in-another-session/</link>
		<comments>http://andrewfraserdba.com/2007/02/14/10046-tracing-in-another-session/#comments</comments>
		<pubDate>Wed, 14 Feb 2007 16:05:40 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[old]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://andrewfraser.wordpress.com/2007/02/14/10046-tracing-in-another-session/</guid>
		<description><![CDATA[To switch 10046 tracing on in another session (first setting on timed statistics and making max_dump_file_size very large):
set pages 9999 verify off
col serial new_value serial noprint
select serial# serial from v$session where sid = &#038;1 ;
exec sys.dbms_system.set_bool_param_in_session(&#038;1,&#038;serial,'timed_statistics',true)
exec sys.dbms_system.set_int_param_in_session(&#038;1,&#038;serial,'max_dump_file_size',999999999)
exec sys.dbms_system.set_ev(&#038;1,&#038;serial,10046,8,'')
And to switch it off:
set pages 9999 verify off
col serial new_value serial noprint
select serial# serial from v$session where [...]]]></description>
			<content:encoded><![CDATA[<p>To switch 10046 tracing on in another session (first setting on timed statistics and making max_dump_file_size very large):</p>
<pre class="brush:sql">set pages 9999 verify off
col serial new_value serial noprint
select serial# serial from v$session where sid = &#038;1 ;
exec sys.dbms_system.set_bool_param_in_session(&#038;1,&#038;serial,'timed_statistics',true)
exec sys.dbms_system.set_int_param_in_session(&#038;1,&#038;serial,'max_dump_file_size',999999999)
exec sys.dbms_system.set_ev(&#038;1,&#038;serial,10046,8,'')</pre>
<p>And to switch it off:</p>
<pre class="brush:sql">set pages 9999 verify off
col serial new_value serial noprint
select serial# serial from v$session where sid = &#038;1 ;
exec sys.dbms_system.set_ev(&#038;1,&#038;serial,10046,0,'')</pre>
<p>Note that you can run new (9i+) tkprof against old (8i and below) 10046 trace files in order to report the wait information. It is also possible to cat multiple trace files together before tkprof&#8217;ing.</p>
<p>Based on Alexander Bubernak&#8217;s post at <a href="http://www.dbasupport.com/oracle/ora10g/10046event.shtml">http://www.dbasupport.com/oracle/ora10g/10046event.shtml</a></p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2007/02/14/10046-tracing-in-another-session/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clone a database</title>
		<link>http://andrewfraserdba.com/2007/02/09/clone-a-database/</link>
		<comments>http://andrewfraserdba.com/2007/02/09/clone-a-database/#comments</comments>
		<pubDate>Fri, 09 Feb 2007 13:13:47 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[old]]></category>
		<category><![CDATA[rman]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://andrewfraser.wordpress.com/2007/02/09/clone-a-database/</guid>
		<description><![CDATA[The below SQL generates a SQL script that can be used to clone a database, putting tablespaces into hot backup mode one at a time. Run it on the source database, and edit the output to specify new target file and directory names, and change cp to rcp or scp if cloning to another server.
Database [...]]]></description>
			<content:encoded><![CDATA[<p>The below SQL generates a SQL script that can be used to clone a database, putting tablespaces into hot backup mode one at a time. Run it on the source database, and edit the output to specify new target file and directory names, and change cp to rcp or scp if cloning to another server.</p>
<p>Database clones can also be done with rman, which has the advantage of avoiding the performance draining hot backup mode.</p>
<pre class="brush:sql">set pages 9999 lines 132 serverout on size 99999
BEGIN
  FOR t IN ( select distinct tablespace_name from dba_data_files )
  LOOP
    dbms_output.put_line('alter tablespace '||t.tablespace_name||' begin backup ;') ;
    FOR f IN ( select file_name from dba_data_files where tablespace_name = t.tablespace_name )
    LOOP
      dbms_output.put_line('host cp '||f.file_name||' '||f.file_name ) ;
    END LOOP ;
    dbms_output.put_line('alter tablespace '||t.tablespace_name||' end backup ;') ;
  END LOOP ;
END ;
/
set lines 80
select 'alter tablespace '||tablespace_name||' add tempfile '||file_name||' size '||bytes/1024/1024||' m ;'
from dba_temp_files
/
prompt alter system switch logfile ;;
prompt alter system backup controlfile to trace ;;</pre>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2007/02/09/clone-a-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slow SQL report</title>
		<link>http://andrewfraserdba.com/2007/02/07/slow-sql-report/</link>
		<comments>http://andrewfraserdba.com/2007/02/07/slow-sql-report/#comments</comments>
		<pubDate>Wed, 07 Feb 2007 14:41:23 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[old]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://andrewfraser.wordpress.com/2007/02/07/slow-sql-report/</guid>
		<description><![CDATA[Lists slow SQL in library cache for tuning investigations:
set pages 9999
spool c.lst
select elapsed_time/1000000 secs, executions,
  elapsed_time/1000000/greatest(executions,1) secs_per_exec,
sql_text from v$sql
where executions > 50
and elapsed_time/1000000/greatest(executions,1) > 1
order by 3 desc
/
spool off
ed c.lst
For older versions of oracle, use buffer_gets or disk_reads in place of elapsed_time.
]]></description>
			<content:encoded><![CDATA[<p>Lists slow SQL in library cache for tuning investigations:</p>
<pre class="brush:sql">set pages 9999
spool c.lst
select elapsed_time/1000000 secs, executions,
  elapsed_time/1000000/greatest(executions,1) secs_per_exec,
sql_text from v$sql
where executions > 50
and elapsed_time/1000000/greatest(executions,1) > 1
order by 3 desc
/
spool off
ed c.lst</pre>
<p>For older versions of oracle, use buffer_gets or disk_reads in place of elapsed_time.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2007/02/07/slow-sql-report/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using 10g datapump and scheduler to copy schemas</title>
		<link>http://andrewfraserdba.com/2007/02/01/using-10g-datapump-and-scheduler-to-copy-schemas/</link>
		<comments>http://andrewfraserdba.com/2007/02/01/using-10g-datapump-and-scheduler-to-copy-schemas/#comments</comments>
		<pubDate>Thu, 01 Feb 2007 16:10:25 +0000</pubDate>
		<dc:creator>Andrew Fraser</dc:creator>
				<category><![CDATA[old]]></category>
		<category><![CDATA[rac]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://andrewfraser.wordpress.com/2007/02/01/using-10g-datapump-and-scheduler-to-copy-schemas/</guid>
		<description><![CDATA[Update 13-Feb-07: Setting the datapump table_exists_action to replace does not overwrite views, sequences, plsql objects. They have to be dropped separately before datapump is called, see gotchas and code below.
Update 02-Mar-07: dba_ views rather than all_ views have to be used to identify what objects to drop prior to datapump, for reasons explained in this [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update</strong> 13-Feb-07: Setting the datapump table_exists_action to <em>replace</em> does not overwrite views, sequences, plsql objects. They have to be dropped separately before datapump is called, see gotchas and code below.</p>
<p><strong>Update</strong> 02-Mar-07: dba_ views rather than all_ views have to be used to identify what objects to drop prior to datapump, for reasons explained in <a href="http://andrewfraser.wordpress.com/2007/03/02/bug-with-wrong-results-from-all_objects-in-stored-plsql-procedures/">this post</a>.</p>
<p>For a nightly process to copy small schemas from one database to another, the normal, or old style, way to do that is with export/import in a cron controlled shell script, which would include a sql-from-sql script to drop all the target schema objects before doing the import.</p>
<p>But that presents problems in RAC, which is what I was working on &#8211; which node does the cron script reside on? What happens if that node is down?</p>
<p>An option would be to have the script run on another machine, one unrelated to the RAC cluster, but that introduces more points of failure, and means sending data back and forward over sql*net.</p>
<p>So instead I used the oracle&#8217;s 10g scheduler and datapump, as below. This data pumps straight over a database link, without having to write to a dump file in between, which is nice. And because it is all in the database, it ought to be unaffected by particular RAC nodes being down.</p>
<p><span id="more-19"></span><br />
Some gotchas:</p>
<ul>
<li>The documentation for dbms_datapump isn&#8217;t at all clear on what the syntax for SCHEMA_LISTS&#8217;s should be. It should be this type of format:
<pre class="brush:sql">name => 'SCHEMA_LIST' , value => '''SCHEMA1'',''SCHEMA2'''</pre>
<p>which is a lot of quotes. Thanks to Sunit Joshi for that tip in <a href="http://www.webservertalk.com/message1791234.html">http://www.webservertalk.com/message1791234.html</a></li>
<li>The dbms_datapump documentation has a bug: dbms_datapump.open does not have a parameter called &#8220;<em>mode</em>&#8220;, it has one called &#8220;<em>job_mode</em>&#8221; instead.</li>
<li>When calling dbms_datapump from within a stored procedure, as opposed to an anonymous pl/sql block, the owner of the stored procedure has to have had &#8220;<em>create table</em>&#8221; privilege granted to them explicitly, rather than through a role. That&#8217;s detailed in metalink note 315488.1, but I wasted a lot of time trying to debug that before I went on to metalink. The error reported doesn&#8217;t help much:
<pre class="brush:sql">ERROR at line 1:
ORA-31626: job does not exist
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 79
ORA-06512: at "SYS.DBMS_DATAPUMP", line 911
ORA-06512: at "SYS.DBMS_DATAPUMP", line 4330
ORA-06512: at "NIGHTLY_IMPORT", line 4
ORA-06512: at line 1</pre>
</li>
<li>Jobs are created disabled by default with dbms_scheduler, you have to specify &#8220;<code>enabled => TRUE</code>&#8221; to get them to run.</li>
<li><em>new 13-Feb-07</em> Setting table_exists_action to &#8216;replace&#8217; overwrites any existing tables ok, but does <em>not</em> replace view definitions, plsql objects, sequences, and so on. They all have to be explicitly dropped before datapump is called. That is quite a tricky counterintuitive limitation of the table_exists_action replace functionality &#8211; why would you want new tables copied over but old sequences left in place? It is suprises like this that make old fashioned (but well understood) exp/imp still worth using.</li>
<li><em>new 13-Feb-07</em> Be aware that the dropped tables will stay on in the recyclebin. There is a good recyclebin article at <a href="http://orafaq.com/node/968">http://orafaq.com/node/968</a>.</li>
</ul>
<p>Good information on this is at <a href="http://orafaq.com/wiki/Datapump">http://orafaq.com/wiki/Datapump</a> and <a href="http://orafaq.com/node/862">http://orafaq.com/node/862</a>.</p>
<p>Here&#8217;s my code. I included a check against a flag table which allows developers to switch the job on and off:</p>
<pre class="brush:sql">create table run_copy ( run_copy varchar2(3) ) tablespace users ;
grant select, insert, update, delete, references on run_copy to public ;
create public synonym run_copy for run_copy ;
insert into run_copy ( run_copy ) values ( 'Yes' ) ;
create database link nightly_import_sourcedb connect to username identified by password using 'sourcedb' ;
-- procedure owner needs explicit create table
grant create table to username ;

CREATE OR REPLACE PROCEDURE nightly_import AS
  -- Andrew Fraser 30 January 2007
  run_import NUMBER ;
  hand NUMBER ;
BEGIN
  run_import := 0 ;
  SELECT COUNT(*) INTO run_import FROM run_copy WHERE UPPER(run_copy) IN ('N','NO') ;
  IF run_import > 0
  THEN
    -- dont run import if someone has set NO flag in run_copy table
    NULL ;
  ELSE
    -- first have to drop plsql and other objects that table_exists_action does not deal with
    FOR d1 IN ( select object_type, owner, object_name from all_objects
      where object_type in ('FUNCTION','PACKAGE','PROCEDURE','SEQUENCE','SYNONYM','VIEW')
      and owner in ('BACKUP','GATEKEEPER','REFDATA','TRANSDATA','WHSUSR','WHS_VIEWER') )
    LOOP
      execute immediate 'drop '||d1.object_type||' '||d1.owner||'.'||d1.object_name ;
    END LOOP ;
    -- then run datapump import itself
    hand := dbms_datapump.open (
      operation    => 'IMPORT' ,
      job_mode     => 'SCHEMA' ,
      remote_link  => 'nightly_import_sourcedb' ) ;
    dbms_datapump.metadata_filter (
      handle       => hand ,
      name         => 'SCHEMA_LIST' ,
      value        => '''BACKUP'',''GATEKEEPER'',''REFDATA'',''TRANSDATA'',''WHSUSR'',''WHS_VIEWER''' ) ;
    dbms_datapump.set_parameter (
      handle       => hand ,
      name         => 'TABLE_EXISTS_ACTION' ,
      value        => 'REPLACE' ) ;
    dbms_datapump.start_job(hand) ;
  END IF ;
END ;
/

BEGIN
DBMS_SCHEDULER.CREATE_JOB (
   job_name           =>  'run_nightly_import' ,
   job_type           =>  'STORED_PROCEDURE' ,
   job_action         =>  'nightly_import' ,
   start_date         =>  TRUNC(sysdate+1)+4/24 , /* start 4am tomorrow */
   repeat_interval    =>  'FREQ=DAILY; INTERVAL=1', /* run every night */
   enabled            =>  TRUE ,
   comments           =>  'Andrew Fraser 30 January 2007');
END;
/</pre>
<p>Even with the code for this method so short, I&#8217;m not sure I would always want to use it over cron and old fashioned export/import. But for RAC, and also for Windows servers (because they lack a decent shell  scripting language), this is the way to go.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfraserdba.com/2007/02/01/using-10g-datapump-and-scheduler-to-copy-schemas/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
