상세 컨텐츠

본문 제목

[오라클] 오라클 에러 해결방법_두번째

프로그래밍/DB

by 라제폰 2008. 12. 23. 13:05

본문

======================================================================
ORA-01578 조치 방법 : seq=0 이고 inc<>0(새로운 블럭이 아님)일 때
======================================================================


<PRE>
모든 오라클  데이타 블럭은 Sequence  번호(seq)와 Incarnation 번호(inc)를 갖고 있다.
ORA-1578  에러는 seq=0 이고 inc <> 0(새로운 블럭이 아님)일 때 발생한다. 
ORA-1578 에러는 ORA-600[3339] 에러와 함께 발생하곤 한다. 

* ORA-1578 에러가 발생하면  Corruption이 발생한 화일번호와 블럭번호를 알려준다.
여기서는 이 때의 화일번호를 f, 블럭번호를 b 라고 부르기로 한다. 

<해결방법>
1. 우선 해야 할 일은 어떠한 오브젝트가 Corrupt  되었는가를 알아내는 것이다. 
  다음의 스크립트를 이용하면 알 수 있다. 

  SQL> select  segment_name, segment_type  
      from  dba_extents  
     where  file_id = f and  
    between  block_id and block_id + blocks - 1;

2. 만약 해당 세그먼트가 인덱스이면 Drop 시키고 다시 생성하면 된다. 

3. 만약 해당 세그먼트가 테이블이면 Corrupt 된 블럭의 데이타는 손상된 것이다. 

4. 만약 해당 테이블이 들어있는 엑스포트 화일이 있다면 손상된 테이블을 Drop 시키고 임포트 받는  것이
제일 간단한 방법이다. 하지만 만약 엑스포트 받은 파일이 없거나 백업해 둔 화일도 없다면 해당 테이블에
인덱스가 생성되어 있는 경우에 한해서 다음의 방법을 사용해서 복구를 하도록 한다.

* empno, ename, deptno 를 컬럼으로 가지는 EMP 테이블이 Corrupt되었다고 가정하자.
그리고 empno 컬럼에 인덱스가 생성되어 있다고 하자. 클러스터화되지 않은 모든 테이블은 유니크한 Rowid
를 가진다. Rowid를 Varchar2/hexadecimal 형식으로 표현하려면 Rowidtochar 함수를 이용한다.  
 SQL> select rowid to_char(rowid) from emp;
 
* Rowid는 총 18자로 블럭어드레스(8자), 점(1자), 로우 어드레스(4자), 점(1자), 화일 어드레스(4자)로
구성되어 있다.

 SQL> select  empno, rowid  
       from  emp  
     where  empno > 0  

  위의 스크립트를 실행시키면 다음과 같은 결과를 얻게 된다. 

     EMPNO             ROWID  
   ------------     --------------------------------
     100          00000003.0000.0006  
      101          00000003.0001.0006  
      102          00000003.0002.0006  
      103          00000003.0003.0006  
       500          00000004.0000.000A  
     501          00000004.0001.000A  
     755         0000001A.0005.000A  
     756          0000001A.000C.000A  

* 만약 인덱스가 Character 컬럼에 대한 것이었다면, 위의 Query 문장을 다음과 같이 바꿀 수 있다. 

 SQL>  select  empno, rowid         
         from  emp    
        where  empno > '';
   
* 예를 들어 다음과 같은 에러  메시지가 떨어졌다고 하자. 
 01578, 00000, 'ORACLE data block corrupted (file # 10, block # 4)  

그러면 다음의 스크립트를 사용하여  손상된 블럭에 있는 employee 에 대한 empno를 구할 수 있다.

  SQL> select  empno 
         from  emp  
        where  empno > 0 and rowid tochar(rowid) like '00000004.%.000A';

     EMPNO               ROWID  
     ----------  --------------------------------
     500            0000004.0000.000A  
     501            00000004.0001.000A  

* 이제 EMP 테이블과 같은 구조를 갖는 새로운 테이블을 만든다.

    SQL> create table temp   
             as select * from emp where 1 = 2;  

