FullStack/21. Java

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

nakanara 2020. 2. 24. 18:21
반응형

현상

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...        
            }
    }

  }

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

참고

반응형