2024-05-24,   조평연

본 포스팅은 CDC plugin 중 하나인 pgoutput 설정 및 파싱하는 방법을 알아보는 내용입니다.

이전에 pgoutput 포스팅에서 포멧이 어떻게 되어있는지를 알아봤습니다.

이번 포스팅에서는 pgoutput 플러그인을 사용하기 위한 설정 방법과 데이터를 파싱하는 방법에 대해서 다루고자 합니다.

1. pgoutput 설정 방법

  • pgoutput 플러그인을 사용하는 가장 큰 이유는 특정 테이블만 논리적 복제를 하기 위함입니다. 이를 위해 publication을 만들어 주어야합니다.

1) publication 생성

  • CREATE PUBLICATION publication이름 FOR TABLE 지정할테이블1, 지정할테이블2, …;

2) 버전 설정

  • .withSlotOption(“proto_version”, 1)

3) publication 이름 지정

  • publication으로 지정한 테이블만 가져온다
  • .withSlotOption(“publication_names”, “test_publication”);

4) test_decoding 에서 사용한 아래 옵션은 사용 불가능 (에러발생)

  • .withSlotOption(“include-xids”, false) //트랜잭션 ID 정보를 포함할지 여부
  • .withSlotOption(“skip-empty-xacts”, true) //빈 트랜잭션을 무시할지 여부
  • .withSlotOption(“include-rewrites”, true) //rewrite된 쿼리를 복제할지 여부
  • .withSlotOption(“include-timestamp”, “on”) //쿼리 실행 시간 정보 포함 여부

2. 파싱 방법

* 아래 두 예시는 어디까지나 예시로 작성되어 서로 일치 하지 않음을 알립니다 *

  • pgoutput 플러그인을 사용해서 테이블의 변화가 생기면 아래와 같은 형태의 byte[] 로 바이트 값을 받게 됩니다.
    {82, 0, 0, 121, -36, 112, 117, 98, 108, 105, 99, 0, 114, 97, 119, 95, 109, 111, 110, 95, 109, 108, 115, 110, 0, 105, 0, 12, 1, 99, 108, 99, 116, 95, 100, 116, 0, 0, 0, 4, -96, -1, -1, -1, -1, 0, 114}

  • 이를 16진수로 변환 해주면 아래와 같이 됩니다.
    73746E675F76616C0000000413000007D400737474735F636400000004130000001800667273745F7265675F647400000004A0FFFFFFFF00667273745F72677

  • 이제 16진수를 2자리씩 잘라서 10진수 또는 문자값으로 바꿔 처리해주면 됩니다.

3. 파싱 코드 작성 방법

* 실제 코드를 작성하기엔 보안상 문제가 생길 수 있어 코드없이 흐름만을 설명하겠습니다. *

  • 원리는 입력되는 byte[] 배열의 전체 사이즈를 구해서 시작지점, 읽은사이즈, 전체사이즈 이렇게 3개를 이용해서 byte[] 를 원하는 크기와 포멧에 맞춰 잘라내는 것입니다.
  • 포멧 포스팅에서 보셨듯이 먼저 최초에 테이블에 변화가 일어나면 R 형태로 1byte가 들어오고 oid와 컬럼이름들이 들어옵니다. 그 뒤에 insert, update, delete 에 해당하는 I, U, D 값이 들어오게 되는데 I, U, D 에서는 oid와 컬럼값들을 알 수 있습니다.
  • 한번 R 값이 들어오고나면 그뒤에 실행되는 DML 문들은 R 없이 I, U, D 값만 받게 되는것이고 처음 들어온 R을 oid 값을 기준으로 객체로 가지고있다가 뒤에 들어오는 값의 oid와 비교하여 컬럼명과 컬럼값을 매칭해주어 반환하는 형태입니다.

업데이트: