-
-
Notifications
You must be signed in to change notification settings - Fork 875
Description
OrientDB Version: 3.1.7
Java Version: 1.8
OS: Windows
Expected behavior
OrientDb Pool should not have any connection leak.
Actual behavior
Orintdb pool size gradually decreasing, and without making network socket connections available again.
Steps to reproduce
I have configured hikari pool with orient db. Initially starting with 100 available orientdb connections for the hikari pool. According to my findings the hikari pool correctly accounts for all connections but I have noticed over time the available connections from orient connection pool gradually reduces until all available connections are lost.
The number of resources using the connections is low and I don't seem to figure out why over time the connections is lost.
I have tried multiple combination of configurations as below but to no effect :-
-Ddb.pool.min=1
-Dclient.channel.maxPool=100
-Dnetwork.lockTimeout=30000
-Dclient.channel.idleAutoClose=true
Below is the logged messages where it can been seen that hikari pool has 5 idle connections but orient resource pool is down to 85 with connections unaccounted for with no errors seen in the logs :-
[OrientDBPool connection closer] DEBUG com.zaxxer.hikari.pool.PoolBase - OrientDBPool - Closing connection com.orientechnologies.orient.jdbc.ConcurrentOrientJdbcConnection@301e18c7: (connection has passed maxLifetime) [OrientDBPool connection closer] DEBUG com.orientechnologies.common.concur.resource.OResourcePool - pool:'com.orientechnologies.common.concur.resource.OResourcePool@2a47597' acquired resource '/127.0.0.1:2424' available 85 out 15 [OrientDBPool connection adder] DEBUG com.orientechnologies.common.concur.resource.OResourcePool - pool:'com.orientechnologies.common.concur.resource.OResourcePool@2a47597' acquired resource '/127.0.0.1:2424' available 84 out 16 [OrientDBPool connection closer] DEBUG com.orientechnologies.common.concur.resource.OResourcePool - pool:'com.orientechnologies.common.concur.resource.OResourcePool@2a47597' returned resource '/127.0.0.1:2424' available 85 out 15 [OrientDBPool connection adder] DEBUG com.orientechnologies.common.concur.resource.OResourcePool - pool:'com.orientechnologies.common.concur.resource.OResourcePool@2a47597' returned resource '/127.0.0.1:2424' available 86 out 14 [OrientDBPool connection adder] DEBUG com.orientechnologies.orient.client.remote.OStorageRemote - Client connected to 127.0.0.1:2424/mining with session id=242 [OrientDBPool connection adder] DEBUG com.orientechnologies.common.concur.resource.OResourcePool - pool:'com.orientechnologies.common.concur.resource.OResourcePool@2a47597' acquired resource '/127.0.0.1:2424' available 85 out 15 [OrientDBPool connection adder] DEBUG com.orientechnologies.common.concur.resource.OResourcePool - pool:'com.orientechnologies.common.concur.resource.OResourcePool@2a47597' returned resource '/127.0.0.1:2424' available 86 out 14 [OrientDBPool connection adder] DEBUG com.zaxxer.hikari.pool.HikariPool - OrientDBPool - Added connection com.orientechnologies.orient.jdbc.ConcurrentOrientJdbcConnection@28bb907f [OrientDBPool housekeeper] DEBUG com.zaxxer.hikari.pool.HikariPool - OrientDBPool - Before cleanup stats (total=5, active=0, idle=5, waiting=0) [OrientDBPool housekeeper] DEBUG com.zaxxer.hikari.pool.HikariPool - OrientDBPool - After cleanup stats (total=5, active=0, idle=5, waiting=0)
Code for creating connection:-
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import com.orientechnologies.orient.core.config.OGlobalConfiguration;
import com.orientechnologies.orient.core.db.ODatabase;
import com.orientechnologies.orient.core.db.ODatabaseDocumentInternal;
import com.orientechnologies.orient.core.db.ODatabaseType;
import com.orientechnologies.orient.core.db.OrientDB;
import com.orientechnologies.orient.core.db.OrientDBConfig;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.util.OURLConnection;
import com.orientechnologies.orient.core.util.OURLHelper;
import com.orientechnologies.orient.jdbc.OrientJdbcDatabaseMetaData;
import com.orientechnologies.orient.jdbc.OrientJdbcPreparedStatement;
import com.orientechnologies.orient.jdbc.OrientJdbcStatement;
public class OrientJdbcConnection implements Connection {
private ODatabaseDocument database;
private String dbUrl;
private Properties info;
private OrientDB orientDB;
private boolean readOnly;
private boolean autoCommit;
private ODatabase.STATUS status;
private boolean orientDBisPrivate;
public OrientJdbcConnection(final String jdbcdDUrl, final Properties info) {
this.dbUrl = jdbcdDUrl.replace("jdbc:orient:", "");
this.info = info;
readOnly = false;
final String username = info.getProperty("user", "admin");
final String password = info.getProperty("password", "admin");
final String serverUsername = info.getProperty("serverUser", "");
final String serverPassword = info.getProperty("serverPassword", "");
OURLConnection connUrl = OURLHelper.parseNew(dbUrl);
orientDB =
new OrientDB(
connUrl.getType() + ":" + connUrl.getPath(),
serverUsername,
serverPassword,
OrientDBConfig.defaultConfig());
if (!serverUsername.isEmpty() && !serverPassword.isEmpty()) {
orientDB.createIfNotExists(
connUrl.getDbName(), connUrl.getDbType().orElse(ODatabaseType.MEMORY));
}
database = orientDB.open(connUrl.getDbName(), username, password);
orientDBisPrivate = true;
status = ODatabase.STATUS.OPEN;
}
public OrientJdbcConnection(ODatabaseDocument database, OrientDB orientDB, Properties info) {
this.database = database;
this.orientDB = orientDB;
this.info = info;
orientDBisPrivate = false;
status = ODatabase.STATUS.OPEN;
}
protected OrientDB getOrientDB() {
return orientDB;
}
public Statement createStatement() throws SQLException {
return new OrientJdbcStatement(this);
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
return new OrientJdbcPreparedStatement(this, sql);
}
public CallableStatement prepareCall(String sql) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
public String nativeSQL(String sql) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
public void clearWarnings() throws SQLException {}
public T unwrap(Class iface) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
public String getUrl() {
return dbUrl;
}
public void close() throws SQLException {
status = ODatabase.STATUS.CLOSED;
if (database != null) {
database.activateOnCurrentThread();
database.close();
database = null;
}
if (orientDBisPrivate) {
orientDB.close();
}
}
public void commit() throws SQLException {
database.commit();
}
public void rollback() throws SQLException {
database.rollback();
}
public boolean isClosed() throws SQLException {
return status == ODatabase.STATUS.CLOSED;
}
public boolean isReadOnly() throws SQLException {
return readOnly;
}
public void setReadOnly(boolean iReadOnly) throws SQLException {
readOnly = iReadOnly;
}
public boolean isValid(int timeout) throws SQLException {
return true;
}
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return null;
}
public Blob createBlob() throws SQLException {
return null;
}
public Clob createClob() throws SQLException {
return null;
}
public NClob createNClob() throws SQLException {
return null;
}
public SQLXML createSQLXML() throws SQLException {
return null;
}
public Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException {
return new OrientJdbcStatement(this);
}
public Statement createStatement(
int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return new OrientJdbcStatement(this);
}
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return null;
}
public boolean getAutoCommit() throws SQLException {
return autoCommit;
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
this.autoCommit = autoCommit;
}
public String getCatalog() throws SQLException {
return database.getName();
}
public void setCatalog(String catalog) throws SQLException {}
public Properties getClientInfo() throws SQLException {
return null;
}
public void setClientInfo(Properties properties) throws SQLClientInfoException {
// noop
}
public String getClientInfo(String name) throws SQLException {
return null;
}
public int getHoldability() throws SQLException {
return ResultSet.CLOSE_CURSORS_AT_COMMIT;
}
public void setHoldability(int holdability) throws SQLException {}
public DatabaseMetaData getMetaData() throws SQLException {
return new OrientJdbcDatabaseMetaData(this, (ODatabaseDocumentInternal) getDatabase());
}
public int getTransactionIsolation() throws SQLException {
return Connection.TRANSACTION_SERIALIZABLE;
}
public void setTransactionIsolation(int level) throws SQLException {}
public Map<String, Class<?>> getTypeMap() throws SQLException {
return null;
}
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {}
public SQLWarning getWarnings() throws SQLException {
return null;
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
throws SQLException {
throw new SQLFeatureNotSupportedException();
}
public CallableStatement prepareCall(
String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
throw new SQLFeatureNotSupportedException();
}
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return new OrientJdbcPreparedStatement(this, sql);
}
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return new OrientJdbcPreparedStatement(this, sql);
}
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return new OrientJdbcPreparedStatement(this, sql);
}
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
throws SQLException {
return new OrientJdbcPreparedStatement(this, resultSetType, resultSetConcurrency, sql);
}
public PreparedStatement prepareStatement(
String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
return new OrientJdbcPreparedStatement(
this, resultSetType, resultSetConcurrency, resultSetHoldability, sql);
}
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
public void rollback(Savepoint savepoint) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
public void setClientInfo(String name, String value) throws SQLClientInfoException {
// noop
}
public Savepoint setSavepoint() throws SQLException {
return null;
}
public Savepoint setSavepoint(String name) throws SQLException {
return null;
}
public ODatabaseDocument getDatabase() {
return database;
}
public void abort(Executor arg0) throws SQLException {}
public int getNetworkTimeout() throws SQLException {
return OGlobalConfiguration.NETWORK_SOCKET_TIMEOUT.getValueAsInteger();
}
/** No schema is supported. */
public String getSchema() throws SQLException {
return null;
}
public void setSchema(String arg0) throws SQLException {}
public void setNetworkTimeout(Executor arg0, int arg1) throws SQLException {
OGlobalConfiguration.NETWORK_SOCKET_TIMEOUT.setValue(arg1);
}
public Properties getInfo() {
return info;
}
}