From 7b564cc3ffdb340f3359c70d2206995e138a151e Mon Sep 17 00:00:00 2001
From: Pierre Queinnec <pierre.queinnec@zenika.com>
Date: Tue, 27 Nov 2012 21:39:27 +0100
Subject: [PATCH] gh-47 Fix an issue with JDBC scans

JDBC scans did not instruct the driver to use a specific fetchsize,
resulting in most cases in an OOM; add support for setting fetchsize.

Also add support for disabling autocommit on the JDBC connections,
mostly because Postgres for example doesn't support setting fetchsize
without disabling autocommit.
---
 jdbc/src/main/conf/db.properties              |  1 +
 .../java/com/yahoo/ycsb/db/JdbcDBClient.java  | 25 ++++++++++++++++---
 .../yahoo/ycsb/db/JdbcDBClientConstants.java  |  8 +++++-
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/jdbc/src/main/conf/db.properties b/jdbc/src/main/conf/db.properties
index c985d57b..dac28e23 100644
--- a/jdbc/src/main/conf/db.properties
+++ b/jdbc/src/main/conf/db.properties
@@ -1,6 +1,7 @@
 # Properties file that contains database connection information.
 
 jdbc.driver=org.h2.Driver
+# jdbc.fetchsize=20
 db.url=jdbc:h2:tcp://foo.com:9092/~/h2/ycsb
 db.user=sa
 db.passwd=
diff --git a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClient.java b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClient.java
index 8d1a6a7e..c800ff0a 100644
--- a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClient.java
+++ b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClient.java
@@ -55,6 +55,7 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants {
   private ArrayList<Connection> conns;
   private boolean initialized = false;
   private Properties props;
+  private Integer jdbcFetchSize;
   private static final String DEFAULT_PROP = "";
   private ConcurrentMap<StatementType, PreparedStatement> cachedStatements;
   
@@ -176,6 +177,19 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants {
 		String passwd = props.getProperty(CONNECTION_PASSWD, DEFAULT_PROP);
 		String driver = props.getProperty(DRIVER_CLASS);
 
+      String jdbcFetchSizeStr = props.getProperty(JDBC_FETCH_SIZE);
+          if (jdbcFetchSizeStr != null) {
+          try {
+              this.jdbcFetchSize = Integer.parseInt(jdbcFetchSizeStr);
+          } catch (NumberFormatException nfe) {
+              System.err.println("Invalid JDBC fetch size specified: " + jdbcFetchSizeStr);
+              throw new DBException(nfe);
+          }
+      }
+
+      String autoCommitStr = props.getProperty(JDBC_AUTO_COMMIT, Boolean.TRUE.toString());
+      Boolean autoCommit = Boolean.parseBoolean(autoCommitStr);
+
       try {
 		  if (driver != null) {
 	      Class.forName(driver);
@@ -185,9 +199,13 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants {
           for (String url: urls.split(",")) {
               System.out.println("Adding shard node URL: " + url);
             Connection conn = DriverManager.getConnection(url, user, passwd);
-		    // Since there is no explicit commit method in the DB interface, all
-		    // operations should auto commit.
-		    conn.setAutoCommit(true);
+
+            // Since there is no explicit commit method in the DB interface, all
+            // operations should auto commit, except when explicitly told not to
+            // (this is necessary in cases such as for PostgreSQL when running a
+            // scan workload with fetchSize)
+            conn.setAutoCommit(autoCommit);
+
             shardCount++;
             conns.add(conn);
           }
@@ -289,6 +307,7 @@ public class JdbcDBClient extends DB implements JdbcDBClientConstants {
     select.append(" >= ");
     select.append("?;");
     PreparedStatement scanStatement = getShardConnectionByKey(key).prepareStatement(select.toString());
+    if (this.jdbcFetchSize != null) scanStatement.setFetchSize(this.jdbcFetchSize);
     PreparedStatement stmt = cachedStatements.putIfAbsent(scanType, scanStatement);
     if (stmt == null) return scanStatement;
     else return stmt;
diff --git a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClientConstants.java b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClientConstants.java
index 79e0525e..120cb645 100644
--- a/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClientConstants.java
+++ b/jdbc/src/main/java/com/yahoo/ycsb/db/JdbcDBClientConstants.java
@@ -35,7 +35,13 @@ public interface JdbcDBClientConstants {
   
   /** The password to use for establishing the connection. */
   public static final String CONNECTION_PASSWD = "db.passwd";
-  
+
+  /** The JDBC fetch size hinted to the driver. */
+  public static final String JDBC_FETCH_SIZE = "jdbc.fetchsize";
+
+  /** The JDBC connection auto-commit property for the driver. */
+  public static final String JDBC_AUTO_COMMIT = "jdbc.autocommit";
+
   /** The name of the property for the number of fields in a record. */
   public static final String FIELD_COUNT_PROPERTY="fieldcount";
   
-- 
GitLab