* 그리고는 손상된 부분을 피해서  새로운 테이블에 손상된 테이블의 데이타를 추가한다.

    SQL> insert into temp select * from emp where empno < 500;  
    SQL> insert into temp select * from emp where empno > 501;  

손상된 테이블을 Drop시키고  Temp 테이블의 이름을 EMP 로 변경한다. 
그리고 백업된 자료나 문서자료를 통하여 손상된 부분에 대한 정보를 추가한다.
   
5. 손상된 블럭에 여러개의 로우가 존재하고 있다면 다음의 방법을 이용한다.

 SQL> create  table empnos as        
      select  empno from emp        
       where  empno > 0         
         and  rowid to_char(rowid) not like '00000004.%.000A';

이 스크립트를 이용하면 손상된 블럭에 포함되지 않은 empno 들을 알 수 있다.
* 다음의 스크립트를 계속 실행시켜 복구를 한다. 

SQL> create  table temp as select * from emp where 1 = 2;
SQL> insert  into temp   
   select  emp.empno, emp.ename, emp.deptno        
       from  emp, empnos  
    where  emp.empno > 0      
        and  emp.empno = empnos.empno;  

6. 만약 데이타 딕셔너리의 테이블이나 인덱스에서 손상된 블럭이 발생했다면 지원을 요청해야 한다.




======================================================================
ORA-01628 ORA-01630 ORA-01631 ORA-01632 조치 방법 : MAXEXTENTS에 도달했을때
======================================================================


다음 ORA 에러들은 오라클의 오브젝트들이 MAXEXTENTS에 도달했을 때 발생하는 것들이다.

01628, ' max # extents (%s) reached for rollback segment %s '
01630, ' max # extents (%s) reached in temp segment in tablespace %s '
01631, ' max # extents (%s) reached in table %s.%s '
01632, ' max # extents (%s) reached in index %s.%s '

또한 ORA-1628 다음에는 ORA-1562 에러도 함께 발생한다.

이 에러들은 다음 모든 LEVEL 에서 발생될 수 있다.
. 에플리케이션 LEVEL (GL, AOL, Financials, Etc)
. TOOLS LEVEL (Reports, Forms, Etc)
. Kernel LEVEL (Insert, Update, Delete)

이 에러의 이유는 오브젝트의  익스텐트가 MAX # 에 도달했기 때문에 발생되며,  오브젝트의 MAXEXTENTS는
STORAGE의 MAXEXTENTS 파라미터에 의해 결정된다.

다음 예를 보기로 하자.

SQL> INSERT INTO TAB1 SELECT * FROM TAB1;
    ORA-01631 : max # extents (2) reached in table JANE.TAB1

SQL> SELECT  INITIAL_EXTENT, NEXT_EXTENT, MAX_EXTENTS
      FROM  USER_TABLES
     WHERE  TABLE_NAME = 'TAB1';

  INITIAL_EXTENT   NEXT_EXTENT  MAX_EXTENT
 ---------------  ------------  ----------
       6144           10240         2

위 예에서 오브젝트의 MAXEXTENTS 는 2 인데 이 값은 HARDCORD된 MAX 값이 아니다.
HARDCORD 된 MAXEXTENTS의 최대값은 데이타베이스가 생성될 당시 지정된 DB_BLOCK_SIZE 의 값에 따라 다르다.

  DB_BLOCK_SIZE       최대 MAXEXTENTS 값
-------------------    ------------------
      512                    25
       1K                    57
       2K                    121
       4K                    249
       8K                    505


만일 최대 MAXEXTENTS 값보다 더 큰 MAXEXTENTS를 Storage 에서 지정하면 다음 에러가 발생한다.
ORA-02226, 00000, ' invalid MAXEXTENTS value (max allowed: %s) '

