【问题标题】:Internal Oracle error when view is queried with an ORDER BY clause使用 ORDER BY 子句查询视图时出现内部 Oracle 错误
【发布时间】:2012-04-02 08:39:07
【问题描述】:

这个问题让我很困惑,所以我想看看是否有其他人遇到过这个问题和/或知道解决方法。

我有以下SELECT 声明:

SELECT * FROM TPM_VIEWSEARCH_EXPORT VS WHERE (PROJECTTYPEID IN (1))

这很好用,尽管它是一个返回大约 3,000 行的非常慢的查询。但是,我想订购结果。所以我尝试:

SELECT * FROM TPM_VIEWSEARCH_EXPORT VS WHERE (PROJECTTYPEID IN (1)) ORDER BY PROJECTID, VERSIONID

当我这样做时,查询会运行大约 25 秒,然后返回:

ORA-00600:内部错误代码,参数:[kokegPinLob1]、[]、[]、 [], [], [], [], [], [], [], [], []

我还可以将ORDER BY 子句移动到视图定义本身,并得到相同的错误。烦人的事情是这种复制只在我们的生产服务器(在 Linux 上运行)上,而不是在我在 Windows 上本地运行的开发服务器上。但是,它确实 100% 的时间重现。

VIEW 定义可能重要也可能不重要,但无论如何:

CREATE VIEW TPM_VIEWSEARCH_EXPORT AS
   SELECT
      V.PROJECTID, V.VERSIONID, V.NAME, V.STAGEID, V.REQUESTTYPE, V.PRIORITY, V.HEALTH, V.TRAININGDELIVERYSTART, V.TRAININGDELIVERYEND, V.MEASUREMENTINFO, V.DESCRIPTION, V.BUSINESSSPONSORLEVELINVOLVE,
      P.INITIATIVEID, P.LEADERSHIPONLY, P.BUSINESSLAUNCHDATE, P.EXPECTEDBUSINESSRESULTS, P.PROJECTTYPEID,
      T.SHORTNAME as ProjectType,
      I.NAME as InitiativeName, 
      C.NAME as TrainingCategory,
      S.NAME as StageName,
      PTO.FIRSTNAME as PTOFirst, PTO.LASTNAME as PTOLast,
      STO.FIRSTNAME as STOFirst, STO.LASTNAME as STOLast,
      LTS.FIRSTNAME as LTSFirst, LTS.LASTNAME as LTSLast,
      R.FIRSTNAME as ReqFirst, R.LASTNAME as ReqLast,
      BS.FIRSTNAME as BSFirst, BS.LASTNAME as BSLast,
      (select WM_CONCAT(FIRSTNAME || ' ' || LASTNAME) from TPM_PROJECTVERSIONSME inner join TPM_USER USING (USERID) where PROJECTID=V.PROJECTID and VERSIONID=V.VERSIONID) as SME,
      (select WM_CONCAT(NAME) from TPM_PROJECTAREAS inner join TPM_AREAS USING (AREAID) where PROJECTID=V.PROJECTID) as Areas,
      (select WM_CONCAT(NAME) from TPM_PROJECTWORKGROUPS inner join TPM_WORKGROUPS USING (WORKGROUPID) where PROJECTID=V.PROJECTID) as Workgroups,
      (select WM_CONCAT(NAME) from TPM_PROJECTVERSIONSYSTEMS inner join TPM_SYSTEMS USING (SYSTEMID) where PROJECTID=V.PROJECTID and VERSIONID=V.VERSIONID) as Systems,
      (select WM_CONCAT(NAME) from TPM_PROJECTVERSIONTEAMS inner join TPM_DEVELOPMENTTEAMS USING (TEAMID) where PROJECTID=V.PROJECTID and VERSIONID=V.VERSIONID) as SupportingDevTeams
   FROM TPM_PROJECTVERSION V
   INNER JOIN TPM_PROJECT P ON P.PROJECTID = V.PROJECTID
   INNER JOIN TPM_PROJECTTYPES T ON T.PROJECTTYPEID = P.PROJECTTYPEID
   INNER JOIN TPM_INITIATIVES I ON I.INITIATIVEID = P.INITIATIVEID
   INNER JOIN TPM_PROJECTSTAGE S ON S.STAGEID = V.STAGEID
   INNER JOIN TPM_PROJECTCATEGORIES PC ON (PC.PROJECTID=V.PROJECTID)
   INNER JOIN TPM_TRAININGCATEGORIES C ON (C.CATEGORYID=PC.CATEGORYID)
   INNER JOIN TPM_USER R ON (V.REQUESTOR=R.USERID)
   INNER JOIN TPM_USER BS ON (V.BUSINESSSPONSOR=BS.USERID)
   LEFT JOIN TPM_USER PTO ON PTO.USERID = V.PRIMARYTRAININGOWNER
   LEFT JOIN TPM_USER STO ON (V.SECONDARYTRAININGOWNER=STO.USERID)
   LEFT JOIN TPM_USER LTS ON (V.LEADTRAININGSPONSOR=LTS.USERID)

