All Products
Search
Document Center

Realtime Compute for Apache Flink:JDBC connector

Last Updated:Oct 10, 2026

Konektor JDBC membaca dari dan menulis ke database relasional—MySQL, PostgreSQL, dan Oracle—menggunakan DDL SQL standar dalam pekerjaan Flink SQL.

Jenis tabel yang didukung: tabel sumber · tabel dimensi · Tabel sink

Mode eksekusi yang didukung: mode streaming · mode batch · SQL API

Pembaruan dan penghapusan pada tabel sink: didukung

Prasyarat

Sebelum memulai, pastikan bahwa:

  • Database dan tabel tujuan sudah tersedia.

  • File JAR driver JDBC untuk database Anda tersedia untuk diunggah.

Batasan

  • Pembacaan terbatas (bounded reads): Tabel sumber JDBC merupakan sumber terbatas. Tugas selesai setelah semua baris dibaca. Untuk menangkap data perubahan secara real-time, gunakan konektor Change Data Capture (CDC) sebagai gantinya—lihat Create a MySQL CDC source table dan Create a PostgreSQL CDC source table (public preview).

  • Versi PostgreSQL: Menulis ke PostgreSQL memerlukan versi 9.5 atau lebih baru karena sink mengandalkan klausa ON CONFLICT.

  • Pengunggahan driver JDBC: Unggah file JAR driver JDBC sebagai dependensi sebelum menjalankan pekerjaan Anda. Driver umum:

    Database Group ID Artifact ID
    MySQL mysql mysql-connector-java
    Oracle com.oracle.database.jdbc ojdbc8
    PostgreSQL org.postgresql postgresql

    Untuk driver yang tidak tercantum di sini, verifikasi kompatibilitasnya sebelum digunakan.

  • Perilaku upsert MySQL: Saat menulis ke tabel sink MySQL dengan primary key, konektor mengeluarkan pernyataan INSERT INTO ... ON DUPLICATE KEY UPDATE ....

    Peringatan

    Menyisipkan baris dengan nilai indeks unik yang duplikat—bahkan jika primary key-nya berbeda—akan menimpa baris yang sudah ada di tabel fisik mana pun yang memiliki batasan indeks unik, sehingga menyebabkan kehilangan data.

Create a JDBC table

CREATE TABLE jdbc_table (
  `id`   BIGINT,
  `name` VARCHAR,
  PRIMARY KEY (id) NOT ENFORCED
) WITH (
  'connector'  = 'jdbc',
  'url'        = 'jdbc:<db-type>://<host>:<port>/<database>',
  'table-name' = '<yourTable>',
  'username'   = '<yourUsername>',
  'password'   = '<yourPassword>'
);

Connector options

General

Option Type Required Default Description
connector STRING Yes — Atur ke jdbc.
url STRING Yes — URL JDBC dari database.
table-name STRING Yes — Nama tabel yang akan dibaca atau ditulis.
username STRING No — Username database. Atur bersama dengan password. Kedua opsi menerima referensi kredensial KMS dalam bentuk secret://kms.<secret-name>.<key>.
password STRING No — Kata sandi database.
kms.endpoint STRING No — Titik akhir gateway bersama atau gateway khusus KMS, misalnya, kms.cn-hangzhou.aliyuncs.com. Lihat KMS endpoints. Diperlukan saat Anda menggunakan kredensial KMS. Untuk detail selengkapnya, lihat KMS credential management integration.
kms.akless.assume-role.role-name STRING No — Nama role RAM yang digunakan untuk membaca kredensial KMS. Role tersebut harus direferensikan terlebih dahulu di bagian Security. Diperlukan saat Anda menggunakan kredensial KMS. Untuk detail selengkapnya, lihat KMS credential management integration.
kms.ca STRING No — Path sertifikat CA dari gateway khusus KMS. Atur opsi ini ke path absolut OSS dalam format oss://flink-fullymanaged-<workspace ID>/artifacts/namespaces/<namespace name>/<file name>. Diperlukan saat Anda menggunakan gateway khusus KMS. Untuk detail selengkapnya, lihat KMS credential management integration.

Source options

