Skip to content

Postgres CDC to ClickHouse

CDC from Postgres order_events into one PicoMQ stream per region, then one ClickHouse table.

Source: examples/connectors/postgres-cdc-clickhouse.

Postgres :5432order_eventspostgres sourcecdc, slot picomq_ordersrouteorders.{data.region}orders.euorders.naorders.apacclickhouse sinkpattern orders\..*unwrap_envelopefield = dataClickHouse :8123order_eventsPostgrespico metadataRustFS :9000WAL and objectsconnectors :8081state volumepicoone stream per regionkafka :9092also in the stack

Run

bash
cd examples/connectors/postgres-cdc-clickhouse
docker compose up -d
./seed.sh
./verify.sh
ServiceHostAuth
Postgres (pgweb)http://localhost:8082pico / pico
PicoMQhttp://localhost:9090
Connectors runtimehttp://localhost:8081
ClickHousehttp://localhost:8123/playpico / pico

Connectors

Source, postgres-source.toml:

toml
[[topics]]
topic = { strategy = "field", path = "data.region", template = "orders.{value}" }
create_topics = true

[plugin_config]
mode = "cdc"
tables = ["public.order_events"]
replication_slot = "picomq_orders"
capture_operations = ["INSERT", "UPDATE"]

Sink, clickhouse-sink.toml:

toml
[[topics]]
pattern = "orders\\..*"

[transforms.unwrap_envelope]
enabled = true
field = "data"

[plugin_config]
table = "order_events"
insert_format = "json_each_row"

The ClickHouse table is not created by the sink. sql/clickhouse.sql creates it at container start.

tableResult
order_eventsOne table, region as a column
order_events_{topic_segment[-1]}order_events_eu, order_events_na, order_events_apac

Verify

PostgresClickHousePicoMQ
CountsSELECT region, count(*) FROM order_events GROUP BY regionSELECT region, uniqExact(id) FROM order_events GROUP BY regionpico ls --prefix /orders.
EU rowsSELECT * FROM order_events WHERE region = 'eu'SELECT * FROM order_events WHERE region = 'eu'pico read /orders.eu

Resume

bash
docker compose kill connectors
docker compose exec postgres psql -U pico -d example -c \
  "INSERT INTO order_events (order_id, region, merchant_id, \"type\", payload)
   VALUES ('ord-eu-resume', 'eu', 'lemongrass', 'placed', '{}'::jsonb);"
docker compose start connectors
./verify.sh

The row inserted while the runtime was down arrives after restart.