병렬 DML

오라클 문서는 병렬 DML(PDML) 범위를 INSERT, UPDATE, DELETE, MERGE(SELECT를 포함하지 않는 DML)로 제한하고 있다.
충분한 1/0 '밴드위스(bandwidth)' 를 가진 멀티 CPU를 보유한 장비에서라면 대량 DML 작업의 속도는 충분히 향상 될 것이다.

PDML처리 방식

  • PDML은 분산쿼리와 같은 방식으로 수행됨
  • 각 병렬서버는 독립된 프로세스처럼 동작하여
  • 분할된 부분은 각각의 언두세그먼트를 사용하며 독립적인 트랜잭션으로 처리됨
  • 변경작업이 모두 수행된 후 독립적인 트랜잭션으로 커밋함 (Fast 2PC Commit)

PDML 테스트


SQL> alter table big_table parallel;

테이블이 변경되었습니다.

SQL> alter session enable parallel dml;

세션이 변경되었습니다.

SQL> update big_table set status = 'done';

10000000 행이 갱신되었습니다.

SQL> -- 다른 세션에서 모니터링
SQL> select a.sid, a.program, b.start_time, b.used_ublk,
  2         b.xidusn ||'.'|| b.xidslot || '.' || b.xidsqn trans_id
  3    from v$session a, v$transaction b
  4   where a.taddr = b.addr
  5     and a.sid in ( select sid
  6                      from v$px_session
  7                     where qcsid = 33 )
  8   order by sid
  9  /

       SID PROGRAM                                                          START_TIME            USED_UBLK TRANS_ID
---------- ---------------------------------------------------------------- -------------------- ---------- -------------------
         7 ORACLE.EXE (P011)                                                01/14/15 09:25:00             1 17.0.4
         8 ORACLE.EXE (P019)                                                01/14/15 09:25:00          7152 25.0.2
         9 ORACLE.EXE (P027)                                                01/14/15 09:25:00          7201 30.0.2
        33 sqlplus.exe                                                      01/14/15 09:25:00             1 1.3.621
        34 ORACLE.EXE (P012)                                                01/14/15 09:25:00             1 5.6.810
...
       223 ORACLE.EXE (P004)                                                01/14/15 09:25:00          1 9.25.815
       224 ORACLE.EXE (P018)                                                01/14/15 09:25:00          7776 11.0.4
       225 ORACLE.EXE (P026)                                                01/14/15 09:25:00          7150 28.0.2

31 개의 행이 선택되었습니다.

SQL> show parameter cpu

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cpu_count                            integer     8
parallel_threads_per_cpu             integer     2
...

결과 : (Default Degree의 영향으로 8 * 2) 병렬슬레이브가 16개 * 2가 나타날 것으로 예상했는데 30개 병렬 슬레이브가 동작함


SQL> alter table big_table parallel 4;

테이블이 변경되었습니다.

SQL> update big_table set status = 'done';

10000000 행이 갱신되었습니다.

SQL> -- 다른 세션에서 모니터링
SQL> select a.sid, a.program, b.start_time, b.used_ublk,
  2         b.xidusn ||'.'|| b.xidslot || '.' || b.xidsqn trans_id
  3    from v$session a, v$transaction b
  4   where a.taddr = b.addr
  5     and a.sid in ( select sid
  6                      from v$px_session
  7                     where qcsid = 33 )
  8   order by sid
  9  /

       SID PROGRAM                                                          START_TIME            USED_UBLK TRANS_ID
---------- ---------------------------------------------------------------- -------------------- ---------- -----------
        33 sqlplus.exe                                                      01/14/15 09:46:03             1 25.18.2
        38 ORACLE.EXE (P000)                                                01/14/15 09:46:03             1 14.22.4
        65 ORACLE.EXE (P001)                                                01/14/15 09:46:03             1 26.1.2
        66 ORACLE.EXE (P005)                                                01/14/15 09:46:03          1892 21.1.2
       101 ORACLE.EXE (P006)                                                01/14/15 09:46:03          5182 6.10.787
       129 ORACLE.EXE (P007)                                                01/14/15 09:46:03          1961 8.29.962
       163 ORACLE.EXE (P002)                                                01/14/15 09:46:03          1 17.1.4
       193 ORACLE.EXE (P003)                                                01/14/15 09:46:03          1 31.1.2
       222 ORACLE.EXE (P004)                                                01/14/15 09:46:03          2265 9.30.816

9 개의 행이 선택되었습니다.

결과 : Degree를 4로 하여 통제된 상황에서 진행하니 인덱스엔트리 병렬을 포함한 8개 슬래이브가 동작하며 예상된 결과로 나타남

PDML 제약사항

  • 트리거는 PDML 작업이 수행되는 동안 작동하지 않는다.
  • PDML은 각 병렬프로세스가 독립적인 트랜잭션으로 수정하므로 재귀참조 무결성 같은 참조 무결성 제약을 지킬 수 없다.
  • PDML로 수정하는 테이블을 커밋 또는 롤백 할 때까지 액세스할 수 없다 .
  • advanced replication은 PDML을 사용할 수 없다. (advanced replication은 트리거 기반이기 때문이다.
  • Deferred 제약조건은 사용할 수 없다.
  • 비트맵 인덱스 또는 LOB 컬럼이 있는 테이블이 파티션되어 있다면 병렬도는 파티션의 수까지만 PDML 이 수행된다.
  • 분산 트랜잭션은 PDML 수행 중에 사용할 수 없다.
  • 클러스터 테이블은 PDML을 사용할 수 없다.

제약조건 위배 시

병렬로 수행되지 않던지 ORA-12838: cannot read / modify an object after modifying it in parallel 같은 오류가 발생할 것이다