ARCHIVES

PostgreSQL을 위한 분산 트랜잭션 매니저 개발을 위한 프로젝트, DTM (Distributed Transaction Manager)

(주)비트나인 2015. 12. 18. 16:21



이번 포스팅에서는 지난 PG conf China에서 소개 되었던 DTM에 대해서 간략히 소개 하겠다. 기회가 된다면 DTM의 자세한 구조와 동작 프로세스 그리고 자세한 예제를 다음 포스팅에 추가 할 것이다.



DTM (Distributed Transaction Manager)PostgreSQL을 위한 분산 트랜잭션 매니저 개발을 위한 프로젝트 이다. 이 프로젝트는 기존의 유사한 프로젝트의 문제점을 보완하고 있다. 기존 프로젝트의 문제점은 다음과 같다.


1. 다음 툴들은 샤딩을 지원하지만 global consistency를 제공 할 수 없다

-Pgshard
-Pgpool

이 툴들은 데이터를 여러 노드들에 저장하고 분산 질의를 통해 결과를 얻는다. 하지만 이들 툴들은 global consistency를 제공 할 수 없기 때문에 다음 예와 같은 상황이 발생한다.


) 한 은행 계좌에서 다른 계좌로 돈을 이체 하는 상황이다. 계좌에 대한 정보는 여러 노드들에 흩어져 있고 전체 잔고를 계산하는 분산 질의를 실행하면 다른 값이 보일 수 있다.


위의 예는 global consistency를 제공하지 하지 않기 때문에 발생 하는 문제다. 하지만 global snapshots을 제공하는 GTM (Global Transaction Monitor)를 제공하는 PostgreSQL-XC/CL은 예제와 같은 문제가 발생하지 않는다. 하지만 PostgreSQL-XC/XL에도 다음과 같은 문제가 있다.


2. PostgreSQL-XC/XLPostgreSQL의 클론이지만 PostgreSQL 메인 프로젝트와 병합이 힘들다.


PostgreSQL-XC/XLPostgreSQL에서 브랜치를 가져와 개발한 프로젝트이다. 하지만 메인 PostgreSQL의 코드를 약 30만 라인 이상을 변경 하였기 때문에 메인 PostgreSQL와 병합이 힘들다. PostgreSQL-XC/XL과는 달리 DTMPostgreSQLextension으로 대부분을 구현하였고, PostgreSQL의 동작을 변경 하기 위해 Postgres callback mechanism을 사용 하였기 때문에 거의 모든 메인 PostgreSQL 코드를 사용한다.


DTM 3가지 처리 방법을 고려 한다.

1.Snapshot sharing (DTM)
2.Timestamps (tsDTM)
3.Incremental distributed snapshot isolation – 다음 포스팅에 추가


모든 접근법은 eXtensible transaction manager API로 구현되었다. (원문 참조)


DTM 처리 방법

DTM 처리 방법은 중앙 집중식 서비스(arbiter라고 부른다.)를 필요로 한다. Arbiter는 다음 항목을 요구 한다.

-트랜잭션 IDs 항당
-트랜잭션에 참여하는 모든 노드들에 consistent snapshots을 제공
-트랜잭션의 commit 또는 rollback에 대한 결정
-분산 트랜잭션들의 상태를 보존 (복구에 사용한다.)

DTM의 구조의 그림은 원문 또는 원문의 PPT 자료 참조하기 바란다. DTMCoordinator가 존재한다. Coordinator는 질의의 분산 실행을 구성한다. Coordinatorlibpq와 같은 표준 프로토콜을 사용하여 Postgres backends와 연결 되어 있다. Coordinator의 구현은 다양한 언어로 가능하다. Coordinator는 표준 SQL문을 사용하여 데이터 노드들과 통신한다. Global transaction의 시작을 표시하기 위한 다음 SQL 함수들을 제공한다.


CREATE FUNCTION dtm_begin_transaction() RETURNS integer

AS 'MODULE_PATHNAME','dtm_begin_transaction'

LANGUAGE C;


CREATE FUNCTION dtm_join_transaction(xid integer) RETURNS void

AS 'MODULE_PATHNAME','dtm_join_transaction'

LANGUAGE C;

-원문 참조 코드

GO로 작성한 coordinator 예제 코드


xid := execQuery(con1, "select dtm_begin_transaction()")

exec(con2, "select dtm_join_transaction($1)", xid)

exec(con1, "begin transaction")

exec(con2, "begin transaction")

exec(con1, "update t set v = v + $1 where u=$2", amount, account1)

exec(con2, "update t set v = v - $1 where u=$2", amount, account2)

var wg sync.WaitGroup

wg.Add(2)

asyncExec(con1, “commit”, &wg)

asyncExec(cnn2, “commit”, &wg)

wg.Wait()

- 원문 참조 코드


Postgres_fdw + DTM 동작 예제 코드


exec(con, "select dtm_begin_transaction()")

exec(con, "begin transaction")

exec(con, "update t set v = v + $1 where u=$2", amount, account1)

exec(con, "update t set v = v - $1 where u=$2", amount, account2)

exec(con, “commit”)


tsDTM 처리 방법

Local timestamps를 사용한 처리 방법 (모든 노도의 시스템 시간은 동기화 되었다는 것을 가정). tsDTM 처리 방법은 병목 현상과 single point of failure가 발생 할 수 있는 중앙 집중식 타임 스탬프 권한을 필요로 하지 않는다. tsDTM에서 Clock 동기화 정확도는 성능에 영향을 주기 때문에 NTP를 사용하는 이유이다. 이 처리 방법은 확장성은 좋지만 리커버리의 성능은 떨어 진다.


다음은 제공하는 SQL 함수이다.


CREATE FUNCTION dtm_extend(gtid cstring default null) RETURNS bigint

AS 'MODULE_PATHNAME','dtm_extend'

LANGUAGE C;


CREATE FUNCTION dtm_access(snapshot bigint, gtid cstring default null) RETURNS bigint

AS 'MODULE_PATHNAME','dtm_access'

LANGUAGE C;


CREATE FUNCTION dtm_begin_prepare(gtid cstring) RETURNS void

AS 'MODULE_PATHNAME','dtm_begin_prepare'

LANGUAGE C;


CREATE FUNCTION dtm_prepare(gtid cstring, csn bigint) RETURNS bigint

AS 'MODULE_PATHNAME','dtm_prepare'

LANGUAGE C;

CREATE FUNCTION dtm_end_prepare(gtid cstring, csn bigint) RETURNS void

AS 'MODULE_PATHNAME','dtm_end_prepare'

LANGUAGE C;

-원문 참조 코드

Coordinator는 할당된 스냅샷을 리턴하는 dtm_extend()를 호출 해야한다. 해당 스냅샷은 dtm_access() 함수를 사용하여 모든 노드들에게 전달된다.


tsDTM 처리 방식은 PostgreSQL-XC/XL에서는 지원하지 않는 local transaction을 지원한다.



기본적으로 알아본 내용이기 때문에 아직 많이 미흡하다. 하지만 다음 포스팅에는 DTM의 원리와 동작 방식을 자세히 다룰 것이다.

원문 PPT - https://wiki.postgresql.org/wiki/File:Dtm.pdf






Posted by Bitnine(비트나인)