Skip to content

Commit

Permalink
[CONJ-838] replace 'slave' terminology by 'replica'
Browse files Browse the repository at this point in the history
Host description is now :
<host>[:<portnumber>]  or address=(host=<host>)[(port=<portnumber>)][(type=(master|replica)
)]

'slave' will still work as an alias for 'replica'
  • Loading branch information
rusher committed Nov 18, 2020
1 parent b8378d0 commit c26c162
Show file tree
Hide file tree
Showing 27 changed files with 234 additions and 223 deletions.

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions documentation/failover_loop.creole
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@
= Failover reconnection

//** This concern only master/slave cluster **//
//** This concern only master/replica cluster **//

On a master/slave cluster, driver will use underlying 2 connections: one to a master instance, one to a slave instance.
On a master/replica cluster, driver will use underlying 2 connections: one to a master instance, one to a replica instance.
When one of the connection fail, if driver does need it at once, it will create a new connection immediately before re-executing query if possible.\\
If the failed connection is not needed immediately, this driver will subscribe to the "failover reconnection" that will be handle in other threads.
Failover threads will attempt to create new connection to replace failing ones, so the interruption is minimal for the queries in progress.
When client asked to use a failed connection, the new connection created by failover thread will replace the failed one.

Example: after a failure on a slave connection, readonly operations are temporary executed on the master connection to avoid interruption client side.
Failover thread will then create a new slave connection that will replace the failed one. Next query will use the new slave connection.
Example: after a failure on a replica connection, readonly operations are temporary executed on the master connection to avoid interruption client side.
Failover thread will then create a new replica connection that will replace the failed one. Next query will use the new replica connection.

A pool of threads is initialized when using a master/slave configuration. The pool size evolves according to the number of connection.
A pool of threads is initialized when using a master/replica configuration. The pool size evolves according to the number of connection.

== Illustration

