You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by re...@apache.org on 2016/01/12 12:36:24 UTC
svn commit: r1724210 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb:
RDBDocumentStore.java RDBDocumentStoreDB.java RDBDocumentStoreJDBC.java
Author: reschke
Date: Tue Jan 12 11:36:24 2016
New Revision: 1724210
URL: http://svn.apache.org/viewvc?rev=1724210&view=rev
Log:
OAK-3645: RDBDocumentStore: change DB server time detection to fetch seconds-since-the-epoch (eliminating timezone issues)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreDB.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java?rev=1724210&r1=1724209&r2=1724210&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java Tue Jan 12 11:36:24 2016
@@ -511,7 +511,7 @@ public class RDBDocumentStore implements
Connection connection = null;
try {
connection = this.ch.getROConnection();
- long result = this.db.determineServerTimeDifferenceMillis(connection, getTable(Collection.NODES));
+ long result = this.db.determineServerTimeDifferenceMillis(connection);
connection.commit();
return result;
} catch (SQLException ex) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreDB.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreDB.java?rev=1724210&r1=1724209&r2=1724210&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreDB.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreDB.java Tue Jan 12 11:36:24 2016
@@ -50,6 +50,16 @@ public enum RDBDocumentStoreDB {
public String checkVersion(DatabaseMetaData md) throws SQLException {
return RDBJDBCTools.versionCheck(md, 1, 4, description);
}
+
+ @Override
+ public String getInitializationStatement() {
+ return "create alias if not exists unix_timestamp as $$ long unix_timestamp() { return System.currentTimeMillis()/1000L; } $$;";
+ }
+
+ @Override
+ public String getCurrentTimeStampInSecondsSyntax() {
+ return "select unix_timestamp()";
+ }
},
DERBY("Apache Derby") {
@@ -59,11 +69,6 @@ public enum RDBDocumentStoreDB {
}
@Override
- public String getCurrentTimeStampInMsSyntax() {
- return "CURRENT_TIMESTAMP";
- }
-
- @Override
public boolean allowsCaseInSelect() {
return false;
}
@@ -76,6 +81,11 @@ public enum RDBDocumentStoreDB {
}
@Override
+ public String getCurrentTimeStampInSecondsSyntax() {
+ return "select extract(epoch from now())::integer";
+ }
+
+ @Override
public String getTableCreationStatement(String tableName) {
return ("create table " + tableName + " (ID varchar(512) not null primary key, MODIFIED bigint, HASBINARY smallint, DELETEDONCE smallint, MODCOUNT bigint, CMODCOUNT bigint, DSIZE bigint, DATA varchar(16384), BDATA bytea)");
}
@@ -115,6 +125,11 @@ public enum RDBDocumentStoreDB {
return RDBJDBCTools.versionCheck(md, 10, 1, description);
}
+ @Override
+ public String getCurrentTimeStampInSecondsSyntax() {
+ return "select cast (days(current_timestamp - current_timezone) - days('1970-01-01') as integer) * 86400 + midnight_seconds(current_timestamp - current_timezone) from sysibm.sysdummy1";
+ }
+
public String getTableCreationStatement(String tableName) {
return "create table " + tableName
+ " (ID varchar(512) not null, MODIFIED bigint, HASBINARY smallint, DELETEDONCE smallint, MODCOUNT bigint, CMODCOUNT bigint, DSIZE bigint, DATA varchar(16384), BDATA blob("
@@ -182,6 +197,11 @@ public enum RDBDocumentStoreDB {
}
@Override
+ public String getCurrentTimeStampInSecondsSyntax() {
+ return "select (trunc(sys_extract_utc(systimestamp)) - to_date('01/01/1970', 'MM/DD/YYYY')) * 24 * 60 * 60 + to_number(to_char(sys_extract_utc(systimestamp), 'SSSSS')) from dual";
+ }
+
+ @Override
public String getInitializationStatement() {
// see https://issues.apache.org/jira/browse/OAK-1914
// for some reason, the default for NLS_SORT is incorrect
@@ -228,6 +248,11 @@ public enum RDBDocumentStoreDB {
}
@Override
+ public String getCurrentTimeStampInSecondsSyntax() {
+ return "select unix_timestamp()";
+ }
+
+ @Override
public String getTableCreationStatement(String tableName) {
// see https://issues.apache.org/jira/browse/OAK-1913
return ("create table " + tableName + " (ID varbinary(512) not null primary key, MODIFIED bigint, HASBINARY smallint, DELETEDONCE smallint, MODCOUNT bigint, CMODCOUNT bigint, DSIZE bigint, DATA varchar(16000), BDATA longblob)");
@@ -328,8 +353,8 @@ public enum RDBDocumentStoreDB {
}
@Override
- public String getCurrentTimeStampInMsSyntax() {
- return "CURRENT_TIMESTAMP";
+ public String getCurrentTimeStampInSecondsSyntax() {
+ return "select datediff(second, dateadd(second, datediff(second, getutcdate(), getdate()), '1970-01-01'), getdate())";
}
@Override
@@ -392,10 +417,13 @@ public enum RDBDocumentStoreDB {
}
/**
- * Query syntax for current time in ms
+ * Query syntax for current time in ms since the epoch
+ *
+ * @return the query syntax or empty string when no such syntax is available
*/
- public String getCurrentTimeStampInMsSyntax() {
- return "CURRENT_TIMESTAMP(4)";
+ public String getCurrentTimeStampInSecondsSyntax() {
+ // unfortunately, we don't have a portable statement for this
+ return "";
}
/**
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java?rev=1724210&r1=1724209&r2=1724210&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java Tue Jan 12 11:36:24 2016
@@ -222,52 +222,42 @@ public class RDBDocumentStoreJDBC {
}
}
- public long determineServerTimeDifferenceMillis(Connection connection, RDBTableMetaData tmd) {
- PreparedStatement stmt = null;
- ResultSet rs = null;
- long result;
- try {
- String t = "select ";
- if (this.dbInfo.getFetchFirstSyntax() == FETCHFIRSTSYNTAX.TOP) {
- t += "TOP 1 ";
- }
- t += this.dbInfo.getCurrentTimeStampInMsSyntax() + " from " + tmd.getName();
- switch (this.dbInfo.getFetchFirstSyntax()) {
- case LIMIT:
- t += " LIMIT 1";
- break;
- case FETCHFIRST:
- t += " FETCH FIRST 1 ROWS ONLY";
- break;
- default:
- break;
- }
+ public long determineServerTimeDifferenceMillis(Connection connection) {
+ String sql = this.dbInfo.getCurrentTimeStampInSecondsSyntax();
- stmt = connection.prepareStatement(t);
- long start = System.currentTimeMillis();
- rs = stmt.executeQuery();
- if (rs.next()) {
- long roundtrip = System.currentTimeMillis() - start;
- long serverTime = rs.getTimestamp(1).getTime();
- long roundedTime = start + roundtrip / 2;
- result = roundedTime - serverTime;
- String msg = String.format("instance timestamp: %d, DB timestamp: %d, difference: %d", roundedTime, serverTime,
- result);
- if (Math.abs(result) >= 2000) {
- LOG.info(msg);
+ if (sql.isEmpty()) {
+ LOG.debug("{}: unsupported database, skipping DB server time check", this.dbInfo.toString());
+ return 0;
+ } else {
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try {
+ stmt = connection.prepareStatement(sql);
+ long start = System.currentTimeMillis();
+ rs = stmt.executeQuery();
+ if (rs.next()) {
+ long roundtrip = System.currentTimeMillis() - start;
+ long serverTimeSec = rs.getInt(1);
+ long roundedTimeSec = ((start + roundtrip / 2) + 500) / 1000;
+ long resultSec = roundedTimeSec - serverTimeSec;
+ String message = String.format("instance timestamp: %d, DB timestamp: %d, difference: %d", roundedTimeSec,
+ serverTimeSec, resultSec);
+ if (Math.abs(resultSec) >= 2) {
+ LOG.info(message);
+ } else {
+ LOG.debug(message);
+ }
+ return resultSec * 1000;
} else {
- LOG.debug(msg);
+ throw new DocumentStoreException("failed to determine server timestamp");
}
- } else {
- throw new DocumentStoreException("failed to determine server timestamp");
+ } catch (Exception ex) {
+ LOG.error("Trying to determine time difference to server", ex);
+ throw new DocumentStoreException(ex);
+ } finally {
+ closeResultSet(rs);
+ closeStatement(stmt);
}
- return result;
- } catch (Exception ex) {
- LOG.error("Trying to determine time difference to server", ex);
- throw new DocumentStoreException(ex);
- } finally {
- closeResultSet(rs);
- closeStatement(stmt);
}
}