source

다이애나는 누구이며, 왜 그녀는 내 데이터베이스 개체를 컴파일하지 못하게 합니까?

gigabyte 2023. 7. 18. 23:09
반응형

다이애나는 누구이며, 왜 그녀는 내 데이터베이스 개체를 컴파일하지 못하게 합니까?

좋아요, 그래서 질문 제목은 약간 당황스럽지만 질문은 충분히 심각합니다.가끔 스키마의 개체를 컴파일하거나 덤프 파일을 가져올 때 다음 오류 메시지가 표시됩니다.

ORA-04028: cannot generate diana for object SCOTT.VW_EMP

이것은 실제로 무엇을 의미하며, 어떻게 피할 수 있습니까?

관련 항목: PL/SQL, 패키지 크기, 트리 노드 구문 분석, 코드 행.

Diana는 데이터베이스 테이블의 구조와 PL/SQL 프로그램 단위의 논리를 속성 트리로 나타내는 Oracle의 인터페이스 정의 언어입니다.

구문 분석 트리 노드 수에는 내부 제한이 있습니다.컴파일러 버전은 코드의 최대 행을 설정합니다.

따라서 PL/SQL 로직의 크기와 코드 라인을 확인합니다.버전이 처리할 수 있는 실제 제한을 아는 것은 불가능하거나 필요하지 않을 수 있습니다.

패키지 크기를 올바르게 조정할 위치를 알면 문제의 절반이 해결됩니다.

나머지 절반도 해결되면 알려주세요, 감사합니다.

오류가 발생한 코드 조각을 공유해 주시겠습니까?

여기 오류가 발생하는 이유를 이해하는 데 도움이 될 수 있는 설명이 있습니다. PL/SQL은 ADA라는 프로그래밍 언어를 기반으로 하기 때문에 PL/SQL에 프로그램을 작성할 때마다 트리 구조 중간 언어인 "DIANA" -> Ada에 대한 설명 중간 속성 표기법을 생성합니다.DIANA는 컴파일러 및 기타 도구에서 내부적으로 사용됩니다.

작동 원리: 1) 컴파일 시 PL/SQL 소스 코드를 시스템 코드로 변환하여 해당 DIA를 생성합니다.

하위 프로그램 또는 패키지의 DIAA 및 시스템 코드는 모두 데이터베이스에 저장됩니다.

실행 시 공유 메모리 풀에 로드됩니다.

DIAEA는 종속 하위 프로그램을 컴파일하는 데 사용되며, 특히 하위 프로그램이 여전히 유효한지 확인/검증하는 데 사용됩니다.하위 프로그램이 테이블, 보기, 동의어 또는 다른 저장된 프로시저와 같은 데이터베이스 개체를 사용할 수 있다는 것을 알고 있기 때문에 이 작업이 필요합니다.다음에 프로그램을 실행할 때 개체가 변경/변경/삭제되었을 수 있습니다.예를 들어, 누군가 테이블을 떨어뜨렸을 수도 있고 저장된 프로세서 기능의 특성이 변경되었을 수도 있습니다.

DIANA를 사용하여 유효성 검사를 수행하면 시스템 코드가 실행됩니다.

프로그램 제한:

공유 메모리 풀에서 패키지 사양, ADT 사양, 독립 실행형 하위 프로그램 또는 익명 블록은 식별자, 키워드, 연산자 등과 같은 토큰에 해당하는 67108864(2**26) DIA 노드로 제한됩니다.이렇게 하면 PL/SQL 컴파일러에 의해 부과된 제한을 초과하지 않는 한 최대 6,000,000줄의 코드가 허용됩니다.

당신은 이 링크를 참조할 수 있습니다: http://docs.oracle.com/cd/E14072_01/appdev.112/e10472/limits.htm #

이제 문제가 발생합니다. - ora-04028:

원인은 다음 중 하나일 수 있습니다.

동일한 뷰에서 선택하는 함수가 호출되는 뷰에서 선택하면 이 오류가 발생하는 버그가 있습니다.

데이터베이스 서버, 클라이언트 또는 rman 카탈로그가 적합한 버전에 없습니다.패치를 적용해야 합니다.

Oracle 11g 인스턴스를 10.2.0.1 RMAN 카탈로그에 등록하려고 합니다.이 작업이 성공하려면 카탈로그를 버전 10.2.0.3 이상으로 업그레이드합니다.

오라클 문서에 따르면