Option Type Required Default Description
scan.partition.column STRING No — Kolom yang digunakan untuk membagi data menjadi partisi. Kolom harus bertipe NUMERIC atau TIMESTAMP, dan database harus mendukung perbandingan tipe tersebut dengan nilai numerik. Lihat Partitioned scan.
scan.partition.num INTEGER No — Jumlah partisi.
scan.partition.lower-bound LONG No — Nilai terkecil dari partisi pertama.
scan.partition.upper-bound LONG No — Nilai terbesar dari partisi terakhir.
scan.fetch-size INTEGER No 0 Jumlah baris yang diambil per putaran komunikasi dengan database. Jika diatur ke 0, opsi ini diabaikan.
scan.auto-commit BOOLEAN No true Mengaktifkan auto-commit untuk transaksi baca.

Sink options

Option Type Required Default Description
sink.buffer-flush.max-rows INTEGER No 100 Jumlah maksimum baris yang dibuffer sebelum flush. Atur ke 0 untuk melakukan flush setiap baris secara langsung.
sink.buffer-flush.interval DURATION No 1000 ms Waktu maksimum untuk menahan baris yang dibuffer sebelum flush. Atur ke 0 untuk melakukan flush setiap baris secara langsung.
sink.max-retries INTEGER No 3 Jumlah maksimum percobaan ulang penulisan saat terjadi kegagalan.
sink.ignore-delete BOOLEAN No false Mengabaikan pesan penghapusan alih-alih meneruskannya. Memerlukan VVR 11.4+.
sink.ignore-delete-mode STRING No ALL Mengontrol pesan penghapusan mana yang diabaikan saat sink.ignore-delete bernilai true. Memerlukan VVR 11.4+. Nilai yang valid: ALL (mengabaikan -D dan -U), REAL_DELETE (mengabaikan -D saja), UPDATE_BEFORE (mengabaikan -U saja).
Catatan

Untuk melakukan flush baris yang dibuffer secara asinkron berdasarkan timer alih-alih jumlah baris, atur sink.buffer-flush.max-rows ke 0 dan konfigurasikan sink.buffer-flush.interval sesuai interval flush yang diinginkan.

Dimension table options

Option Type Required Default Description
lookup.cache.max-rows INTEGER No — Jumlah maksimum baris dalam cache lookup. Saat cache penuh, baris yang paling jarang digunakan akan kedaluwarsa. Caching dinonaktifkan kecuali jika kedua opsi lookup.cache.max-rows dan lookup.cache.ttl diatur.
lookup.cache.ttl DURATION No — Waktu maksimum baris yang dicache tetap valid sebelum kedaluwarsa.
lookup.cache.caching-missing-key BOOLEAN No true Menyimpan hasil lookup kosong untuk menghindari kueri database berulang untuk kunci yang tidak ditemukan. Atur ke false untuk melewati penyimpanan hasil kosong.
lookup.max-retries INTEGER No 3 Jumlah maksimum percobaan ulang saat kueri database gagal.

PostgreSQL options

Option Type Required Default Description
source.extend-type.enabled BOOLEAN No false Saat true, tabel sumber dan tabel dimensi memetakan kolom JSONB dan UUID PostgreSQL ke STRING Flink. Untuk join lookup pada kolom UUID, tambahkan juga stringtype=unspecified ke URL JDBC agar PostgreSQL melakukan kueri berdasarkan tipe aktual alih-alih casting.

Key behaviors

Partitioned scan

Untuk mengaktifkan pembacaan paralel dari tabel sumber, konfigurasikan opsi scan.partition.column, scan.partition.lower-bound, dan scan.partition.upper-bound bersama dengan scan.partition.num. Kolom partisi harus bertipe numeric atau TIMESTAMP. Untuk detail cara split dihitung, lihat Partitioned Scan dalam dokumentasi Apache Flink.

Lookup cache

Secara default, setiap kueri join lookup langsung mengakses database. Aktifkan cache LRU dengan mengatur kedua opsi lookup.cache.max-rows dan lookup.cache.ttl untuk mengurangi beban database dengan sedikit kompromi pada kesegaran data.

Idempotent writes

Saat tabel sink memiliki primary key, konektor mengeluarkan pernyataan upsert spesifik database. Untuk MySQL, konektor menggunakan INSERT ... ON DUPLICATE KEY UPDATE ....

Examples