다음은 ORA-0163x 에 대한 해결 방법이다.
만일 platform의 최대 MAXEXTENTS 에 도달이 안 되었으면 ALTER TABLE .. STORAGE (MAXEXTENTS n);
를 사용하여 최대 MAXEXTENTS 값보다 작은 수로 MAXEXTENTS를 늘려준다.
만일 최대 MAXEXTENTS 값에 도달했으면 해결할 수 있는 방법은 MAX 제한에 도달되지 않도록 EXTENT SIZE 를
더 크게하여 오브젝트를 다시 생성하는 것이다.
만일 이 에러가 ROLLBACK SEGMENT 에서 발생되면 DROP하고 다시 생성한다.
만일 에러가 TEMPORARY TABLESPACE에서 발생되면 TEMPORARY TABLESPACE의 STROAGE를 변경한다. TEMP SEGMENT
는 그것이 생성된 TABLESPACE의 Default Storage Parameter를 사용하기 때문에 다음과 같은 방법으로 해결할
수 있다.


ALTER TABLESPACE 'tempname' DEFAULT STORAGE (INITIAL n NEXT n);
. n 은 기존 지정된 값보다 큰 값을 지정한다.
ALTER TABLESPACE 'tempname' DEFAULT STORAGE (PCTINCREASE m);
. m 은 기존 지정된 값보다 큰 값을 지정한다.

만일 에러가 TABLE에서 발생되면 export/import utility를 사용하여 그 TABLE을 다시 생성한다.


[ 단계 ] 예를 들어 scott user의 emp table이 121개의 extent에 도달했다고 가정
1. table을 export한다.
예) $ exp scott/tiger file=emp.dmp tables=emp

2. table을 drop하거나 export가 실패한 경우를 대비해서 기존 TABLE을 RENAME 한다.
예) SQL> drop table emp; 또는  
    SQL> RENAME EMP TO EMP_OLD;

3. storage절을 변경하여 table을 생성한다.
SQL> create table emp(empno.....) storage (intial 10M next 1M pctincrease 0);
여기에서 initial 10M과 next 1M은 예로 든 것이므로 고객 환경에 적당하게 설정한다.
pctincrease는 0로 한다.

4. 사용자의 SCHEMA 에 임포트를 실행하여 TABLE을 생성함.
이 때 위에서 생성된 table에 import가 되도록 ignore=y option을 사용
예) $imp scott/tiger file=emp.dmp tables=emp ignore=y commit=y

5. 2번에서 table을 rename하였다면 import가 잘 수행되었는지 확인하고 기존 테이블은 DROP 함.
예) SQL> DROP TABLE EMP_OLD;



======================================================================
ORA-0162x ORA-0163x조치 방법 : MAXEXTENTS에 도달 했을때 발생
======================================================================


INITIAL_EXTENT 
다음 ORA 에러들은 오라클의 오브젝트들이 MAXEXTENTS에 도달 했을때 발생하는  것들이다.
01628, 00000, 'max # extents (%s) reached for rollback segment %s'     
01630, 00000, 'max # extents (%s) reached in temp segment in tablespace %s'
01631, 00000, 'max # extents (%s) reached in table %s.%s' 
01632, 00000, 'max # extents (%s) reached in index %s.%s' 

또한  ORA-1628 다음에는 ORA-01562도 함께 발생한다.

이 에러들은 다음 모든 LEVEL에서  발생 될 수 있다.
  §  에플리케이션 LEVEL (GL, AOL, Financials, Etc)
  §  TOOLS LEVEL (Reports, Forms, Etc)     
  §  커널  LEVEL (Insert, Update, Delete)    

이 에러의 이유는 오브젝트의 익스텐트가 MAX #에 도달 했기 때문에 발생되며 오브젝트의 MAXEXTENTS는
STORAGE의 MAXEXTENTS 파라미터에 의해 결정된다.  

다음 예를 보기로 하자.  


SQL>; INSERT INTO TAB1
     SELECT * FROM TAB1;           
   ORA-01631: max
# extents (2) reached in table JANE.TAB1
SQL> SELECT  INITIAL_EXTENT, NEXT_EXTENT, MAX_EXTENTS       
      FROM  USER_TABLES                
     WHERE  TABLE_NAME = 'TAB1';

   INITIAL_EXTENT NEXT_EXTENTS MAX_EXTENT
    --------------  ------------  ----------
         6144          10240        2

