List:Commits« Previous MessageNext Message »
From:mark.matthews Date:December 9 2010 5:44pm
Subject:bzr push into connector-j/branches/branch_5_1 branch (mark.matthews:1029 to
1031)
View as plain text  
 1031 mark.matthews@stripped	2010-12-09
      Added ability to include current thread name as a statement comment visible
           in MySQL's "SHOW PROCESSLIST" and Innodb deadlock diagnostics, enable with
           "includeThreadNamesAsStatementComment=true".

    modified:
      CHANGES
      src/com/mysql/jdbc/ConnectionProperties.java
      src/com/mysql/jdbc/ConnectionPropertiesImpl.java
      src/com/mysql/jdbc/LoadBalancedMySQLConnection.java
      src/com/mysql/jdbc/LocalizedErrorMessages.properties
      src/com/mysql/jdbc/MysqlIO.java
      src/com/mysql/jdbc/ReplicationConnection.java
      src/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java
 1030 mark.matthews@stripped	2010-12-09
      Added ability to include the current java thread dump in the exception message
           given for deadlock/wait lock timeout exceptions, enable with 
           "includeThreadDumpInDeadlockExceptions=true" in your JDBC url.

    modified:
      CHANGES
      src/com/mysql/jdbc/ConnectionProperties.java
      src/com/mysql/jdbc/ConnectionPropertiesImpl.java
      src/com/mysql/jdbc/LoadBalancedMySQLConnection.java
      src/com/mysql/jdbc/LocalizedErrorMessages.properties
      src/com/mysql/jdbc/MysqlIO.java
      src/com/mysql/jdbc/ReplicationConnection.java
      src/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java
      src/testsuite/simple/ConnectionTest.java
 1029 mark.matthews@stripped	2010-12-09
      Fixed an issue where statement comments set via Connection.setStatementComment() weren't represented in autoGenerateTestcaseScript=true output.

    modified:
      CHANGES
      src/com/mysql/jdbc/MysqlIO.java
      src/testsuite/regression/ConnectionRegressionTest.java
=== modified file 'CHANGES'
--- a/CHANGES	2010-12-09 14:20:23 +0000
+++ b/CHANGES	2010-12-09 17:41:00 +0000
@@ -5,6 +5,14 @@ nn-nn-11 - Version 5.1.15
    - Fixed an issue where statement comments set via Connection.setStatementComment()
      weren't represented in autoGenerateTestcaseScript=true output.
      
+   - Added ability to include the current java thread dump in the exception message
+     given for deadlock/wait lock timeout exceptions, enable with 
+     "includeThreadDumpInDeadlockExceptions=true" in your JDBC url.
+
+   - Added ability to include current thread name as a statement comment visible
+     in MySQL's "SHOW PROCESSLIST" and Innodb deadlock diagnostics, enable with
+     "includeThreadNamesAsStatementComment=true".
+     
 12-06-10 - Version 5.1.14
 
    - Fix for Bug#58728, NPE in com.mysql.jdbc.jdbc2.optional.StatementWrappe.getResultSet()

