package io.mycat.backend.postgresql.heartbeat; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import io.mycat.backend.PhysicalDBPool; import io.mycat.backend.PhysicalDatasource; import io.mycat.backend.heartbeat.DBHeartbeat; import io.mycat.backend.heartbeat.MySQLHeartbeat; import io.mycat.backend.postgresql.PostgreSQLDataSource; import io.mycat.server.config.node.DataHostConfig; import io.mycat.sqlengine.OneRawSQLQueryResultHandler; import io.mycat.sqlengine.SQLJob; import io.mycat.sqlengine.SQLQueryResult; import io.mycat.sqlengine.SQLQueryResultListener; import io.mycat.util.TimeUtil; public class PostgreSQLDetector implements SQLQueryResultListener<SQLQueryResult<Map<String, String>>> { private static final String[] MYSQL_SLAVE_STAUTS_COLMS = new String[] { "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" }; private PostgreSQLHeartbeat heartbeat; private final AtomicBoolean isQuit; private volatile long heartbeatTimeout; private volatile long lastSendQryTime; private volatile SQLJob sqlJob; private long lasstReveivedQryTime; public PostgreSQLDetector(PostgreSQLHeartbeat heartbeat) { this.heartbeat = heartbeat; this.isQuit = new AtomicBoolean(false); } @Override public void onResult(SQLQueryResult<Map<String, String>> result) { if (result.isSuccess()) { int balance = heartbeat.getSource().getDbPool().getBalance(); PhysicalDatasource source = heartbeat.getSource(); Map<String, String> resultResult = result.getResult(); if (source.getHostConfig().isShowSlaveSql() &&(source.getHostConfig().getSwitchType() == DataHostConfig.SYN_STATUS_SWITCH_DS || PhysicalDBPool.BALANCE_NONE!=balance ) ) { String Slave_IO_Running =resultResult!=null? resultResult.get( "Slave_IO_Running"):null; String Slave_SQL_Running = resultResult!=null?resultResult.get( "Slave_SQL_Running"):null; if (Slave_IO_Running != null && Slave_IO_Running.equals(Slave_SQL_Running) && Slave_SQL_Running.equals("Yes")) { heartbeat.setDbSynStatus(DBHeartbeat.DB_SYN_NORMAL); String Seconds_Behind_Master = resultResult.get( "Seconds_Behind_Master"); if (null != Seconds_Behind_Master && !"".equals(Seconds_Behind_Master)) { heartbeat.setSlaveBehindMaster(Integer .valueOf(Seconds_Behind_Master)); } } else if(source.isSalveOrRead()) { MySQLHeartbeat.LOGGER .warn("found MySQL master/slave Replication err !!! " + heartbeat.getSource().getConfig()); heartbeat.setDbSynStatus(DBHeartbeat.DB_SYN_ERROR); } } heartbeat.setResult(PostgreSQLHeartbeat.OK_STATUS, this, null); } else { heartbeat.setResult(PostgreSQLHeartbeat.ERROR_STATUS, this, null); } lasstReveivedQryTime = System.currentTimeMillis(); } public PostgreSQLHeartbeat getHeartbeat() { return heartbeat; } public long getHeartbeatTimeout() { return heartbeatTimeout; } public void heartbeat() { lastSendQryTime = System.currentTimeMillis(); PostgreSQLDataSource ds = heartbeat.getSource(); String databaseName = ds.getDbPool().getSchemas()[0]; String[] fetchColms = {}; if (heartbeat.getSource().getHostConfig().isShowSlaveSql()) { fetchColms = MYSQL_SLAVE_STAUTS_COLMS; } OneRawSQLQueryResultHandler resultHandler = new OneRawSQLQueryResultHandler(fetchColms, this); sqlJob = new SQLJob(heartbeat.getHeartbeatSQL(), databaseName, resultHandler, ds); sqlJob.run(); } public void close(String msg) { SQLJob curJob = sqlJob; if (curJob != null && !curJob.isFinished()) { curJob.teminate(msg); sqlJob = null; } } public boolean isHeartbeatTimeout() { return TimeUtil.currentTimeMillis() > Math.max(lastSendQryTime, lasstReveivedQryTime) + heartbeatTimeout; } public long getLastSendQryTime() { return lastSendQryTime; } public long getLasstReveivedQryTime() { return lasstReveivedQryTime; } public void quit() { } public boolean isQuit() { return isQuit.get(); } }