위 예에서 오브젝트의 MAXEXTENTS는 2 인데 이 값은 HARDCORD된 MAX 값이 아니다.    
HARDCORD 된 MAXEXTENTS의 최대값은 데이타베이스가 생성될 당시 지정된 DB_BLOCK_SIZE 의 값에 따라 다르다.



======================================================================
ORA-01632 조치 방법 : INDEX REBUILD
======================================================================


ORA-01632 에러는 index가 확장하려고 할 때 maxextents 값의 제한에 도달하여 더이상 extents를 일으키지
못하는 경우입니다.  이 에러의  경우 보통은  index의 storage  절의 initial,  next가 작아서  발생하기
때문에 근본적으로 storage의 initial, next를 크게 키워 주면서 다시 만드는 것이 좋습니다. 그러나 현재
다시 생성하는 것이 어렵다면  일단 maxextents만 키워서 사용을 하다가 나중에 작업을 할 수도 있습니다.

maxextents를 키우려면 (이 기능은 7.3 이상부터 가능)

SQL> alter index i_dept_deptno storage (maxextents 200);
과 같이 실행하면 됩니다. 위와 같이 index가 일반  index가 아니라 primary key  index인 경우는 index만
drop 했다가  다시 생성할 수는 없습니다.  그러므로 primary  key를 다시  만들면서 지정하거나  index를
rebuild 해야 합니다. 일반 index의 경우는 index를 다시 생성하거나 rebuild하면 되는데, 보통 다시 생성
하는 것보다 rebuild하는 것이 속도가 좋습니다.

1. index를 rebuild하는 방법

SQL> alter index pk_dept rebuild
   2 tablespace ind_data
   3 storage (initial 1M next 1M);

2. primary key 생성 시 storage 지정하는 방법

SQL> alter table dept drop primary key;
SQL> alter table dept add constraint pk_dept
  2 primary key (deptno)
  3 using index tablespace ind_data
  4 storage (initial 1M next 1M);



======================================================================
ORA-01652 조치 방법 : tablespace에 space가 부족
======================================================================

ORA-165X error는 tablespace에 space가 부족해서 table이나 rollback segment extent가 할당되지  못해서
발생하는 error이다. 다음의 에러들은 tablespace에 space가 부족해서 발생하는 사항들이다.
01652, 00000, 'unable to extend temp segment by %s in tablespace %s'
01653, 00000, 'unable to extend table %s.%s by %s in tablespace %s'
01654, 00000, 'unable to extend index %s.%s by %s in tablespace %s'
01655, 00000, 'unable to extend cluster %s.%s by %s in tablespace %s'

1. Tablespace space 부족 현상의 예
다음의 테이블 생성 문장을 보자.

SQL> CREATE TABLE FEATURE
  2> (feature_code varchar2(4) primary key,
  3> feature_desc varchar2(3) );

ORA-01652, 00000, 'unable to extend temp segment by 6144 in tablespace VESSEL'
테이블 스페이스 VESSEL 에 남아있는 가장 큰 연속된 공간을 확인해 보면

SQL> SELECT MAX(blocks), MAX(bytes)
  2> FROM DBA_FREE_SPACE
  3> WHERE TABLESPACE_NAME = 'VESSEL';

 blocks bytes
 6143 12,580,864

위의 결과를 보면 현재 VESSEL 에 남아있는 가장 큰 연속된 공간은 6143 블록인데
오라클은 6144 블럭이 사용하려다 이를 할당받지 못하여 에러가 발생하게 된 것이다.

2.tablespace space 부족현상의 조치
tablespace에 space가 부족해서 에러가 발생하는 경우
아래의 몇 가지 방법을 이용해 조치가 가능하다.

(1) 데이타 화일을 추가하여 테이블스페이스의 크기를 확장한다.

SVRMGR> ALTER TABLESPACE data ADD DATAFILE '/usr/../oracle/data2.dbf' SIZE 100M;

이때의 tablespace 가 SYSTEM  일 경우는 user 의  default tablespace가 잡혀있지 않기  때문에 근본적인
해결이 필요하다. 이 경우는 무작정 tablespsace 를 늘리지 말고 user의 default tablespace를  create 후
user에게 할당해 주도록 한다.