PL/SQL은 프로그래밍 언어 Ada를 기반으로 합니다. PL/SQL은 트리 구조의 중간 언어인 Ada(DIANA)에 대한 설명 중간 속성 표기법의 변형을 사용합니다.IDL(Interface Definition Language)이라는 메타 표기법을 사용하여 정의되며, DIAA는 컴파일러 및 기타 도구에서 내부적으로 사용됩니다.

컴파일 시 PL/SQL 소스 코드는 시스템에서 읽을 수 있는 m-code로 변환됩니다.절차 또는 패키지의 DIANA 및 m-code는 모두 데이터베이스에 저장됩니다.실행 시 공유 메모리 풀에 로드됩니다.DIANA는 종속 프로시저를 컴파일하는 데 사용되며, m-code는 단순히 실행됩니다.

유감스럽게도 구문 분석된 크기에서 다이아나 노드의 수를 추정할 수 없습니다.예를 들어, 두 번째 장치에는 더 복잡한 SQL 문이 포함되어 있기 때문에 구문 분석 크기가 같은 두 프로그램 장치에는 각각 1500 및 2000 DIA 노드가 필요할 수 있습니다.

탐에게 묻기

다이애나 노드 계산에 대한 자세한 내용은 이 책 "Ada-Europe '93: 제12회 Ada-Europe 국제 회의, "Ada Sans Frontieres", 프랑스 파리, 1993년 6월 14-18일을 읽어보십시오. 의사록"

다음 지원 참고 사항은 이 주제를 잘 다룹니다.

Article-ID:         <Note:62603.1>
Folder:             PLSQL
Topic:              General Information Articles
Title:              'PLS-123 Program too Large' - Size Limitations on PLSQL 
                    Packages
Document-Type:      BULLETIN
Impact:             MEDIUM
Skill-Level:        NOVICE
Server-Version:     07 to 08
Updated-Date:       13-JUN-2000 17:41:01
References:         

개요

이 문서에는 PL/SQL 패키지 크기 제한에 대한 정보가 포함되어 있습니다.한계에 도달하면 다음 오류가 표시됩니다.

PLS-123 Program too large

PL/SQL 패키지의 크기 제한

8.1.3 이전 릴리스에서는 대형 프로그램으로 인해 PLS-123 오류가 발생했습니다.이 문제는 버그의 결과가 아니라 컴파일러의 실제 제한 때문에 발생했습니다.

PL/SQL 단위를 컴파일할 때 컴파일러는 구문 분석 트리를 작성합니다.PL/SQL 장치의 최대 크기는 구문 분석 트리의 크기에 따라 결정됩니다.이 트리에는 최대 개수의 다이아나 노드가 있습니다.

7.3까지는 2 * * 14 (16K) 다이애나 노드를 가질 수 있었고, 8.0 ~ 8.1.3에서는 2 * 15 (32K) 다이애나 노드가 허용되었습니다.8.1.3에서는 패키지 및 유형 본문에 대해 이 트리에 2 * * 26 (즉, 64M) 다이애나 노드를 가질 수 있도록 이 제한이 완화되었습니다.

소스 코드 제한

소스 코드 줄의 측면에서 한계를 쉽게 변환할 수 있는 방법은 없지만, 소스 코드 줄당 약 5~10개의 노드가 있다는 것이 우리의 관찰이었습니다.8.1.3 이전 버전에서는 컴파일러가 최대 3,000줄의 코드를 깨끗하게 컴파일할 수 있었습니다.

8.1.3부터는 패키지 본문과 형식 본문에 대한 제한이 완화되어 약 6,000,000줄의 코드를 가질 수 있게 되었습니다.

참고: 이 새로운 제한은 패키지 본문 및 유형 본문에만 적용됩니다.또한 이 특정 컴파일러 제한에 도달하기 전에 다른 컴파일러 제한에 도달하기 시작할 수 있습니다.

소스 코드 크기의 경우 토큰(식별자, 연산자, 함수 등)의 길이가 평균 4자라고 가정합니다.그러면 최대 값은 다음과 같습니다.

   Up to 7.3:         4 * (2 * * 14)=64K
   From 8.0 to 8.1.3: 4 * (2 * * 15)=128K
   With 8.1.3:        4 * (2 * * 25)=256M

이것은 대략적인 견적입니다.코드에 공백이 많거나 식별자가 긴 경우 이보다 큰 소스 코드가 나타날 수 있습니다.소스가 매우 짧은 식별자 등을 사용하는 경우 소스 코드가 이보다 작을 수도 있습니다.

이는 프로그램 단위당이므로 패키지 본문에 이 제한이 발생할 가능성이 높습니다.

패키지의 현재 크기 확인 방법