Ketiga contoh berikut menggunakan konektor blackhole atau datagen sebagai pasangan ringan agar pernyataan bersifat mandiri.

Read from a database (source table)

CREATE TEMPORARY TABLE jdbc_source (
  `id`   INT,
  `name` VARCHAR
) WITH (
  'connector'  = 'jdbc',
  'url'        = 'jdbc:mysql://localhost:3306/mydb',
  'table-name' = '<yourTable>',
  'username'   = '<yourUsername>',
  'password'   = '<yourPassword>'
);

CREATE TEMPORARY TABLE blackhole_sink (
  `id`   INT,
  `name` VARCHAR
) WITH (
  'connector' = 'blackhole'
);

INSERT INTO blackhole_sink SELECT * FROM jdbc_source;

Write to a database (sink table)

CREATE TEMPORARY TABLE datagen_source (
  `name` VARCHAR,
  `age`  INT
) WITH (
  'connector' = 'datagen'
);

CREATE TEMPORARY TABLE jdbc_sink (
  `name` VARCHAR,
  `age`  INT
) WITH (
  'connector'  = 'jdbc',
  'url'        = 'jdbc:mysql://localhost:3306/mydb',
  'table-name' = '<yourTable>',
  'username'   = '<yourUsername>',
  'password'   = '<yourPassword>'
);

INSERT INTO jdbc_sink SELECT * FROM datagen_source;

Enrich a stream with database lookups (dimension table)

CREATE TEMPORARY TABLE datagen_source (
  `id`       INT,
  `data`     BIGINT,
  `proctime` AS PROCTIME()
) WITH (
  'connector' = 'datagen'
);

CREATE TEMPORARY TABLE jdbc_dim (
  `id`   INT,
  `name` VARCHAR
) WITH (
  'connector'  = 'jdbc',
  'url'        = 'jdbc:mysql://localhost:3306/mydb',
  'table-name' = '<yourTable>',
  'username'   = '<yourUsername>',
  'password'   = '<yourPassword>'
);

CREATE TEMPORARY TABLE blackhole_sink (
  `id`   INT,
  `data` BIGINT,
  `name` VARCHAR
) WITH (
  'connector' = 'blackhole'
);

-- Look up the matching name for each stream record at processing time
INSERT INTO blackhole_sink
SELECT T.`id`, T.`data`, H.`name`
FROM datagen_source AS T
JOIN jdbc_dim FOR SYSTEM_TIME AS OF T.proctime AS H
  ON T.id = H.id;

Data type mappings

MySQL Oracle PostgreSQL Flink SQL
TINYINT — — TINYINT
SMALLINT, TINYINT UNSIGNED — SMALLINT, INT2, SMALLSERIAL, SERIAL2 SMALLINT
INT, MEDIUMINT, SMALLINT UNSIGNED — INTEGER, SERIAL INT
BIGINT, INT UNSIGNED — BIGINT, BIGSERIAL BIGINT
BIGINT UNSIGNED — — DECIMAL(20, 0)
FLOAT BINARY_FLOAT REAL, FLOAT4 FLOAT
DOUBLE, DOUBLE PRECISION BINARY_DOUBLE FLOAT8, DOUBLE PRECISION DOUBLE
NUMERIC(p, s), DECIMAL(p, s) SMALLINT, FLOAT(s), DOUBLE PRECISION, REAL, NUMBER(p, s) NUMERIC(p, s), DECIMAL(p, s) DECIMAL(p, s)
BOOLEAN, TINYINT(1) — BOOLEAN BOOLEAN
DATE DATE DATE DATE
TIME [(p)] DATE TIME [(p)] [WITHOUT TIMEZONE] TIME [(p)] [WITHOUT TIMEZONE]
DATETIME [(p)] TIMESTAMP [(p)] [WITHOUT TIMEZONE] TIMESTAMP [(p)] [WITHOUT TIMEZONE] TIMESTAMP [(p)] [WITHOUT TIMEZONE]
CHAR(n), VARCHAR(n), TEXT CHAR(n), VARCHAR(n), CLOB CHAR(n), CHARACTER(n), VARCHAR(n), CHARACTER VARYING(n), TEXT, JSONB, UUID STRING
BINARY, VARBINARY, BLOB RAW(s), BLOB BYTEA BYTES
— — ARRAY ARRAY

What's next