Here is an example of a failover on a aurora cluster of 3 instances (one master and 2 slaves).\\
Here is an example of a failover on a aurora cluster of 3 instances (one master and 2 replicas).\\
(Source code https://github.com/rusher/connector-aurora-fail-test/tree/master)

We can see 2 kinds of threads :
* Threads named "test-thread-XXX" do 130 queries "SELECT 1". 1/3 use master connection, 2/3 slave connection.
* Threads named "test-thread-XXX" do 130 queries "SELECT 1". 1/3 use master connection, 2/3 replica connection.
* Threads "mariaDb-reconnection-XXX" are created by the driver to handle failover.
==== Colour signification:
Expand Down
14 changes: 7 additions & 7 deletions documentation/use-mariadb-connector-j-driver.creole
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ jdbc:(mysql|mariadb):[replication:|failover:|sequential:|aurora:]//<hostDescript

HostDescription:
{{{
<host>[:<portnumber>] or address=(host=<host>)[(port=<portnumber>)][(type=(master|slave))]
<host>[:<portnumber>] or address=(host=<host>)[(port=<portnumber>)][(type=(master|replica))]
}}}

Host must be a DNS name or IP address. In case of ipv6 and simple host
description, the IP address must be written inside brackets. The default port
is {{{3306}}}. The default type is {{{master}}}. If {{{replication}}} failover is
set, by default the first host is master, and the others are slaves.
set, by default the first host is master, and the others are replicas.

Examples :
* {{{localhost:3306}}}
Expand All @@ -92,7 +92,7 @@ Failover was introduced in Connector/J 1.2.0.

|=sequential |Failover support for master replication cluster (for example Galera) without High availability. The hosts will be connected in the order in which they were declared.\\\\Example when using the jdbc url string "jdbc:mariadb:replication:host1,host2,host3/test" : \\When connecting, the driver will always first try host1, and if not available host2 and so on. After a host fail, the driver will reconnect according to this order. \\//since 1.3.0//|
|=failover | High availability (random picking connection initialisation) with failover support for master replication cluster (for example Galera). \\//since 1.2.0//|
|=replication | High availability (random picking connection initialisation) with failover support for master/slave replication cluster (one or multiple masters) \\//since 1.2.0//|
|=replication | High availability (random picking connection initialisation) with failover support for master/replica replication cluster (one or multiple masters) \\//since 1.2.0//|
|=aurora | High availability (random picking connection initialisation) with failover support for Amazon Aurora replication cluster \\//since 1.2.0//|

See [[failover-and-high-availability-with-mariadb-connector-j|failover description]] for more information.
Expand Down Expand Up @@ -192,13 +192,13 @@ See [[use-mariadb-connector-j-driver.creole#using-pooling|using pooling]] for mo
\\\\
== Failover/High availability URL parameters

|=autoReconnect|With basic failover: if true, will attempt to recreate connection after a failover. \\With standard failover: if true, will attempt to recreate connection even if there is a temporary solution (like using a master connection temporary until reconnect to a slave connection) \\//Default is false. Since 1.1.7//|
|=autoReconnect|With basic failover: if true, will attempt to recreate connection after a failover. \\With standard failover: if true, will attempt to recreate connection even if there is a temporary solution (like using a master connection temporary until reconnect to a replica connection) \\//Default is false. Since 1.1.7//|
|=retriesAllDown|When searching a valid host, maximum number of connection attempts before throwing an exception.\\//Default: 120 seconds. Since 1.2.0//|
|=failoverLoopRetries|When searching silently for a valid host, maximum number of connection attempts.\\This differs from the "retriesAllDown" parameter because this silent search is for example used after a disconnection of a slave connection when using the master connection\\//Default: 120. Since 1.2.0//|
|=failoverLoopRetries|When searching silently for a valid host, maximum number of connection attempts.\\This differs from the "retriesAllDown" parameter because this silent search is for example used after a disconnection of a replica connection when using the master connection\\//Default: 120. Since 1.2.0//|
|=validConnectionTimeout|With multiple hosts, after this time in seconds has elapsed, verifies that the connections haven’t been lost.\\When 0, no verification will be done. \\//Default:120 seconds. Since 1.2.0//|
|=loadBalanceBlacklistTimeout|When a connection fails, this host will be blacklisted for the "loadBalanceBlacklistTimeout" amount of time.\\When connecting to a host, the driver will try to connect to a host in the list of non-blacklisted hosts and, only if none are found, attempt blacklisted ones.\\This blacklist is shared inside the classloader.\\//Default: 50 seconds. Since 1.2.0//|
|=assureReadOnly|If true, in high availability, and switching to a read-only host, assure that this host is in read-only mode by setting the session to read-only.\\//Default to false. Since 1.3.0//|
|=allowMasterDownConnection|When using master/slave configuration, permit to create connection when master is down. If all masters are down, default connection is then a slave and Connection.isReadOnly() will then return true. \\//Default: false. Since 2.2.0//|
|=allowMasterDownConnection|When using master/replica configuration, permit to create connection when master is down. If all masters are down, default connection is then a replica and Connection.isReadOnly() will then return true. \\//Default: false. Since 2.2.0//|
|=galeraAllowedState|Usually, Connection.isValid just send an empty packet to server, and server send a small response to ensure connectivity. When this option is set, connector will ensure server that "wsrep_local_state" correspond to allowed values (separated by comma). example "4,5".\\//Default: empty. Since 2.2.5//|
\\\\

Expand Down Expand Up @@ -349,7 +349,7 @@ This reset goal is that next Connection get from pool has the same state as a ne
Reset operations :
* rollback remaining active transaction
* reuse the configured database if changed
* default connection read-only state to false (master in a masters/slaves configuration) if changed
* default connection read-only state to false (master in a masters/replicas configuration) if changed
* re-initialize socket timeout if changed
* autocommit reset to default
* Transaction Isolation if changed
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/org/mariadb/jdbc/HostAddress.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public static List<HostAddress> parse(String spec, HaMode haMode) {
if (i == 0 && arr.get(i).type == null) {
arr.get(i).type = ParameterConstant.TYPE_MASTER;
} else if (i != 0 && arr.get(i).type == null) {
arr.get(i).type = ParameterConstant.TYPE_SLAVE;
arr.get(i).type = ParameterConstant.TYPE_REPLICA;
}
}
}
Expand Down Expand Up @@ -196,10 +196,11 @@ private static HostAddress parseParameterHostAddress(String str) {
result.host = value.replace("[", "").replace("]", "");
} else if ("port".equals(key)) {
result.port = getPort(value);
} else if ("type".equals(key)
&& (value.equals(ParameterConstant.TYPE_MASTER)
|| value.equals(ParameterConstant.TYPE_SLAVE))) {
result.type = value;
} else if ("type".equals(key)) {
if (value.equals(ParameterConstant.TYPE_MASTER)
|| value.equals(ParameterConstant.TYPE_REPLICA)) {
result.type = value;
} else if ("slave".equals(value)) result.type = ParameterConstant.TYPE_REPLICA;
}
}
return result;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/mariadb/jdbc/UrlParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
* (for example localhost:3306)<br>
* <br>
* - complex :<br>
* {@code address=[(type=(master|slave))][(port=<portnumber>)](host=<host>)}<br>
* {@code address=[(type=(master|replica))][(port=<portnumber>)](host=<host>)}<br>
* <br>
* <br>
* type is by default master<br>
Expand All @@ -94,7 +94,7 @@
* <p>Some examples :<br>
* {@code jdbc:mariadb://localhost:3306/database?user=greg&password=pass}<br>
* {@code
* jdbc:mariadb://address=(type=master)(host=master1),address=(port=3307)(type=slave)(host=slave1)/database?user=greg&password=pass}
* jdbc:mariadb://address=(type=master)(host=master1),address=(port=3307)(type=replica)(host=replica1)/database?user=greg&password=pass}
* <br>
*/
public class UrlParser implements Cloneable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ public boolean isQueryRelaunchable(Method method, Object[] args) {
switch (method.getName()) {
case "executeQuery":
if (!((Boolean) args[0])) {
return true; // launched on slave connection
return true; // launched on replica connection
}
if (args[2] instanceof String) {
return ((String) args[2]).toUpperCase(Locale.ROOT).startsWith("SELECT");
Expand All @@ -385,7 +385,7 @@ public boolean isQueryRelaunchable(Method method, Object[] args) {
break;
case "executePreparedQuery":
if (!((Boolean) args[0])) {
return true; // launched on slave connection
return true; // launched on replica connection
}
ServerPrepareResult serverPrepareResult = (ServerPrepareResult) args[1];
return (serverPrepareResult.getSql()).toUpperCase(Locale.ROOT).startsWith("SELECT");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@
import org.mariadb.jdbc.internal.protocol.Protocol;
import org.mariadb.jdbc.internal.util.pool.GlobalStateInfo;

public abstract class AbstractMastersSlavesListener extends AbstractMastersListener {
public abstract class AbstractMastersReplicasListener extends AbstractMastersListener {

private static final Logger logger = LoggerFactory.getLogger(AbstractMastersSlavesListener.class);
private static final Logger logger =
LoggerFactory.getLogger(AbstractMastersReplicasListener.class);
// These reference are when failloop reconnect failing connection, but lock is already held by
// another thread (query in progress), so switching the connection wait for the query to be
// finish.
Expand All @@ -77,13 +78,13 @@ public abstract class AbstractMastersSlavesListener extends AbstractMastersListe
/* =========================== Failover variables ========================================= */
private volatile long secondaryHostFailNanos = 0;

protected AbstractMastersSlavesListener(UrlParser urlParser, final GlobalStateInfo globalInfo) {
protected AbstractMastersReplicasListener(UrlParser urlParser, final GlobalStateInfo globalInfo) {
super(urlParser, globalInfo);
this.secondaryHostFail.set(true);
}

/**
* Handle failover on master or slave connection.
* Handle failover on master or replica connection.
*
* @param method called method
* @param args methods parameters
Expand Down Expand Up @@ -168,7 +169,7 @@ public long getSecondaryHostFailNanos() {
}

/**
* Set slave connection lost variables.
* Set replica connection lost variables.
*
* @return true if fail wasn't seen before
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,14 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
if (!mustBeOnMaster
&& serverPrepareResult.getUnProxiedProtocol().isMasterConnection()
&& !this.listener.hasHostFail()) {
// PrepareStatement was to be executed on slave, but since a failover was running on
// master connection. Slave connection is up
// again, so has to be re-prepared on slave
// PrepareStatement was to be executed on replica, but since a failover was running on
// master connection. Replica connection is up
// again, so has to be re-prepared on replica
try {
logger.trace(
"re-prepare query \"{}\" on slave (was " + "temporary on master since failover)",
"re-prepare query \"{}\" on replica (was temporary on master since failover)",
serverPrepareResult.getSql());
this.listener.rePrepareOnSlave(serverPrepareResult, false);
this.listener.rePrepareOnReplica(serverPrepareResult, false);
} catch (SQLException q) {
// error during re-prepare, will do executed on master.
}
Expand Down Expand Up @@ -285,7 +285,7 @@ && hasToHandleFailover((SQLException) e.getTargetException())) {
throw e;
}
case METHOD_RESET:
// listener will report reset on any active connections (Master/slave)
// listener will report reset on any active connections (Master/replica)
listener.reset();
return null;
default:
Expand Down Expand Up @@ -326,7 +326,7 @@ private Object executeInvocation(Method method, Object[] args, boolean isSecondE

// error is "The MariaDB server is running with the %s option so it cannot execute this
// statement"
// checking that server was master has not been demote to slave without resetting
// checking that server was master has not been demote to replica without resetting
// connections
if (queryException.getErrorCode() == 1290
&& !isSecondExecution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ void prolog(long maxRows, MariaDbConnection connection, MariaDbStatement stateme

boolean checkMasterStatus(SearchFilter searchFilter);

void rePrepareOnSlave(ServerPrepareResult oldServerPrepareResult, boolean mustExecuteOnMaster)
void rePrepareOnReplica(ServerPrepareResult oldServerPrepareResult, boolean mustExecuteOnMaster)
throws SQLException;

void reset() throws SQLException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
import org.mariadb.jdbc.internal.util.dao.ReconnectDuringTransactionException;
import org.mariadb.jdbc.internal.util.pool.GlobalStateInfo;

public class AuroraListener extends MastersSlavesListener {
public class AuroraListener extends MastersReplicasListener {

private static final Logger logger = Logger.getLogger(AuroraListener.class.getName());
private final Pattern auroraDnsPattern =
Expand Down Expand Up @@ -158,15 +158,15 @@ public void reconnectFailedConnection(SearchFilter initialSearchFilter) throws S
if (!searchFilter.isInitialConnection()
&& (isExplicitClosed()
|| (searchFilter.isFineIfFoundOnlyMaster() && !isMasterHostFail())
|| searchFilter.isFineIfFoundOnlySlave() && !isSecondaryHostFail())) {
|| searchFilter.isFineIfFoundOnlyReplica() && !isSecondaryHostFail())) {
return;
}

if (!searchFilter.isFailoverLoop()) {
try {
checkWaitingConnection();
if ((searchFilter.isFineIfFoundOnlyMaster() && !isMasterHostFail())
|| searchFilter.isFineIfFoundOnlySlave() && !isSecondaryHostFail()) {
|| searchFilter.isFineIfFoundOnlyReplica() && !isSecondaryHostFail()) {
return;
}
} catch (ReconnectDuringTransactionException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public void initializeConnection() throws SQLException {
*/
public void preExecute() throws SQLException {
lastQueryNanos = System.nanoTime();
// if connection is closed or failed on slave
// if connection is closed or failed on replica
if (this.currentProtocol != null && this.currentProtocol.isClosed()) {
preAutoReconnect();
}
Expand Down Expand Up @@ -338,9 +338,9 @@ public boolean checkMasterStatus(SearchFilter searchFilter) {
return false;
}

public void rePrepareOnSlave(
ServerPrepareResult oldServerPrepareResult, boolean mustExecuteOnSlave) {
// no slave
public void rePrepareOnReplica(
ServerPrepareResult oldServerPrepareResult, boolean mustExecuteOnReplica) {
// no replica
}

/**
Expand Down
Loading

0 comments on commit c26c162

Please sign in to comment.