흐르는 시간의 블로그...

내가 DB 장애로 골머리를 앓고 있으니...

웹개발자인 직원이 아래의 쿼리를 보내 왔다.


아무 생각없이 돌려 봤다.

full outer join을 써 놨다.

우리회사에서 초당 업데이트가 70번 이상 발생하는 최강의 복잡도와 Lock이 최상인 테이블 두개를 붙여놨다.


결국 과거에 작업을 하고 뒤처리를 안한것이다. ㅠ.ㅠ

나도 그 직원도 서로 잊어버린 결과라고나 할까.

...


SELECT Disk_Reads DiskReads, Executions, SQL_Text SQLText

FROM

(

SELECT Disk_Reads, Executions, LTRIM(SQL_Text) SQL_Text,

Operation, Options,

Row_Number() OVER

(Partition By sql_text ORDER BY Disk_Reads * Executions DESC)

KeepHighSQL

FROM

(

SELECT Avg(Disk_Reads) OVER (Partition By sql_text) Disk_Reads,

Max(Executions) OVER (Partition By sql_text) Executions,

sql_text, p.operation,p.options

FROM v$sql t, v$sql_plan p

WHERE t.hash_value=p.hash_value AND p.operation='TABLE ACCESS'

AND p.options='FULL' AND p.object_owner NOT IN ('SYS','SYSTEM')

AND t.Executions > 1

)

ORDER BY DISK_READS * EXECUTIONS DESC

)

WHERE KeepHighSQL = 1

AND rownum <=30;

GRANT EXECUTE ON UBIKHANS.table_exists TO ubiread;

/*GRANT EXECUTE ON function TO  계정;*/


ORA-01000: 최대 열기 커서 수를 초과‎가 발생 했다.


OCCI를 통해 코딩을 하는지라...
(모르는게 너무 많다.)


일단 첫번째 문제는 ...

설정 가져오기 쓰레드에서 select ... for update를 통해 데이터를 가져 왔는데...
데이터가 없는 경우 free result를 불러주지 않았다.
이때 auto commit도 끈 상태였다.
일괄 트랜잭션 처리하려고 했던 지라... 그렇게 했는데...
어쨋든 제대로 동작하지 않았다.


두번째 문제는...

첫번째 문제의 경우에 free result와 commit를 해줬는데도 불구하고 제대로 작동하지 않은 점이다.


결국... 해결은...

곳곳에 commit()를 호출하여 처리하기는 하였다.
free result하기 이전에 말이다.

우쨋거나 여섯시간 가량 문제 없이 돌아가줬다.
...


1. RAC 노드1 에서 crs 재시작 후 확인

$ crs_stop -f ora.rac.db
Attempting to stop `ora.rac.db` on member `rac1`
Stop of `ora.rac.db` on member `rac1` succeeded.

$ crs_start -f ora.rac.db
Attempting to start `ora.rac.db` on member `rac1`
Start of `ora.rac.db` on member `rac1` succeeded.

$ crs_stat -t
Name Type Target State Host
------------------------------------------------------------
ora.rac.db application ONLINE ONLINE rac2
ora....vice.cs application ONLINE ONLINE rac1
ora....ac1.srv application ONLINE ONLINE rac1
ora....c1.inst application ONLINE ONLINE rac1
ora....c2.inst application ONLINE ONLINE rac2
ora....SM1.asm application ONLINE ONLINE rac1
ora....C1.lsnr application ONLINE ONLINE rac1
ora.rac1.gsd application ONLINE ONLINE rac1
ora.rac1.ons application ONLINE ONLINE rac1
ora.rac1.vip application ONLINE ONLINE rac1
ora....SM2.asm application ONLINE ONLINE rac2
ora....C2.lsnr application ONLINE ONLINE rac2
ora.rac2.gsd application ONLINE ONLINE rac2
ora.rac2.ons application ONLINE ONLINE rac2
ora.rac2.vip application ONLINE ONLINE rac2

※ Target, State 모두 ONLINE 표시확인 = RAC구성 완료





2. rac1 리스너 상태 확인

[oracle@rac1 ~]$ lsnrctl status

LSNRCTL for Linux: Version 10.2.0.5.0 - Production on 07-MAR-2012 16:34:22

Copyright (c) 1991, 2010, Oracle. All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias LISTENER_RAC1
Version TNSLSNR for Linux: Version 10.2.0.5.0 - Production
Start Date 07-MAR-2012 15:47:02
Uptime 0 days 0 hr. 47 min. 19 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /home/oracle/product/10g/db/network/admin/listener.ora
Listener Log File /home/oracle/product/10g/db/network/log/listener_rac1.log
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.204.28)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.204.128)(PORT=1521)))
Services Summary...
Service "oltp_service" has 1 instance(s).
Instance "rac1", status READY, has 2 handler(s) for this service...
Service "rac" has 2 instance(s).
Instance "rac1", status READY, has 2 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
Service "rac_XPT" has 2 instance(s).
Instance "rac1", status READY, has 2 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
The command completed successfully

▶ Service "oltp_service" has 1 instance(s).
Instance "rac1", status READY, has 2 handler(s) for this service...
메시지가 중간에 표시되면 oltp_service 정상 작동 상태






3. RAC 노드1 에서 oltp_service 생성

1) rac1는 oltp_service, rac2는 fail-over로 생성

$ srvctl add service -d rac -s oltp_service -r rac1 -a rac2




2) oltp_service 시작

[oracle@rac1 ~]$ srvctl start service -d RAC -s oltp_service



3) oltp_service 상태확인

[oracle@rac1 ~]$ srvctl status service -d RAC -s oltp_service
Service oltp_service is running on instance(s) rac1
▶ "oltp_service 서비스가 rac1 인스턴스에서 실행 중임"
: 정상 동작





4. 서비스 파라미터 상태 확인

1) 현재상태 확인
** RAC 노드1

$ sqlplus / as sysdba;
SQL> show parameter service;

NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
service_names string oltp_service




** RAC 노드2

SQL> show parameter service;
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
service_names string rac





2) 캐시 퓨전 확인 - rac1 강제 종료 → rac2 가 oltp_service로 전환됨

① 강제종료후 확인
** RAC 노드1

SQL> shutdown abort;



** RAC 노드2

SQL> show parameter service;
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
service_names string oltp_service




② rac1 DB open 후 확인

SQL> startup
SQL> show parameter service

NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
service_names string rac




※ oltp_service 재배치 방법

$ srvctl relocate service -d rac -s oltp_service -i rac2 -t rac1