=== modified file 'src/com/mysql/jdbc/ConnectionProperties.java'
--- a/src/com/mysql/jdbc/ConnectionProperties.java	2010-08-18 18:30:33 +0000
+++ b/src/com/mysql/jdbc/ConnectionProperties.java	2010-12-09 17:41:00 +0000
@@ -1559,9 +1559,17 @@ public interface ConnectionProperties {
 	public abstract void setUtf8OutsideBmpIncludedColumnNamePattern(String regexPattern);
 	
 	public abstract boolean getIncludeInnodbStatusInDeadlockExceptions();
-	
+
 	public abstract void setIncludeInnodbStatusInDeadlockExceptions(boolean flag);
 	
+	public abstract boolean getIncludeThreadDumpInDeadlockExceptions();
+	
+	public abstract void setIncludeThreadDumpInDeadlockExceptions(boolean flag);
+	
+	public abstract boolean getIncludeThreadNamesAsStatementComment();
+	
+	public abstract void setIncludeThreadNamesAsStatementComment(boolean flag);
+	
 	public abstract boolean getBlobsAreStrings();
 
 	public abstract void setBlobsAreStrings(boolean flag);

=== modified file 'src/com/mysql/jdbc/ConnectionPropertiesImpl.java'
--- a/src/com/mysql/jdbc/ConnectionPropertiesImpl.java	2010-09-22 22:16:08 +0000
+++ b/src/com/mysql/jdbc/ConnectionPropertiesImpl.java	2010-12-09 17:41:00 +0000
@@ -978,9 +978,21 @@ public class ConnectionPropertiesImpl im
 	private BooleanConnectionProperty includeInnodbStatusInDeadlockExceptions = new BooleanConnectionProperty(
 			"includeInnodbStatusInDeadlockExceptions",
 			false,
-			"Include the output of \"SHOW ENGINE INNODB STATUS\" in exception messages when deadlock exceptions are detected?",
+			Messages.getString("ConnectionProperties.includeInnodbStatusInDeadlockExceptions"),
 			"5.0.7", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE);
 	
+	private BooleanConnectionProperty includeThreadDumpInDeadlockExceptions = new BooleanConnectionProperty(
+			"includeThreadDumpInDeadlockExceptions",
+			false,
+			Messages.getString("ConnectionProperties.includeThreadDumpInDeadlockExceptions"),
+			"5.1.15", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE);
+	
+	private BooleanConnectionProperty includeThreadNamesAsStatementComment = new BooleanConnectionProperty(
+			"includeThreadNamesAsStatementComment",
+			false,
+			Messages.getString("ConnectionProperties.includeThreadNamesAsStatementComment"),
+			"5.1.15", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE);
+	
 	private BooleanConnectionProperty ignoreNonTxTables = new BooleanConnectionProperty(
 			"ignoreNonTxTables", //$NON-NLS-1$
 			false,
@@ -4611,4 +4623,20 @@ public class ConnectionPropertiesImpl im
 		return loadBalanceAutoCommitStatementRegex.getValueAsString();
 	}
 
+	public void setIncludeThreadDumpInDeadlockExceptions(boolean flag) {
+		this.includeThreadDumpInDeadlockExceptions.setValue(flag);
+	}
+
+	public boolean getIncludeThreadDumpInDeadlockExceptions() {
+		return includeThreadDumpInDeadlockExceptions.getValueAsBoolean();
+	}
+
+	public void setIncludeThreadNamesAsStatementComment(boolean flag) {
+		this.includeThreadNamesAsStatementComment.setValue(flag);
+	}
+
+	public boolean getIncludeThreadNamesAsStatementComment() {
+		return includeThreadNamesAsStatementComment.getValueAsBoolean();
+	}
+
 }

=== modified file 'src/com/mysql/jdbc/LoadBalancedMySQLConnection.java'
--- a/src/com/mysql/jdbc/LoadBalancedMySQLConnection.java	2010-08-19 21:33:21 +0000
+++ b/src/com/mysql/jdbc/LoadBalancedMySQLConnection.java	2010-12-09 17:41:00 +0000
@@ -2513,11 +2513,23 @@ public class LoadBalancedMySQLConnection
 		
 	}
 
-	public synchronized void setTypeMap(Map map) throws SQLException {
+	public boolean getIncludeThreadDumpInDeadlockExceptions() {
+		return getActiveMySQLConnection().getIncludeThreadDumpInDeadlockExceptions();
+	}
+
+	public void setIncludeThreadDumpInDeadlockExceptions(boolean flag) {
+		getActiveMySQLConnection().setIncludeThreadDumpInDeadlockExceptions(flag);
+	}
+
+	public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
 		getActiveMySQLConnection().setTypeMap(map);
 	}
-	
-	
-	
 
