資料庫環境:windows server 2008 Mysql 5.5
問題描述:一個遺留專案,其中有個超慢查詢,大概需要查3-4個小時左右,其中涉及到多表的union以及sub等聚合函式操作。問題在于:如果在資料庫服務器上執行這個sql是沒有問題的,能夠正常執行,就是慢而已。但是如有在另一個服務器上執行這個sql過段時間(大概2個小時左右),就會出現以下例外:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 7,875,323 milliseconds ago. The last packet sent successfully to the server was 7,875,002 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3030)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2916)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3459)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1957)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2107)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2086)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1365)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3005)
at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:440)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3003)
at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:440)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3003)
at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:440)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3003)
at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.execute(PreparedStatementProxyImpl.java:136)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:493)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:55)
at com.sun.proxy.$Proxy95.execute(Unknown Source)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:56)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:70)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:57)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:259)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:132)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:105)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:104)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:98)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:354)
at com.sun.proxy.$Proxy16.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:194)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:114)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:58)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:43)
at com.sun.proxy.$Proxy91.getSBUDay(Unknown Source)
at com.jy.quartz.SBUJob.work(SBUJob.java:38)
at com.jy.quartz.SBUJob.start(SBUJob.java:29)
at com.jy.quartz.Clarify.start(Clarify.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:311)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113)
at org.quartz.core.JobRunShell.run(JobRunShell.java:207)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:560)
Caused by: java.net.SocketException: 連接超時
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:113)
at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:160)
at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:188)
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2472)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2927)
經過以下嘗試,仍未解決:
1、查看了mysql的wait_timeout和interactive_timeout引數都是2147000,不是這2個引數導致的。
2、net_read_timeout/net_write_timeout都設定成28800,測驗后還是這個錯誤。
3、后來懷疑是服務安全狗的問題,停掉測驗還是這個錯誤
4、之后懷疑是資料庫服務器-Windows系統KeepAliveTime這個引數配置的太小,調成28800000(8小時),仍舊報此錯誤。
5、之后把客戶機服務器的KeepAliveTime引數也調成調成28800000(8小時),發現客戶端由原來的2小時報錯變成8小時報錯了。錯誤資訊相同。
6、執行show full processlist 發現,慢查詢那個連接,大概執行8000多秒之后就自動消失了。懷疑是Mysql有個限制,把超時的慢查詢強制殺死。但是翻了官方引數配置,沒發現有這種引數。
注:由于是遺留專案,要進行優化耗費巨大。所有想不優化sql的情況下解決這個問題。
各位Mysql專家,希望能給一些建議。感謝!
uj5u.com熱心網友回復:
自頂一下。。。uj5u.com熱心網友回復:
第6條補充一下,在資料庫服務器上的localhost連接不會出現自動消失的情況
uj5u.com熱心網友回復:
max_execution_time引數是否設定?jdbc的連接池設定,在使用連接時,檢查連接的可用性
uj5u.com熱心網友回復:
Mysql 5.5 沒有這個引數
uj5u.com熱心網友回復:
在客戶端上如果能正常執行, 回傳的資料量有多少?uj5u.com熱心網友回復:
很少,3000條左右,但是原始表資料量很大,差不多1千萬左右。這個sql主要是對某一天的資料做統計分析
uj5u.com熱心網友回復:
你這個運算量不小了, 1千萬的資料經過統計分析到3000條, 這其實是報表, 而不是一般的查詢。
建議你把這一塊做成報表, 每天凌晨用事件生成報表結果表, 用戶只查詢報表結果表即可, 沒有必要強求 mysql 即時處理。
uj5u.com熱心網友回復:
我的經驗是每天找個空閑時間定時處理,把處理結果可以寫到一個表中。第二天查這個表就可以了。在看下資料庫索引和搜索條件優化。uj5u.com熱心網友回復:
一千萬條就要進行分塊處理,和多開幾個執行緒。轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/73685.html
標籤:MySQL
下一篇:Mysql 復雜查詢能否可行
