변경 데이터 캡처
데이터베이스에서 행 수준 변경을 스트리밍합니다. CDC 소스는 insert, update, delete를 캡처하고, 선택적으로 각 구독자에게 기존 행의 일관된 스냅샷을 먼저 넘겨준 다음, 모든 것을 드라이버 중립적인 변경 이벤트로 전달합니다. 소스는 항목 ID로 주소를 지정하며 Lua에서는 cdc 모듈로 소비합니다.
항목 kind
| Kind | 설명 |
|---|---|
db.cdc.postgres |
Postgres 논리 복제 (pgoutput 플러그인) |
db.cdc.sqlite |
db.sql.sqlite 리소스를 통해 관찰되는 SQLite 쓰기 |
두 kind 모두 동일한 Lua API, 동일한 소스 정보 레코드, 동일한 변경 이벤트 형태를 노출합니다. 다른 것은 보장 집합이며, 이는 소스마다 기능으로 게시됩니다.
Postgres 구성
- name: pg_cdc
kind: db.cdc.postgres
host: ${env:DB_HOST}
port: 5432
database: app
username: ${env:DB_USER}
password: ${env:app.secrets:db_password}
slot_name: wippy_slot
publication: wippy_pub
tables:
- public.users
- public.orders
snapshot: true
streaming: true
standby_interval: "10s"
status_interval: "10s"
lifecycle:
auto_start: true
| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
host |
string | 필수 | Postgres 호스트 |
port |
int | 필수 | Postgres 포트 (0보다 커야 함) |
database |
string | 필수 | 데이터베이스 이름 |
username |
string | 필수 | 복제 사용자 (REPLICATION 권한 필요) |
password |
string | 필수 | 비밀번호 (인라인 또는 ${env:NAME}) |
slot_name |
string | 필수 | 논리 복제 슬롯 이름 |
publication |
string | - | Postgres publication, tables가 비어 있으면 필수 |
tables |
[]string | - | 캡처할 테이블 (schema.table), 생략하면 publication의 테이블 사용 |
snapshot |
bool | false | 구독자별 스냅샷 인계에 대한 항목 기본값 |
streaming |
bool | false | 스트리밍 pgoutput 프로토콜 버전 사용 |
temporary |
bool | false | 임시 복제 슬롯 사용 (연결 해제 시 제거됨) |
failover |
bool | false | 페일오버 슬롯 모드 활성화 (temporary와 상호 배타적) |
standby_interval |
duration | 10s |
스탠바이 상태 메시지 간격 (예: 10s) |
status_interval |
duration | 30s |
서버로의 상태 업데이트 간격 |
snapshot_fetch_size |
int | 1000 | 스냅샷 배치당 가져오는 행 수 (0 이상이어야 함) |
max_transaction_changes |
int | 1000000 | 트랜잭션 하나를 디코딩하는 동안 버퍼링하는 최대 변경 수 |
max_transaction_bytes |
int | 268435456 | 트랜잭션 하나를 디코딩하는 동안 버퍼링하는 최대 논리 바이트 (256 MiB) |
max_inflight_changes |
int | 1000000 | 진행 중인 모든 트랜잭션에 걸쳐 보유하는 최대 변경 수 |
max_inflight_bytes |
int | 268435456 | 진행 중인 모든 트랜잭션에 걸쳐 보유하는 최대 논리 바이트 (256 MiB) |
subscriptions |
object | - | 구독 승인 한도, 구독 한도 참조 |
options |
map | - | 추가 커넥션 옵션 |
lifecycle |
object | - | 라이프사이클 구성 |
max_* 필드에 0을 주면 기본값이 선택됩니다. 디코더는 결코 무제한이 아닙니다. 음수 값은 거부됩니다.
자격 증명의 ${env:NAME} 자리표시자는 디코드 시점에 환경 레지스트리를 통해 해석됩니다.
SQLite 구성
SQLite 소스는 자체 데이터베이스를 열지 않습니다. 기존 db.sql.sqlite 리소스를 빌려 그 리소스의 커밋된 변경 관찰자를 구독하므로, 정확히 그 Wippy SQL 리소스를 통해 이루어진 쓰기만 캡처합니다. 다른 프로세스, 다른 커넥션, 외부 도구의 쓰기는 관찰되지 않습니다.
- name: cdcdb
kind: db.sql.sqlite
file: /var/data/app.db
lifecycle:
auto_start: true
- name: changes
kind: db.cdc.sqlite
db_resource: app:cdcdb
tables:
- users
- orders
snapshot: true
status_interval: "30s"
lifecycle:
auto_start: true
| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
db_resource |
string | 필수 | 관찰할 db.sql.sqlite 리소스의 항목 ID |
name |
string | - | 허용되지만, 소스 이름은 항상 항목 ID입니다 |
tables |
[]string | - | 캡처할 테이블, 모든 테이블을 원하면 생략 |
snapshot |
bool | false | 구독자별 스냅샷 인계에 대한 항목 기본값 |
status_interval |
duration | 30s |
상태 업데이트 간격 |
subscriptions |
object | - | 구독 승인 한도, 구독 한도 참조 |
lifecycle |
object | - | 라이프사이클 구성 |
소스는 SQL 리소스를 라이프사이클 요구사항으로 선언하므로, 슈퍼바이저가 데이터베이스를 먼저 시작하고 데이터베이스 세대가 교체되면 소스를 재시작합니다.
sqlite_preupdate_hook 빌드 태그로 빌드된 런타임이 필요합니다. 공식 빌드에는 포함되어 있습니다. 태그가 없으면 드라이버는 실패 시 차단됩니다. db.cdc.sqlite 항목을 생성하면 아무것도 캡처하지 못하는 소스를 시작하는 대신 sqlite cdc requires the sqlite_preupdate_hook build tag를 반환합니다.
구독 한도
각 소스는 제한된 수의 구독자를 승인하고 그들의 최악의 경우 백로그를 미리 예약합니다. 스냅샷 슬롯은 스냅샷이 활성화된 스트림이 닫힐 때까지 예약된 상태로 유지됩니다.
subscriptions:
max_subscriptions: 1024
max_snapshot_subscriptions: 4
max_bytes: 268435456
| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
max_subscriptions |
int | 1024 | 소스가 승인하는 동시 구독 수 |
max_snapshot_subscriptions |
int | 4 | 스냅샷이 활성화된 동시 구독 수 |
max_bytes |
int | 268435456 | 예약되는 전체 구독자 백로그 바이트 (256 MiB) |
0을 주면 기본값이 선택되고, 음수 값은 거부됩니다. 한도를 소진하면 재시도 가능한 errors.UNAVAILABLE로 구독이 실패합니다.
동작 방식
- Postgres 소스는 복제 사용자로 연결해
slot_name이 지정한 슬롯을 생성(또는 재개)합니다. SQLite 소스는db_resource를 빌려 그 리소스의 커밋된 변경 관찰자를 구독합니다. - 행 변경은
op가insert,update,delete또는truncate인 드라이버 중립적 변경 이벤트로 디코딩됩니다. - 스트림에
snapshot이 활성화된 구독자는 — 항목의snapshot필드에서든 스트림의opts.snapshot에서든 — 기존 행을op = "snapshot"이벤트로 먼저 수신한 다음, 둘 사이에 빈틈 없이 라이브 변경으로 이어집니다. - Postgres 소스는 서버가 WAL 세그먼트를 해제할 수 있도록 주기적으로 LSN을 확인 응답합니다(
standby_interval). - 소스는 자신의 항목 ID로 등록되며, Lua 코드는
cdc.stream으로 구독합니다.
기능
모든 소스는 자신이 보장하는 바를 게시하므로, 소비자는 항목 kind가 아니라 기능으로 분기합니다.
| 기능 | db.cdc.postgres |
db.cdc.sqlite |
의미 |
|---|---|---|---|
snapshot |
예 | 예 | 원자적 스냅샷/라이브 인계를 지원 |
capture_resume |
예, temporary가 아닌 경우 |
아니오 | 소스 진행 상태가 재연결을 넘어 유지됨 |
replayable |
아니오 | 아니오 | 개별 구독자가 과거 이벤트를 재생할 수 있음 |
captures_external_writes |
예 | 아니오 | 이 런타임 밖에서 이루어진 쓰기를 캡처 |
before_images |
아니오 | 예 | update와 delete에서 변경 이전 전체 행 이미지를 보장 |
coalesced |
아니오 | 예 | 트랜잭션 내에서 한 행에 반복된 쓰기가 병합되어 도착할 수 있음 |
기능 플래그는 소스 진행 상태를 설명하는 것이지 내구성 있는 전달을 뜻하지 않습니다. 어떤 드라이버도 뒤처지거나 연결이 끊긴 개별 구독자를 위해 이벤트를 재생하지 않습니다.
소스 정보
각 소스는 cdc.source와 cdc.list_sources가 반환하는 정보 레코드로 기술됩니다.
| 필드 | 타입 | 설명 |
|---|---|---|
id |
string | 항목 ID |
kind |
string | db.cdc.postgres 또는 db.cdc.sqlite |
name |
string | 소스 이름 (항목 ID) |
state |
string | unknown, starting, running, faulted 또는 stopped |
generation |
string | 현재 소스 세대, 소스가 교체되면 변경됨 |
epoch |
string | generation과 동일한 값 |
engine |
string | 엔진 이름 (sqlite) |
db_resource |
string | 관찰 대상 SQL 리소스 항목 ID (db.cdc.sqlite) |
slot |
string | 복제 슬롯 이름 (db.cdc.postgres) |
publication |
string | 구성된 경우 Postgres publication |
tables |
[]string | 구성된 경우 캡처 대상 테이블 |
streaming |
bool | 소스가 현재 실행 중인지 여부 |
failover |
bool | 페일오버 슬롯 모드 (db.cdc.postgres) |
temporary |
bool | 임시 슬롯 (db.cdc.postgres) |
snapshot |
bool | 항목 수준 스냅샷 기본값 |
faulted |
bool | 소스가 faulted 상태인지 여부 |
error |
string | 기록된 경우 마지막 소스 오류 |
admission |
object | active, snapshots, reserved_bytes, rejected |
capabilities |
object | 기능 참조 |
admission은 큐가 얼마나 찼는지가 아니라 예약 수를 셉니다. active는 승인된 구독 수, snapshots는 스냅샷이 활성화된 부분집합, reserved_bytes는 예약된 백로그 예산, rejected는 한도로 인해 거부된 누적 구독 수입니다.
권한
| 작업 | 리소스 | 설명 |
|---|---|---|
cdc.source |
소스 항목 ID | 소스 정보 읽기, cdc.list_sources도 필터링 |
cdc.subscribe |
소스 항목 ID | 변경 스트림 열기 |
CDC 권한은 데이터베이스 접근과 별개입니다. 소스는 변경 이전 이미지를 포함해 캡처된 모든 행을 노출할 수 있습니다. 스트림 필터는 전달 범위를 좁힐 뿐이며, 소스에 대한 접근을 부여하지 않습니다.
- name: cdc_reader
kind: security.policy
policy:
effect: allow
actions: [cdc.source, cdc.subscribe]
resources: [app:changes]