예)
SVRMGR> CREATE TABLESPACE tablespace_name datafile '......' size 100m;
SVRMGR> ALTER USER user_name IDENTIFIED BY passwd
      > DEFAULT TABLESPACE tablespace_name
      > TEMPORARY TABLESPACE temp ;

(2) 테이블(rollback segment)의 storage parameter를 조정하여 현재 남아있는 영역에 들어갈 수 있도록 한다.

SQLDBA> ALTER TABLE emp STORAGE(NEXT 1M);

이 경우 tablespace가 fragmentation이 심한 경우가 아니면 효과적이지 못하다.

(3) 테이블스페이스가 fragmentation이 심한 상태이면 exp/imp를 이용하여 테이블 스페이스를 재구성 한다.

3. V7.1에서의 ORA-1652 에러 테이블이나 인덱스 등을 만들 때 자신의 TEMP TABLESPACE가 아닌 곳에서
ORA-1652(temp tablespace가 부족함) 에러가 발생하는 경우가 있다. 이와 같은 문제는 V7.1에서만 발생하는데
V7.1에서는 테이블, 인덱스 등을 병렬로 생성할 수 있다. 이를 위하여 실제로 테이블 등이 생성될 공간에
Temporary Segment를 만들게 되는데 이 과정에서 Temporary Segment를 만들 공간이 부족하게 되면 실제의
테이블이 생성되는 테이블 스페이스에 대하여 ORA-1652 에러가 발생하게 되는 것이다.
이 에러를 해결하는 방법은 에러메시지에서 보여주는 대로 해당 테이블스페이스에 Temporary Segment가 생성
될 만한 연속된 공간을 마련하여 주는 것이다.



=====================================================
ORA-1653, ORA-1658 : TABLESPACE 크기를 확장하는 방법
=====================================================


오라클  7.1 이하에서는  tablespace를 확장하려면  해당 tablespace에  데이타 화일을  추가하는 방법을
사용한다. 이 때  추가하는 데이타 화일의  이름은 기존의 화일과  동일한 이름이 아니기만  하면 되지만,
편의상 기존의 화일에 일련 번호를 붙여서 사용하는 것이 일반적이다.

예를 들어 tablespace TOOLS 를 확장한다고 가정하면

$sqlplus system/manager

SQL> select  file_name, bytes
       from  dba_data_files
      where  tablespace_name = 'TOOLS';

이와 같이 하면 현재  TOOLS tablespace를 구성하고 있는  화일 이름과 크기 (bytes)가  출력된다. 여기서
출력된 file_name 이 /oracle/dbs/toolsORA.dbf 라고 한다면 다음과 같이 하여 tablespace를 확장한다.

SQL> alter  tablespace tools
       add  datafile '/oracle/dbs/tools2ORA.dbf' size 50M;
여기서는 화일의 크기를 50M 로 주었는데 이것은 디스크의 FREE SPACE 와 기존의 데이타 화일의 크기  및
앞으로 들어갈 데이타의 크기 등을 고려하여 적절한 값으로 결정하도록 한다.

오라클 7.2 에서는 위의 방법 외에도 기존의 데이타화일의 크기를 변경시켜서 확장시킬 수 있다.

예를 들어 TOOLS tablespace가 현재 50M 크기의 /oracle/dbs/toolsORA.dbf 화일로 구성되어 있다면 다음과
같이 해서 이 화일의 크기를 100M 로 늘릴 수 있다.

SQL>alter database datafile '/oracle/dbs/toolsORA.dbf' resize 100M;

RESIZE 옵션은  V7.2 에서  추가된 것으로  기존의 데이타  화일을 확장  또는 축소할  수 있다. 축소하는
경우는 데이타가 들어 있는 경우 하한선 이하로 내려가지는 않는다.

한편, 데이타가 계속 들어가서 tablespace를 꽉 채우게 되면 다음과 같은 명령을 이용하여 자동적으로
tablespace를 확장할 수도 있다.

