MongoDB CDC
MongoDB CDC source connector
Support Those Engines
SeaTunnel Zeta
Flink
Key Features
Description
The MongoDB CDC connector allows for reading snapshot data and incremental data from MongoDB database.
Supported DataSource Info
In order to use the Mongodb CDC connector, the following dependencies are required. They can be downloaded via install-plugin.sh or from the Maven central repository.
| Datasource | Supported Versions | Dependency |
|---|---|---|
| MongoDB | universal | Download |
Availability Settings
MongoDB version: MongoDB version >= 4.0.
Cluster deployment: replica sets or sharded clusters.
Storage Engine: WiredTiger Storage Engine.
Permissions:
changeStreamandread.
// 1) Switch to the target database
use <DB_NAME>
// 2) Create role (common permissions for CDC scenarios)
db.createRole({
role: "<ROLE_NAME>",
privileges: [
{
resource: { db: "<DB_NAME>", collection: "" },
actions: [
"collStats",
"splitVector",
"listDatabases",
"find",
"listCollections",
"changeStream"
]
}
],
roles: []
})
// 3) Create user and bind read + custom role
db.createUser({
user: "<USER_NAME>",
pwd: "<PASSWORD>",
roles: [
{ role: "read", db: "<DB_NAME>" },
{ role: "<ROLE_NAME>", db: "<DB_NAME>" }
]
})
// 4) Grant additional role to user (use when user exists or additional authorization is needed)
db.grantRolesToUser("<USER_NAME>", ["<ROLE_NAME>"])
Data Type Mapping
The following table lists the field data type mapping from MongoDB BSON type to Seatunnel data type.
| MongoDB BSON Type | SeaTunnel Data Type |
|---|---|
| ObjectId | STRING |
| String | STRING |
| Boolean | BOOLEAN |
| Binary | BINARY |
| Int32 | INTEGER |
| Int64 | BIGINT |
| Double | DOUBLE |
| Decimal128 | DECIMAL |
| Date | DATE |
| Timestamp | TIMESTAMP |
| Object | ROW |
| Array | ARRAY |
For specific types in MongoDB, we use Extended JSON format to map them to Seatunnel STRING type.
| MongoDB BSON type | SeaTunnel STRING |
|---|---|
| Symbol | {"_value": {"$symbol": "12"}} |
| RegularExpression | {"_value": {"$regularExpression": {"pattern": "^9$", "options": "i"}}} |
| JavaScript | {"_value": {"$code": "function() { return 10; }"}} |
| DbPointer | {"_value": {"$dbPointer": {"$ref": "db.coll", "$id": {"$oid": "63932a00da01604af329e33c"}}}} |
Tips
1.When using the DECIMAL type in SeaTunnel, be aware that the maximum range cannot exceed 34 digits, which means you should use decimal(34, 18).
Source Options
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| hosts | String | Yes | - | The comma-separated list of hostname and port pairs of the MongoDB servers, or a standard MongoDB connection URI using mongodb:// or mongodb+srv://. For example: localhost:27017,localhost:27018 or mongodb+srv://cluster.example.net. |
| username | String | No | - | Name of the database user to be used when connecting to MongoDB. Required only when MongoDB authentication is enabled. |
| password | String | No | - | Password to be used when connecting to MongoDB. Required only when MongoDB authentication is enabled. |
| database | List | Yes | - | Database names to watch for changes. Regular expressions are supported, for example ["inventory"] or ["db.*"]. |
| collection | List | Yes | - | Collection names to watch for changes. Each value should use the fully qualified database.collection format, for example ["inventory.products", "inventory.orders"]. Regular expressions are supported. |
| schema | Config | No | - | Schema for one collection, including field names, field types, and optional primary key. For more details, see Schema Feature. |
| tables_configs | List | No | - | Schema list for multiple collections. Each item contains a schema block. The number and order of tables_configs items must match the collection list. |
| connection.options | String | No | - | Ampersand-separated MongoDB connection options. For example: replicaSet=test&connectTimeoutMS=300000. |
| batch.size | Integer | No | 1024 | Cursor batch size used when reading snapshot data. |
| poll.max.batch.size | Integer | No | 1024 | Maximum number of change stream documents to include in one poll batch. |
| poll.await.time.ms | Integer | No | 1000 | Time in milliseconds to wait before checking for new change stream results. |
| heartbeat.interval.ms | Integer | No | 0 | Time in milliseconds between heartbeat messages. Use 0 to disable heartbeat messages. |
| incremental.snapshot.chunk.size.mb | Integer | No | 64 | Chunk size, in MB, for incremental snapshot reading. |
| startup.mode | Enum | No | INITIAL | Optional startup mode for MongoDB CDC consumer. Valid values are initial, latest, and timestamp. See the Startup Mode section below. |
| startup.timestamp | Long | No | - | Start from the specified epoch timestamp in milliseconds. Only used when startup.mode is timestamp. |
| exactly_once | Boolean | No | false | Enable exactly-once semantics. Enabling this may increase memory usage during large table snapshot recovery. |
| debezium | Config | No | - | Pass-through Debezium properties used by the embedded engine. |
| common-options | No | - | Source plugin common parameters. For details, see Source Common Options. |
Startup Mode
The startup.mode option controls where the connector starts reading when a job is submitted:
initial(default): reads a snapshot of the monitored collections first, then switches to the change stream.latest: skips the snapshot entirely and starts from the latest change-stream position, so only changes made after the job starts are captured. Snapshot-related options such asincremental.snapshot.chunk.size.mbare ignored in this mode.timestamp: skips the snapshot and starts reading the change stream from the position given bystartup.timestamp.
When a job is restored from a checkpoint or savepoint, it resumes from the checkpointed change-stream position regardless of startup.mode, so a restart never falls back to a new snapshot.
For example, to consume only changes made after the job starts:
source {
MongoDB-CDC {
hosts = "mongo0:27017"
database = ["inventory"]
collection = ["inventory.products"]
startup.mode = "latest"
schema = {
fields {
"_id" : string,
"name" : string,
"description" : string,
"weight" : string
}
}
}
}
Tips
1.If the collection changes at a slow pace, it is strongly recommended to set an appropriate value greater than 0 for the heartbeat.interval.ms parameter. When we recover a Seatunnel job from a checkpoint or savepoint, the heartbeat events can push the resumeToken forward to avoid its expiration.
2.MongoDB has a limit of 16MB for a single document. Change documents include additional information, so even if the original document is not larger than 15MB, the change document may exceed the 16MB limit, resulting in the termination of the Change Stream operation.
3.It is recommended to use immutable shard keys. In MongoDB, shard keys allow modifications after transactions are enabled, but changing the shard key can cause frequent shard migrations, resulting in additional performance overhead. Additionally, modifying the shard key can also cause the Update Lookup feature to become ineffective, leading to inconsistent results in CDC (Change Data Capture) scenarios.
4.schemaandtables_configsare mutually exclusive. Useschemafor one collection andtables_configsfor multiple collections.
Change Streams
Change Stream is a new feature provided by MongoDB 3.6 for replica sets and sharded clusters that allows applications to access real-time data changes without the complexity and risk of tailing the oplog. Applications can use change streams to subscribe to all data changes on a single collection, a database, or an entire deployment, and immediately react to them.
Lookup Full Document for Update Operations is a feature provided by Change Stream which can configure the change stream to return the most current majority-committed version of the updated document. Because of this feature, we can easily collect the latest full document and convert the change log to Changelog Stream.
The format of the data captured by delete events in change streams: delete event
{
"_id": { <Resume Token> },
"operationType": "delete",
"clusterTime": <Timestamp>,
"ns": {
"db": "engineering",
"coll": "users"
},
"documentKey": {
"_id": ObjectId("599af247bb69cd89961c986d")
}
}
The fullDocument document is omitted as the document no longer exists at the time the change stream cursor sends the delete event to the client.
How to Create a MongoDB CDC Data Synchronization Jobs
CDC Data Print to Client
The following example demonstrates how to create a data synchronization job that reads cdc data from MongoDB and prints it on the local client:
env {
# You can set engine configuration here
parallelism = 1
job.mode = "STREAMING"
checkpoint.interval = 5000
}
source {
MongoDB-CDC {
hosts = "mongo0:27017"
database = ["inventory"]
collection = ["inventory.products"]
username = stuser
password = stpw
schema = {
table = "inventory.products"
primaryKey {
name = "id"
columnNames = ["_id"]
}
fields {
"_id" : string,
"name" : string,
"description" : string,
"weight" : string
}
}
}
}
sink {
Console {
parallelism = 1
}
}
CDC Data Write to MysqlDB
The following example demonstrates how to create a data synchronization job that reads cdc data from MongoDB and write to mysql database:
env {
# You can set engine configuration here
parallelism = 1
job.mode = "STREAMING"
checkpoint.interval = 5000
}
source {
MongoDB-CDC {
hosts = "mongo0:27017"
database = ["inventory"]
collection = ["inventory.products"]
username = stuser
password = stpw
schema = {
table = "inventory.products"
fields {
"_id" : string,
"name" : string,
"description" : string,
"weight" : string
}
}
}
}
sink {
jdbc {
url = "jdbc:mysql://mysql_cdc_e2e:3306"
driver = "com.mysql.cj.jdbc.Driver"
username = "st_user"
password = "seatunnel"
generate_sink_sql = true
# You need to configure both database and table
database = mongodb_cdc
table = products
primary_keys = ["_id"]
}
}
Multi-table Synchronization
The following example demonstrates how to read CDC data from multiple MongoDB collections and write each collection to the matching MySQL table. The sink table uses ${table_name}, so inventory.products and inventory.orders are routed to their own target tables.
env {
# You can set engine configuration here
parallelism = 1
job.mode = "STREAMING"
checkpoint.interval = 5000
}
source {
MongoDB-CDC {
hosts = "mongo0:27017"
database = ["inventory"]
collection = ["inventory.products", "inventory.orders"]
username = superuser
password = superpw
tables_configs = [
{
schema {
table = "inventory.products"
fields {
"_id" : string,
"name" : string,
"description" : string,
"weight" : string
}
}
},
{
schema {
table = "inventory.orders"
fields {
"_id" : string,
"order_number" : int,
"order_date" : string,
"quantity" : int,
"product_id" : string
}
}
}
]
}
}
sink {
jdbc {
url = "jdbc:mysql://mysql_cdc_e2e:3306/mongodb_cdc"
driver = "com.mysql.cj.jdbc.Driver"
username = "st_user"
password = "seatunnel"
generate_sink_sql = true
database = mongodb_cdc
table = "${table_name}"
primary_keys = ["_id"]
}
}
CDC Metadata Fields
MongoDB CDC exposes metadata fields that can be used by the Metadata transform:
| Field | Type | Description |
|---|---|---|
| database | STRING | Source database name. |
| table | STRING | Source collection name. |
| rowKind | STRING | Change type, such as insert, update, or delete. |
| ts_ms | LONG | Source event timestamp in milliseconds. |
| delay | LONG | Delay between event time and processing time in milliseconds. |
Example:
transform {
Metadata {
metadata_fields {
Database = database
Table = table
RowKind = rowKind
EventTime = ts_ms
Delay = delay
}
}
}
Format of real-time streaming data
{
_id : { <BSON Object> }, // Identifier of the open change stream, can be assigned to the 'resumeAfter' parameter for subsequent resumption of this change stream
"operationType" : "<operation>", // The type of change operation that occurred, such as: insert, delete, update, etc.
"fullDocument" : { <document> }, // The full document data involved in the change operation. This field does not exist in delete operations
"ns" : {
"db" : "<database>", // The database where the change operation occurred
"coll" : "<collection>" // The collection where the change operation occurred
},
"to" : { // These fields are displayed only when the operation type is 'rename'
"db" : "<database>", // The new database name after the change
"coll" : "<collection>" // The new collection name after the change
},
"source":{
"ts_ms":"<timestamp>", // The timestamp when the change operation occurred
"table":"<collection>" // The collection where the change operation occurred
"db":"<database>", // The database where the change operation occurred
"snapshot":"false" // Identify the current stage of data synchronization
},
"documentKey" : { "_id" : <value> }, // The _id field value of the document involved in the change operation
"updateDescription" : { // Description of the update operation
"updatedFields" : { <document> }, // The fields and values that the update operation modified
"removedFields" : [ "<field>", ... ] // The fields and values that the update operation removed
}
"clusterTime" : <Timestamp>, // The timestamp of the Oplog log entry corresponding to the change operation
"txnNumber" : <NumberLong>, // If the change operation is executed in a multi-document transaction, this field and value are displayed, representing the transaction number
"lsid" : { // Represents information related to the Session in which the transaction is located
"id" : <UUID>,
"uid" : <BinData>
}
}
Changelog
Change Log
| Change | Commit | Version |
|---|---|---|
| [Feature][Core] Add plugin directory support for each connector (#9650) | https://github.com/apache/seatunnel/commit/4beb2b9336 | 2.3.12 |
| [Feature][Connectors-v2] Optimize the size of CDC JAR Files (#9546) | https://github.com/apache/seatunnel/commit/1dd19c6823 | 2.3.12 |
| [Fix][Mongo-CDC] Fix the issue where mongo isExactlyOnce defaults to true, causing room to malfunction (#9454) | https://github.com/apache/seatunnel/commit/814b19537c | 2.3.12 |
| [Fix][Mongo-cdc] Fallback to timestamp startup mode when resume token has expired (#8754) | https://github.com/apache/seatunnel/commit/afc990d84e | 2.3.10 |
| [Improve] restruct connector common options (#8634) | https://github.com/apache/seatunnel/commit/f3499a6eeb | 2.3.10 |
| [Feature][Mongodb-CDC] Support multi-table read (#8029) | https://github.com/apache/seatunnel/commit/49cbaeb9b3 | 2.3.9 |
| [Bug][connectors-v2] fix mongodb bson convert exception (#8044) | https://github.com/apache/seatunnel/commit/b222c13f2f | 2.3.9 |
| [Feature][Core] Support cdc task ddl restore for zeta (#7463) | https://github.com/apache/seatunnel/commit/8e322281ed | 2.3.9 |
| [Feature][Transform-v2] Add metadata transform (#7899) | https://github.com/apache/seatunnel/commit/699d16552a | 2.3.9 |
| [Bug][Connector-v2] MongoDB CDC Set SeatunnelRow's tableId (#7935) | https://github.com/apache/seatunnel/commit/f3970d6188 | 2.3.9 |
| [Improve] Add conditional of start.mode with timestamp in mongo cdc option rule (#6770) | https://github.com/apache/seatunnel/commit/65ae7782c9 | 2.3.6 |
| [Fix][Connector-V2] Fix connector support SPI but without no args constructor (#6551) | https://github.com/apache/seatunnel/commit/5f3c9c36a5 | 2.3.5 |
| [Improve][CDC] Optimize memory allocation for snapshot split reading (#6281) | https://github.com/apache/seatunnel/commit/4856645837 | 2.3.5 |
| [Fix][Connector-V2] Fix mongodb cdc start up mode option values not right (#6338) | https://github.com/apache/seatunnel/commit/c07f56fbc4 | 2.3.5 |
| [Improve][Common] Introduce new error define rule (#5793) | https://github.com/apache/seatunnel/commit/9d1b2582b2 | 2.3.4 |
| [Bug][CDC] Fix state recovery error when switching a single table to multiple tables (#5784) | https://github.com/apache/seatunnel/commit/37fcff347e | 2.3.4 |
| [Improve][CDC] Clean unused code (#5785) | https://github.com/apache/seatunnel/commit/b5a66d3dbe | 2.3.4 |
| [Dependency]Bump org.apache.avro:avro (#5583) | https://github.com/apache/seatunnel/commit/bb791a6d9e | 2.3.4 |
| [Improve] Remove catalog tag for config file (#5645) | https://github.com/apache/seatunnel/commit/dc509aa080 | 2.3.4 |
| [Improve][Pom] Add junit4 to the root pom (#5611) | https://github.com/apache/seatunnel/commit/7b4f7db2a2 | 2.3.4 |
| [Feature][CDC] Support MongoDB CDC running on flink (#5644) | https://github.com/apache/seatunnel/commit/8c569b1541 | 2.3.4 |
[Improve] Refactor CatalogTable and add SeaTunnelSource::getProducedCatalogTables (#5562) | https://github.com/apache/seatunnel/commit/41173357f8 | 2.3.4 |
| [BUG][Connector-V2][Mongo-cdc] Incremental data kind error in snapshot phase (#5184) | https://github.com/apache/seatunnel/commit/ead1c5fd8c | 2.3.3 |
| [Hotfix]Fix array index anomalies caused by #5057 (#5195) | https://github.com/apache/seatunnel/commit/1c33429506 | 2.3.3 |
| [Hotfix][MongodbCDC]Refine data format to adapt to universal logic (#5162) | https://github.com/apache/seatunnel/commit/4b4b5f9640 | 2.3.3 |
| [Hotfix][Mongodb cdc] Solve startup resume token is negative (#5143) | https://github.com/apache/seatunnel/commit/e964c03dca | 2.3.3 |
| [Hotfix]Fix mongodb cdc e2e instability (#5128) | https://github.com/apache/seatunnel/commit/6f30b29662 | 2.3.3 |
| [Feature][connector-v2][mongodbcdc]Support source mongodb cdc (#4923) | https://github.com/apache/seatunnel/commit/d729fcba4c | 2.3.3 |