+	public boolean getIncludeThreadNamesAsStatementComment() {
+		return getActiveMySQLConnection().getIncludeThreadNamesAsStatementComment();
+	}
+
+	public void setIncludeThreadNamesAsStatementComment(boolean flag) {
+		getActiveMySQLConnection().setIncludeThreadNamesAsStatementComment(flag);
+	}
 }

=== modified file 'src/com/mysql/jdbc/LocalizedErrorMessages.properties'
--- a/src/com/mysql/jdbc/LocalizedErrorMessages.properties	2010-09-22 22:16:08 +0000
+++ b/src/com/mysql/jdbc/LocalizedErrorMessages.properties	2010-12-09 17:41:00 +0000
@@ -498,6 +498,9 @@ ConnectionProperties.gatherPerfMetrics=S
 ConnectionProperties.generateSimpleParameterMetadata=Should the driver generate simplified parameter metadata for PreparedStatements when no metadata is available either because the server couldn't support preparing the statement, or server-side prepared statements are disabled?
 ConnectionProperties.holdRSOpenOverStmtClose=Should the driver close result sets on Statement.close() as required by the JDBC specification?
 ConnectionProperties.ignoreNonTxTables=Ignore non-transactional table warning for rollback? (defaults to 'false').
+ConnectionProperties.includeInnodbStatusInDeadlockExceptions=Include the output of "SHOW ENGINE INNODB STATUS" in exception messages when deadlock exceptions are detected?
+ConnectionProperties.includeThreadDumpInDeadlockExceptions=Include a current Java thread dump in exception messages when deadlock exceptions are detected?
+ConnectionProperties.includeThreadNamesAsStatementComment=Include the name of the current thread as a comment visible in "SHOW PROCESSLIST", or in Innodb deadlock dumps, useful in correlation with "includeInnodbStatusInDeadlockExceptions=true" and "includeThreadDumpInDeadlockExceptions=true". 
 ConnectionProperties.initialTimeout=If autoReconnect is enabled, the initial time to wait between re-connect attempts (in seconds, defaults to '2').
 ConnectionProperties.interactiveClient=Set the CLIENT_INTERACTIVE flag, which tells MySQL to timeout connections based on INTERACTIVE_TIMEOUT instead of WAIT_TIMEOUT
 ConnectionProperties.jdbcCompliantTruncation=Should the driver throw java.sql.DataTruncation exceptions when data is truncated as is required by the JDBC specification when connected to a server that supports warnings (MySQL 4.1.0 and newer)? This property has no effect if the server sql-mode includes STRICT_TRANS_TABLES.

=== modified file 'src/com/mysql/jdbc/MysqlIO.java'
--- a/src/com/mysql/jdbc/MysqlIO.java	2010-12-09 14:20:23 +0000
+++ b/src/com/mysql/jdbc/MysqlIO.java	2010-12-09 17:41:00 +0000
@@ -34,6 +34,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
 import java.lang.ref.SoftReference;
 import java.math.BigInteger;
 import java.net.ConnectException;