패키지의 크기를 확인하기 위해 사용할 수 있는 가장 가까운 관련 번호는 데이터 사전 보기 USER_OBJECT_SIZE에서 PARSED_SIZE입니다.이 값은 SYS에 저장된 다이아나의 크기(바이트)를 제공합니다.IDL_xxx$ 테이블이며 공유 풀의 크기가 아닙니다.

PL/SQL 코드의 DIANA 부분(컴파일 중에 사용됨)의 크기는 시스템 테이블보다 공유 풀에서 훨씬 큽니다.

예를 들어 USER_OBJECT_SIZE의 PARSED_SIZE가 50K 이하인 경우 64K 제한과 관련된 문제가 발생하기 시작할 수 있습니다.

패키지의 경우, DIAEA의 구문 분석된 크기 또는 크기는 사양 및 본문에 대해 별도로 적용되지 않고 전체 개체에만 적용됩니다.

패키지에 대해 parsed_size를 선택하면 규격 및 본문에 대해 별도의 소스 및 코드 크기가 수신되지만 패키지 규격에 대해 라인에 출력되는 전체 개체에 대해 의미 있는 구문 분석 크기만 수신됩니다.패키지 본문의 줄에 있는 parsed_size에 대해 0이 출력됩니다.

다음 예에서는 이 동작을 보여 줍니다.

CREATE OR REPLACE PACKAGE example AS  
  PROCEDURE dummy1;  
END example;  
/  
CREATE OR REPLACE PACKAGE BODY example AS  
  PROCEDURE dummy1 IS  
  BEGIN  
    NULL;  
  END;  
END;  
/  

SQL> start t1.sql;  

Package created.  


Package body created.  

SQL> select parsed_size from user_object_size where name='EXAMPLE';  


PARSED_SIZE  
-----------  
        185  
          0  


SQL> select * from user_object_size where name='EXAMPLE';  

  .....

Oracle은 DIAEA와 MCODE를 모두 데이터베이스에 저장합니다. MCODE는 실행되는 실제 코드이며, 특정 라이브러리 장치 X의 DIAEA에는 라이브러리 장치 X를 사용하여 절차를 컴파일하는 데 필요한 정보가 포함되어 있습니다.

다음은 몇 가지 참고 사항입니다.

다이아나는 IDL로 대표됩니다.IDL의 선형 버전은 디스크에 저장됩니다.실제 구문 분석 트리가 작성되어 공유 풀에 저장됩니다.이러한 이유로 공유 풀의 DIANA 크기가 일반적으로 디스크보다 큽니다.

호출된 프로시저에 대한 DIAA는 프로시저를 생성할 때만 공유 풀에 필요합니다.프로덕션 시스템에서는 공유 풀에 DIAEA가 필요하지 않습니다(단, MCODE에만 해당).

릴리스 7.2부터는 패키지 본문의 DIAA가 버려지고 사용되지 않으며 데이터베이스에 저장되지 않습니다.이것이 패키지 본체의 PARSED_SIZE(즉, DIANA의 크기)가 0인 이유입니다.

따라서 큰 절차와 기능은 항상 패키지 내에서 정의되어야 합니다!

패키지는 절차와 마찬가지로 데이터베이스의 DIAA에 저장됩니다.그러나 패키지를 사용하여 종속성 체인을 해제할 수 있으며, 이를 제거할 수도 있습니다.모든 생산(실제) 코드는 패키지에 있어야 하며, 독립적인 절차나 기능에 있어서는 안 된다고 생각합니다.

Oracle 10.2.5(Unpublished Bug 9342254; 문서 ID 1505092.1 참조)에 Oracle 11.1 이상 수정이 있는 버그가 있습니다. 이 문제가 여기서 발생한 것 같습니다.

공유 풀의 플러시를 실행하여 해결할 수 있습니다.

ALTER SYSTEM FLUSH SHARED_POOL

NB. 이것은 매우 오래된 질문이지만, 다른 사람이 질문을 마주칠 경우를 대비하여 이 질문을 여기에 남깁니다.Nineside와 저는 실제로 같은 회사에서 일했고, 이것을 독립적으로 발견했습니다.

디버그 모드에서 큰 패키지를 컴파일할 때도 비슷한 문제가 있었습니다.디버깅 정보의 크기가 디버그 기호 테이블의 크기에 대한 컴파일러 제한을 초과하는 경우 발생합니다.다음을 사용하여 디버그 모드를 끌 수 있습니다.

alter session set plsql_debug=false; 

또는 전체 데이터베이스에 대해:

alter system set plsql_debug=false;

언급URL : https://stackoverflow.com/questions/7764656/who-is-diana-and-why-wont-she-let-my-database-objects-compile

반응형