Monday, 10 June 2013

Failed to get Database connection and its hangin with OracleDriver - Linux

Issue:
          Failed to get database connection from Oracle DriverManager. Its hanging with Linux Layer.

Code for creating the connection:
  Class.forName("oracle.jdbc.driver.OracleDriver");
        String url = getJDBCUrl(credentials.getDbServer());

        final Connection con = DriverManager.getConnection(url, credentials.getUserName(), credentials.getPassword());
        con.setAutoCommit(autoCommit);


Observed Error message from the Java:
java.sql.SQLRecoverableException: IO Error: Connection reset
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:428)
        at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:536)
        at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:228)
        at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
        at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
        at java.sql.DriverManager.getConnection(Unknown Source)
        at java.sql.DriverManager.getConnection(Unknown Source)

Root cause of the issue:
          The URL string is encoded and passed by the Oracle driver for security reason. For encoding the url string they are using some random number. In Linux, the random number is generated by the Oracle Driver with the help of /dev/random.

          The /dev/random is the default one to get the random number. The is a possibility of blocking the /dev/random access when entropy pool is full. Entropy pool might be full for the heavy loaded machine.

          The interesting thing is, we can’t find the root cause of this issue easily since some time block might be there and its gets freed in short span of time. Here is the man output as per Unix for random.
          When read, the /dev/random device will only return random bytes within the estimated number of bits of noise in the entropy pool. /dev/random should be suitable for uses that need very high quality randomness such as one-time pad or key generation. When the entropy pool is empty, reads from /dev/random will block until additional environmental noise is gathered.

Fix of the issue:
          We have expose JVM to use /dev/urandom instead of /dev/random. The /dev/urandom is an non-blocking queue. Here is the man pages details as per Unix for urandam.

A read from the /dev/urandom device will not block waiting for more entropy. As a result, if there is not sufficient entropy in the entropy pool, the returned values are theoretically vulnerable to a cryptographic attack on the algorithms used by the driver. Knowledge of how to do this is not available in the current non-classified literature, but it is theoretically possible that such an attack may exist. If this is a concern in your application, use /dev/random instead.

          Add the following JVM option to fix this issue:
                        -Djava.security.egd=file:///dev/urandom

No comments:

Post a Comment