?? connectionimpl.java
字號:
/** The logger we're going to use */ private Log log = NULL_LOGGER; /** * If gathering metrics, what was the execution time of the longest query so * far ? */ private long longestQueryTimeMs = 0; /** Is the server configured to use lower-case table names only? */ private boolean lowerCaseTableNames = false; /** When did the master fail? */ private long masterFailTimeMillis = 0L; /** * The largest packet we can send (changed once we know what the server * supports, we get this at connection init). */ private int maxAllowedPacket = 65536; private long maximumNumberTablesAccessed = 0; /** Has the max-rows setting been changed from the default? */ private boolean maxRowsChanged = false; /** When was the last time we reported metrics? */ private long metricsLastReportedMs; private long minimumNumberTablesAccessed = Long.MAX_VALUE; /** Mutex */ private final Object mutex = new Object(); /** The JDBC URL we're using */ private String myURL = null; /** Does this connection need to be tested? */ private boolean needsPing = false; private int netBufferLength = 16384; private boolean noBackslashEscapes = false; private long numberOfPreparedExecutes = 0; private long numberOfPrepares = 0; private long numberOfQueriesIssued = 0; private long numberOfResultSetsCreated = 0; private long[] numTablesMetricsHistBreakpoints; private int[] numTablesMetricsHistCounts; private long[] oldHistBreakpoints = null; private int[] oldHistCounts = null; /** A map of currently open statements */ private Map openStatements; private LRUCache parsedCallableStatementCache; private boolean parserKnowsUnicode = false; /** The password we used */ private String password = null; private long[] perfMetricsHistBreakpoints; private int[] perfMetricsHistCounts; /** Point of origin where this Connection was created */ private Throwable pointOfOrigin; /** The port number we're connected to (defaults to 3306) */ private int port = 3306; /** * Used only when testing failover functionality for regressions, causes the * failover code to not retry the master first */ private boolean preferSlaveDuringFailover = false; /** Properties for this connection specified by user */ protected Properties props = null; /** Number of queries we've issued since the master failed */ private long queriesIssuedFailedOver = 0; /** Should we retrieve 'info' messages from the server? */ private boolean readInfoMsg = false; /** Are we in read-only mode? */ private boolean readOnly = false; /** Cache of ResultSet metadata */ protected LRUCache resultSetMetadataCache; /** The timezone of the server */ private TimeZone serverTimezoneTZ = null; /** The map of server variables that we retrieve at connection init. */ private Map serverVariables = null; private long shortestQueryTimeMs = Long.MAX_VALUE; /** A map of statements that have had setMaxRows() called on them */ private Map statementsUsingMaxRows; private double totalQueryTimeMs = 0; /** Are transactions supported by the MySQL server we are connected to? */ private boolean transactionsSupported = false; /** * The type map for UDTs (not implemented, but used by some third-party * vendors, most notably IBM WebSphere) */ private Map typeMap; /** Has ANSI_QUOTES been enabled on the server? */ private boolean useAnsiQuotes = false; /** The user we're connected as */ private String user = null; /** * Should we use server-side prepared statements? (auto-detected, but can be * disabled by user) */ private boolean useServerPreparedStmts = false; private LRUCache serverSideStatementCheckCache; private LRUCache serverSideStatementCache; private Calendar sessionCalendar; private Calendar utcCalendar; private String origHostToConnectTo; // we don't want to be able to publicly clone this... private int origPortToConnectTo; private String origDatabaseToConnectTo; private String errorMessageEncoding = "Cp1252"; // to begin with, changes after we talk to the server private boolean usePlatformCharsetConverters; /* * For testing failover scenarios */ private boolean hasTriedMasterFlag = false; /** * The comment (if any) that we'll prepend to all statements * sent to the server (to show up in "SHOW PROCESSLIST") */ private String statementComment = null; /**' * For the delegate only */ protected ConnectionImpl() { } /** * Creates a connection to a MySQL Server. * * @param hostToConnectTo * the hostname of the database server * @param portToConnectTo * the port number the server is listening on * @param info * a Properties[] list holding the user and password * @param databaseToConnectTo * the database to connect to * @param url * the URL of the connection * @param d * the Driver instantation of the connection * @exception SQLException * if a database access error occurs */ protected ConnectionImpl(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) throws SQLException { this.charsetToNumBytesMap = new HashMap(); this.connectionCreationTimeMillis = System.currentTimeMillis(); this.pointOfOrigin = new Throwable(); // Stash away for later, used to clone this connection for Statement.cancel // and Statement.setQueryTimeout(). // this.origHostToConnectTo = hostToConnectTo; this.origPortToConnectTo = portToConnectTo; this.origDatabaseToConnectTo = databaseToConnectTo; try { Blob.class.getMethod("truncate", new Class[] {Long.TYPE}); this.isRunningOnJDK13 = false; } catch (NoSuchMethodException nsme) { this.isRunningOnJDK13 = true; } this.sessionCalendar = new GregorianCalendar(); this.utcCalendar = new GregorianCalendar(); this.utcCalendar.setTimeZone(TimeZone.getTimeZone("GMT")); // // Normally, this code would be in initializeDriverProperties, // but we need to do this as early as possible, so we can start // logging to the 'correct' place as early as possible...this.log // points to 'NullLogger' for every connection at startup to avoid // NPEs and the overhead of checking for NULL at every logging call. // // We will reset this to the configured logger during properties // initialization. // this.log = LogFactory.getLogger(getLogger(), LOGGER_INSTANCE_NAME); // We store this per-connection, due to static synchronization // issues in Java's built-in TimeZone class... this.defaultTimeZone = Util.getDefaultTimeZone(); if ("GMT".equalsIgnoreCase(this.defaultTimeZone.getID())) { this.isClientTzUTC = true; } else { this.isClientTzUTC = false; } this.openStatements = new HashMap(); this.serverVariables = new HashMap(); this.hostList = new ArrayList(); if (hostToConnectTo == null) { this.host = "localhost"; this.hostList.add(this.host); } else if (hostToConnectTo.indexOf(',') != -1) { // multiple hosts separated by commas (failover) StringTokenizer hostTokenizer = new StringTokenizer( hostToConnectTo, ",", false); while (hostTokenizer.hasMoreTokens()) { this.hostList.add(hostTokenizer.nextToken().trim()); } } else { this.host = hostToConnectTo; this.hostList.add(this.host); } this.hostListSize = this.hostList.size(); this.port = portToConnectTo; if (databaseToConnectTo == null) { databaseToConnectTo = ""; } this.database = databaseToConnectTo; this.myURL = url; this.user = info.getProperty(NonRegisteringDriver.USER_PROPERTY_KEY); this.password = info .getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY); if ((this.user == null) || this.user.equals("")) { this.user = ""; } if (this.password == null) { this.password = ""; } this.props = info; initializeDriverProperties(info); try { createNewIO(false); this.dbmd = getMetaData(); } catch (SQLException ex) { cleanup(ex); // don't clobber SQL exceptions throw ex; } catch (Exception ex) { cleanup(ex); StringBuffer mesg = new StringBuffer(128); if (getParanoid()) { mesg.append("Cannot connect to MySQL server on "); mesg.append(this.host); mesg.append(":"); mesg.append(this.port); mesg.append(".\n\n"); mesg.append("Make sure that there is a MySQL server "); mesg.append("running on the machine/port you are trying "); mesg .append("to connect to and that the machine this software is " + "running on "); mesg.append("is able to connect to this host/port " + "(i.e. not firewalled). "); mesg .append("Also make sure that the server has not been started " + "with the --skip-networking "); mesg.append("flag.\n\n"); } else { mesg.append("Unable to connect to database."); } mesg.append("Underlying exception: \n\n"); mesg.append(ex.getClass().getName()); if (!getParanoid()) { mesg.append(Util.stackTraceToString(ex)); } throw SQLError.createSQLException(mesg.toString(), SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE); } } private void addToHistogram(int[] histogramCounts, long[] histogramBreakpoints, long value, int numberOfTimes, long currentLowerBound, long currentUpperBound) { if (histogramCounts == null) { createInitialHistogram(histogramBreakpoints, currentLowerBound, currentUpperBound); } for (int i = 0; i < HISTOGRAM_BUCKETS; i++) { if (histogramBreakpoints[i] >= value) { histogramCounts[i] += numberOfTimes; break; } } } private void addToPerformanceHistogram(long value, int numberOfTimes) { checkAndCreatePerformanceHistogram(); addToHistogram(this.perfMetricsHistCounts, this.perfMetricsHistBreakpoints, value, numberOfTimes, this.shortestQueryTimeMs == Long.MAX_VALUE ? 0 : this.shortestQueryTimeMs, this.longestQueryTimeMs); } private void addToTablesAccessedHistogram(long value, int numberOfTimes) { checkAndCreateTablesAccessedHistogram(); addToHistogram(this.numTablesMetricsHistCounts, this.numTablesMetricsHistBreakpoints, value, numberOfTimes, this.minimumNumberTablesAccessed == Long.MAX_VALUE ? 0 : this.minimumNumberTablesAccessed, this.maximumNumberTablesAccessed); } /** * Builds the map needed for 4.1.0 and newer servers that maps field-level * charset/collation info to a java character encoding name. * * @throws SQLException * DOCUMENT ME! */ private void buildCollationMapping() throws SQLException { if (versionMeetsMinimum(4, 1, 0)) { TreeMap sortedCollationMap = null; if (getCacheServerConfiguration()) { synchronized (serverConfigByUrl) { sortedCollationMap = (TreeMap) serverCollationByUrl .get(getURL()); } } java.sql.Statement stmt = null; java.sql.ResultSet results = null; try { if (sortedCollationMap == null) { sortedCollationMap = new TreeMap(); stmt = createStatement(); if (stmt.getMaxRows() != 0) { stmt.setMaxRows(0); } results = stmt .executeQuery("SHOW COLLATION"); while (results.next()) { String charsetName = results.getString(2); Integer charsetIndex = Constants.integerValueOf(results.getInt(3)); sortedCollationMap.put(charsetIndex, charsetName); } if (getCacheServerConfiguration()) { synchronized (serverConfigByUrl) { serverCollationByUrl.put(getURL(), sortedCollationMap); } } } // Now, merge with what we already know int highestIndex = ((Integer) sortedCollationMap.lastKey()) .intValue(); if (CharsetMapping.INDEX_TO_CHARSET.length > highestIndex) { highestIndex = CharsetMapping.INDEX_TO_CHARSET.length; } this.indexToCharsetMapping = new String[highestIndex + 1]; for (int i = 0; i < CharsetMapping.INDEX_TO_CHARSET.length; i++) { this.indexToCharsetMapping[i] = CharsetMapping.INDEX_TO_CHARSET[i]; } for (Iterator indexIter = sortedCollationMap.entrySet() .iterator(); indexIter.hasNext();) { Map.Entry indexEntry = (Map.Entry) indexIter.next(); String mysqlCharsetName = (String) indexEntry.getValue(); this.indexToCharsetMapping[((Integer) indexEntry.getKey()) .intValue()] = CharsetMapping .getJavaEncodingForMysqlEncoding(mysqlCharsetName, this); } } catch (java.sql.SQLException e) { throw e; } finally { if (results != null) { try {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -