1. 압축률

  • 현재 DB2 DW의 압축률 = 70% 수준 (table 단위의 block compression)
  • 현재 운영 Oracle의 압축률 = 55% 수준 (row 단위 compression)
  • DB2 BLU (columnar)의 압축률 = 95% (hybrid compression)
  • DB2 Netezza (columnar)의 압축률 = 75%
  • 오라클 HCC (columnar)의 압축률 = 85% ~ 92.5% (외부 압축 알고리즘 도입)


    ■ 압축률
    - Query Low : 85%
    - Query High :   
    - Archive Low :
    - Archive High : 92.5%

실질적으로 운영환경에서 사용할 수 있는 압축방식은 제공되는 4 가지 옵션 중
성능의 문제로 인해 Query Low 하나라고 보면 되겠고,

Archive Low/High 압축의 경우는
곧바로 읽을 수 있다는 장점이 있는 마그네틱 테이프를 생각하시면 되겠다.


■ Query Low
    CU (Compression Unit)의 크기 : 32k
    LZO 알고리즘

■ Query High
    CU 크기 : 32~64k
    ZLIB 알고리즘

■ Archive Low
    CU 크기 : 32~256k
    ZLIB 알고리즘


■ Archive High
    BZIP2 알고리즘






2. 성능
압축 시 데이터 크기 자체가 줄어들음으로 인해, 조회 성능은 개선되나,
데이터 ETL 시 불리하다.

■ Insert 성능

query low = 20초
query high = 40초
archive low = 40초
archive high = 240초


■ SQL 쿼리 성능

비압축 = IO bound :171초, CPU bound : 13초
query low = IO bound :91초, CPU bound : 16초
query high = IO bound :73초, CPU bound : 19초
archive low = IO bound :74초, CPU bound : 19초
archive high = IO bound :118초, CPU bound : 33초





3. 기타 기술적인 제약

- 특성 상 데이터의 Sort 상태를 유지하여야 압축률이 높아짐

- 조회한 데이터를 메모리 버퍼에 올리거나, aggregate 또는 sort 동작을 위해 temporary 영역에 넣으려면 압축을 해제해야 함

- Index를 읽어 데이터를 조회할 때, 하나의 CU를 여러 번 압축 해제 해야 하는 문제로 성능이 저하될 수 있음
  ∵ 정렬된 rowid 순서로 select하는 게 아니라, 컬럼 데이터 순서로 정렬된 rowid 포인터로 CU를 읽기 때문

- HCC 압축된 row에 update가 수행되면, 이 데이터는 압축이 풀리면서 기존의 낮은 압축률 공간으로 옮겨지며
  이 과정도 느릴 뿐더러, 향후 조회 시 HCC블럭, OLTP블럭 두 군데를 읽어야 하므로 성능 저하
  업데이트가 있는 테이블에는 HCC를 적용하지 않을 것을 권고

- 하나의 row를 업데이트 하더라도, 그 row가 걸쳐있는 전체 CU를 lock 걸어야 하는데, 이로 인해 빈번한 lock wait 발생 가능, 동시성 저하

- 이를 해결하기 위해서는 Oracle 12c Advanced Compression 옵션을 구매해야 하며, 적용 시 일반적인 RDBMS의 row level locking이 가능해짐

- 그러나, 이 정보를 관리하기 위한 overhead가 발생하여, 약 10% 가량의 데이터 사이즈가 증가함

- partition table의 경우, 압축된 후의 사이즈가 충분히 크지 않으면 direct path read 플랜 (스마트 스캔을 가능하게 하는) 으로 풀리지 않게 되고,
이로인해 결국 스마트 스캔을 하지 않게 되면서, 셀 노드의 CPU로 압축해제 하지 못하고, DB 서버에 CPU 부하를 주게 될 수 있음.
다시 말해, 월별 건수가 애매하게 작으면 DB서버 CPU 부하 상당량 발생 (이 기준점은 알 수 없음)



4. 환경 고려사항


- HCC 압축을 하기 위해서는 모든 insert문을 수정해야 함. INSERT /*+ APPEND */ INTO


- HCC가 적용된 DB의 백업본을 복구하기 위해서도 Exadata가 필요함 (Exadata Storage server 이외의 HW에서는 HCC 사용에 제약이 걸려있어)

- 오라클 ZFS 스토리지 어플라이언스에 복구가 가능하기는 하나, 스토리지를 백업본 크기의 10배를 준비해야 하며,
   ALTER TABLE NOCOMPRESS로 압축을 다 풀기 전에는 조회 불가

Posted by in0de
,

v$session 다이내믹 퍼포먼스 뷰를 조회하다보면,

ORA-29275 : 부분 다중바이트 문자 오류가 발생하는 경우가 있는데
이는 sys.v$session 뷰의 action varchar2(32 또는 64 byte) 컬럼이 문제이다.

 

이 action 컬럼은 DBMS_APPLICATION_INFO.SET_ACTION 프로시저로
애플리케이션이 하는 일을 사용자가 이름 붙여주는 것으로서,
어떤 SQL 로직의 실행 단계를 태그하고자 할 때 사용할 수 있는 컬럼이다.

 

최초 프로그램이 접속하면 다음과 같이 모듈명과 실행 작업을 지정해주고

BEGIN
  DBMS_APPLICATION_INFO.set_module(module_name => '1. 주문',
                                   action_name => '1.1 주문 접수');
  -- 수행할 SQL
END;
/

 

일련의 실행 단계마다, action 에 대해서

BEGIN
  DBMS_APPLICATION_INFO.set_action(action_name => '1.2 재고 조회');
 
  -- 수행할 SQL
