通信链路故障时 Grails 重新连接到 mysql

Posted

技术标签:

【中文标题】通信链路故障时 Grails 重新连接到 mysql【英文标题】:Grails reconnect to mysql when having communications link failure 【发布时间】:2018-12-24 18:29:49 【问题描述】:

我遇到了一个困扰了很长时间的错误,仍然没有解决办法

每当我收到:

2018-07-16 11:21:27,815 [线程 4] 警告 spi.SqlExceptionHelper - SQL 错误:0,SQLState:08S01 2018-07-16 11:21:27,815 [Thread-4] 错误 spi.SqlExceptionHelper - 通信链接失败

从服务器成功收到的最后一个数据包是 197,301 毫秒前。最后一个成功发送到服务器的数据包是 197,301 毫秒前。

应用程序似乎永远不会重新连接。即使这是我的数据源配置(它是外部配置):

dataSource.dbCreate=none
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://****/*****?autoReconnect=true&failOverReadOnly=false&maxReconnects=10
dataSource.username=***
dataSource.password=******
dataSource.properties.maxActive = 50
dataSource.properties.maxIdle = 25
dataSource.properties.minIdle = 1
dataSource.properties.initialSize = 1
dataSource.properties.numTestsPerEvictionRun = 3
dataSource.properties.maxWait = 10000
dataSource.properties.testOnBorrow = true
dataSource.properties.testWhileIdle = true
dataSource.properties.testOnReturn = true
dataSource.properties.validationQuery = "select now()"
dataSource.properties.minEvictableIdleTimeMillis = 300000
dataSource.properties.timeBetweenEvictionRunsMillis = 300000

我看到了几个关于这个问题的问题,但没有什么能真正为我解决这个问题。

注意:我只是想强调这种情况很少发生,所以我不是要解决链接连接失败的问题,我只是希望在重试后重新连接时系统不会挂起(另一个 C 进程充分处理了这个问题,所以我怀疑问题出在 Hibernate 或 Grails)

这些是我的mysql配置

[client]
port=3306
socket=/data/db/mysql/mysql.sock

[mysqld]
port=3306
datadir=/data/db/mysql
socket=/data/db/mysql/mysql.sock
log-bin=/data/db/mysql/mysql-bin
binlog_format=row
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
server-id=1
max_connections=250

[mysqld_safe]
log-bin=/data/db/mysql/mysql-bin
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
server-id=1
max_connections=250

其他一些信息

    | wait_timeout                            | 28800           
    | tx_isolation                            | REPEATABLE-READ             
    | thread_handling                         | one-thread-per-connection   
    | Table_locks_immediate                   | 15090998      |
    | Table_locks_waited                      | 7453          |     
    | table_definition_cache                  | 256                                                                                      
    | table_lock_wait_timeout                 | 50                                                                                        
    | table_open_cache                        | 64                                                                                       
    | table_type                              | MyISAM     

|Bytes_received                     | 2844964922    |
| Bytes_sent                        | 5623597485    |
| Com_select                        | 15003437      |
| Com_set_option                    | 35905         |
| Handler_commit                    | 10842183      |
| Handler_delete                    | 76            |
| Handler_discover                  | 0             |
| Handler_prepare                   | 410224        |
| Handler_read_first                | 90118         |
| Handler_read_key                  | 47411397      |
| Handler_read_next                 | 6354573941    |
| Handler_read_prev                 | 2900331388    |
| Handler_read_rnd                  | 449           |
| Handler_read_rnd_next             | 2183682054024 |
| Handler_rollback                  | 44            |                                                              |                                                      

【问题讨论】:

@WilsonHauck 我试图从表格中放入最重要的信息。我只是想强调这种情况很少发生,所以我不是试图解决失败的问题,我只是希望在重试后碰巧重新连接时系统不会挂起(另一个 C 进程充分处理了这个问题,所以我怀疑问题出在 Hibernate 或 Grails) 您的服务器上有多少内存?由于您已经困扰了一段时间,您可以通过发布 A) SHOW GLOBAL STATUS 的 TEXT RESULTS 来缩短所需的问题数量;在正常运行时间 24 小时后和 B) 显示全局变量; .我怀疑在分析您发布的数据后,您将能够显着减少 handler_read_rnd_next。 ***.com/questions/21698675/… 可能会有帮助 @DanyY - 好吧,许多STATUS 值本身是无用的——不知道Uptime 获得“每秒”。 table_open_cache 看起来很低,但缺少“太低”的指标。 table_type 早就被删除了; MySQL 的version 是什么? @RickJames 这是 mysql 5.6-我无法从 mysql 检索所有信息。但正如我所说,我不想更改 MySql 的配置,我很好有这个错误(因为它每月发生一次)我只是不希望如果它发生一次整个过程就会挂起,所以我希望进程重试 【参考方案1】:

这可能是由于初始数据源池大小和您的 mysql 超时配置造成的。 我使用以下配置:

dataSource 
    pooled = true
    jmxExport = true
    dbCreate = 'validate'
    driverClassName = 'com.mysql.jdbc.Driver'
    dialect = 'org.hibernate.dialect.MySQL5InnoDBDialect'

    properties 
        jmxEnabled = true
        maxActive = 50
        maxIdle = 25
        minIdle = 5
        initialSize = 5
        minEvictableIdleTimeMillis = 60000
        timeBetweenEvictionRunsMillis = 5000
        maxWait = 10000
        maxAge = 10 * 60000
        numTestsPerEvictionRun = 3
        testOnBorrow = true
        testWhileIdle = true
        testOnReturn = false
        ignoreExceptionOnPreLoad = true
        validationQuery = "SELECT 1"
        validationQueryTimeout = 3
        jdbcInterceptors = "ConnectionState;StatementCache(max=200)"
        defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
        abandonWhenPercentageFull = 100
        removeAbandonedTimeout = 120
        removeAbandoned = true
        logAbandoned = false
        dbProperties 
            autoReconnect = true
            jdbcCompliantTruncation = false
            zeroDateTimeBehavior = 'convertToNull'
        
    

还有:

dataSource 
    url = "jdbc:mysql://localhost:3306/dbname?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&autoReconnect=true"
    username = "user"
    password = "xxxxx"
    logSql = true

【讨论】:

我知道失去连接的原因,当系统有负载时会发生这种情况......但我想要的是之后重新连接而不是一直挂起【参考方案2】:

应用程序在另一个数据库上工作正常吗? 请检查您的 mysql 设置并分享以下行中的内容:

sudo nano /etc/mysql/my.cnf
wait_timeout = 28800
interactive_timeout = 28800

我认为这可能不是 grails 问题。

【讨论】:

以上是关于通信链路故障时 Grails 重新连接到 mysql的主要内容,如果未能解决你的问题,请参考以下文章

使用 JDBC 和 MySQL 解决“通信链路故障”[重复]

通信链路故障 发送到服务器的最后一个数据包是 1 毫秒前。

MAC OS com.mysql.cj.exceptions.CJCommunicationsException:通信链路故障

通信链路故障 - 从服务器成功接收到的最后一个数据包是 [重复]

在将我的登录页面连接到 MySql 时,我收到 CommunicationException 错误

无法连接到 SOCKS 代理:连接被拒绝:连接