All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.tomitakussaari.mysqlcluscon.read_cluster.ReadClusterConnectionChecker Maven / Gradle / Ivy

Go to download

JDBC Driver for always connecting to valid server in your Mariadb/Mysql/Galera cluster

The newest version!
package com.github.tomitakussaari.mysqlcluscon.read_cluster;

import com.github.tomitakussaari.mysqlcluscon.ConnectionChecker;
import com.github.tomitakussaari.mysqlcluscon.ConnectionStatus;
import com.github.tomitakussaari.mysqlcluscon.MysclusconDriver;
import lombok.RequiredArgsConstructor;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

@RequiredArgsConstructor
public class ReadClusterConnectionChecker implements ConnectionChecker {

    private static final Logger LOGGER = Logger.getLogger(ReadClusterConnectionChecker.class.getName());
    private final int maxSlaveLag;

    public ReadClusterConnectionChecker(Map> queryParameters) {
        this(getParameter(queryParameters, "maxSlaveLag", 2));
    }

    @Override
    public ConnectionStatus connectionStatus(Connection conn, int timeoutInSeconds) {
        try {
            if (conn.isValid(timeoutInSeconds)) {
                try (Statement stmt = conn.createStatement()) {
                    stmt.setQueryTimeout(timeoutInSeconds);
                    return slaveStatus(stmt);
                }
            }
        } catch (Exception e) {
            if(e instanceof SQLException && "42000".equals(((SQLException) e).getSQLState())) {
                LOGGER.log(Level.WARNING, "Access denied (?) while checking status of connection: "+conn, e);
            } else {
                LOGGER.log(Level.FINE, "Error while checking connection status for: "+conn, e);
            }
        }
        return ConnectionStatus.DEAD;
    }

    private static Integer getParameter(Map> queryParameters, String parameter, Integer defaultValue) {
        return Integer.valueOf(queryParameters.getOrDefault(parameter, new ArrayList<>()).stream().findFirst().orElse(defaultValue.toString()));
    }

    private ConnectionStatus slaveStatus(final Statement stmt) throws SQLException {
        try (ResultSet rs = stmt.executeQuery("SHOW SLAVE STATUS")) {
            if(rs.next()) {
                final boolean running = "Yes".equals(rs.getObject("Slave_IO_Running")) && "Yes".equals(rs.getObject("Slave_SQL_Running"));
                final boolean notTooMuchBehind = rs.getInt("Seconds_Behind_Master") <= this.maxSlaveLag;
                if(running && notTooMuchBehind) {
                    return ConnectionStatus.OK;
                } else if (running) {
                    return ConnectionStatus.BEHIND;
                } else {
                    return ConnectionStatus.STOPPED;
                }
            }
            return ConnectionStatus.OK; //Assume its master and thus working fine
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy