PostgreSQL에서 TXID_CURRENT()와 DBLINK를 이용해서 XID를 아주 빠르게 증가시키는 방법

간혹, PostgreSQL의 내부 동작원리를 파악하기 위해서 XID를 아주 큰 값 (10억 또는 20억)으로 증가시켜야 할 경우가 있습니다. 이러한 경우, 이전 포스팅에서 소개한 것과 같이 DBLINK를 이용한 LOOP COMMIT 방식을 사용할 수도 있지만, DML을 통해 10억건 이상을 생성(또는 생성 후 삭제)하는 것은 리소스 소모적이며 그에 따라 오랜 시간이 소요됩니다. 따라서 아주 빠르게 XID를 증가시킬 수 있는 방법이 필요합니다. 가장 효과적인 방법은 TXID_CURRENT() 함수를 이용하는 것입니다. SELECT 수행 시에는 XID가 증가하지 않지만, SELECT TXID_CURRENT();를 수행하면 XID가 1 증가합니다. 이러한 속성을 이용해서 다음과 같은 프로시저를 작성합니다. (제 환경에서 XID를 10억 증가시키는데 소요되는 시간은 대략 20시간 정도입니다. DB LINK & LOOP COMMIT 방식은 10일 이상 소요될 것으로 예상된 것에 비하면 10배 이상 빠른 방법입니다)

1. DBLINK를 이용해서 TXID_CURRENT()를 호출하는 get_xid() 프로시저 생성

CREATE OR REPLACE FUNCTION get_xid() RETURNS INTEGER AS $$
DECLARE
rval integer;
BEGIN
       SELECT txid into rval
       FROM dblink('myconn','select cast(cast(txid_current() AS text) AS integer) txid') as t1(txid integer);

       RETURN rval;
END;
$$ LANGUAGE plpgsql;

2. get_xid() 프로시저를 반복적으로 호출하는 loop_get_xid() 프로시저 생성

CREATE or replace FUNCTION loop_get_xid(v_begin integer, v_end integer) RETURNS VOID AS $$
DECLARE
rval integer;
BEGIN

    FOR i in v_begin..v_end LOOP
        SELECT get_xid() INTO rval;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

3. loop_get_xid() 프로시저를 호출하는 Shell 생성

-- call_loop_get_xid.sh의 내용
-- call_loop_get_xid.sh을 10개 세션에서 동시에 수행합니다.
-- 제 경우, 대략 초당 3만개의 XID가 증가했습니다.
PGPASSWORD=oracle psql test -p 5433 -Upostgres <<EOF1
select dblink_connect('myconn','dbname=test port=5433 user=postgres password=oracle');
select loop_get_xid(1,50000000);
EOF1
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s