<?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>Fans Or Not &#187; Database</title>
	<atom:link href="http://www.orafans.net/category/database/feed" rel="self" type="application/rss+xml" />
	<link>http://www.orafans.net</link>
	<description>寒山问拾得</description>
	<lastBuildDate>Sun, 22 Aug 2010 02:48:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>EBS 11i数据库升级(9i-&gt;10g)几点事项</title>
		<link>http://www.orafans.net/2010/06/ebs-11i-database-upgrade-9i-10g.html</link>
		<comments>http://www.orafans.net/2010/06/ebs-11i-database-upgrade-9i-10g.html#comments</comments>
		<pubDate>Wed, 09 Jun 2010 07:31:00 +0000</pubDate>
		<dc:creator>Zeeno</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[E-Business Suite]]></category>

		<guid isPermaLink="false">http://www.orafans.net/?p=612</guid>
		<description><![CDATA[最近几日在评估和测试EBS的系统升级(11i升级到R12)，虽然官方的升级文档里介绍的比较详细了，但是依旧会出现一些容易疏忽的问题，这里做一些记录。这里并不是单纯的数据库升级，需要考虑EBS的特殊应用。对于升级方案，标准的有三种： 同时升级数据库和应用。 先升级数据库到10gR2，然后升级应用到R12。 先升级数据库到11gR2，然后升级应用到R12。 其中第2和第3种方案有点类似，都是将整个升级方案划分为两个阶段，只是数据库版本不同。实际上，从技术上看，第1种方案也是两步走，只是在应用层跳过一些过渡性的补丁直接升级到R12。 在数据库升级方面，升级路线主要有下面两种： 路线1: 9.2.0.6 -> 9.2.0.8 -> 11.2.0.1 如果是Solaris系统，则要求系统版本至少为 Solaris 10 Update 6。 路线2: 9.2.0.6 -> 10.2.0.1 -> 10.2.0.4 注：最新patchset是10.2.0.5，只是升级文档依旧停留在10.2.0.4。 从一般认识上讲，Oracle数据库在下一个大版本出来后，上一个版本才被认为是相对更稳定的，所以此处选择第二条路线。 数据库升级方式简单而言有以下几种： DBUA，直接通过图形化工具升级，这个最简单。 Manual，类似于上一种方式，只是手工进行各个步骤的升级操作。 Export/Import 有利于数据表的整理，重构数据库，比如修改字符集、数据文件、表空间参数等，在升级时间上，比DBUA和Manual两种方式都要长。 利用数据复制等技术，升级备用环境后再切换。 由于允许停机，并且暂无特殊的要求，所以这里使用DBUA做升级操作。 在升级之前，建议卸载statspack，并且先解决Invalid Objects的问题。此外，数据库升级后DBLINK需要重建，所以先准备相关重建脚本。下面按照文档步骤升级数据库9.2.0.6 至 10.2.0.4，每个步骤都列在下面，对几个步骤中需要额外关注的地方做了备注。 Verify software versions 检查现在软件版本，基本上应该不会有问题的，留意一下AD版本，最新版本是11i.AD.I.7，不过要求11i.AD.I.6就可以了。 Migrate to Oracle Portal 10g (conditional) Deregister the current database server (conditional) Update application tier [...]]]></description>
			<content:encoded><![CDATA[<p>最近几日在评估和测试EBS的系统升级(11i升级到R12)，虽然官方的升级文档里介绍的比较详细了，但是依旧会出现一些容易疏忽的问题，这里做一些记录。这里并不是单纯的数据库升级，需要考虑EBS的特殊应用。对于升级方案，标准的有三种：</p>
<ol>
<li>同时升级数据库和应用。</li>
<li>先升级数据库到10gR2，然后升级应用到R12。</li>
<li>先升级数据库到11gR2，然后升级应用到R12。</li>
</ol>
<p>其中第2和第3种方案有点类似，都是将整个升级方案划分为两个阶段，只是数据库版本不同。实际上，从技术上看，第1种方案也是两步走，只是在应用层跳过一些过渡性的补丁直接升级到R12。</p>
<p>在数据库升级方面，升级路线主要有下面两种：</p>
<ol>
<li>路线1: 9.2.0.6 -> 9.2.0.8 -> 11.2.0.1<br />
如果是Solaris系统，则要求系统版本至少为 Solaris 10 Update 6。</li>
<li>路线2: 9.2.0.6 -> 10.2.0.1 -> 10.2.0.4<br />
注：最新patchset是10.2.0.5，只是升级文档依旧停留在10.2.0.4。</li>
</ol>
<p>从一般认识上讲，Oracle数据库在下一个大版本出来后，上一个版本才被认为是相对更稳定的，所以此处选择第二条路线。</p>
<p>数据库升级方式简单而言有以下几种：</p>
<ol>
<li>DBUA，直接通过图形化工具升级，这个最简单。</li>
<li>Manual，类似于上一种方式，只是手工进行各个步骤的升级操作。</li>
<li>Export/Import<br />
有利于数据表的整理，重构数据库，比如修改字符集、数据文件、表空间参数等，在升级时间上，比DBUA和Manual两种方式都要长。</li>
<li>利用数据复制等技术，升级备用环境后再切换。</li>
</ol>
<p>由于允许停机，并且暂无特殊的要求，所以这里使用DBUA做升级操作。</p>
<p>在升级之前，建议卸载statspack，并且先解决Invalid Objects的问题。此外，数据库升级后DBLINK需要重建，所以先准备相关重建脚本。下面按照文档步骤升级数据库9.2.0.6 至 10.2.0.4，每个步骤都列在下面，对几个步骤中需要额外关注的地方做了备注。</p>
<ol>
<li>Verify software versions<br />
检查现在软件版本，基本上应该不会有问题的，留意一下AD版本，最新版本是11i.AD.I.7，不过要求11i.AD.I.6就可以了。</li>
<li>Migrate to Oracle Portal 10g (conditional)</li>
<li>Deregister the current database server (conditional)</li>
<li>Update application tier context file with new database listener port number (conditional)</li>
<li>Export OLAP analytical workspaces (conditional)</li>
<li>Prepare to create the 10.2.0 Oracle home<br />
设置ORACLE_HOME环境变量，如 export ORACLE_HOME=/u08/test/proddb/10.2.0</li>
<li>Install the base 10.2.0 software<br />
安装10gR2软件，不要选择升级现有数据库，因为要先打一些补丁。这个过程最后会写oraclehomproperties.xml，要保证对应目录有可写权限。比如我曾遭遇了这个错误<br />
inventory/ContentsXML/oraclehomproperties.xml (Permission denied).</li>
<li>Install Oracle Database 10g Products from the 10g Companion CD</li>
<li>Perform 10.2.0.4 patch set pre-installation tasks<br />
这是正常的打数据库补丁操作，留意几个环境变量的修改就可以了。如：</p>
<pre class="brush:text">
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/perl/bin:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export PERL5LIB=$ORACLE_HOME/perl/lib:$ORACLE_HOME/perl/lib/site_perl:$PERL5LIB</pre>
</li>
<li>Perform 10.2.0.4 patch set installation tasks</li>
<li>Create nls/data/9idata directory</li>
<li>Apply additional 10.2.0.4 RDBMS patches</li>
<li>Shut down Applications server processes and database listener</li>
<li>Prepare to upgrade</li>
<li>Upgrade the database instance<br />
执行utlu102i.sql查看升级后的变动情况，然后执行DBMS_STATS.GATHER_SCHEMA_STATS 收集统计数据以加快升级速度。在升级的时候如果没有列出所需的ORACLE_HOME，则需要检查并整理一下oratab。</li>
<li>Modify initialization parameters<br />
对于sga_target等参数，最好先计算以下之前的SGA大小再设置，其余的参考文档设置即可。</li>
<li>Additional database configuration</li>
<li>Perform 10.2.0.4 patch set post-installation tasks</li>
<li>Install Oracle Data Mining and OLAP</li>
<li>Natively compile PL/SQL code (optional)</li>
<li>Fix Korean lexers<br />
升级韩语分词，对于简体中文用户不必进行。<br />
注意：如果将来需要升级EBS至R12，则这一步是必须的，否则升级过程中会出错：</p>
<pre class="brush:text">
Uploading from staging tables
  Error loading seed data for CS_KB_SOLN_CATEGORIES_VL:  CATEGORY_ID = 1,  ORA-29877: failed in the execution of the ODCIINDEXUPDATE routine
ORA-20000: Oracle Text error:
DRG-50857: oracle error in textindexmethods.ODCIIndexUpdate
ORA-20000: Oracle Text error:
DRG-10602: failed to queue DML change to column   for primary key
DRG-13201: KOREAN_LEXER is desupported
ORA-30576: ConText Option dictionary loading error
</pre>
</li>
<li>Import OLAP analytical workspaces (conditional)<br />
同上，如果将来需要升级EBS至R12，则这一步是必须的，稍微不同的时，到时可以不必做“升级”操作，而是直接删除重建：</p>
<pre class="brush:sql">
exec dbms_aw.execute('aw delete zpb.zpbcode');
exec dbms_aw.execute('aw delete zpb.zpbdata');
exec dbms_aw.execute('aw delete zpb.zpbannot');
sqlplus '/ as sysdba' @$APPL_TOP/zpb/12.0.0/patch/115/SQL/zpbmakeaws.sql
</pre>
</li>
<li>Start the new database listener (conditional) </li>
<li>Run adgrants.sql (conditional)</li>
<li>Grant create procedure privilege on CTXSYS</li>
<li>Implement and run AutoConfig<br />
先检查TNS_ADMIN变量是否指向新的路径，并检查listener.ora，看SID_LIST_TEST中是否已经添加了相应的SID，netca创建的listener.ora可能会缺少这个信息。<br />
这里尤其需要留意的是，adbldxml.pl 创建配置文件后，如果做adconfig.pl会报错：</p>
<pre class="brush:text">
Can't locate object method "runPipedCmd" via package "ADX::util::Sysutil" at /u08/test/proddb/10.2.0/appsutil/bin/adconfig.pl line 806.
</pre>
<p>这是由于PERL5LIB没有包含新的appsutil中的perl lib所致，手工加上再执行就可以了。<br />
afdbprf.sh 这一步还会报错：</p>
<pre class="brush:text">ORA-12504: TNS:listener was not given the SID in CONNECT_DATA</pre>
<p>手工执行可以通过，可能是afdbprf.sh 中传递变量有问题。</li>
<li>Gather statistics for SYS schema<br />
dbms_stats.gather_schema_stats这一步没有问题，但是执行dbms_stats.gather_fixed_objects_stats时会报错：</p>
<pre class="brush:text">
declare
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [1350], [1], [13], [], [], [], [],
[]
ORA-06512: at "SYS.DBMS_STATS", line 13210
ORA-06512: at "SYS.DBMS_STATS", line 13517
ORA-06512: at "SYS.DBMS_STATS", line 14039
ORA-06512: at line 3
ORA-06512: at line 33</pre>
<p>这应该是个BUG，据说在11gR2中被修复了。</li>
<li>Re-create custom database links (conditional)<br />
升级之前就已经准备好了DBLINK的重建脚本，直接重建即可。</li>
<li>Re-create grants and synonyms</li>
<li>Apply Oracle Receivables patch</li>
<li>Restart Applications server processes (conditional)</li>
</ol>
<p>按标准步骤做完后，数据库成功升级到10.2.0.4，升级后需要留意以下事项：</p>
<ul>
<li>检查 .profile ，使用使用新的环境变量。</li>
<li>如果有快速启动脚本之类的，看是否指向了新的路径。</li>
<li>检查AutoConfig新创建的env文件，看PATH变量是否正确，删除指向旧数据库的路径。</li>
<li>用adadmin重新生成messages并编译包，否则Web页面登录可能会报错：
<pre class="brush:text">
oracle.apps.fnd.framework.OAException: Application: FND, Message Name: FND_GENERIC_MESSAGE. Tokens: MESSAGE = java.sql.SQLException: ORA-00003: Message 3 not found;  product=RDBMS; facility=ORA
ORA-06512: ? "SYS.DBMS_UTILITY", line 70
ORA-06512: ? line 1
</pre>
</li>
<li>最好转换SYSTEM表空间到Local Management。</li>
</ul>
<p>主要参考文档<br />
Database Preparation Guidelines for an E-Business Suite Release 12.1.1 Upgrade [ID 761570.1]<br />
Oracle Applications Release 11i with Oracle 10g Release 2 (10.2.0) [ID 362203.1]	</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2010/06/ebs-11i-database-upgrade-9i-10g.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Planning Manager诊断过程和10046事件</title>
		<link>http://www.orafans.net/2010/05/planning-manager-10046-event.html</link>
		<comments>http://www.orafans.net/2010/05/planning-manager-10046-event.html#comments</comments>
		<pubDate>Wed, 26 May 2010 08:37:46 +0000</pubDate>
		<dc:creator>Zeeno</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[E-Business Suite]]></category>

		<guid isPermaLink="false">http://www.orafans.net/?p=560</guid>
		<description><![CDATA[在一次Planning Manager性能问题的诊断中，用到了Oracle ERP环境中非常典型的诊断操作和过程，特全程记录于此。 当发现某个程序存在性能问题时，首先当然是快速检查一下SESSION的相关信息，看看主要在执行或等待些什么： SELECT stat.sid, n.name, n.class, stat.value FROM v$sesstat stat, v$statname n WHERE stat.statistic# = n.statistic# AND stat.sid = 121 ORDER BY upper(n.name); 这里观察到bytes received via SQL*Net from client, bytes sent via SQL*Net to client 和 SQL*Net roundtrips to/from client 都在飙升。这对应了两个events：SQL*Net message to client和SQL*Net message from client，这两个事件数值大并不意味着网络状况不好，前者仅仅表示Oracle数据库将数据放入TCP send buffer的时间，而后者表示从客户端接收到反馈指令的时间，两者反映了SQL*Net和数据库之间的时间消耗，而不是网络传输的时间消耗。基于对系统架构的了解，排除SQL*Net的性能问题，那么两个事件预示了什么呢？ SELECT * FROM v$sess_io [...]]]></description>
			<content:encoded><![CDATA[<p>在一次Planning Manager性能问题的诊断中，用到了Oracle ERP环境中非常典型的诊断操作和过程，特全程记录于此。</p>
<p>当发现某个程序存在性能问题时，首先当然是快速检查一下SESSION的相关信息，看看主要在执行或等待些什么：</p>
<pre class="brush:sql">
SELECT stat.sid,
       n.name,
       n.class,
       stat.value
  FROM v$sesstat  stat,
       v$statname n
 WHERE stat.statistic# = n.statistic#
   AND stat.sid = 121
 ORDER BY upper(n.name);
</pre>
<p>这里观察到<strong>bytes received via SQL*Net from client</strong>, <strong>bytes sent via SQL*Net to client</strong> 和 <strong>SQL*Net roundtrips to/from client</strong> 都在飙升。这对应了两个events：<strong>SQL*Net message to client</strong>和<strong>SQL*Net message from client</strong>，这两个事件数值大并不意味着网络状况不好，前者仅仅表示Oracle数据库将数据放入TCP send buffer的时间，而后者表示从客户端接收到反馈指令的时间，两者反映了SQL*Net和数据库之间的时间消耗，而不是网络传输的时间消耗。基于对系统架构的了解，排除SQL*Net的性能问题，那么两个事件预示了什么呢？</p>
<pre class="brush:sql">
SELECT * FROM v$sess_io v WHERE v.sid = 61;
</pre>
<p>观察会话中的数据库读取情况，CONSISTENT_GETS 值在持续增长。结合上面SQL*Net的情况，大致可以判断出该程序在反复执行某个查询语句，每次获取的数据量很小但频率很高。我们知道，客户端在读取数据时，可能影响的因素有Array Fetch Size、SQL*Net中的SDU和数据库服务器每次读取的数据量，简单计算SQL*Net每次传输大致的数据量后将问题定位到SQL的性能问题上。</p>
<p>开始跟踪Planning Manager的全过程。Planning Manager 是一种特殊的并发程序(Immediate)，它直接依附于并发管理器MRP Manager执行。但是作为并发请求，它的常规诊断方式是一样的。如果有计划管理器在运行，则先停掉它，然后启用Trace：<br />
<a href="http://www.orafans.net/2010/05/planning-manager-10046-event.html/2010-05-26_134025" rel="attachment wp-att-559"><img src="http://www.orafans.net/wp-content/uploads/2010/05/2010-05-26_134025.png" alt="" title="2010-05-26_134025" width="600" height="401" class="alignnone size-full wp-image-559" /></a><br />
关于详细操作和Trace文件的查找可参考另一篇文章《<a href="/2008/05/trace-concurrent-request.html">跟踪(Trace)并发请求</a>》</p>
<p>进入MRP计划管理员设置界面，启动Planning Manager。对于其他独立的并发请求，可以直接手工提交。等待Planning Manager处理完预先准备的接口数据后，立即取消该请求，并取消Trace。</p>
<p>接下来就是对Trace文件的解读。对于并发请求的Trace，其实就是对应的一次10046事件(event)，该事件可简单分为以下四个级别：</p>
<ul>
<li><strong>Level 1</strong>: 跟踪SQL</li>
<li><strong>Level 4</strong>: Level 1 + 跟踪绑定变量</li>
<li><strong>Level 8</strong>: Level 1 + 跟踪等待事件</li>
<li><strong>Level 12</strong>: Level 4 + Level 8 (跟踪SQL, 绑定变量和等待事件)</li>
</ul>
<p>手工方式的话可通过下面的命令启用：</p>
<pre class="brush:sql">
alter session set events='10046 trace name context forever, level 8' ;
</pre>
<p>它和下面的命令类似：</p>
<pre class="brush:sql">ALTER SESSION SET SQL_TRACE = TRUE</pre>
<p>只是前一个命令，可以根据需要指定不同的level，比如此处的level 8，表示跟踪到SQL和等待事件，而不获取绑定变量的数据。也可以通过包DBMS_System来启用，例如：</p>
<pre class="brush:sql">
EXEC DBMS_System.Set_Sql_Trace_In_Session(sid, serial#, true );
EXEC DBMS_System.Set_Ev(sid, serial#, event, level, name);
</pre>
<p>在某些场合下，针对并发请求的跟踪可能会产生不止一个Trace文件，此时第一个Trace文件中会指明第二个Trace文件标识，如：</p>
<pre class="brush:text">
PARSE #41:c=0,e=565,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=19728618248238
EXEC #41:c=0,e=781,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=19728618249248
=====================
PARSING IN CURSOR #41 len=54 dep=1 uid=44 oct=42 lid=44 tim=19728618250006 hv=4121095646 ad='f7b931f8'
ALTER SESSION SET TRACEFILE_IDENTIFIER='XZB_CR8909488'
END OF STMT
PARSE #41:c=0,e=249,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=19728618250001

*** TRACE DUMP CONTINUES IN FILE
……/udump/test_ora_14443_XZB_CR8909488.trc ***
</pre>
<p>先来大致看一下Trace文件中都有些什么。</p>
<pre class="brush:text">
Dump file ……/udump/test_ora_14443.trc
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.6.0 - Production
ORACLE_HOME = /u08/test/proddb/9.2.0
System name:	SunOS
Node name:	erptest
Release:	5.10
Version:	Generic_118833-03
Machine:	sun4u
Instance name: TEST
Redo thread mounted by this instance: 1
Oracle process number: 59
Unix process pid: 14443, image: oracle@erptest (TNS V1-V3)
</pre>
<p>这是文件头，显示了相关环境信息。接着往下翻，关键在具体某条SQL的执行情况上，如下：</p>
<pre class="brush:text">
=====================
PARSING IN CURSOR #75 len=332 dep=0 uid=44 oct=3 lid=44 tim=19728619902280 hv=3581312695 ad='f2b4eb00'
select count(*)  into :b0  from wip_requirement_operations wro ,mtl_system_items items where ((((((wro.inventory_item_id=items.inventory_item_id and wro.organization_id=items.organization_id) and items.bom_item_type=4) and wro.wip_entity_id=:b1) and wro.wip_supply_type=6) and wro.organization_id=:b2) and wro.inventory_item_id=:b3)
END OF STMT
PARSE #75:c=10000,e=2221,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=0,tim=19728619902273
EXEC #75:c=0,e=2841,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=19728619905363
WAIT #75: nam='db file sequential read' ela= 6392 p1=66 p2=135783 p3=1
……
FETCH #74:c=0,e=1248,p=0,cr=36,cu=0,mis=0,r=0,dep=0,og=4,tim=19728777309437
WAIT #74: nam='SQL*Net message to client' ela= 6 p1=1952673792 p2=1 p3=0
WAIT #74: nam='SQL*Net message from client' ela= 338 p1=1952673792 p2=1 p3=0
EXEC #74:c=0,e=256,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=19728777310344
WAIT #74: nam='SQL*Net message to client' ela= 1 p1=1952673792 p2=1 p3=0
WAIT #74: nam='SQL*Net message from client' ela= 205 p1=1952673792 p2=1 p3=0
EXEC #75:c=0,e=110,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=19728777310795
WAIT #75: nam='SQL*Net message to client' ela= 2 p1=1952673792 p2=1 p3=0
FETCH #75:c=30000,e=26138,p=0,cr=2028,cu=0,mis=0,r=1,dep=0,og=4,tim=19728777336976
WAIT #75: nam='SQL*Net message from client' ela= 278 p1=1952673792 p2=1 p3=0
FETCH #74:c=0,e=749,p=0,cr=36,cu=0,mis=0,r=0,dep=0,og=4,tim=19728777338168
WAIT #74: nam='SQL*Net message to client' ela= 2 p1=1952673792 p2=1 p3=0
WAIT #74: nam='SQL*Net message from client' ela= 304 p1=1952673792 p2=1 p3=0
EXEC #74:c=0,e=112,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=19728777338769
WAIT #74: nam='SQL*Net message to client' ela= 1 p1=1952673792 p2=1 p3=0
WAIT #74: nam='SQL*Net message from client' ela= 227 p1=1952673792 p2=1 p3=0
EXEC #75:c=0,e=272,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=19728777339533
WAIT #75: nam='SQL*Net message to client' ela= 7 p1=1952673792 p2=1 p3=0
FETCH #75:c=30000,e=27212,p=0,cr=2028,cu=0,mis=0,r=1,dep=0,og=4,tim=19728777366810
WAIT #75: nam='SQL*Net message from client' ela= 415 p1=1952673792 p2=1 p3=0
……
</pre>
<p>这里显示了cursor语句的执行情况，发现编号为#74和#75的语句执行次数非常多，并且间隔执行，每次execute速度很快，fetch消耗时间相对较多，每次读取后立即发送给客户端。（格式的解读参考附注）</p>
<p>由于无法查看源代码，也没有任何技术文档，所以这里，大胆猜测这两个语句在一个LOOP中执行的可能性非常大。Tkprof格式化后，迅速定位最耗时的那个步骤：</p>
<pre class="brush:text">
select count(*)  into :b0
from
 wip_requirement_operations wro ,mtl_system_items items where
  ((((((wro.inventory_item_id=items.inventory_item_id and wro.organization_id=
  items.organization_id) and items.bom_item_type=4) and wro.wip_entity_id=:b1)
   and wro.wip_supply_type=6) and wro.organization_id=:b2) and
  wro.inventory_item_id=:b3)

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.01       0.00          0          0          0           0
Execute   8890      0.89       0.92          0          0          0           0
Fetch     8890    223.66     231.45       1951   18028921          0        8890
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    17781    224.56     232.37       1951   18028921          0        8890

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 44  

Rows     Row Source Operation
-------  ---------------------------------------------------
   8890  SORT AGGREGATE
      0   NESTED LOOPS
   8890    TABLE ACCESS BY INDEX ROWID MTL_SYSTEM_ITEMS_B
   8890     INDEX UNIQUE SCAN MTL_SYSTEM_ITEMS_B_U1 (object id 18977994)
      0    TABLE ACCESS BY INDEX ROWID WIP_REQUIREMENT_OPERATIONS
61341000     INDEX RANGE SCAN WIP_REQUIREMENT_OPERATIONS_N1 (object id 18977444)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                      1951        0.08         11.65
  SQL*Net message to client                    8891        0.00          0.03
  SQL*Net message from client                  8891        0.01          2.82
  latch free                                     19        0.01          0.12
</pre>
<p>到这里终于确定了主要问题所在，下一步就是对该语句进行优化。由于无法修改代码，因此只能从执行计划角度考虑。检查该语句的执行计划，仔细检查发现虽然利用了索引WIP_REQUIREMENT_OPERATIONS_N1，看上去很漂亮，但是仔细检查索引字段发现这是个组合索引，若走这个索引或导致大量的逻辑块读。到此，整个诊断过程也顺利结束了。</p>
<p>附Trace格式解读：</p>
<pre class="brush:text">
PARSING IN CURSOR
len	Length of SQL statement.
dep	Recursive depth of the cursor.
uid	Schema user id of parsing user.
oct	Oracle command type.
lid	Privilege user id.
ela	Elapsed time. 8i: in 1/1000th of a second, 9i: 1/1'000'000th of a second
tim	Timestamp.
hv	Hash id.
ad	SQLTEXT address (see?v$sqlarea?and?v$sqltext).

PARSE, EXEC or FETCH
#n	n = number of cursor
c	cpu time
e	elapsed time
p	physical reads
cr	consistant reads
cu	current mode reads
mis	miss in cache
r	rows processed
dep	recursive depth
og	optimizer goal
tim	time</pre>
<p>详见 <a href="http://www.adp-gmbh.ch/ora/misc/trace_file_format.html">http://www.adp-gmbh.ch/ora/misc/trace_file_format.html</a> </p>
<p>有用的链接：</p>
<ul>
<li>《<a href="http://www.informit.com/articles/article.aspx?p=30628">SQL*Net Performance Tuning Using Underlying Network Protocols</a>》</li>
<li>《<a href="http://blog.tanelpoder.com/2008/02/07/sqlnet-message-to-client-wait-gotcha/">SQL*Net message to client wait isn’t really what it’s thought to be</a>》</li>
</ul>
<p><strong>Update</strong><br />
2010-05-27 其实是可以看到源代码的，下一篇文章会详细阐述。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2010/05/planning-manager-10046-event.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>我们需要监控什么？</title>
		<link>http://www.orafans.net/2010/05/what-should-we-monitor.html</link>
		<comments>http://www.orafans.net/2010/05/what-should-we-monitor.html#comments</comments>
		<pubDate>Mon, 24 May 2010 08:55:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Database]]></category>

		<guid isPermaLink="false">http://www.orafans.net/?p=555</guid>
		<description><![CDATA[今天一个很偶然的时间里，我想看看我们的系统有没有异常，其中某个检查点是通过下面这个SQL进行的： SQL> SELECT local_tran_id, 2 state, 3 fail_time 4 FROM dba_2pc_pending 5 / LOCAL_TRAN_ID STATE FAIL_TIME ---------------------- ---------------- --------- 31.16.528671 collecting 25-FEB-10 通常情况下，我关注更多地是业务数据异常，很少动手检查此类底层的问题，也不会发现任何异常，但是这次，它来了。当然，在我发现下面这个错误之前，它丝毫不是个问题： SQL> commit force '31.16.528671'; commit force '31.16.528671' * ERROR at line 1: ORA-02058: no prepared transaction found with ID 31.16.528671 SQL> exec dbms_transaction.purge_lost_db_entry(''); BEGIN dbms_transaction.purge_lost_db_entry(''); END; * ERROR at line 1: ORA-30019: [...]]]></description>
			<content:encoded><![CDATA[<p>今天一个很偶然的时间里，我想看看我们的系统有没有异常，其中某个检查点是通过下面这个SQL进行的：</p>
<pre class="brush:sql">
SQL> SELECT local_tran_id,
  2         state,
  3         fail_time
  4    FROM dba_2pc_pending
  5  /

LOCAL_TRAN_ID          STATE            FAIL_TIME
---------------------- ---------------- ---------
31.16.528671           collecting       25-FEB-10
</pre>
<p>通常情况下，我关注更多地是业务数据异常，很少动手检查此类底层的问题，也不会发现任何异常，但是这次，它来了。当然，在我发现下面这个错误之前，它丝毫不是个问题：</p>
<pre class="brush:sql">
SQL> commit force '31.16.528671';
commit force '31.16.528671'
*
ERROR at line 1:
ORA-02058: no prepared transaction found with ID 31.16.528671

SQL> exec dbms_transaction.purge_lost_db_entry('');
BEGIN dbms_transaction.purge_lost_db_entry(''); END;

*
ERROR at line 1:
ORA-30019: Illegal rollback Segment operation in Automatic Undo mode
ORA-06512: at "SYS.DBMS_TRANSACTION", line 65
ORA-06512: at "SYS.DBMS_TRANSACTION", line 85
ORA-06512: at line 1
</pre>
<p>一种可能的情况是连接的远程数据库或DBLINK此时不可用，由于最近系统修改比较多，且数据不重要，已经没有追查线索的必要了。解决办法参考Metalink  [<strong>ID 290405.1</strong>]：</p>
<pre class="brush:text">
1.) alter session set "_smu_debug_mode" = 4;
2.) commit; -- so that the call to DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY is the first
                  -- step of the transaction
3.) execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');
</pre>
<p>如果业务数据并不重要，那么解决办法非常简单。这里觉得有点遗憾的是，过去了如此许久才发现问题。基本上，我们的监控处于最原始的手工阶段，这也是为什么我最近评估各类自动化监控系统的主要原因之一。我曾发过一个感叹：</p>
<blockquote><p>我觉得，如果出一本数据库监控专题的书籍肯定会火，专门介绍如何设置度量和策略，介绍每个监控点。其实这类监控范围，也或许代表了DBA工作职责和经验的体现吧。(via <a href="http://twitter.com/zeenoxie/status/14414314360">Twitter</a>)</p></blockquote>
<p>企业的信息化是一个渐进的过程，我们因需求而变化。之前，我们曾经希望有一整套的现成的方案告诉我们如何监控，需要监控什么。但是现在，我基本上可以肯定，每个企业的情况都不相同，寻求一套普适的方案并不值得推荐，因需而定，这才是一个正常的成长过程。</p>
<p>所以我收回之前的Tweet……</p>
<p><strong>Update</strong><br />
<a href="http://twitter.com/zeenoxie/status/14947474495">1</a>. 将零碎的知识整理成系统性的规范，并进行有序管理，这是当前应该做的事。但是常常独木难支，并且缺少一套有效的知识管理系统来支撑这种渐进的优化。</p>
<p><a href="http://twitter.com/zeenoxie/status/14909965378">2</a>. 近日陆续梳理ERP系统的方方面面，发现很多待优化的模块，也发现了很多日常工作中完全可能避免的性能问题。将个人的良好经验形成团队的规范行为，是一个不断积累的过程。尤其的，可以将一些常规项目集成到监控系统中去。</p>
<p><a href="http://twitter.com/zeenoxie/status/14825301600">3</a>. 有时候，让功能顾问去解决功能问题可能是个错误的选择，他们更倾向于面对业务问题。纯技术顾问也解决不了，需兼而得之。</p>
<p>……</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2010/05/what-should-we-monitor.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>案例：主物料界面性能问题</title>
		<link>http://www.orafans.net/2010/04/poor-performance-master-item-screen.html</link>
		<comments>http://www.orafans.net/2010/04/poor-performance-master-item-screen.html#comments</comments>
		<pubDate>Tue, 06 Apr 2010 05:35:51 +0000</pubDate>
		<dc:creator>Zeeno</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[E-Business Suite]]></category>

		<guid isPermaLink="false">http://www.orafans.net/?p=499</guid>
		<description><![CDATA[案例： 物料查询主界面(Master Item Screen)更新速度极慢，有时候需要数分钟才能保存。 诊断： 做Form Trace，诊断日志中可以发现下面一段SQL执行效率很低： Trace file: /……/udump/test_ora_16779_XZB.trc Sort options: fchela ******************************************************************************** count = number of times OCI procedure was executed cpu = cpu time in seconds executing elapsed = elapsed time in seconds executing disk = number of physical reads of buffers from disk query = number of buffers gotten for consistent [...]]]></description>
			<content:encoded><![CDATA[<p>案例：<br />
物料查询主界面(Master Item Screen)更新速度极慢，有时候需要数分钟才能保存。</p>
<p>诊断：<br />
做Form Trace，诊断日志中可以发现下面一段SQL执行效率很低：</p>
<pre class="brush:text">
Trace file: /……/udump/test_ora_16779_XZB.trc
Sort options: fchela
********************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call
********************************************************************************

SELECT WTG_ROWID,ROWID
FROM
 DR$WAITING  WHERE WTG_CID = :b1  AND WTG_PID = :b2

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        0      0.00       0.00          0          0          0           0
Execute      2      0.00       4.85          0          0          0           0
Fetch        2  68700.00   68223.81      30187      30398          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4  68700.00   68228.66      30187      30398          0           0

Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 31     (recursive depth: 2)
</pre>
<p>DR$WAITING 是Oracle Text相关表之一，和DR$PENDING等一系列表一样，主要用于全文检索相关功能的正常运作。简单来讲，DR$PENDING用于索引同步，当同步完成时里面的记录会自动删除，如果同步过程中相关记录又被修改，则相关信息暂时存放于DR$WAITING。检查该表行数：</p>
<pre class="brush:sql">
SELECT COUNT(1) FROM dr$waiting;
SELECT COUNT(1) FROM dr$pending;
</pre>
<p>如果存在大量记录（比如百万级），通常意味着相关程序没有正常进行(同步)。针对EBS环境，Metalink 382809.1 中介绍了几个常规的用于清理无效记录的请求：</p>
<ol>
<li>Rebuild Help Search Index (AFLOBBLD)</li>
<li>JTF Item InterMedia Index Optimizing operation (JTFOPTI)
<ul>
<li>参数p_optimize_level: FAST|FULL</li>
<li>参数p_runtime: 数值，默认为最大</li>
</ul>
</li>
<li>JTF Item InterMedia Index Sync Operation (JTFSYNC)</li>
<li>MES InterMedia Index Optimizing operation (AMVOPTI)</li>
<li>MES InterMedia Index Sync Operation (AMVSYNC)</li>
<li>Knowledge Management Index Synchronization (CS_KB_SYNC_INDEX)</li>
<li>Rebuilding Intermedia Index for Task Names (JTFTKIMD)</li>
<li>Synchronize JTF_NOTES_TL_C1 index (JTF_NOTES_TL_C1_SYNC)</li>
</ol>
<p>对于全文索引而言，所谓同步即加入新的关键词，而优化则意味着清理过期、失效的关键词。如果以上并发请求执行完毕后在DR$PENDING依旧存在记录，则可以手工进行同步：</p>
<pre class="brush:sql">
SELECT du.username,
       idx.idx_name
  FROM ctxsys.dr$index idx,
       dba_users       du
 WHERE du.user_id = idx.idx_owner#
   AND EXISTS
 (SELECT NULL FROM ctxsys.dr$pending pnd WHERE pnd.pnd_cid = idx.idx_id)
</pre>
<p>如：</p>
<pre class="brush:sql">
SQL> exec ctx_ddl.sync_index('AMV.AMV_C_CHANNELS_DESC_CTX');
</pre>
<p>正常情况下，全部手工处理一遍后，DR$WAITING中记录数应该为0。从DBA角度，CTX_DDL包中有几个优化索引的Procedure，可以考虑定期执行优化程序(清理被删除的Term)。<br />
<span id="more-499"></span><br />
在本例中，尽管执行了以上步骤，并不意味着主物料查询界面的效率会有多大提升。由于高水印(High Water)的关系，查询DR$WAITING的速度并不会有多大提升。此时检查DR$WAITING中记录，当记录数为0时，进行TRUNCATE操作，该操作可以去除高水印对查询效率的影响。如果DR$WAITING中记录数不为0，对于DR$PENDING存在的记录，可以删除这些记录后重新同步：</p>
<pre class="brush:sql">
DELETE FROM dr$waiting
 WHERE EXISTS (SELECT 1
          FROM dr$pending
         WHERE dr$pending.pnd_cid = dr$waiting.wtg_cid
           AND dr$pending.pnd_pid = dr$waiting.wtg_pid
           AND dr$pending.pnd_rowid = dr$waiting.wtg_rowid)
</pre>
<p>(正常情况下，这些记录会被自动删除)</p>
<p>重新进入主物料界面，对操作做Trace后查看日志：</p>
<pre class="brush:text">
SELECT WTG_ROWID,ROWID
FROM
 DR$WAITING  WHERE WTG_CID = :b1  AND WTG_PID = :b2

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        0      0.00       0.00          0          0          0           0
Execute      2      0.00       4.04          0          0          0           0
Fetch        2      0.00       1.20          0          6          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       5.24          0          6          0           0

Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 31     (recursive depth: 2)
</pre>
<p>Oracle Text极其相关表的信息可以参考《Text Application Developer&#8217;s Guide》和《Text Reference》。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2010/04/poor-performance-master-item-screen.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>三种有效的优化措施</title>
		<link>http://www.orafans.net/2010/04/three-ebs-optimize-way.html</link>
		<comments>http://www.orafans.net/2010/04/three-ebs-optimize-way.html#comments</comments>
		<pubDate>Fri, 02 Apr 2010 12:06:36 +0000</pubDate>
		<dc:creator>Zeeno</dc:creator>
				<category><![CDATA[Database]]></category>

		<guid isPermaLink="false">http://www.orafans.net/?p=492</guid>
		<description><![CDATA[Oracle EBS作为一款打包好的ERP应用产品，绝大多数情况下是无法通过修改程序来实现优化目的。因而对于多数人而言，提到优化往往意味着成本，意味着投入，比如购买更好更多地硬件，设计N层(通常是两层，数据库和Apps分开)架构，通过BI将报表负担和日常业务剥离开来，上点层次的企业或许可以考虑弄个高可用性方案(RAC/DG)等等，这些投入从某种意义上来说，是昂贵的。很多没有想通的用户，往往在3年、5年这些坎上活得非常痛苦，好不容易磨合的差不多了，可偏偏这系统似老牛破车慢得不行了。等想通这个环节了，又可以迎来新的春天。 我们知道，经过优化的OLTP应用，毫无疑问可支持TB级的数据量，但是这种优化是需要一定功夫的。Oracle EBS宣称其本身便是经过优化的，这是常规而言，实际应用下来，却还有不小的调整余地。如何在当前的IT预算之内，做出显著的性能提升呢？其实从DBA的角度来看，还是有一些免费的实用的优化方案可供选用的： Purging/Archive，清理或归档过期数据。Oracle EBS内置了很多过期数据删除程序，比如删除过期工作流数据、日志、接口表数据等。11i中有将近214个类似程序，R12中约有260个。可以在Purge Portal配置一些常规的清理/归档程序。 Partition，数据表分区。合理的分区，可以优化大多数查询语句访问路径，减少备份、恢复时间，更合理的分配存储空间。比如总帐数据按会计期间进行分区，工作流数据按类型进行分区等。 ILM，信息生命周期管理。Oracle ILM方案是免费的，可以通过APEX提供一个图形化的助理界面。所谓生命周期是指数据按照时间线索区分的重要性分级，比如三年前的数据，本月的数据等，将一些很久以前的基本不访问但是又必须保留的数据存放到相对廉价的存储设备上。 Oracle EBS中已经对于某些类型的表进行了分区，还有一些则提供了备选的分区方案（比如工作流相关表，参考《工作流之大表分区》），这些都是常见的情形。每家企业情况不同，某一类数据在一些企业里数据量很小，但是在另一些企业里却极大，这时就需要自行分析功能和相关表结构，针对数据访问特点进行分区。一般而言，一个表的数据如果超过了2G，应当开始考虑一下分区方案。 Oracle ILM方案向对于很多第三方解决方案而言，虽然简单了些，但是无需额外费用。作为代价之一，Oracle EBS没有现成的解决方案，所以也需要技术顾问自行分析功能特点将数据进行分类，这是有点难度的工作。 在这些方面，一个不了解Oracle EBS产品的DBA很难提供有针对性的优化建议，所以技术顾问们，或许可以在这个领域深入一把。]]></description>
			<content:encoded><![CDATA[<p>Oracle EBS作为一款打包好的ERP应用产品，绝大多数情况下是无法通过修改程序来实现优化目的。因而对于多数人而言，提到优化往往意味着成本，意味着投入，比如购买更好更多地硬件，设计N层(通常是两层，数据库和Apps分开)架构，通过BI将报表负担和日常业务剥离开来，上点层次的企业或许可以考虑弄个高可用性方案(RAC/DG)等等，这些投入从某种意义上来说，是昂贵的。很多没有想通的用户，往往在3年、5年这些坎上活得非常痛苦，好不容易磨合的差不多了，可偏偏这系统似老牛破车慢得不行了。等想通这个环节了，又可以迎来新的春天。</p>
<p>我们知道，经过优化的OLTP应用，毫无疑问可支持TB级的数据量，但是这种优化是需要一定功夫的。Oracle EBS宣称其本身便是经过优化的，这是常规而言，实际应用下来，却还有不小的调整余地。如何在当前的IT预算之内，做出显著的性能提升呢？其实从DBA的角度来看，还是有一些免费的实用的优化方案可供选用的：</p>
<ol>
<li>Purging/Archive，清理或归档过期数据。Oracle EBS内置了很多过期数据删除程序，比如删除过期工作流数据、日志、接口表数据等。11i中有将近214个类似程序，R12中约有260个。可以在Purge Portal配置一些常规的清理/归档程序。</li>
<li>Partition，数据表分区。合理的分区，可以优化大多数查询语句访问路径，减少备份、恢复时间，更合理的分配存储空间。比如总帐数据按会计期间进行分区，工作流数据按类型进行分区等。</li>
<li>ILM，信息生命周期管理。<a href="http://www.oracle.com/technology/deploy/ilm/index.html">Oracle ILM</a>方案是免费的，可以通过<a href="http://www.oracle.com/technology/products/database/application_express/index.html">APEX</a>提供一个图形化的助理界面。所谓生命周期是指数据按照时间线索区分的重要性分级，比如三年前的数据，本月的数据等，将一些很久以前的基本不访问但是又必须保留的数据存放到相对廉价的存储设备上。</li>
</ol>
<p>Oracle EBS中已经对于某些类型的表进行了分区，还有一些则提供了备选的分区方案（比如工作流相关表，参考《<a href="http://www.orafans.net/2008/12/workflow-table-partition.html">工作流之大表分区</a>》），这些都是常见的情形。每家企业情况不同，某一类数据在一些企业里数据量很小，但是在另一些企业里却极大，这时就需要自行分析功能和相关表结构，针对数据访问特点进行分区。一般而言，一个表的数据如果超过了2G，应当开始考虑一下分区方案。</p>
<p>Oracle ILM方案向对于很多第三方解决方案而言，虽然简单了些，但是无需额外费用。作为代价之一，Oracle EBS没有现成的解决方案，所以也需要技术顾问自行分析功能特点将数据进行分类，这是有点难度的工作。</p>
<p>在这些方面，一个不了解Oracle EBS产品的DBA很难提供有针对性的优化建议，所以技术顾问们，或许可以在这个领域深入一把。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2010/04/three-ebs-optimize-way.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Loader Worker 和Sql*Loader 参数</title>
		<link>http://www.orafans.net/2010/03/loader-worker-sqlloader.html</link>
		<comments>http://www.orafans.net/2010/03/loader-worker-sqlloader.html#comments</comments>
		<pubDate>Thu, 25 Mar 2010 01:00:10 +0000</pubDate>
		<dc:creator>Zeeno</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[E-Business Suite]]></category>

		<guid isPermaLink="false">http://www.orafans.net/?p=479</guid>
		<description><![CDATA[之前介绍过MRP技术概览，其中有一个过程便是Loader Worker(装入程序工作流程)，该过程实际上是通过Sql*Loader从操作系统数据文件中将数据加载到数据库中。而在主计划设置选项中，其中一项是设置Sql*Loader参数： 那么这些参数究竟是什么含义？我们又如何通过调整这些参数来优化Loader Worker的性能呢？ 先来观察Loader Worker，会发现其执行时有两个或三个参数，如： CTRL_FILE=/u08/test/prodcomn/admin/out/TEST/M1922497MRLD_ITEMS.ctl DATA_FILE=/u08/test/prodcomn/admin/out/TEST/M1922497MRLD_ITEMS.dat DISCARD_FILE=/u08/test/prodcomn/admin/out/TEST/M1922497MRLD_ITEMS.dis 其中CTRL_FILE和DATA_FILE是每个并发请求都会有的，DISCARD_FILE会在部分并发请求中存在，比如载入MRP_SYSTEM_ITEMS表数据时就有该参数。想要理解这些参数的含义，便要先了解Sql*Loader参数的含义。 Sql*Loader 参数有数十个，相关的有如下几个： CONTROL 该参数指定了一个决定Sql*Loader行为的配置文件，它决定了需要从哪个数据文件读取数据，载入到哪张表里，分别有哪些字段等等。对应于Loader Worker的参数CTRL_FILE。 DATA 该参数指定了数据来源，也就是从哪个数据文件中读取记录。指定的数据文件每行的数据往往有特定的格式，有特定的分隔符区分每个字段的值。对应于Loader Worker的参数DATA_FILE。 DISCARD 该参数指定了一个文件用于记录那些未被正常导入到数据库中的记录。对应于Load Worker的参数DISCARD_FILE。 BINDSIZE Sql*Loader分批从数据文件中读取记录并提交到数据库中，每批的大小是有限制。该参数决定了Sql*Loader从数据文件读取记录大小的上限，除了每次读取的记录数必须小于ROWS指定的数目外，大小上不得超过BINDSIZE所指定的数值。该参数计量单位是Byte。 ROWS (每次Commit的记录数) 在Conventional Path模式时，它限定了bind array最大记录数。在Direct Path模式时，它限定了保存之前从数据文件中读取的最大记录数。它的作用和BINDSIZE类似，只是一个限制了记录数，一个限制了记录大小。 READSIZE (读缓存大小) 该参数仅针对从数据文件载入数据的方式时有效，默认值为64k，最大值因系统平台各有不同。在Conventional Path模式时，bind array 受限于读缓存，也就是说，在系统内存和bind array足够大的前提下，如果读缓存越大，则可以有更多的记录在commit前被读取，这也就意味着载入性能越好。当READSIZE小于BINDSIZE时，则READSIZE会被自动加大。 上述参数中，BINDSIZE和ROWS对应于Sql*Loader参数设置界面的相应字段，其他参数则对应于并发请求的相应参数。 在执行时，Sql*Loader会先将数据读取到bind array，然后一次性insert到表中并commit，关于Sql*Loader的具体工作原理，可以另行写一篇文章叙述，简单了讲，就是说多数情况下（可用的连续内存空间够大），两个参数越大，意味着更少的Commit次数，更高的效率（当然，这也不是绝对的，只是简单这么一说），所以从性能优化角度看，要确定调整这两个参数以在相应的环境中达到最优。对于数据行数量和大小的关系，可以用以下公式来计算： bind array 大小= ROWS * (固定宽度字段长度之和 + 可变长度字段最大长度之和 + ( 可变长度字段数 * 字段分割符长度) ) 虽然公式看着简单，但是针对具体情况计算起来却也繁琐。有一个简单的方式可以大致获取所需信息： 1. [...]]]></description>
			<content:encoded><![CDATA[<p>之前介绍过<a href="/2009/08/mrp-tech-preview.html">MRP技术概览</a>，其中有一个过程便是Loader Worker(装入程序工作流程)，该过程实际上是通过Sql*Loader从操作系统数据文件中将数据加载到数据库中。而在主计划设置选项中，其中一项是设置Sql*Loader参数：<br />
<a href="http://www.orafans.net/2010/03/loader-worker-sqlloader.html/mrpsqldr" rel="attachment wp-att-480"><img src="http://www.orafans.net/wp-content/uploads/2010/03/MRPSQLDR.png" alt="" title="MRPSQLDR" width="500" height="354" class="alignnone size-full wp-image-480" /></a><br />
那么这些参数究竟是什么含义？我们又如何通过调整这些参数来优化Loader Worker的性能呢？</p>
<p>先来观察Loader Worker，会发现其执行时有两个或三个参数，如：</p>
<ol>
<li>CTRL_FILE=/u08/test/prodcomn/admin/out/TEST/M1922497MRLD_ITEMS.ctl</li>
<li>DATA_FILE=/u08/test/prodcomn/admin/out/TEST/M1922497MRLD_ITEMS.dat</li>
<li>DISCARD_FILE=/u08/test/prodcomn/admin/out/TEST/M1922497MRLD_ITEMS.dis</li>
</ol>
<p>其中CTRL_FILE和DATA_FILE是每个并发请求都会有的，DISCARD_FILE会在部分并发请求中存在，比如载入MRP_SYSTEM_ITEMS表数据时就有该参数。想要理解这些参数的含义，便要先了解Sql*Loader参数的含义。</p>
<p>Sql*Loader 参数有数十个，相关的有如下几个：</p>
<ul>
<li><strong>CONTROL</strong><br />
该参数指定了一个决定Sql*Loader行为的配置文件，它决定了需要从哪个数据文件读取数据，载入到哪张表里，分别有哪些字段等等。对应于Loader Worker的参数CTRL_FILE。</li>
<li><strong>DATA</strong><br />
该参数指定了数据来源，也就是从哪个数据文件中读取记录。指定的数据文件每行的数据往往有特定的格式，有特定的分隔符区分每个字段的值。对应于Loader Worker的参数DATA_FILE。</li>
<li><strong>DISCARD</strong><br />
该参数指定了一个文件用于记录那些未被正常导入到数据库中的记录。对应于Load Worker的参数DISCARD_FILE。</li>
<li><strong>BINDSIZE</strong><br />
Sql*Loader分批从数据文件中读取记录并提交到数据库中，每批的大小是有限制。该参数决定了Sql*Loader从数据文件读取记录大小的上限，除了每次读取的记录数必须小于ROWS指定的数目外，大小上不得超过BINDSIZE所指定的数值。该参数计量单位是Byte。</li>
<li><strong>ROWS</strong> (每次Commit的记录数)<br />
在Conventional Path模式时，它限定了bind array最大记录数。在Direct Path模式时，它限定了保存之前从数据文件中读取的最大记录数。它的作用和BINDSIZE类似，只是一个限制了记录数，一个限制了记录大小。</li>
<li><strong>READSIZE</strong> (读缓存大小)<br />
该参数仅针对从数据文件载入数据的方式时有效，默认值为64k，最大值因系统平台各有不同。在Conventional Path模式时，bind array 受限于读缓存，也就是说，在系统内存和bind array足够大的前提下，如果读缓存越大，则可以有更多的记录在commit前被读取，这也就意味着载入性能越好。当READSIZE小于BINDSIZE时，则READSIZE会被自动加大。</li>
</ul>
<p>上述参数中，BINDSIZE和ROWS对应于Sql*Loader参数设置界面的相应字段，其他参数则对应于并发请求的相应参数。<br />
<span id="more-479"></span><br />
在执行时，Sql*Loader会先将数据读取到bind array，然后一次性insert到表中并commit，关于Sql*Loader的具体工作原理，可以另行写一篇文章叙述，简单了讲，就是说多数情况下（可用的连续内存空间够大），两个参数越大，意味着更少的Commit次数，更高的效率（当然，这也不是绝对的，只是简单这么一说），所以从性能优化角度看，要确定调整这两个参数以在相应的环境中达到最优。对于数据行数量和大小的关系，可以用以下公式来计算：</p>
<blockquote><p>bind array 大小= ROWS  * (固定宽度字段长度之和 + 可变长度字段最大长度之和 + ( 可变长度字段数   * 字段分割符长度) )</p></blockquote>
<p>虽然公式看着简单，但是针对具体情况计算起来却也繁琐。有一个简单的方式可以大致获取所需信息：<br />
1. 观察MRP运行过程，在Loader Worker这一步时根据参数备份对应的CONTROL文件和数据文件。<br />
2. 根据CONTROL文件里面所指定表，创建一个相同结构的表。<br />
3. 修改CONTROL文件，将表名和数据文件修改为之前备份的文件名。例：</p>
<pre class="brush:text">
OPTIONS (BINDSIZE=1000000, ROWS=1000, SILENT=(FEEDBACK,DISCARDS))
LOAD DATA
INFILE 'test.dat'
APPEND
INTO TABLE APPS.TEST_TBL

FIELDS TERMINATED BY '|' # 是个特殊字段，会导致feedproxy无法显示
(
inventory_item_id,
 organization_id,
description nullif( description ='-23453'),
 category_id nullif( category_id ='-23453'),
……
LAST_UPDATE_DATE SYSDATE,
CREATION_DATE SYSDATE
)
</pre>
<p>4. 运行Sql*Loader，增加参数LOG，将过程日志记录下来。</p>
<pre class="brush:bash">bash-3.00$ sqlldr userid=apps/apps_pwd control=test.ctl log=test.log</pre>
<p>5. 查看日志文件，可看到以下关键信息：</p>
<pre class="brush:text">
SQL*Loader: Release 8.0.6.3.0 - Production on Thu Mar 25 08:28:17 2010

(c) Copyright 1999 Oracle Corporation.  All rights reserved.

Control File:   test.ctl
Data File:      test.dat
  Bad File:     test.bad
  Discard File:  none specified

 (Allow all discards)

Number to load: ALL
Number to skip: 0
Errors allowed: 50
Bind array:     1000 rows, maximum of 1000000 bytes #这里是Sql*Loader参数设置的
Continuation:    none specified
Path used:      Conventional
Silent options: FEEDBACK and DISCARDS

……

Table APPS.TEST_TBL:
  406082 Rows successfully loaded.
  0 Rows not loaded due to data errors.
  0 Rows not loaded because all WHEN clauses were failed.
  0 Rows not loaded because all fields were null.

Space allocated for bind array:                 992880 bytes(60 rows) #达到了BINDSIZE上限
Space allocated for memory besides bind array:        0 bytes

Total logical records skipped:          0
Total logical records read:        406082
Total logical records rejected:         0
Total logical records discarded:        0

Run began on Thu Mar 25 08:28:17 2010
Run ended on Thu Mar 25 08:30:27 2010

Elapsed time was:     00:02:10.51
CPU time was:         00:01:21.52
</pre>
<p>平均每一行需要空间 992880/60 ~= 16548 Bytes ~= 16.16 K，再增加一行就超出了BINDSIZE所限1000000，所以这里每次最多只允许读取60行记录。</p>
<p>调整这两个参数，将BINDSIZE设置为165480000，ROWS设置为10000，重新运行Sql*Loader:</p>
<pre class="brush:text">
Space allocated for bind array:               165480000 bytes(10000 rows)
Space allocated for memory besides bind array:        0 bytes

Total logical records skipped:          0
Total logical records read:        406082
Total logical records rejected:         0
Total logical records discarded:        0

Run began on Thu Mar 25 08:56:22 2010
Run ended on Thu Mar 25 08:58:12 2010

Elapsed time was:     00:01:50.49
CPU time was:         00:01:26.52
</pre>
<p>这里，根据每行记录的大小，结合实际系统情况，就可以调整BINDSIZE和ROWS到一个更合适的数值了。当然，多数情况下，保持默认值即可，并没有多少调整的必要。</p>
<p>关于Sql*Loader的载入方式，有Conventional Path和Direct Path两种模式，由配置文件<strong>MRP:Use Direct Load Option</strong>控制，修改为Direct Path模式或许会发现执行速度快了不少，但是强烈不建议采用这种模式。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2010/03/loader-worker-sqlloader.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RMAN和数据库管道(PIPE)</title>
		<link>http://www.orafans.net/2010/03/rman-database-pipe.html</link>
		<comments>http://www.orafans.net/2010/03/rman-database-pipe.html#comments</comments>
		<pubDate>Sun, 21 Mar 2010 11:02:29 +0000</pubDate>
		<dc:creator>Zeeno</dc:creator>
				<category><![CDATA[Database]]></category>

		<guid isPermaLink="false">http://www.orafans.net/?p=469</guid>
		<description><![CDATA[数据库管道(PIPE)是一种多SESSION间传递消息的机制，可以通过包DBMS_PIPE进行消息的发布和接收，主要用作外部服务消息接口，也可以用于多个独立进程之间的通讯。在Oracle EBS环境中，MRP的计算过程就用到了数据库管道技术。RMAN也可以通过数据库管道进行操作，通过管道接口，可以直接使用PL/SQL来操作RMAN行为并获得输出结果。通过数据库管道技术，可以设计出基于RMAN的第三方备份、恢复管理系统。 用于RMAN的必须是私有管道，这是出于安全考虑。私有管道有如下限制： 各SESSION用户(USERID)必须和管道创建者一致 存储过程的执行权限和管道创建者(USERID)一致 用户必须通过SYSDBA角色连接到数据库 RMAN拥有两个私有管道，一个用于接收，一个用于发布。在启动RMAN时可以通过PIPE参数指定管道名称(此处为ABC)，比如： [oradba@localhost ~]$ rman PIPE ABC TARGET / TIMEOUT 60 Recovery Manager: Release 11.2.0.1.0 - Production on Sun Mar 21 16:43:28 2010 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 该进程会等待DBMS_PIPE传入指令，如果60秒后无任何指令传入，则自动退出。若不加TIMEOUT参数，则RMAN会一直等待指令传入。 RMAN会自动打开两个私有管道，ORA$RMAN_ABC_IN和ORA$RMAN_ABC_OUT，前者用于接收消息，后者用于发布消息，消息类型都是VARCHAR2。第一次启用时，RMAN会自动初始化这两个管道，如果需要在启动RMAN之前就存入指令，则需要首先手工使用DBMS_PIPE.CREATE_PIPE创建管道。 l_status := dbms_pipe.create_pipe(pipename =>l_pipename,private => true); private 参数必须为true，否则默认会创建公共管道，无法用于RMAN。 发布指令到RMAN: DECLARE l_status INT; BEGIN dbms_pipe.pack_message('show [...]]]></description>
			<content:encoded><![CDATA[<p>数据库管道(PIPE)是一种多SESSION间传递消息的机制，可以通过包DBMS_PIPE进行消息的发布和接收，主要用作外部服务消息接口，也可以用于多个独立进程之间的通讯。在Oracle EBS环境中，MRP的计算过程就用到了数据库管道技术。RMAN也可以通过数据库管道进行操作，通过管道接口，可以直接使用PL/SQL来操作RMAN行为并获得输出结果。通过数据库管道技术，可以设计出基于RMAN的第三方备份、恢复管理系统。</p>
<p>用于RMAN的必须是私有管道，这是出于安全考虑。私有管道有如下限制：</p>
<ul>
<li>各SESSION用户(USERID)必须和管道创建者一致</li>
<li>存储过程的执行权限和管道创建者(USERID)一致</li>
<li>用户必须通过SYSDBA角色连接到数据库</li>
</ul>
<p>RMAN拥有两个私有管道，一个用于接收，一个用于发布。在启动RMAN时可以通过PIPE参数指定管道名称(此处为<strong>ABC</strong>)，比如：</p>
<pre class="brush:text">
[oradba@localhost ~]$ rman PIPE ABC TARGET / TIMEOUT 60
Recovery Manager: Release 11.2.0.1.0 - Production on Sun Mar 21 16:43:28 2010
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
</pre>
<p>该进程会等待DBMS_PIPE传入指令，如果60秒后无任何指令传入，则自动退出。若不加TIMEOUT参数，则RMAN会一直等待指令传入。</p>
<p>RMAN会自动打开两个私有管道，ORA$RMAN_<strong>ABC</strong>_IN和ORA$RMAN_<strong>ABC</strong>_OUT，前者用于接收消息，后者用于发布消息，消息类型都是VARCHAR2。第一次启用时，RMAN会自动初始化这两个管道，如果需要在启动RMAN之前就存入指令，则需要首先手工使用DBMS_PIPE.CREATE_PIPE创建管道。</p>
<pre class="brush:sql">l_status := dbms_pipe.create_pipe(pipename =>l_pipename,private => true);</pre>
<p>private 参数必须为true，否则默认会创建公共管道，无法用于RMAN。</p>
<p>发布指令到RMAN:</p>
<pre class="brush:sql">
DECLARE
  l_status INT;
BEGIN
  dbms_pipe.pack_message('show all;');
  l_status    :=dbms_pipe.send_message('ORA$RMAN_ABC_IN');
  IF l_status <> 0 THEN
    RAISE_APPLICATION_ERROR(-20010, 'Error while sending.  Status = ' || l_status);
  END IF;
END;
</pre>
<p>打印RMAN输出结果:</p>
<pre class="brush:sql">
DECLARE
  l_message VARCHAR2(1000);
  l_status  INT DEFAULT 0;
BEGIN
  --  l_status := dbms_pipe.create_pipe(pipename =>l_pipename,private => true);
  WHILE (l_status = 0 )
  LOOP
    l_status    :=dbms_pipe.receive_message(pipename =>'ORA$RMAN_ABC_OUT',timeout=>3);
    IF l_status <> 0 THEN
      EXIT;
    END IF;
    dbms_pipe.unpack_message(l_message);
    dbms_output.put_line('received message:' || l_message);
  END LOOP;
END;
</pre>
<p>测试环境为：</p>
<pre class="brush:text">
SQL*Plus: Release 11.2.0.1.0 Production on Sun Mar 21 18:49:23 2010

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2010/03/rman-database-pipe.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>connect by</title>
		<link>http://www.orafans.net/2009/02/connect-by.html</link>
		<comments>http://www.orafans.net/2009/02/connect-by.html#comments</comments>
		<pubDate>Tue, 24 Feb 2009 08:24:02 +0000</pubDate>
		<dc:creator>Zeeno</dc:creator>
				<category><![CDATA[Database]]></category>

		<guid isPermaLink="false">http://www.orafans.org/?p=251</guid>
		<description><![CDATA[对于层级结构的数据，connect by是个非常好用的东西。今天在查询组织层次结构的时候（根据一个部门列出所有下属部门）发现里面还有个小陷阱。原始的语句如下： SELECT pos.organization_id_child, pos.d_child_name, pos.organization_id_parent, pos.d_parent_name, LEVEL, sys_connect_by_path(pos.d_child_name, '/') path FROM per_org_structure_elements_v pos WHERE pos.org_structure_version_id = 65 -- 注意这里 START WITH pos.organization_id_child = 133 CONNECT BY PRIOR pos.organization_id_child = pos.organization_id_parent; 由于组织层次结构有版本控制，所以这里使用WHERE条件筛选当前的层次结构，但是结果中却出来很多同样level的重复数据。尝试换用如下SQL： SELECT pos.organization_id_child, pos.d_child_name, pos.organization_id_parent, pos.d_parent_name, LEVEL, sys_connect_by_path(pos.d_child_name, '/') path FROM (SELECT * FROM per_org_structure_elements_v p WHERE p.org_structure_version_id = 65) pos START WITH pos.organization_id_child [...]]]></description>
			<content:encoded><![CDATA[<p>对于层级结构的数据，connect by是个非常好用的东西。今天在查询组织层次结构的时候（根据一个部门列出所有下属部门）发现里面还有个小陷阱。原始的语句如下：</p>
<pre class="brush:sql">
SELECT pos.organization_id_child,
       pos.d_child_name,
       pos.organization_id_parent,
       pos.d_parent_name,
       LEVEL,
       sys_connect_by_path(pos.d_child_name, '/') path
  FROM per_org_structure_elements_v pos
WHERE pos.org_structure_version_id = 65 -- 注意这里
 START WITH pos.organization_id_child = 133
CONNECT BY PRIOR pos.organization_id_child = pos.organization_id_parent;
</pre>
<p>由于组织层次结构有版本控制，所以这里使用WHERE条件筛选当前的层次结构，但是结果中却出来很多同样level的<strong>重复数据</strong>。尝试换用如下SQL：</p>
<pre class="brush:sql">
SELECT pos.organization_id_child,
       pos.d_child_name,
       pos.organization_id_parent,
       pos.d_parent_name,
       LEVEL,
       sys_connect_by_path(pos.d_child_name, '/') path
  FROM (SELECT *
          FROM per_org_structure_elements_v p
         WHERE p.org_structure_version_id = 65) pos
 START WITH pos.organization_id_child = 133
CONNECT BY PRIOR pos.organization_id_child = pos.organization_id_parent;
</pre>
<p>出来预期结果。</p>
<p>翻阅了《Oracle® Database SQL Reference》，没有发现语法问题。数据库版本是 Oracle9i Enterprise Edition Release 9.2.0.6.0 。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2009/02/connect-by.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ORA-00600: kwqidrdq: loop</title>
		<link>http://www.orafans.net/2009/02/ora-00600-kwqidrdq-loop.html</link>
		<comments>http://www.orafans.net/2009/02/ora-00600-kwqidrdq-loop.html#comments</comments>
		<pubDate>Thu, 12 Feb 2009 08:51:02 +0000</pubDate>
		<dc:creator>Zeeno</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Workflow]]></category>

		<guid isPermaLink="false">http://www.orafans.org/?p=231</guid>
		<description><![CDATA[在新克隆的应用环境中启用Workflow Deferred Agent Listener总是错误，错误信息为： [Feb 12, 2009 3:34:45 PM CST]:1234424085866:Thread[inboundThreadGroup1,5,inboundThreadGroup]:0:-1:test.domain.com.cn:10.0.0.2:-1:-1:ERROR:[SVC-GSM-WFALSNRSVC-12681-10002 : oracle.apps.fnd.wf.bes.AgentListenerProcessor.read()]:Could not executeUpdate() on { CALL WF_EVENT.LISTEN ( p_agent_name => :1, p_wait => :2, p_correlation => :3, p_deq_condition => null, p_message_count => :4, p_max_error_count => :5 )} -> java.sql.SQLException: ORA-00600: internal error code, arguments: [kwqidrdq: loop], [0], [0], [0], [0], [], [], [] ORA-06512: [...]]]></description>
			<content:encoded><![CDATA[<p>在新克隆的应用环境中启用Workflow Deferred Agent Listener总是错误，错误信息为：</p>
<pre class="brush:text">
[Feb 12, 2009 3:34:45 PM CST]:1234424085866:Thread[inboundThreadGroup1,5,inboundThreadGroup]:0:-1:test.domain.com.cn:10.0.0.2:-1:-1:ERROR:[SVC-GSM-WFALSNRSVC-12681-10002 : oracle.apps.fnd.wf.bes.AgentListenerProcessor.read()]:Could not executeUpdate() on { CALL   WF_EVENT.LISTEN  (  p_agent_name => :1, p_wait => :2, p_correlation => :3, p_deq_condition => null, p_message_count => :4, p_max_error_count => :5  )} -> java.sql.SQLException: ORA-00600: internal error code, arguments: [kwqidrdq: loop], [0], [0], [0], [0], [], [], []
ORA-06512: at "APPS.WF_EVENT", line 1560
ORA-06512: at line 1
</pre>
<p>检查Alert，日志显示:</p>
<pre class="brush:text">
Thu Feb 12 16:09:55 2009
Errors in file /u08/code/dev/proddb/9.2.0/admin/DEV_test/udump/dev_ora_9675.trc:
ORA-00600: internal error code, arguments: [kwqidrdq: loop], [0], [0], [0], [0], [], [], []
</pre>
<p>通过pfiles查看9675进程，是oracleDEV，确定不是第三方程序引起的。这个错误的产生通常和AQ相关，而WF_DEFERRED正是基于AQ的，这样问题范围就缩小了。</p>
<p>解决步骤如下：</p>
<p>1. 用sysdba权限登录，停用AQ Time Managers：</p>
<pre class="brush:sql">alter system set aq_tm_processes = 0</pre>
<p>2. 检查相应的QUEUE_TABLE：</p>
<pre class="brush:sql">
SELECT * FROM applsys.aq$_wf_deferred_i i
 WHERE NOT EXISTS
 (SELECT t.msgid FROM applsys.wf_deferred t WHERE i.msgid = t.msgid);

SELECT * FROM applsys.aq$_wf_deferred_h h
 WHERE NOT EXISTS
 (SELECT t.msgid FROM applsys.wf_deferred t WHERE h.msgid = t.msgid);

SELECT * FROM applsys.aq$_wf_deferred_t ti
 WHERE NOT EXISTS
 (SELECT t.msgid FROM applsys.wf_deferred t WHERE ti.msgid = t.msgid);</pre>
<p>如果存在记录，则删除之。</p>
<p>3. 重启AQ Time Managers：</p>
<pre class="brush:sql">alter system set aq_tm_processes = 1</pre>
<p>问题解决。还有一种更简单的方式，就是重建QUEUE_TABLE，不过这需要在不丢失数据的前提下。</p>
<p>Ref Metalink: <a href="https://metalink.oracle.com/CSP/main/showdoc?db=NOT&#038;id=1070715.6">1070715.6</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2009/02/ora-00600-kwqidrdq-loop.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>stackx</title>
		<link>http://www.orafans.net/2008/06/stackx.html</link>
		<comments>http://www.orafans.net/2008/06/stackx.html#comments</comments>
		<pubDate>Thu, 05 Jun 2008 00:56:17 +0000</pubDate>
		<dc:creator>Zeeno</dc:creator>
				<category><![CDATA[Database]]></category>

		<guid isPermaLink="false">http://www.orafans.org/?p=28</guid>
		<description><![CDATA[Stackx (Metalink: 362791.1) 是用于分析core文件的shell脚本，可用于IBM AIX， Intel Linux (RedHat and SuSE)， HP-UX (10.* and 11.*)， HP Tru64 和 Sun Solaris (2.5 - 2.10)环境。

当应用程序产生错误时（比如访问禁止的内存区域）可能会被操作系统强行终止并产生core文件，里面包含程序调用的相关函数。stackx从该二进制文件中读取相关的stack trace信息，并形成可读的文本。

下面是在Solaris的示例：
<code>
######################################################################
stackx core / stack trace extraction utility
version 1.1 (c) 2005, 2006 Oracle Corp. all rights reserved.
Reporting:  Thu Jun 5 08:48:46 CST 2008
Machine  :  SunOS mytest 5.10 Generic_118833-03 sun4u sparc SUNW,Sun-Fire-V890
CPU Bits :  32
Core file:  ../core
Core date:  Jun 3 16:42
Tool(s)  :  /usr/bin/pstack /usr/bin/pmap /usr/bin/pflags
Program  :  f60webmx
Core extraction section follows
######################################################################
<debugging>
core '../core' of 29359:	f60webmx webfile=5,180,test_9008_MYTEST
 fef60fd8 ixncwst_WriteString (f98e78, fa6508, 0, 1, 100, f98e78) + 4
  (省略 N 字)
 000887bc main     (2, ffbfb76c, 8000, de1ff0, 64, 8) + 188
 0008860c _start   (0, 0, 0, 0, 0, 0) + dc
</debugging>
######################################################################
PMAP OUTPUT
core '../core' of 29359:	f60webmx webfile=5,180,test_9008_MYTEST
00010000    4032K r-x--  /u01/test/myappl/fnd/11.5.0/bin/f60webmx
  (省略 N 字)
FF3F0000       8K rwx--  /lib/ld.so.1
FFBEC000      80K rwx--    [ stack ]
 total     72264K
######################################################################
PFLAGS OUTPUT
core '../core' of 29359:	f60webmx webfile=5,180,test_9008_MYTEST
	data model = _ILP32  flags = MSACCT&#124;MSFORK
 /1:	flags = 0
	sigmask = 0xffffbefc,0x0000ffff  cursig = SIGSEGV

######################################################################
stackx done.
</code>
]]></description>
			<content:encoded><![CDATA[<p>Stackx (Metalink: 362791.1) 是用于分析core文件的shell脚本，可用于IBM AIX， Intel Linux (RedHat and SuSE)， HP-UX (10.* and 11.*)， HP Tru64 和 Sun Solaris (2.5 &#8211; 2.10)环境。</p>
<p>当应用程序产生错误时（比如访问禁止的内存区域）可能会被操作系统强行终止并产生core文件，里面包含程序调用的相关函数。stackx从该二进制文件中读取相关的stack trace信息，并形成可读的文本。</p>
<p>下面是在Solaris的示例：</p>
<pre>
######################################################################
stackx core / stack trace extraction utility
version 1.1 (c) 2005, 2006 Oracle Corp. all rights reserved.
Reporting:  Thu Jun 5 08:48:46 CST 2008
Machine  :  SunOS mytest 5.10 Generic_118833-03 sun4u sparc SUNW,Sun-Fire-V890
CPU Bits :  32
Core file:  ../core
Core date:  Jun 3 16:42
Tool(s)  :  /usr/bin/pstack /usr/bin/pmap /usr/bin/pflags
Program  :  f60webmx
Core extraction section follows
######################################################################
<debugging>
core '../core' of 29359:	f60webmx webfile=5,180,test_9008_MYTEST
 fef60fd8 ixncwst_WriteString (f98e78, fa6508, 0, 1, 100, f98e78) + 4
  (省略 N 字)
 000887bc main     (2, ffbfb76c, 8000, de1ff0, 64, <img src='http://www.orafans.net/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> + 188
 0008860c _start   (0, 0, 0, 0, 0, 0) + dc
</debugging>
######################################################################
PMAP OUTPUT
core '../core' of 29359:	f60webmx webfile=5,180,test_9008_MYTEST
00010000    4032K r-x--  /u01/test/myappl/fnd/11.5.0/bin/f60webmx
  (省略 N 字)
FF3F0000       8K rwx--  /lib/ld.so.1
FFBEC000      80K rwx--    [ stack ]
 total     72264K
######################################################################
PFLAGS OUTPUT
core '../core' of 29359:	f60webmx webfile=5,180,test_9008_MYTEST
	data model = _ILP32  flags = MSACCT|MSFORK
 /1:	flags = 0
	sigmask = 0xffffbefc,0x0000ffff  cursig = SIGSEGV

######################################################################
stackx done.
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.orafans.net/2008/06/stackx.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
