This feature is in and subject to change. To share feedback and/or issues, contact Support.
- Conflict resolution: As changes to a table replicate from the source to the destination cluster, there can be conflicts during some operations that the job will handle with conflict resolution. When LDR is started, the job creates a dead letter queue (DLQ) table with each replicating table. LDR will send any unresolved conflicts to the DLQ, which you should monitor as LDR continues to replicate changes between the source and destination clusters.
- Schema changes: The tables that are part of the LDR job may require schema changes, which need to be coordinated manually. There are some schema changes that are supported while LDR jobs are actively running.
- Jobs: and can operate on clusters running LDR . You may want to consider where you start and how you manage , , , and so on when you’re running LDR.
Conflict resolution
In LDR, conflicts are detected at both the and the level, which determines how LDR resolves the conflict.KV level conflicts
LDR uses last write wins (LWW) conflict resolution based on the of the replicating write. LDR will resolve conflicts by inserting the row with the latest MVCC timestamp. Conflicts at the KV level are detected when there is either:- An
UPDATEoperation replicated to the destination cluster. - A cross-cluster write occurs, which means both clusters are writing to the same key. For example, if the LDR stream attempts to apply a row to the destination cluster where the existing row on the destination was not written by the LDR stream.
SQL level conflicts
When a conflict cannot apply due to violating , for example, a schema constraint, LDR will send the row to the DLQ.Dead letter queue (DLQ)
When the LDR job starts, it will create a DLQ table with each replicating table so that unresolved conflicts can be tracked. The DLQ will contain the writes that LDR cannot apply after the retry period of a minute, which could occur if there is a unique index on the destination table (for more details, refer to ).LDR will not pause when the writes are sent to the DLQ, you must manage the DLQ manually.
incoming_row column and apply the row manually to another table with SQL statements.
As an example, for an LDR stream created on the movr.public.promo_codes table:
movr.crdb_replication.dlq_113_public_promo_codes DLQ:
Schema changes
When you start LDR on a table, the job will lock the schema, which will prevent any accidental that would cause issues for LDR. There are some supported schema changes that you can perform on a replicating table, otherwise it is necessary to stop LDR in order to coordinate the schema change.Supported schema changes
There are some supported schema changes, which you can perform during LDR without restarting the job:| Allowlist schema change | Exceptions |
|---|---|
| |
| N/A | |
| changes | N/A |
| N/A | |
|
LDR will not replicate the allowlist schema changes to the destination table. Therefore, you must perform the schema change carefully on both the source and destination cluster.
Coordinate other schema changes
To perform any other schema change on the table, use the following approach to redirect application traffic to one cluster. You’ll need to drop the existing LDR jobs, perform the schema change, and start new LDR jobs, which will require a full initial scan. If you are running LDR in a unidirectional setup, follow Coordinate schema changes for unidirectional LDR.Redirect application traffic to one cluster
You have a bidirectional LDR setup with a stream between cluster A to cluster B, and a stream between cluster B to cluster A.- Redirect your application traffic to one cluster, for example, cluster A.
-
Wait for all traffic from cluster B to replicate to cluster A. Check this is complete with:
This is complete when
replicated_timeon cluster B surpasses the time at which you redirected application traffic, which indicates that all traffic from cluster B has been replicated to cluster A. -
Drop the LDR job on both clusters. Canceling the LDR streams will remove the history retention job, which will cause the data to be garbage collected according to the setting. Use :
- Perform the schema change on cluster A.
- Drop the existing table from cluster B.
- Recreate the table and its new schema on cluster B.
-
Create new LDR streams for the table on both clusters A and B. Run
CREATE LOGICAL REPLICATION STREAMfrom the destination cluster for each stream:If your table does not contain any user-defined types or dependencies, use the syntax to start the stream for a fast, offline initial scan and automatic destination table setup.
Coordinate schema changes for unidirectional LDR
If you have a unidirectional LDR setup, you should cancel the running LDR stream and redirect all application traffic to the source cluster.-
Drop the LDR job on the destination cluster. Canceling the LDR job will remove the history retention job, which will cause the data to be garbage collected according to the setting. Use :
-
Once the job has
canceled, perform the required schema change on both the source and destination tables. -
Start a new LDR job from the destination cluster:
If your table does not contain any user-defined types or dependencies, use the syntax to start the stream for a fast, offline initial scan and automatic destination table setup.
Jobs and LDR
You can run changefeed and backup on any cluster that is involved in an LDR job. Both source and destination clusters in LDR are active, which means they can both serve production reads and writes as well as run and .Changefeeds
will emit for the writes that occur to the watched table. If the watched table is also the destination to which LDR is streaming, the changefeed will additionally emit messages for the writes from the LDR job. For example:- You create a changefeed watching the
test_tableon cluster A. - You start LDR from cluster A
test_tablereplicating to cluster B’stest_table. There are writes totest_tablehappening on both clusters. At this point, the changefeed is only emitting messages for cluster A (the source of the LDR job). - You start another LDR job from cluster B to cluster A to create bidirectional LDR. This second LDR job sends writes occurring on cluster B
test_tableinto cluster Atest_table. The changefeed on cluster A will now start emitting messages for both the writes occuring from application traffic in cluster A and also the writes incoming from LDR running from cluster B to cluster A.
Backups
can run on either cluster in an LDR stream. If you’re backing up a table that is the destination table to which an LDR job is streaming, the backup will include writes that occur to the table from the LDR job.TTL
If you’re running jobs, you may not want to include these deletes in LDR. You can ignore row-level TTL deletes in LDR with the set on the table in the source cluster. If you would like to ignore TTL deletes in LDR, you can use thediscard = ttl-deletes option in the .