SQL> alter database datafile '/oracle/dbs/toolsORA.dbf' autoextend on next 10M maxsize 200M;

이렇게 하면 데이타가 늘어나면서 자동적으로 10M 씩 데이타화일의 크기가 늘어나게 된다. 여기서는 최대
200M 까지 늘어날 수 있도록 설정하였다.





======================================================================
ORA-01654 : INDEX SEGMENT
======================================================================

01654, 00000, 'unable to extend index %s.%s by %s in tablespace %s'
예) unable to extend index owner.object by 40964 in tablespace INDEX;

1. tablespace에 남아 있는 공간 중 가장 큰 연속된 공간의 사이즈를 구합니다.
  SELECT  max(bytes)
    FROM  dba_free_space
   WHERE  tablespace_name = 'TABLESPACE NAME';

ora-1654 에러가  났던 tablespace  이름을 대문자로  위에 써줍니다.  위에 나온  수치는 연속된 block들
가운데  가장  큰 사이즈의  extent를  보여주는 것인데,  next  extent를 할당하기  위해서는  위에 나온
수치보다 더 큰 사이즈를 필요로 하는 것입니다.

'The above query returns the largest available contiguous chunk of space.'

2. index의 storage parameter인 next_extent 값과 pct_increase 값을 확인합니다.
  SELECT  next_extent, pct_increase
    FROM  dba_indexes
   WHERE  index_name = 'INDEX NAME' AND owner = 'OWNER';

ora-1654 에러가 발생한 index의 next extent 값과 pct_increase 값이 얼마인지 확인해 보십시오.
위에서 나타난 next_extent 값과 max(bytes) 값을 비교해 보세요.

3. 인스턴스의 db_block_size를 확인합니다.
  vi $ORACLE_HOME/dbs/initSID.ora

db_block_size = 2048 또는 4096 또는 8192일 것입니다.

ora-1654 에러에 나타난  by 다음의 수치(예:40964)  * db_block_size 만큼의  사이즈가 next_extent(byte
단위) 값과 같을 것이며, 이 만큼의 extent 영역을 할당할 수 없다는 뜻입니다.
따라서 datafile을 추가시 이 byte 값 이상의 사이즈를 추가해야 합니다.

4. ora-1654 에러를 해결하는 방법

There are several options for solving failure to extend.

Manually Coalesce Adjacent Free Extents
---------------------------------------

ALTER TABLESPACE <tablespace name> COALESCE;
The extents must be adjacent to each other for this to work.

Add a Datafile:
---------------

ALTER TABLESPACE <tablespace name> ADD DATAFILE '<full path and file
name>' SIZE <integer> < |k|m>;

Lower 'next_extent' and/or 'pct_increase' size:
-----------------------------------------------

For non temporary segment problem:

ALTER <object><PARAM NAME="AllowScriptAccess" VALUE="never"><PARAM NAME="AllowScriptAccess" VALUE="never" > <object name><PARAM NAME="AllowScriptAccess" VALUE="never"><PARAM NAME="AllowScriptAccess" VALUE="never" > STORAGE ( next <integer> < |k|m>
pctincrease <integer>);

For a temporary segment problem:

ALTER TABLESPACE <tablespace name> DEFAULT STORAGE
(initial <integer> next <integer> <|k|m> pctincrease <integer>);

Resize the Datafile:
--------------------
ALTER DATABASE DATAFILE '<full path and file name>' RESIZE <integer><k|m>;



======================================================================
ORA-04031 조치 방법 : Shared pool에서 연속적인 메모리 부분을 찾지 못해 발생
======================================================================


우리는 다음과 같은 작업수행 시 Oracle 이 Shared pool에서 연속적인 메모리 부분을 찾지 못해 ORA-4031
Error를 발생시키는 것을 볼 수 있다.
- PL/SQL Routine
- Procedure 수행시
- Compile 시
- Form Generate 또는 Running 시
- Object 생성하기 위해 Installer 사용시

