MySQL Master/Slave replication using jdbc url
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If a Java application talks to a MySQL primary-replica setup, the JDBC URL alone does not magically solve routing, failover, or stale reads. Connector/J does support a replication-aware URL, but you still need to understand what the driver does with read-only versus read-write connections.
The key idea is simple: write traffic belongs on the primary, while read traffic can go to replicas when stale data is acceptable. The driver can help with that split, but only if the application uses it correctly.
What the Replication JDBC URL Does
Older examples often say "master/slave," but current MySQL documentation uses "source/replica" or "primary/replica." The URL pattern is still recognizable:
That tells Connector/J it is connecting to a replication topology rather than a single server. Once the driver has that context, it can choose a host based on the connection mode.
The important point is that this is not query-by-query SQL parsing. The driver does not inspect every statement and decide whether it "looks like" a read or a write. Instead, the normal signal is whether the connection is marked read-only.
Read-Only Mode Controls Routing
With a replication connection, setReadOnly(true) is the application's way to say "this unit of work can go to a replica." If the connection is not read-only, the driver should use the primary.
Here is a minimal example with plain JDBC:
For write-oriented work:
That is the core behavior to remember. If your application never marks connections read-only, the replication URL does not buy you much.
Why Many Production Systems Use Separate Pools
Even though the replication URL is valid, many teams still prefer two explicit data sources:
- one pool pinned to the primary
- one pool pinned to replicas
That design is less clever, but often more predictable. Connection pools reuse connections, and state such as read-only mode must be reset reliably between borrowers. If that reset is mishandled, a request can inherit the wrong intent from a previous one.
A split approach is easier to reason about:
Then your service layer chooses the appropriate pool based on the operation. This also makes metrics, tracing, and operational debugging clearer because the architecture matches the database topology directly.
Replication Lag Still Exists
A replication-aware URL does not fix consistency. If a user writes a row on the primary and immediately performs a read, a replica may still be behind. That means the second request can legally return old data even though the setup is "working."
This is where application requirements matter:
- if the request needs read-after-write consistency, use the primary
- if stale reads are acceptable, replicas are fine
- if failover matters, test the actual host-switch behavior in your environment
In other words, the JDBC URL is only a transport detail. Correctness still depends on your consistency rules.
A Practical Pattern
For many applications, the cleanest model is:
- send writes and strongly consistent reads to the primary
- send dashboard, search, or reporting reads to replicas
- keep those paths explicit in code
If you choose the replication URL route, verify how your framework and connection pool interact with setReadOnly. If you choose separate pools, make the read-versus-write choice explicit in the service layer. Both can work well; the second option is usually easier to debug.
Common Pitfalls
The most common mistake is assuming Connector/J will inspect SQL text and route individual statements automatically. In practice, the application usually has to communicate intent through connection state.
Another frequent problem is forgetting that pooled connections are reused. If a framework or pool does not restore read-only state correctly, one request can accidentally inherit another request's routing mode.
Teams also underestimate replication lag. A technically correct replication URL does not guarantee that a follow-up read from a replica will see the latest committed write.
Finally, do not treat failover as solved just because the URL lists multiple hosts. Test primary loss, replica unavailability, and reconnect behavior under your real driver and pool settings.
Summary
- MySQL Connector/J supports a replication-aware JDBC URL for primary-replica topologies.
- Read routing normally depends on
setReadOnly(true), not on SQL parsing. - Separate read and write pools are often simpler and safer than one smart pool.
- Replication lag still affects correctness, especially for read-after-write flows.
- Test routing and failover behavior in your actual environment instead of assuming the driver will do exactly what you want.

