본문 바로가기

개발 관련 지식/알티베이스(Altibase)

[알티베이스] Communication link failure 에러 코드 발생

* Communication link failure 에러 코드 발생

 

* 개요

: 해당 에러 코드는 DB 작업을 프로그램을 짜서 돌리던 중 발생한 에러 코드로, 서버로부터 연결이 단절된 것으로 보여진다.

 해당 에러 코드를 분석하여 이와 같은 상황이 발생하지 않도록 보완해야 할 듯 보인다.

 

* 발생 환경

1. 알티베이스 접속

2. for문을 통해 1만번 실행된다.

3. 100만건 이상 되는 데이터를 한번 쿼리하여 Fetch 된 데이터에 대해 Cursor가 하나씩 이동하면서

 한 row당 데이터를 업데이트 하는 작업을 진행한다.

4. Fetch 된 한 ROW의 특정 컬럼값을 가지고 다른 테이블에서 또 조회하여 그 값으로 업데이트 한다.

5. 총 3번의 업데이트를 하게 되있는데, 그중의 하나는 다이나믹sql로 구현되어 있다.

6. 다이나믹sql로 구현된 쿼리는 테이블명을 월별로 나눠놓았기 때문에 다이나믹으로 구현되었으며,

 해당 테이블은 존재하지 않을 수도 있다.

7. 테이블이 존재하지 않을 경우에도 특정값으로 업데이트를 진행하도록 한다.

8. 3번의 업데이트가 끝나면, 처리가 완료되었다는 표시를 위해 FLAG 값을 업데이트하여

 총 4번의 업데이트가 진행된다.

9. 한 ROW의 4번의 업데이트가 완료되면 usleep()을 주어 부하가 가지 않도록 한다.

10. DB 작업이 모두 끝나면 알티베이스 접속 종료

 

* 에러가 발생한 경우

1. usleep(1000) ~ usleep(100000) 을 준 경우(0.01초 ~ 0.0001초)

=> 1천건이 지나갔을 무렵에 [Communication link failure] 에러 발생

=> 이후에는 [Connection does not exist] 에러와 함께 Connect 이 끊겨있는 상태로 에러가 계속 발생

 

2. usleep(1000000) 을 준 경우(1초)

=> 500건이 조금 지났을 무렵에 [Client's Query Exceeded in Execution Time Limitation] 에러 발생

 

* 에러 발생에 대한 예상 원인

1. usleep 을 조금씩 늘려준 결과, usleep을 1초까지 늘려주었는데도 발생하는 것을 보면 usleep의 문제는 아닌 것으로 판단된다.

2. 에러코드를 확인해보자.

Communication link failure : 연결 링크가 실패되었다?

Connection does not exist : 연결이 제대로 되어 있지 않다?

Client's Query Exceeded in Execution Time Limitation : fetch 타임아웃 에러..

3. 결론은.. Fetch 타임아웃 에러인듯 보인다..

 

* 해당 문제를 해결하기 위한 보완사항

1. Fetch 타임아웃을 해결하기 위해서는 해당 타임아웃으로 설정된 값을 변경해주는 방법이 있다.

=> 시스템에 영향이 있을 수 있는 부분이라, 다른 방법을 모색해봐야겠다..

 - query_timeout

: 특정 질의(정렬 혹은 긴 조인 등)의 수행 시간이 길어짐에 따라 데이터베이스 크기가 비정상적으로 증가하는 것을 막기 위해 이 값을 설정한다. 질의 수행 시간이 프로퍼티 파일에 설정된 값보다 커지면 현재 트랜잭션 연산을 부분 철회한다.

 

 - utrans_timeout

: 변경 연산(UPDATE, INSERT, DELETE)을 수행하는 트랜잭션의 수행 시간이 길어짐에 따라 로그 파일의 개수가 비정상적으로 증가하는 것을 막기 위하여 이 값을 설정한다. 수행 시간이 프로퍼티 파일에 설정된 값보다 커지면 세션 연결을 해제하고 현재 트랜잭션을 철회한다.

 

 - 타임아웃 설정 변경 alter문

1. ALTER SESSION SET QUERY_TIMEOUT = 0;(현재 접속된 세션만 적용)

2. ALTER SESSION SET UTRANS_TIMEOUT = 0;(현재 접속된 세션만 적용)

3. ALTER SESSION SET FETCH_TIMEOUT = 0;(현재 접속된 세션만 적용)

4. ALTER SYSTEM SET QUERY_TIMEOUT = 0;(전체 시스템에 적용)

5. ALTER SYSTEM SET UTRANS_TIMEOUT = 0;(전체 시스템에 적용)

6. ALTER SYSTEM SET FETCH_TIMEOUT = 0;(전체 시스템에 적용)

 

2. Fetch를 최대한 적게 하기 위해 나누어서 처리를 해야 할 것으로 보여진다.

=> 쿼리를 나눌 수 없을 경우를 위해 다른 방법을 모색해봐야겠다..

 

3. flag 값이 존재하니 이와 함께 limit 절을 이용하여 건건이 처리되도록 해야겠다.(해당 방식 당첨~!!!!)

=> 소스 구조가 조금 바뀌게 될 듯 보인다.

처음 한번의 쿼리의 Fetch로 한 row 마다 업데이트 하던 부분을 limit 절을 이용하여 한 건만 쿼리되도록 수정..

(flag값으로 처리가 안된 데이터만을 검색하고 limit 1로 1건만 쿼리되도록 변경)

 

 

[참고 링크] http://arrkaize86.tistory.com/entry/알티베이스-에러-코드-분석