@@ -2049,7 +2052,11 @@ public class MysqlIO {
 	    	long queryEndTime = 0;
 
     		String statementComment = this.connection.getStatementComment();
-
+    		
+    		if (this.connection.getIncludeThreadNamesAsStatementComment()) {
+    			statementComment = (statementComment != null ? statementComment + ", " : "") + "java thread: " + Thread.currentThread().getName();
+    		}
+    		
 	    	if (query != null) {
 	    		// We don't know exactly how many bytes we're going to get
 	    		// from the query. Since we're dealing with Unicode, the
@@ -3588,7 +3595,7 @@ public class MysqlIO {
                     }
                 }
 
-                appendInnodbStatusInformation(xOpen, errorBuf);
+                appendDeadlockStatusInformation(xOpen, errorBuf);
 
                 if (xOpen != null && xOpen.startsWith("22")) {
                 	throw new MysqlDataTruncation(errorBuf.toString(), 0, true, false, 0, 0, errno);
@@ -3620,7 +3627,7 @@ public class MysqlIO {
         }
     }
 
-    private void appendInnodbStatusInformation(String xOpen,
+    private void appendDeadlockStatusInformation(String xOpen,
 			StringBuffer errorBuf) throws SQLException {
 		if (this.connection.getIncludeInnodbStatusInDeadlockExceptions()
 				&& xOpen != null
@@ -3655,6 +3662,69 @@ public class MysqlIO {
 				}
 			}
 		}
+		
+		if (this.connection.getIncludeThreadDumpInDeadlockExceptions()) {
+			errorBuf.append("\n\n*** Java threads running at time of deadlock ***\n\n");
+			
+			ThreadMXBean threadMBean = ManagementFactory.getThreadMXBean();
+			long[] threadIds = threadMBean.getAllThreadIds();
+
+			ThreadInfo[] threads = threadMBean.getThreadInfo(threadIds,
+					Integer.MAX_VALUE);
+			List<ThreadInfo> activeThreads = new ArrayList<ThreadInfo>();
+
+			for (ThreadInfo info : threads) {
+				if (info != null) {
+					activeThreads.add(info);
+				}
+			}
+
+			for (ThreadInfo threadInfo : activeThreads) {
+				// "Thread-60" daemon prio=1 tid=0x093569c0 nid=0x1b99 in
+				// Object.wait()
+
+				errorBuf.append('"');
+				errorBuf.append(threadInfo.getThreadName());
+				errorBuf.append("\" tid=");
+				errorBuf.append(threadInfo.getThreadId());
+				errorBuf.append(" ");
+				errorBuf.append(threadInfo.getThreadState());
+
+				if (threadInfo.getLockName() != null) {
+					errorBuf.append(" on lock=" + threadInfo.getLockName());
+				}
+				if (threadInfo.isSuspended()) {
+					errorBuf.append(" (suspended)");
+				}
+				if (threadInfo.isInNative()) {
+					errorBuf.append(" (running in native)");
+				}
+
+				StackTraceElement[] stackTrace = threadInfo.getStackTrace();
+
+				if (stackTrace.length > 0) {
+					errorBuf.append(" in ");
+					errorBuf.append(stackTrace[0].getClassName());
+					errorBuf.append(".");
+					errorBuf.append(stackTrace[0].getMethodName());
+					errorBuf.append("()");
+				}
+
+				errorBuf.append("\n");
+
+				if (threadInfo.getLockOwnerName() != null) {
+					errorBuf.append("\t owned by " + threadInfo.getLockOwnerName()
+							+ " Id=" + threadInfo.getLockOwnerId());
+					errorBuf.append("\n");
+				}
+
+				for (int j = 0; j < stackTrace.length; j++) {
+					StackTraceElement ste = stackTrace[j];
+					errorBuf.append("\tat " + ste.toString());
+					errorBuf.append("\n");
+				}
+			}
+		}
 	}
 
     /**

=== modified file 'src/com/mysql/jdbc/ReplicationConnection.java'
--- a/src/com/mysql/jdbc/ReplicationConnection.java	2010-08-18 18:30:33 +0000
+++ b/src/com/mysql/jdbc/ReplicationConnection.java	2010-12-09 17:41:00 +0000
@@ -506,15 +506,6 @@ public class ReplicationConnection imple
 
 	// For testing
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see java.sql.Connection#setTypeMap(java.util.Map)
-	 */
-	public synchronized void setTypeMap(Map arg0) throws SQLException {
-		this.currentConnection.setTypeMap(arg0);
-	}
-
 	private synchronized void switchToMasterConnection() throws SQLException {
 		swapConnections(this.masterConnection, this.slavesConnection);
 	}
@@ -2541,6 +2532,26 @@ public class ReplicationConnection imple
 		currentConnection.setLoadBalanceAutoCommitStatementThreshold(loadBalanceAutoCommitStatementThreshold);
 		
 	}
-	
 