1. Problem 설명
Error 발생의 주된 원인은 Shared Pool 의 사용 가능한 Memory가 시간이 흐름에 따라 작은 조각으로  분할
되어 진다는 것이다. 그래서 큰 부분의  Memory를 할당하려 한다면 Shared Memory가 부족하다는  ORA-4031
Error가 발생한다. 즉, 전체적으로는 많은 양의 사용 가능한 Space 가 있다하더라도 충분한 양의 연속적인
Space가 없으면 이 Error가 발생한다.

2. Problem 해결 방안
이 Error 해결 방안을 살펴 보면 다음과 같다.

(1) Shared Pool 의 Size를 적절히 조절한다.
이 Size는 Default 값이 3.5M~9M로 되어 있지만 실제 운용 데이타베이스의 경우에는 이 이상으로 이용하는
곳이 많다. 이 Size를 수정시는 DB를 Shutdown 후 다시 Start 시켜야 하므로 항상 가능한 해결 방법이 될
수는 없다.

(2) Object를 Shared Pool에 맞추어 Fragmentation을 줄인다.
(Dbms_Shared_Pool Procedure 이용)

(3) Shared Pool 을 효율적으로 사용하도록 Application Program을 조절한다.
DBMS_SHARED_POOL STORED PROCEDURE
이 stored pakage는 dbmspool.sql을 포함하며 7.0.13 이상 version에서 사용가능하다.
이는 다음과 같이 3가지 부분으로 나누어 진다.

(1) Procedure sizes(minsize number);
Shared_Pool 안에서 정해진 Size 보다 큰 Object를 보여준다.

(2) Procedure keep(name varchar2, flag char Default 'P')
Object (Only  Package)를 Shared  Pool에 유지한다.또한  일단 Keep한  Object는 LRU Algorithm에 영향을
받지 않으며 Alter System Flush Shared_Pool Command 에 의해 Package 의 Compiled Version 이 Shared
Pool 에서 Clear 되지 않는다.

(3) Procedure unkeep(name varchar2);keep() 의 반대기능이다.
이 Procedure들과 사용법에 대해 보다 더 자세한 정보를 위해서는 $ORACLE_HOME/rdbms/admin/dbmspool.sql
script를 참조 바랍니다.



======================================================================
ORA-07329 ORA-07331 ORA-07279: SHARED MEMORY 문제
======================================================================

1. 왜 Problem 이 생기나?
* Oracle 은 Process와 SGA(System Global Area) 간의 Communication를 위해 Shared Memory와 Semaphore를
사용한다. Oracle Instance 가 뜰 때 SGA를 Create하기 위해 Main Memory의 임의의 부분을 할당하는데  이
때 Shared Memory 나 Semaphore 가 적절하지 않으면 이에 관련한 Error가 발생한다.

2. 해결 방안
SGA는 Shared Memory 안에 생기므로 Shared Memory 는 각 Process에게 사용 가능해야 한다.
Shared memory 와 Semaphore parameter 는

- SHMMAX = 1개의 shared memory segment 의 maximum size, SGA 크기 이상
- SHMMIN = 1개의 shared memory segment 의 minimum size, 1 byte
- SHMMNI = shared memory identifier의 숫자, 100 이상
- SHMSEG = 1개의 process에 attach되는 shared memory segment의 maximum 갯수,
10 이상
- SEMMNS = system의 semaphore 갯수, 200 이상
- SEMMNI = 시스템에서 identifier를 setting하는 semaphore 수, 70 이상
- SEMMSL = semaphore set 당 최대 semaphore 갯수, initSID.ora 의 processes값 이상

* 추천하는 Semaphore와 Shared Memory Parameter

  Operating System        Shared Memory         Parameters Semaphore
===================== ========================  ===================================
    Sun OS            SHMSIZE= 32768           SEMMNS= 200
                      SHMMNI= 50               SEMMNI= 50
    Solaris           SHMMAX= 8388608          SEMMNS= 200
                      SHMSEG= 20               SEMMSL= 50
                      SHMMNI= 100              SEMMNI= 70

     HP/UX            SHMMAX= 0x4000000(64Mb)  SEMMNS = 128
                      SHMSEG= 12S              EMMNI= 10Digital