END;
/

와 같이 이름지어주어, 모니터링 시 확인할 수 있도록 하는 컬럼이다.

 

어쨌든 이 컬럼으로 인해 Toad 등의 애플리케이션에서
세션 조회가 불가능한 경우에는 action 컬럼에 대해

TO_SINGLE_BYTE('ACTION') 과 같이 함수를 씌워서 직접 조회해볼 수는 있다.

 

SELECT /*+  RULE */ s.inst_id AS node
   , s.username
   , CASE
   WHEN SUBSTR( s.action, 1, 4 ) = 'FRM:' THEN s.module || '(Form)'
   WHEN SUBSTR( s.action, 1, 4 ) = 'Onli' THEN s.module || '(Form)'
   WHEN SUBSTR( s.action, 1, 4 ) = 'Conc' THEN s.module || '(Conc)'
   ELSE s.module
  END AS module
   , SUBSTR( CASE WHEN SIGN( LENGTHB( s.program ) - 16 ) = 1 THEN SUBSTR( s.program, 1, 16 ) || '..' ELSE s.program END, 1, 16 ) AS program
   , s.osuser||'@'||s.machine AS who
   --, s.port
   , last_call_et
   , TO_CHAR( logon_time, 'mm-dd HH24:MI:SS' ) AS logon_time
   , s.sql_id
   , 'kill -9 ' || p.spid AS OSKILLCMD
   , 'alter system kill session ' || '''' || s.sid || ',' || s.serial# || ',@' || s.inst_id || '''' || ';  --'||p.spid||'' AS ORACLEKILLCMD
   , s.terminal AS USER_INFO
   , SUBSTR( LPAD( TRIM( TO_CHAR( ROUND( p.pga_alloc_mem / 1024 / 1024 ), '999,999' ) ) || 'M', 5, ' ' ), 1, 6 ) AS pga
   --, TRIM( ( SELECT SUBSTR( sql_text, 1, 120 ) FROM v$sql sq WHERE sq.sql_id = s.sql_id AND s.sql_hash_value = sq.hash_value AND ROWNUM = 1 ) ) AS sql_text
   , CASE
   WHEN s.blocking_session IS NULL THEN ''
   ELSE SUBSTR( s.blocking_session_status, 1, 3 ) || '(' || s.blocking_instance || ')' || ( s.blocking_session - 1 )
  END AS BLOCKING_SID
   , s.seconds_in_wait
   , SUBSTR( s.event, 1, 32 ) AS wait_event
   , TO_SINGLE_BYTE( s.action ) AS action
   , ( SELECT  sql_text
    FROM   v$sql sq
    WHERE   sq.sql_id = s.sql_id AND s.sql_hash_value = sq.hash_value AND ROWNUM = 1 )
   AS sql_text
FROM gv$session s, gv$process p
WHERE s.paddr = p.addr
AND  s.inst_id = p.inst_id
AND  s.status = 'ACTIVE'
AND  s.event NOT IN ( 'queue messages'
        , 'pipe get'
        , 'jobq slave wait'
        , 'Streams AQ: waiting for messages in the queue'
        , 'class slave wait')
AND  s.username IS NOT NULL
AND  s.audsid <> USERENV( 'SESSIONID' )                     -- which is not my session
--order by s.inst_id,status1 desc,username1 desc , substr(s.action,1,3) desc, module1,last_call_et
ORDER BY s.inst_id, s.status DESC, last_call_et DESC

/

Posted by in0de
,

DPF 환경에서 오류 등으로 인해 특정 노드가 자동으로 재기동되어 올라왔을 때

모니터링 툴이 없다면 어느 노드에서 언제 문제가 발생하였는 지 확인하는 것도 쉽지 않다.

이럴 때 모든 노드의 db2diag.log를 일일이 확인해야 하는데, 그 작업량이 만만치 않다.


이런 경우 다음과 같이 조회하여 어느 노드에서 언제 재기동되었는 지 대략의 시간을 확인할 수 있다.


db2 "SELECT DBPARTITIONNUM, DB_CONN_TIME FROM SYSIBMADM.SNAPDB order by 1"

DBPARTITIONNUM DB_CONN_TIME             
-------------- --------------------------
             0 2015-03-04-14.39.12.711837
             1 2015-03-18-11.38.02.950709
             2 2015-03-18-11.38.02.950741
             3 2015-03-18-11.38.02.950723
             4 2015-03-18-11.38.02.950742
             5 2015-06-12-04.27.20.267942
             6 2015-06-12-04.27.24.363985
             7 2015-06-12-04.27.24.363985
             8 2015-06-12-04.27.24.364009
             9 2015-06-12-04.27.24.364020
            10 2015-06-12-04.27.24.364009
            11 2015-06-12-04.27.24.364009
            12 2015-06-12-04.27.24.364011
            13 2015-03-18-11.38.02.952040
            14 2015-03-18-11.38.02.951850
            15 2015-03-18-11.38.02.951862
            16 2015-03-18-11.38.02.951868
            17 2015-03-18-11.38.02.951868
            18 2015-03-18-11.38.02.951908
            19 2015-03-18-11.38.02.951870
            20 2015-03-18-11.38.02.951976
            21 2015-03-18-11.38.02.950909
            22 2015-03-18-11.38.02.950996
            23 2015-03-18-11.38.02.950994
            24 2015-03-18-11.38.02.951033
            25 2015-03-18-11.38.02.950951
            26 2015-03-18-11.38.02.951059
            27 2015-03-18-11.38.02.950974
            28 2015-03-18-11.38.02.951017


Posted by in0de
,