안그래도 DB에 관련된 지식이 완전 바닥인데 거기다 이런일까지 겪게되어 DB가 더 무서워졌다..


"ora-1000" ?.. 누구냐 넌.....



테스트 서버에선 아무 이상 없었는데 운영 서버에서는 대략 5~8시간만에 ora-1000을 내뿜으며 DB가 멘붕이 된다..


검색을 해보니 오픈커서라는게 기본으로 설정된 수치를 초과해서 글탄다. 기본 설정 수치는 300...


또.. connection, preparedStatement,, 등등 열고 닫고를 제대로 못해줘서 그런거라던데...

혹은 loop내에서 대량으로 인서트 혹은 셀렉트 할때라던가...


사실 요즘은 DB도 프레임웍을 쓰기때문에 conn이나 prestatement 이런걸 직접적으로 열고 닫는일은 없다..

직접 열고닫고 한다해도 열고닫는일을 소스상에 도배하는 일은 없을테지 -_-


사실 검색해서 나온 내용들은 너무 오래된 옛날 얘기들이라 현재로써는 문제점으로 삼을수가 없었다.

그리고 난 근본적인 원인을 찾지 못했다. 단지 방어적인 설정으로 일단 인공호흡만 죽어라 하는..;



가장 이해가 안됬던건 무언가 액션이 일어날때 반응하는 오픈커서 갯수는 테스트 서버에서는 20에서 많게는 50~60개? 정도가 쌓이는데 운영서버에서는 최소 80개 정도를 시작으로 300개까지 도달하는 시간이 5~8시간 정도 되는것 같더라..


테스트 서버에서는 300를 채울래야 채울수가 없었고 수치를 50으로 설정해서 테스트를 해서 ora-1000을 재현했다..


여기서 해볼수 있는건 오픈커서를 강제적으로 없애버리는거...


--설정된 커서 갯수 확인

show parameter open_cursors;


--50으로 설정

ALTER SYSTEM SET open_cursors=50;


-- 사용중인 해당 계정에 sid별 오픈커서 확인

select

o.sid, osuser, machine, count(*) num_curs

from

v$open_cursor o, v$session s

where

user_name = 'scott' and o.sid=s.sid

group by o.sid, osuser, machine

order by num_curs desc;


페이지를 이동할때마다 위 쿼리를 실행해보면 커서가 쌓이는걸 볼수 있다..

근데 저런게 한번 열리면 시간이 지나면 알아서 닫혀야 하는거 아닌가? 처음엔 닫히질 않더라.. 줄어들지 않으니 계속 쌓이다 보면 뻗어버리나보지.


할튼 닫아주는게 목적이였으니..


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<property name="driverClassName" value="${database.main.driverClassName}" />

<property name="url" value="${database.main.url}" />

<property name="username" value="${database.main.username}" />

<property name="password" value="${database.main.password}" />

<!-- 수정 전 

<property name="defaultAutoCommit" value="true" />

<property name="poolPreparedStatements" value="true" /> 아마도 이것때문에 닫히질 않았을꺼라 생각됨. * 참고

<property name="maxActive" value="30" />

<property name="maxIdle" value="10" />

<property name="minIdle" value="3" />

<property name="initialSize" value="3" />

<property name="maxWait" value="10000" />

-->

<!-- 수정 후 --> 

<property name="maxActive" value="100" />

<property name="maxIdle" value="10" />

<property name="minIdle" value="3" />

<property name="initialSize" value="10" />

<property name="maxWait" value="10000" />

<property name="testOnBorrow" value="true" />

<property name="testOnReturn" value="true" />

<property name="validationQuery" value="select 1 from dual" />

<property name="testWhileIdle" value="true" />

<property name="timeBetweenEvictionRunsMillis" value="130000" /> 정해진

<property name="minEvictableIdleTimeMillis" value="120000" /> 시간에 따라

<property name="numTestsPerEvictionRun" value="100" /> 100개씩검사

<property name="removeAbandonedTimeout" value="30" /> 30초 동안 사용하지 않았을때

<property name="removeAbandoned" value="true" /> 삭제

<property name="logAbandoned" value="false" />

</bean>




이 방법이 맞는지도 모르겠고 저렇게 짧은 시간에 커넥션을 확인해서 강제적으로 삭제해주는게 서버에 어떠한 영향을 미칠지.. 그것 조차도 모른다.

아직은 4~5일 정도 문제없이 버텨주고 있고 오픈커서 역시 40~50개 정도가 유지되고 있다는 얘기만 들었다.


이런 문제에 대해 도움을 받고싶어도.. 어디다 물어봐야 하는지도 모르겄다 -_-

+ Recent posts