运行生产服务器的 DBA 声称这是一个已知的 Oracle 错误,但没有可用的补丁。这真的是 Oracle 的 bug,还是这个问题与视图定义或数据库中的数据有关。

更新:

Oracle 版本(开发机,可以工作):

Oracle Database 11g Express Edition Release 11.2.0.2.0 - Beta
PL/SQL Release 11.2.0.2.0 - Beta
CORE    11.2.0.2.0  Production
TNS for 32-bit Windows: Version 11.2.0.2.0 - Beta
NLSRTL Version 11.2.0.2.0 - Production

Oracle 版本(生产):

TNS for Solaris: Version 11.2.0.2.0 - Production
PL/SQL Release 11.2.0.2.0 - Production
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
NLSRTL Version 11.2.0.2.0 - Production
CORE    11.2.0.2.0  Production

【问题讨论】:

  • 两种环境下的查询计划是否相同?您知道 DBA 认为是哪个错误导致了错误吗?如果不通过 Metalink 并查看生成的跟踪文件,我的猜测是问题至少部分是由于使用了未记录的 WM_CONCAT 函数。您是否可能使用不同的技术来进行字符串聚合?如果您使用的是 11.2,可以改用 LISTAGG 函数吗?
  • @JustinCave - 我已经在帖子中添加了两个版本。我似乎在两者上都有一个 LISTAGG,但无法找出正确的语法来让它与该查询一起工作..
  • @JustinCave - 说真的,如果你在西雅图地区,我欠你一杯。切换到 LISTAGG 不仅可以修复错误,而且可以将我的查询从 46 分钟缩短到 30 秒左右!神圣的废话..
  • @JustinCave - 你能添加一个答案让我接受吗?谢谢!

标签: sql oracle oracle11g


【解决方案1】:

Justin Cave 在评论中推荐的解决方案是切换到 LISTAGG 函数而不是 WM_CONCAT。这种方法不仅避免了crash,而且查询速度也从46分钟左右提高到30秒左右。更新后的代码是:

  (select LISTAGG(LASTNAME || ', ' || FIRSTNAME, '; ') WITHIN GROUP (ORDER BY LASTNAME, FIRSTNAME) from TPM_PROJECTVERSIONSME inner join TPM_USER USING (USERID) where PROJECTID=V.PROJECTID and VERSIONID=V.VERSIONID) as SME,
  (select LISTAGG(NAME, '; ') WITHIN GROUP (ORDER BY NAME) from TPM_PROJECTAREAS inner join TPM_AREAS USING (AREAID) where PROJECTID=V.PROJECTID) as Areas,
  (select LISTAGG(NAME, '; ') WITHIN GROUP (ORDER BY NAME) from TPM_PROJECTWORKGROUPS inner join TPM_WORKGROUPS USING (WORKGROUPID) where PROJECTID=V.PROJECTID) as Workgroups,
  (select LISTAGG(NAME, '; ') WITHIN GROUP (ORDER BY NAME) from TPM_PROJECTVERSIONSYSTEMS inner join TPM_SYSTEMS USING (SYSTEMID) where PROJECTID=V.PROJECTID and VERSIONID=V.VERSIONID) as Systems,
  (select LISTAGG(NAME, '; ') WITHIN GROUP (ORDER BY NAME) from TPM_PROJECTVERSIONTEAMS inner join TPM_DEVELOPMENTTEAMS USING (TEAMID) where PROJECTID=V.PROJECTID and VERSIONID=V.VERSIONID) as SupportingDevTeams

【讨论】:

    【解决方案2】:

    这是 Oracle 程序异常的通用内部错误号。它表明一个进程遇到了低级别的意外情况。此消息的原因包括:

    超时

    文件损坏

    内存中的数据检查失败

    硬件、内存或 I/O 错误

    错误恢复的文件

    第一个参数是内部消息号。其他参数是各种数字、名称和字符串。这些数字可能会在不同版本的 Oracle 之间改变含义。

    行动:收集以下信息后将此错误报告给 Oracle 客户支持:

    【讨论】:

    • 谢谢!我们已经向 Oracle 提交了服务请求,所以他们可能有兴趣看看。从该列表中,我会说超时将是最好的猜测,因为它是一个如此庞大的查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 2011-09-02
    相关资源
    最近更新 更多