+	public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public boolean getIncludeThreadDumpInDeadlockExceptions() {
+		return currentConnection.getIncludeThreadDumpInDeadlockExceptions();
+	}
+
+	public void setIncludeThreadDumpInDeadlockExceptions(boolean flag) {
+		currentConnection.setIncludeThreadDumpInDeadlockExceptions(flag);
+		
+	}
+
+	public boolean getIncludeThreadNamesAsStatementComment() {
+		return currentConnection.getIncludeThreadNamesAsStatementComment();
+	}
+
+	public void setIncludeThreadNamesAsStatementComment(boolean flag) {
+		currentConnection.setIncludeThreadNamesAsStatementComment(flag);
+	}
 }

=== modified file 'src/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java'
--- a/src/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java	2010-08-18 18:30:33 +0000
+++ b/src/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java	2010-12-09 17:41:00 +0000
@@ -397,21 +397,6 @@ public class ConnectionWrapper extends W
 		// compiler can't tell
 	}
 
-	/**
-	 * Passes call to method on physical connection instance. Notifies listeners
-	 * of any caught exceptions before re-throwing to client.
-	 * 
-	 * @see java.sql.Connection#setTypeMap()
-	 */
-	public void setTypeMap(java.util.Map map) throws SQLException {
-		checkClosed();
-
-		try {
-			this.mc.setTypeMap(map);
-		} catch (SQLException sqlException) {
-			checkAndFireConnectionError(sqlException);
-		}
-	}
 
 	/**
 	 * Passes call to method on physical connection instance. Notifies listeners
@@ -2740,5 +2725,30 @@ public class ConnectionWrapper extends W
 		
 	}
 
+	public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+		checkClosed();
 
+		try {
+			this.mc.setTypeMap(map);
+		} catch (SQLException sqlException) {
+			checkAndFireConnectionError(sqlException);
+		}
+	}
+
+	public boolean getIncludeThreadDumpInDeadlockExceptions() {
+		return this.mc.getIncludeThreadDumpInDeadlockExceptions();
+	}
+
+	public void setIncludeThreadDumpInDeadlockExceptions(boolean flag) {
+		this.mc.setIncludeThreadDumpInDeadlockExceptions(flag);
+		
+	}
+
+	public boolean getIncludeThreadNamesAsStatementComment() {
+		return this.mc.getIncludeThreadNamesAsStatementComment();
+	}
+
+	public void setIncludeThreadNamesAsStatementComment(boolean flag) {
+		this.mc.setIncludeThreadNamesAsStatementComment(flag);
+	}
 }
\ No newline at end of file

=== modified file 'src/testsuite/simple/ConnectionTest.java'
--- a/src/testsuite/simple/ConnectionTest.java	2010-11-29 15:52:25 +0000
+++ b/src/testsuite/simple/ConnectionTest.java	2010-12-09 16:55:32 +0000
@@ -203,6 +203,7 @@ public class ConnectionTest extends Base
 
 			Properties props = new Properties();
 			props.setProperty("includeInnodbStatusInDeadlockExceptions", "true");
+			props.setProperty("includeThreadDumpInDeadlockExceptions", "true");
 
 			Connection deadlockConn = getConnectionWithProps(props);
 			deadlockConn.setAutoCommit(false);
@@ -244,6 +245,11 @@ public class ConnectionTest extends Base
 			assertTrue(
 					"Can't find INNODB MONITOR in:\n\n" + sqlEx.getMessage(),
 					sqlEx.getMessage().indexOf("INNODB MONITOR") != -1);
+			
+			assertTrue(
+					"Can't find thread dump in:\n\n" + sqlEx.getMessage(),
+					sqlEx.getMessage().indexOf("testsuite.simple.ConnectionTest.testDeadlockDetection") != -1);
+			
 		} finally {
 			this.conn.setAutoCommit(true);
 		}


Attachment: [text/bzr-bundle] bzr/mark.matthews@oracle.com-20101209174100-kuoilq0a8u08v6d7.bundle
Thread
bzr push into connector-j/branches/branch_5_1 branch (mark.matthews:1029 to1031) mark.matthews9 Dec