본문 바로가기
FullStack/21. Java

Oracle 템프 테이블 스페이스 사용량 증가

by nakanara 2020. 2. 24.
반응형

현상

Oracle로 구성된 시스템에서 계속해서 템프 테이블 사용량이 증가함.
초기에는 DB Connection이 닫히지 않은 오류가 있는지 확인하였지만, 해당 현상은 없고, 모니터링을 위해서 #Scounter로 확인하였지만 닫히지 않은 Conntion은 발견하지 못하였다.

모니터링하던 중 With문을 사용해서 쿼리를 작성한 곳에서만 발생.

 -- 확인 SQL
 select se.username,
       sum(su.blocks*ts.block_size/1024/1024)mb_used
       from v$sort_usage su,
       v$session se,
       dba_tablespaces ts,
       v$process pr
where su.session_addr = se.saddr
and se.paddr = pr.addr
and su.tablespace = ts.tablespace_name
group by se.username
order by mb_used desc

우선 해결은 페이징을 위해서 ResultSet에서 가져온 데이터 중 페이징에 관련된 정보만 추출한 후 break 해서 빠져나간 것이 문제였던 것 같다.
정상적으로 close를 다 하고 있었고, 모니터링 툴을 이용한 Connection의 누락도 없었는데 v$sort_usage에서 계속 누적된다.


PreparedStatement pstmt = null;
ResultSet rs = null;
List rows = new ArrayList();

try {
  pstmt = con.prepareStatement(query);
  rs = pstmt.executeQuery();

  while (rs.next()) {

    if(/* 페이지 이전의 데이터 */ ) {
      continue;
    }
    if(/* 페이지 이후 데이터 */) {
      break;
    }

    /* 필요 데이터 */
    // rows ...

  }catch(Exception e) {

  } finally {

    if(rs != null) {
      try { 
        rs.close();
            } catch (Exception e) {        
        //Log...        
            }
    }

    if(pstmt != null) {
      try { 
        pstmt.close();
            } catch (Exception e) {                
        //Log...        
            }
    }

  }

수정:: ResultSet의 cursor을 이동시킨 후 종료

PreparedStatement pstmt = null;
ResultSet rs = null;
List rows = new ArrayList();

try {
  // 커서 옵션 변경
  pstmt = con.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  rs = pstmt.executeQuery();

  while (rs.next()) {

    if(/* 페이지 이전의 데이터 */ ) {
      continue;
    }
    if(/* 페이지 이후 데이터 */) {
      rs.last(); // 마지막 페이지 이동 후 
      break;
    }

    /* 필요 데이터 */
    // rows ...

  }catch(Exception e) {

  } finally {

    if(rs != null) {
      try { 
        rs.close();
            } catch (Exception e) {        
        //Log...        
            }
    }

    if(pstmt != null) {
      try { 
        pstmt.close();
            } catch (Exception e) {                
        //Log...        
            }
    }

  }

정상적으로 쿼리가 실행되며, 템프 테이블이 누적되어 사용량이 증가하지 않는다.

참고

반응형