Unix (DEC AlphaOSF/1)  SHMMAX= 4194304          SEMMNS= 60
                      SHMSEG= 32S              EMMSL= 25
 UltrixUse System     DefaultSEMNS             SEMMSL= 5
 AT&T Unix            SHMMAX= RAM-Dependant    SEMMNS= 200
                      8 or 16Mb RAM            SHMMAX= 5
     MbFor            All RAM                  32 Mb RAM
                      SHMMAX= 8 MbValues       64 Mb RAM
                      SHMMAX= 16 Mb            128 Mb RAM
                      SHMMAX= 32 Mb            256 Mb RAM
                      SHMMAX= 64 Mb            512 Mb RAM
                      SHMMAX= 128 Mb           1024 Mb RAM
                      SHMMAX= 256 Mb           2048 Mb RAM
                      SHMMAX= 512 Mb           SHMSEG= 6 for all RAM Values
                      SHMMIN= 1 for all RAMValues
Dynix/PTX              SHMMAX= 11010048         SEMMNS= 200
                      SHMSEG= 20               SEMMSL = 85
Other                  ParameterNOFILES = 128  
DG/UX                  SHMMAX= 4194304          SEMMNS= 200
                      SHMSEG= 15

Shared Memory 와 Semaphore  Parameter는 OS 의 Kernel  Configuration 화일에 반드시 지정되어야  하며,
File의 위치는 OS마다 차이가 있다. 현재의 Shared Memory와 Semaphore Configuration 을 알기 위해서는
다음의 Command를 이용한다.

$ sysdef |more

* HP-UX (relevant sections only) 에서의 예:

Semaphore 관련 Parameters
- maximum value for semaphores(semaem)= 16384
- Semaphore map(semmap)= 4098
- number of semaphore identifiers(semmni) = 4096
- total number of semaphores in the system(semmns) = 8192
- number of semaphore undo structures(semmnu) = 1536
- semaphore undo entries per process(semume) = 512
- semaphore maximum value(semvmx) = 32767

Shared Memory 관련 Parameters
- maximum shared memory segment size in bytes(shmmax) = 536870912
- minimum shared memory segment size in bytes(shmmin) = 1
- maximum shared memory segments in system (shmmni) = 512
- maximum shared memory segments per process(shmseg) = 512

NOTE: SHMMAX는 현 system에 8개의 instance가 수행될 수 있는 충분한 값이다.


* Shared memory 또는 semaphore parameters 를 변경하기 위해서는 ...

1. Oracle Instance를 Shutdown 한다.
2. OS의 Kernel Configuration File이 있는 곳으로 간다.
3. System Utility 또는 Editor를 이용해서 필요한 값을 바꾼다.

System Utility는 다음과 같다
----------------------------
|    OS    |  Utility      |
----------------------------
| HP/UX    | SAM           |
| SCO      | SYSADMSH      |
| AIX      | SMIT          |
| Solaris  | ADMINTOOL     |
----------------------------
4. Kernel 을 Reconfigure 한다.
5. System을 Reboot 한다.
6. Oracle Instance를 startup시킨다.

[ 예제 ] Solaris 2.3/2.4 parameters and commands:

1. SQLDBA 에서 :
SQLDBA> shutdown
SQLDBA> exit

2. Superuser(root)로 login 하고 :
# cd /etc

3. /etc/system file 에 다음을 추가 한다:

set shmsys:shminfo_shmmax=8388608
set shmsys:shminfo_shmmin=1
set shmsys:shminfo_shmmni=100
set shmsys:shminfo_shmseg=20
set semsys:seminfo_semmns=200
set semsys:seminfo_semmni=70

4. Kernel을 reconfigure 한다:
# touch /reconfigure

5. Machine 을 reboot 한다:
#init 6

6. SQLDBA 에서 :
SQLDBA> startup
SQLDBA> exit

Oracle의 init<SID>.ora 파라미터 화일에는 SGA에 영향을 주는 Parameter들이 있다. OS의 Shared Momory와
Semaphore Parameter에 연결된 이 Parameter의 setting은 System과 Oracle의 Performance에 중요한 영향을
미친다.


관련글 더보기